diff --git a/package.json b/package.json index b41d108..87c2ae5 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "sass": "^1.44.0", "sass-loader": "^10", "vue": "^3.0.0", + "vue-debounce": "^3.0.2", "vue-router": "^4.0.0-0", "webpack": "^5.64.4" }, diff --git a/server/app/api.py b/server/app/api.py index d6dfe0b..ff12b8b 100644 --- a/server/app/api.py +++ b/server/app/api.py @@ -2,15 +2,14 @@ from app.models import Artists from app.helpers import ( all_songs_instance, - convert_one_to_json, getTags, - convert_to_json, remove_duplicates, save_image, - # isValidFile, create_config_dir, extract_thumb, run_fast_scandir, + convert_one_to_json, + convert_to_json, home_dir, app_dir, ) @@ -32,8 +31,27 @@ artist_instance = Artists() img_path = "http://127.0.0.1:8900/images/thumbnails/" +all_the_f_music = [] + + +def getAllSongs(): + all_the_f_music.clear() + all_the_f_music.extend(all_songs_instance.get_all_songs()) + + def main_whatever(): create_config_dir() + # populate() + getAllSongs() + + +@bp.route('/') +def adutsfsd(): + for song in all_the_f_music: + print(os.path.join(home_dir, song['filepath'])) + os.chmod(os.path.join(home_dir, song['filepath']), 0o755) + + return "Done" main_whatever() @@ -50,16 +68,10 @@ def search_by_title(): artists = [] s = all_songs_instance.find_song_by_title(query) - songs = convert_to_json(s) - al = all_songs_instance.search_songs_by_album(query) - songs_by_album = convert_to_json(al) - ar = all_songs_instance.search_songs_by_artist(query) - songs_by_artists = convert_to_json(ar) - - for song in songs_by_album: + for song in al: album_obj = { "name": song["album"], "artists": song["artists"], @@ -67,16 +79,16 @@ def search_by_title(): if album_obj not in albums: albums.append(album_obj) - - for album in albums: - try: - image = convert_one_to_json(all_songs_instance.get_song_by_album(album['name'], album['artists']))['image'] - except: - image: None - - album['image'] = image - for song in songs_by_artists: + for album in albums: + # try: + # image = convert_one_to_json(all_songs_instance.get_song_by_album(album['name'], album['artists']))['image'] + # except: + # image: None + + album['image'] = "image" + + for song in ar: a = song["artists"].split(', ') for artist in a: @@ -89,7 +101,7 @@ def search_by_title(): if artist_obj not in artists: artists.append(artist_obj) - return {'songs': remove_duplicates(songs), 'albums': albums, 'artists': artists} + return {'songs': remove_duplicates(s), 'albums': albums, 'artists': artists} @bp.route('/populate') @@ -107,10 +119,9 @@ def populate(): for file in files: file_in_db_obj = all_songs_instance.find_song_by_path(file) - song_obj = convert_one_to_json(file_in_db_obj) try: - image = song_obj['image'] + image = file_in_db_obj['image'] if not os.path.exists(os.path.join(app_dir, 'images', 'thumbnails', image)): extract_thumb(file) @@ -126,15 +137,16 @@ def populate(): bar.next() bar.finish() + return {'msg': 'updated everything'} + @bp.route("/folder/artists") def get_folder_artists(): dir = request.args.get('dir') songs = all_songs_instance.find_songs_by_folder(dir) - songs_array = convert_to_json(songs) - without_duplicates = remove_duplicates(songs_array) + without_duplicates = remove_duplicates(songs) artists = [] @@ -152,7 +164,7 @@ def get_folder_artists(): artist_obj = artist_instance.find_artists_by_name(artist) if artist_obj != []: - final_artists.append(convert_to_json(artist_obj)) + final_artists.append(artist_obj) return {'artists': final_artists} @@ -160,12 +172,10 @@ def get_folder_artists(): @bp.route("/populate/images") def populate_images(): all_songs = all_songs_instance.get_all_songs() - songs_array = convert_to_json(all_songs) - remove_duplicates(songs_array) artists = [] - for song in songs_array: + for song in all_songs: this_artists = song['artists'].split(', ') for artist in this_artists: @@ -204,9 +214,8 @@ def populate_images(): bar.finish() artists_in_db = artist_instance.get_all_artists() - artists_in_db_array = convert_to_json(artists_in_db) - return {'sample': artists_in_db_array[:25]} + return {'sample': artists_in_db[:25]} @bp.route("/artist/") @@ -215,13 +224,11 @@ def getArtistData(artist: str): print(artist) artist = urllib.parse.unquote(artist) artist_obj = artist_instance.get_artists_by_name(artist) - artist_obj_json = convert_to_json(artist_obj) def getArtistSongs(): songs = all_songs_instance.find_songs_by_artist(artist) - songs_array = convert_to_json(songs) - return songs_array + return songs artist_songs = getArtistSongs() songs = remove_duplicates(artist_songs) @@ -231,12 +238,11 @@ def getArtistData(artist: str): albums_with_count = [] albums = all_songs_instance.find_songs_by_album_artist(artist) - albums_array = convert_to_json(albums) for song in songs: song['artists'] = song['artists'].split(', ') - for song in albums_array: + for song in albums: if song['album'] not in artist_albums: artist_albums.append(song['album']) @@ -259,7 +265,7 @@ def getArtistData(artist: str): return albums_with_count - return {'artist': artist_obj_json, 'songs': songs, 'albums': getArtistAlbums()} + return {'artist': artist_obj, 'songs': songs, 'albums': getArtistAlbums()} @bp.route("/f/") @@ -295,17 +301,23 @@ def getFolderTree(folder: str = None): # if not file: # getTags(entry.path) - songs_array = all_songs_instance.find_songs_by_folder( - req_dir) + # songs_array = all_songs_instance.find_songs_by_folder( + # req_dir) - songs = convert_to_json(songs_array) + songs = [] + + for x in all_the_f_music: + if x['folder'] == req_dir: + songs.append(x) for song in songs: - song['artists'] = song['artists'].split(', ') - song['image'] = img_path + song['image'] + try: + song['artists'] = song['artists'].split(', ') or None + except: + pass - song['type']['name'] = "folder" - song['type']['id'] = req_dir + print(song['image']) + song['image'] = img_path + song['image'] return {"files": remove_duplicates(songs), "folders": sorted(folders, key=lambda i: i['name'])} @@ -313,11 +325,10 @@ def getFolderTree(folder: str = None): @bp.route('/qwerty') def populateArtists(): all_songs = all_songs_instance.get_all_songs() - songs = convert_to_json(all_songs) artists = [] - for song in songs: + for song in all_songs: artist = song['artists'].split(', ') for a in artist: @@ -336,11 +347,10 @@ def populateArtists(): @bp.route('/albums') def getAlbums(): s = all_songs_instance.get_all_songs() - ss = convert_to_json(s) albums = [] - for song in ss: + for song in s: al_obj = { "name": song['album'], "artist": song['artists'] @@ -358,19 +368,18 @@ def getAlbumSongs(query: str): artist = query.split('::')[1].replace('|', '/') songs = all_songs_instance.find_songs_by_album(album, artist) - songs_array = remove_duplicates(convert_to_json(songs)) print(artist) - for song in songs_array: + for song in songs: song['artists'] = song['artists'].split(', ') song['image'] = img_path + song['image'] album_obj = { "name": album, - "count": len(songs_array), - "duration": sum(song['length'] for song in songs_array), - "image": songs_array[0]['image'], - "artist": songs_array[0]['album_artist'] + "count": len(songs), + "duration": sum(song['length'] for song in songs), + "image": songs[0]['image'], + "artist": songs[0]['album_artist'] } - return {'songs': songs_array, 'info': album_obj} + return {'songs': songs, 'info': album_obj} diff --git a/server/app/helpers.py b/server/app/helpers.py index 537a08b..bffe70e 100644 --- a/server/app/helpers.py +++ b/server/app/helpers.py @@ -23,7 +23,6 @@ music_dirs = os.environ.get("music_dirs") home_dir = os.path.expanduser('~') + "/" app_dir = home_dir + '/.musicx' - PORT = os.environ.get("PORT") @@ -204,11 +203,14 @@ def get_folders(): def remove_duplicates(array): song_num = 0 - while song_num < len(array): + while song_num < len(array) -1: for index, song in enumerate(array): - if array[song_num]["title"] == song["title"] and array[song_num]["album"] == song["album"] and array[song_num]["artists"] == song["artists"] and index != song_num: - array.remove(song) - + try: + + if array[song_num]["title"] == song["title"] and array[song_num]["album"] == song["album"] and array[song_num]["artists"] == song["artists"] and index != song_num: + array.remove(song) + except: + print('whe') song_num += 1 return array diff --git a/server/app/models.py b/server/app/models.py index d154f07..6b9c2c1 100644 --- a/server/app/models.py +++ b/server/app/models.py @@ -1,5 +1,25 @@ import pymongo -from bson import ObjectId +import json +from bson import ObjectId, json_util + + +def convert_one_to_json(song): + json_song = json.dumps(song, default=json_util.default) + loaded_song = json.loads(json_song) + + return loaded_song + + +def convert_to_json(array): + songs = [] + + for song in array: + json_song = json.dumps(song, default=json_util.default) + loaded_song = json.loads(json_song) + + songs.append(loaded_song) + + return songs class Mongo: @@ -40,41 +60,58 @@ class AllSongs(Mongo): {'filepath': song_obj['filepath']}, {"$set": song_obj}, upsert=True) def get_all_songs(self): - return self.collection.find().limit(25) - + return convert_to_json(self.collection.find()) + def get_song_by_id(self, file_id): - return self.collection.find_one({'_id': ObjectId(file_id)}) + song = self.collection.find_one({'_id': ObjectId(file_id)}) + return convert_one_to_json(song) def get_song_by_album(self, name, artist): - return self.collection.find_one({'album': name, 'album_artist': artist}) + song = self.collection.find_one( + {'album': name, 'album_artist': artist}) + return convert_one_to_json(song) def search_songs_by_album(self, query): - return self.collection.find({'album': {'$regex': query, '$options': 'i'}}) + songs = self.collection.find( + {'album': {'$regex': query, '$options': 'i'}}) + return convert_to_json(songs) def search_songs_by_artist(self, query): - return self.collection.find({'artists': {'$regex': query, '$options': 'i'}}) + songs = self.collection.find( + {'artists': {'$regex': query, '$options': 'i'}}) + return convert_to_json(songs) def find_song_by_title(self, query): self.collection.create_index([('title', pymongo.TEXT)]) - return self.collection.find({'title': {'$regex': query, '$options': 'i'}}) + song = self.collection.find( + {'title': {'$regex': query, '$options': 'i'}}) + return convert_to_json(song) def find_songs_by_album(self, name, artist): - return self.collection.find({'album': name, 'album_artist': artist}) + songs = self.collection.find({'album': name, 'album_artist': artist}) + return convert_to_json(songs) def find_songs_by_folder(self, query): - return self.collection.find({'folder': query}).sort('title', pymongo.ASCENDING) + songs = self.collection.find({'folder': query}).sort( + 'title', pymongo.ASCENDING) + return convert_to_json(songs) def find_songs_by_folder_og(self, query): - return self.collection.find({'folder': query}) + songs = self.collection.find({'folder': query}) + return convert_to_json(songs) def find_songs_by_artist(self, query): - return self.collection.find({'artists': query}) + songs = self.collection.find({'artists': query}) + return convert_to_json(songs) def find_songs_by_album_artist(self, query): - return self.collection.find({'album_artist': {'$regex': query, '$options': 'i'}}) + songs = self.collection.find( + {'album_artist': {'$regex': query, '$options': 'i'}}) + return convert_to_json(songs) def find_song_by_path(self, path): - return self.collection.find_one({'filepath': path}) + song = self.collection.find_one({'filepath': path}) + return convert_one_to_json(song) def remove_song_by_filepath(self, filepath): try: diff --git a/src/components/FolderView/SearchBox.vue b/src/components/FolderView/SearchBox.vue index 3f528f6..d01f064 100644 --- a/src/components/FolderView/SearchBox.vue +++ b/src/components/FolderView/SearchBox.vue @@ -28,7 +28,7 @@ export default { } .folder-top .fname { - width: 50%; + // width: 50%; display: flex; align-items: center; diff --git a/src/components/FolderView/SongList.vue b/src/components/FolderView/SongList.vue index 8543021..315682e 100644 --- a/src/components/FolderView/SongList.vue +++ b/src/components/FolderView/SongList.vue @@ -137,6 +137,12 @@ export default { const current = ref(perks.current); const search_query = ref(state.search_query); + function doNothing(e) { + e.preventDefault(); + e.stopImmediatePropagation(); + console.log('mwathani') + } + const searchSongs = computed(() => { const songs = []; @@ -162,6 +168,7 @@ export default { return { searchSongs, + doNothing, songtitle, songTitleWidth, minWidth, diff --git a/src/components/RightSideBar/NowPlaying.vue b/src/components/RightSideBar/NowPlaying.vue index bb4d787..f796a94 100644 --- a/src/components/RightSideBar/NowPlaying.vue +++ b/src/components/RightSideBar/NowPlaying.vue @@ -97,14 +97,7 @@ export default { height: 14rem; margin-top: .5rem; padding: 0.5rem; - background: rgb(14, 14, 14); - background: linear-gradient( - 326deg, - rgb(0, 0, 0) 0%, - rgb(10, 10, 10) 13%, - rgba(0, 0, 0, 1) 43%, - rgba(0, 0, 0, 1) 100% - ); + background: $card-dark; display: grid; grid-template-rows: 3fr 1fr; @@ -137,17 +130,12 @@ export default { width: 100%; height: 0.25rem; cursor: pointer; - background: #1488cc; /* fallback for old browsers */ - background: -webkit-linear-gradient( - to right, - #1488cc, - #2b32b2 - ); /* Chrome 10-25, Safari 5.1-6 */ + background: #1488cc; background: linear-gradient( to right, #1488cc, #2b32b2 - ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + ); } input::-webkit-slider-thumb { diff --git a/src/components/Search.vue b/src/components/Search.vue index 33b0145..d16c3d9 100644 --- a/src/components/Search.vue +++ b/src/components/Search.vue @@ -88,21 +88,13 @@ import { ref, toRefs } from "@vue/reactivity"; import { onMounted, watch } from "@vue/runtime-core"; import state from "@/composables/state.js"; +import searchMusic from "../composables/searchMusic.js"; +// import useDebounce from "../composed/useDebounce.js"; export default { emits: ["expandSearch", "collapseSearch"], props: ["search"], setup(props, { emit }) { - const songs = [ - { - title: "Thriller", - artist: "Michael jackson", - }, - { - title: "We are the world", - artist: "Michael jackson", - }, - ]; const options = [ { title: "🎵 Track", @@ -129,6 +121,7 @@ export default { icon: "🈁", }, ]; + const loading = ref(state.loading); const searchComponent = ref(null); const filters = ref(state.filters); @@ -183,6 +176,8 @@ export default { } watch(query, (new_query) => { + searchMusic(new_query); + state.search_query.value = new_query; if (new_query !== "") { counter = 0; @@ -206,13 +201,14 @@ export default { }); }); + return { addFilter, activateMagicFlag, removeMagicFlag, removeFilter, removeLastFilter, - songs, + songs: state.search_tracks, albums, artists, query, @@ -222,6 +218,7 @@ export default { filters, searchComponent, loading, + searchMusic, }; }, }; @@ -363,7 +360,7 @@ export default { .right-search .heading { font-size: small; position: relative; - padding: $small; + padding: $small; display: flex; align-items: center; diff --git a/src/composables/perks.js b/src/composables/perks.js index a310fc6..bf53d19 100644 --- a/src/composables/perks.js +++ b/src/composables/perks.js @@ -3,6 +3,7 @@ import { watch } from "@vue/runtime-core"; import media from "./mediaNotification.js"; import state from "./state.js"; +import playAudio from "./playAudio.js"; const current = ref(state.current); @@ -107,14 +108,27 @@ setTimeout(() => { }); }, 1000); -window.addEventListener("keyup", (e) => { - e.preventDefault(); +var _key_down_fired = false; + +window.addEventListener("keydown", (e) => { - if (e.ctrlKey && e.code == "KeyF") { + if (e.code == "Space" && !_key_down_fired) { + e.stopImmediatePropagation(); + e.preventDefault(); + playAudio.playPause(); + _key_down_fired = true; + + } else if (e.ctrlKey && e.code == "KeyF") { console.log('Ctrl F') } }); +window.addEventListener("keyup", (e) => { + if (e.code == "Space") { + _key_down_fired = false; + } +}) + export default { putCommas, readQueue, diff --git a/src/composables/searchMusic.js b/src/composables/searchMusic.js new file mode 100644 index 0000000..786ccbf --- /dev/null +++ b/src/composables/searchMusic.js @@ -0,0 +1,16 @@ +import state from "./state.js"; + +const base_url = "http://127.0.0.1:9876/search?q="; + +async function search(query) { + const url = base_url + query; + + const res = await fetch(url); + const json = await res.json(); + state.search_tracks.value = json.songs; + state.search_albums.value = json.albums; + state.search_artists.value = json.artists; + console.log(state.search); +} + +export default search; \ No newline at end of file diff --git a/src/composables/state.js b/src/composables/state.js index 2677e87..d4b0318 100644 --- a/src/composables/state.js +++ b/src/composables/state.js @@ -34,6 +34,9 @@ const loading = ref(false); const is_playing = ref(false); +const search_tracks = ref([]); +const search_albums = ref([]); +const search_artists = ref([]); export default { search_query, @@ -44,4 +47,7 @@ export default { magic_flag, loading, is_playing, + search_tracks, + search_albums, + search_artists, }; diff --git a/src/composables/useDebounce.js b/src/composables/useDebounce.js new file mode 100644 index 0000000..e69de29 diff --git a/yarn.lock b/yarn.lock index 14c119e..24de183 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8729,6 +8729,11 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +vue-debounce@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/vue-debounce/-/vue-debounce-3.0.2.tgz#3b29c33db7cd2a8c20f77e0be66beda1b85f7e8d" + integrity sha512-+shuc9Ry+AFqJbN7BMfagazB81/bTiPWvUZ4KBjambgrd3B5EQBojxeGzeNZ21xRflnwB098BG1d0HtWv8WyzA== + vue-eslint-parser@^7.10.0: version "7.11.0" resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz#214b5dea961007fcffb2ee65b8912307628d0daf"