diff --git a/server/app/api.py b/server/app/api.py index 1095dd23..d20458c8 100644 --- a/server/app/api.py +++ b/server/app/api.py @@ -283,10 +283,6 @@ def get_folder_tree(folder: str): if track.filepath == entry.path: songs.append(track) - # for track in all_the_f_music: - # if track.filepath == req_dir: - # songs.append(track) - return { "files": helpers.remove_duplicates(songs), "folders": sorted(folders, key=lambda i: i["name"]), diff --git a/server/app/functions.py b/server/app/functions.py index 79c85fff..0df31d97 100644 --- a/server/app/functions.py +++ b/server/app/functions.py @@ -185,11 +185,11 @@ def extract_thumb(audio_file_path: str) -> str: small_img = png.resize((250, 250), Image.ANTIALIAS) small_img.save(img_path, format="webp") except: - return use_defaults() + return None return webp_path else: - return use_defaults() + return None def parse_artist_tag(audio): @@ -309,7 +309,6 @@ def get_tags(fullpath: str) -> dict: "length": round(audio.info.length), "bitrate": round(int(audio.info.bitrate) / 1000), "filepath": fullpath, - "image": extract_thumb(fullpath), "folder": os.path.dirname(fullpath).replace(helpers.home_dir, ""), } @@ -342,4 +341,43 @@ def get_album_bio(title: str, albumartist: str): def get_all_albums(): - albums = [] \ No newline at end of file + print("processing albums started ...") + + all_tracks = instances.songs_instance.get_all_songs() + album_dicts = [] + + for track in all_tracks: + album_dict = { + "album": track["album"], + "artist": track["albumartist"], + } + + if album_dict not in album_dicts: + album_dicts.append(album_dict) + + for album in album_dicts: + album_tracks = [ + track + for track in all_tracks + if track["album"] == album["album"] + and track["albumartist"] == album["artist"] + ] + + album["count"] = len(album_tracks) + album["duration"] = helpers.get_album_duration(album_tracks) + album["date"] = album_tracks[0]["date"] + album["artistimage"] = ( + "http://127.0.0.1:8900/images/artists/" + + album_tracks[0]["albumartist"].replace("/", "::") + + ".webp" + ) + + if len(album_tracks) == 1: + album["image"] = extract_thumb(album_tracks[0]["filepath"]) + + if len(album_tracks) > 1: + album["image"] = helpers.get_album_image(album_tracks) + + instances.album_instance.insert_album(album) + + print("done processing albums") diff --git a/server/app/helpers.py b/server/app/helpers.py index ab509626..2df97a0a 100644 --- a/server/app/helpers.py +++ b/server/app/helpers.py @@ -43,8 +43,9 @@ def reindex_tracks(): flag = False while flag is False: - functions.populate() - functions.populate_images() + # functions.populate() + functions.get_all_albums() + # functions.populate_images() # functions.save_t_colors() time.sleep(300) @@ -188,6 +189,23 @@ def get_album_duration(album: List[models.Track]) -> int: album_duration = 0 for track in album: - album_duration += track.length + try: + album_duration += track.length + except AttributeError: + album_duration += track["length"] return album_duration + + +def get_album_image(album: list) -> str: + """ + Gets the image of an album. + """ + + for track in album: + img = functions.extract_thumb(track["filepath"]) + + if img is not None: + return img + + return functions.use_defaults() \ No newline at end of file diff --git a/server/app/instances.py b/server/app/instances.py index 954bc7fc..8d0c0ec5 100644 --- a/server/app/instances.py +++ b/server/app/instances.py @@ -1,7 +1,6 @@ -from app.models import AllSongs -from app.models import Artists -from app.models import TrackColors +from app.models import AllSongs, Artists, TrackColors, Albums songs_instance = AllSongs() artist_instance = Artists() -track_color_instance = TrackColors() \ No newline at end of file +track_color_instance = TrackColors() +album_instance = Albums() diff --git a/server/app/models.py b/server/app/models.py index bf5b59f5..5d8bb68d 100644 --- a/server/app/models.py +++ b/server/app/models.py @@ -4,7 +4,7 @@ import pymongo from bson import ObjectId, json_util -def convert_one_to_json(song): +def convert_one(song): """ Converts a single mongodb cursor to a json object. """ @@ -14,7 +14,7 @@ def convert_one_to_json(song): return loaded_song -def convert_to_json(array): +def convert_many(array): """ Converts a list of mongodb cursors to a list of json objects. """ @@ -100,35 +100,35 @@ class AllSongs(Mongo): """ Returns all tracks in the database. """ - return convert_to_json(self.collection.find()) + return convert_many(self.collection.find()) def get_song_by_id(self, file_id: str) -> dict: """ Returns a track object by its mongodb id. """ song = self.collection.find_one({"_id": ObjectId(file_id)}) - return convert_one_to_json(song) + return convert_one(song) def get_song_by_album(self, name: str, artist: str) -> dict: """ Returns a single track matching the album in the query params. """ song = self.collection.find_one({"album": name, "albumartist": artist}) - return convert_one_to_json(song) + return convert_one(song) def search_songs_by_album(self, query: str) -> list: """ Returns all the songs matching the albums in the query params (using regex). """ songs = self.collection.find({"album": {"$regex": query, "$options": "i"}}) - return convert_to_json(songs) + return convert_many(songs) def search_songs_by_artist(self, query: str) -> list: """ Returns all the songs matching the artists in the query params. """ songs = self.collection.find({"artists": {"$regex": query, "$options": "i"}}) - return convert_to_json(songs) + return convert_many(songs) def find_song_by_title(self, query: str) -> list: """ @@ -136,35 +136,35 @@ class AllSongs(Mongo): """ self.collection.create_index([("title", pymongo.TEXT)]) song = self.collection.find({"title": {"$regex": query, "$options": "i"}}) - return convert_to_json(song) + return convert_many(song) def find_songs_by_album(self, name: str, artist: str) -> list: """ Returns all the tracks exactly matching the album in the query params. """ songs = self.collection.find({"album": name, "albumartist": artist}) - return convert_to_json(songs) + return convert_many(songs) def find_songs_by_folder(self, query: str) -> list: """ Returns a sorted list of all the tracks exactly matching the folder in the query params """ songs = self.collection.find({"folder": query}).sort("title", pymongo.ASCENDING) - return convert_to_json(songs) + return convert_many(songs) def find_songs_by_folder_og(self, query: str) -> list: """ Returns an unsorted list of all the tracks exactly matching the folder in the query params """ songs = self.collection.find({"folder": query}) - return convert_to_json(songs) + return convert_many(songs) def find_songs_by_artist(self, query: str) -> list: """ Returns a list of all the tracks exactly matching the artists in the query params. """ songs = self.collection.find({"artists": query}) - return convert_to_json(songs) + return convert_many(songs) def find_songs_by_albumartist(self, query: str): """ @@ -173,14 +173,14 @@ class AllSongs(Mongo): songs = self.collection.find( {"albumartist": {"$regex": query, "$options": "i"}} ) - return convert_to_json(songs) + return convert_many(songs) def get_song_by_path(self, path: str) -> dict: """ Returns a single track matching the filepath in the query params. """ song = self.collection.find_one({"filepath": path}) - return convert_one_to_json(song) + return convert_one(song) def remove_song_by_filepath(self, filepath: str): """ @@ -227,7 +227,7 @@ class TrackColors(Mongo): Returns a track color object by its filepath. """ track_color = self.collection.find_one({"filepath": filepath}) - return convert_one_to_json(track_color) + return convert_one(track_color) @dataclass @@ -266,3 +266,67 @@ class Track: self.image = "http://127.0.0.1:8900/images/thumbnails/" + tags["image"] self.tracknumber = tags["tracknumber"] self.discnumber = tags["discnumber"] + + +class Albums(Mongo): + """ + The class for all album-related database operations. + """ + + def __init__(self): + super(Albums, self).__init__("ALBUMS") + self.collection = self.db["ALBUMS"] + + def insert_album(self, album: dict) -> None: + """ + Inserts a new album object into the database. + """ + return self.collection.update_one( + {"album": album["album"], "artist": album["artist"]}, + {"$set": album}, + upsert=True, + ).upserted_id + + def get_album_by_id(self, id: str) -> dict: + """ + Returns a single album matching the id in the query params. + """ + album = self.collection.find_one({"_id": ObjectId(id)}) + return convert_one(album) + + def get_album_by_name(self, name: str) -> dict: + """ + Returns a single album matching the name in the query params. + """ + album = self.collection.find_one({"album": name}) + return convert_one(album) + + def get_album_by_artist(self, name: str) -> dict: + """ + Returns a single album matching the artist in the query params. + """ + album = self.collection.find_one({"albumartist": name}) + return convert_one(album) + + +@dataclass +class Album: + """ + Album class + """ + + albumid: str + album: str + artist: str + albumartist: str + year: int + image: str + tracks: list + + def __init__(self, tags): + self.albumid = tags["_id"]["$oid"] + self.album = tags["album"] + self.artist = tags["artist"] + self.albumartist = tags["albumartist"] + self.year = tags["year"] + self.image = "" \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index fb95eead..6b4ee05a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,19 +3,18 @@