From cf14610509ff83a20b4da2f1df09e72b4dc5c651 Mon Sep 17 00:00:00 2001 From: geoffrey45 Date: Mon, 21 Mar 2022 01:00:13 +0300 Subject: [PATCH] breakdown models.py into db module and object models --- server/app/db/__init__.py | 39 ++++ server/app/db/albums.py | 53 ++++++ server/app/db/artists.py | 38 ++++ server/app/db/playlists.py | 62 ++++++ server/app/db/trackcolors.py | 28 +++ server/app/db/tracks.py | 132 +++++++++++++ server/app/models.py | 359 ++++------------------------------- 7 files changed, 391 insertions(+), 320 deletions(-) create mode 100644 server/app/db/__init__.py create mode 100644 server/app/db/albums.py create mode 100644 server/app/db/artists.py create mode 100644 server/app/db/playlists.py create mode 100644 server/app/db/trackcolors.py create mode 100644 server/app/db/tracks.py diff --git a/server/app/db/__init__.py b/server/app/db/__init__.py new file mode 100644 index 00000000..dcd1c29b --- /dev/null +++ b/server/app/db/__init__.py @@ -0,0 +1,39 @@ +import pymongo +import json +from bson import json_util + + +class Mongo: + """ + The base class for all mongodb classes. + """ + + def __init__(self, database): + mongo_uri = pymongo.MongoClient() + self.db = mongo_uri[database] + + +def convert_one(song): + """ + Converts a single mongodb cursor to a json object. + """ + json_song = json.dumps(song, default=json_util.default) + loaded_song = json.loads(json_song) + + return loaded_song + + +def convert_many(array): + """ + Converts a list of mongodb cursors to a list of json objects. + """ + + 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 diff --git a/server/app/db/albums.py b/server/app/db/albums.py new file mode 100644 index 00000000..fb79e9a9 --- /dev/null +++ b/server/app/db/albums.py @@ -0,0 +1,53 @@ +from app import db +from bson import ObjectId + +convert_many = db.convert_many +convert_one = db.convert_one + + +class Albums(db.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_all_albums(self) -> list: + """ + Returns all the albums in the database. + """ + albums = self.collection.find() + return convert_many(albums) + + 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, artist: str) -> dict: + """ + Returns a single album matching the name in the query params. + """ + album = self.collection.find_one({"album": name, "artist": artist}) + 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) diff --git a/server/app/db/artists.py b/server/app/db/artists.py new file mode 100644 index 00000000..7b890b5f --- /dev/null +++ b/server/app/db/artists.py @@ -0,0 +1,38 @@ +from app import db +from bson import ObjectId + + +class Artists(db.Mongo): + """ + The artist class for all artist related database operations. + """ + + def __init__(self): + super(Artists, self).__init__("ALL_ARTISTS") + self.collection = self.db["THEM_ARTISTS"] + + def insert_artist(self, artist_obj: dict) -> None: + """ + Inserts an artist into the database. + """ + self.collection.update_one( + artist_obj, {"$set": artist_obj}, upsert=True + ).upserted_id + + def get_all_artists(self) -> list: + """ + Returns a list of all artists in the database. + """ + return self.collection.find() + + def get_artist_by_id(self, artist_id: str) -> dict: + """ + Returns an artist matching the mongo Id. + """ + return self.collection.find_one({"_id": ObjectId(artist_id)}) + + def get_artists_by_name(self, query: str): + """ + Returns all the artists matching the query. + """ + return self.collection.find({"name": query}).limit(20) diff --git a/server/app/db/playlists.py b/server/app/db/playlists.py new file mode 100644 index 00000000..8f958a14 --- /dev/null +++ b/server/app/db/playlists.py @@ -0,0 +1,62 @@ +from app import db, models +from bson import ObjectId + +convert_many = db.convert_many +convert_one = db.convert_one + + + +class Playlists(db.Mongo): + """ + The class for all playlist-related database operations. + """ + + def __init__(self): + super(Playlists, self).__init__("PLAYLISTS") + self.collection = self.db["PLAYLISTS"] + + def insert_playlist(self, playlist: dict) -> None: + """ + Inserts a new playlist object into the database. + """ + return self.collection.update_one( + {"name": playlist["name"]}, + {"$set": playlist}, + upsert=True, + ).upserted_id + + def get_all_playlists(self) -> list: + """ + Returns all the playlists in the database. + """ + playlists = self.collection.find() + return convert_many(playlists) + + def get_playlist_by_id(self, id: str) -> dict: + """ + Returns a single playlist matching the id in the query params. + """ + playlist = self.collection.find_one({"_id": ObjectId(id)}) + return convert_one(playlist) + + def add_track_to_playlist(self, playlistid: str, track: models.Track): + """ + Adds a track to a playlist. + """ + track = { + "title": track.title, + "artists": track.artists, + "album": track.album, + } + + return self.collection.update_one( + {"_id": ObjectId(playlistid)}, + {"$push": {"tracks": track}}, + ).modified_count + + def get_playlist_by_name(self, name: str) -> dict: + """ + Returns a single playlist matching the name in the query params. + """ + playlist = self.collection.find_one({"name": name}) + return convert_one(playlist) diff --git a/server/app/db/trackcolors.py b/server/app/db/trackcolors.py new file mode 100644 index 00000000..58b7f610 --- /dev/null +++ b/server/app/db/trackcolors.py @@ -0,0 +1,28 @@ +from app import db + + +class TrackColors(db.Mongo): + """ + The class for all track-related database operations. + """ + + def __init__(self): + super(TrackColors, self).__init__("TRACK_COLORS") + self.collection = self.db["TRACK_COLORS"] + + def insert_track_color(self, track_color: dict) -> None: + """ + Inserts a new track object into the database. + """ + return self.collection.update_one( + {"filepath": track_color["filepath"]}, + {"$set": track_color}, + upsert=True, + ).upserted_id + + def get_track_color_by_track(self, filepath: str) -> dict: + """ + Returns a track color object by its filepath. + """ + track_color = self.collection.find_one({"filepath": filepath}) + return db.convert_one(track_color) diff --git a/server/app/db/tracks.py b/server/app/db/tracks.py new file mode 100644 index 00000000..81411ee0 --- /dev/null +++ b/server/app/db/tracks.py @@ -0,0 +1,132 @@ +from app import db +from bson import ObjectId + +convert_many = db.convert_many +convert_one = db.convert_one + + +class AllSongs(db.Mongo): + """ + The class for all track-related database operations. + """ + + def __init__(self): + super(AllSongs, self).__init__("ALL_SONGS") + self.collection = self.db["ALL_SONGS"] + + # def drop_db(self): + # self.collection.drop() + + def insert_song(self, song_obj: dict) -> None: + """ + Inserts a new track object into the database. + """ + return self.collection.update_one( + {"filepath": song_obj["filepath"]}, {"$set": song_obj}, upsert=True + ).upserted_id + + def get_all_songs(self) -> list: + """ + Returns all tracks in the database. + """ + 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(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(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_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_many(songs) + + def find_song_by_title(self, query: str) -> list: + """ + Finds all the tracks matching the title in the query params. + """ + self.collection.create_index([("title", db.pymongo.TEXT)]) + song = self.collection.find({"title": {"$regex": query, "$options": "i"}}) + 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_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", db.pymongo.ASCENDING) + 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_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_many(songs) + + def find_songs_by_albumartist(self, query: str): + """ + Returns a list of all the tracks containing the albumartist in the query params. + """ + songs = self.collection.find( + {"albumartist": {"$regex": query, "$options": "i"}} + ) + 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(song) + + def remove_song_by_filepath(self, filepath: str): + """ + Removes a single track from the database. Returns a boolean indicating success or failure of the operation. + """ + try: + self.collection.delete_one({"filepath": filepath}) + return True + except: + return False + + def remove_song_by_id(self, id: str): + """ + Removes a single track from the database. Returns a boolean indicating success or failure of the operation. + """ + try: + self.collection.delete_one({"_id": ObjectId(id)}) + return True + except: + return False diff --git a/server/app/models.py b/server/app/models.py index 902721ad..3948361f 100644 --- a/server/app/models.py +++ b/server/app/models.py @@ -1,233 +1,7 @@ -import json from dataclasses import dataclass -import pymongo -from bson import ObjectId, json_util - - -def convert_one(song): - """ - Converts a single mongodb cursor to a json object. - """ - json_song = json.dumps(song, default=json_util.default) - loaded_song = json.loads(json_song) - - return loaded_song - - -def convert_many(array): - """ - Converts a list of mongodb cursors to a list of json objects. - """ - - 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: - """ - The base class for all mongodb classes. - """ - - def __init__(self, database): - mongo_uri = pymongo.MongoClient() - self.db = mongo_uri[database] - - -class Artists(Mongo): - """ - The artist class for all artist related database operations. - """ - - def __init__(self): - super(Artists, self).__init__("ALL_ARTISTS") - self.collection = self.db["THEM_ARTISTS"] - - def insert_artist(self, artist_obj: dict) -> None: - """ - Inserts an artist into the database. - """ - self.collection.update_one( - artist_obj, {"$set": artist_obj}, upsert=True - ).upserted_id - - def get_all_artists(self) -> list: - """ - Returns a list of all artists in the database. - """ - return self.collection.find() - - def get_artist_by_id(self, artist_id: str) -> dict: - """ - Returns an artist matching the mongo Id. - """ - return self.collection.find_one({"_id": ObjectId(artist_id)}) - - def get_artists_by_name(self, query: str): - """ - Returns all the artists matching the query. - """ - return self.collection.find({"name": query}).limit(20) - - -class AllSongs(Mongo): - """ - The class for all track-related database operations. - """ - - def __init__(self): - super(AllSongs, self).__init__("ALL_SONGS") - self.collection = self.db["ALL_SONGS"] - - # def drop_db(self): - # self.collection.drop() - - def insert_song(self, song_obj: dict) -> None: - """ - Inserts a new track object into the database. - """ - return self.collection.update_one( - {"filepath": song_obj["filepath"]}, {"$set": song_obj}, upsert=True - ).upserted_id - - def get_all_songs(self) -> list: - """ - Returns all tracks in the database. - """ - 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(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(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_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_many(songs) - - def find_song_by_title(self, query: str) -> list: - """ - Finds all the tracks matching the title in the query params. - """ - self.collection.create_index([("title", pymongo.TEXT)]) - song = self.collection.find({"title": {"$regex": query, "$options": "i"}}) - 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_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_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_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_many(songs) - - def find_songs_by_albumartist(self, query: str): - """ - Returns a list of all the tracks containing the albumartist in the query params. - """ - songs = self.collection.find( - {"albumartist": {"$regex": query, "$options": "i"}} - ) - 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(song) - - def remove_song_by_filepath(self, filepath: str): - """ - Removes a single track from the database. Returns a boolean indicating success or failure of the operation. - """ - try: - self.collection.delete_one({"filepath": filepath}) - return True - except: - return False - - def remove_song_by_id(self, id: str): - """ - Removes a single track from the database. Returns a boolean indicating success or failure of the operation. - """ - try: - self.collection.delete_one({"_id": ObjectId(id)}) - return True - except: - return False - - -class TrackColors(Mongo): - """ - The class for all track-related database operations. - """ - - def __init__(self): - super(TrackColors, self).__init__("TRACK_COLORS") - self.collection = self.db["TRACK_COLORS"] - - def insert_track_color(self, track_color: dict) -> None: - """ - Inserts a new track object into the database. - """ - return self.collection.update_one( - {"filepath": track_color["filepath"]}, - {"$set": track_color}, - upsert=True, - ).upserted_id - - def get_track_color_by_track(self, filepath: str) -> dict: - """ - Returns a track color object by its filepath. - """ - track_color = self.collection.find_one({"filepath": filepath}) - return convert_one(track_color) +from typing import List +from app import api +from app import settings @dataclass @@ -266,95 +40,6 @@ class Track: 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_all_albums(self) -> list: - """ - Returns all the albums in the database. - """ - albums = self.collection.find() - return convert_many(albums) - - 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, artist: str) -> dict: - """ - Returns a single album matching the name in the query params. - """ - album = self.collection.find_one({"album": name, "artist": artist}) - 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) - - -class Playlists(Mongo): - """ - The class for all playlist-related database operations. - """ - - def __init__(self): - super(Playlists, self).__init__("PLAYLISTS") - self.collection = self.db["PLAYLISTS"] - - def insert_playlist(self, playlist: dict) -> None: - """ - Inserts a new playlist object into the database. - """ - return self.collection.update_one( - {"name": playlist["name"]}, - {"$set": playlist}, - upsert=True, - ).upserted_id - - def get_all_playlists(self) -> list: - """ - Returns all the playlists in the database. - """ - playlists = self.collection.find() - return convert_many(playlists) - - def get_playlist_by_id(self, id: str) -> dict: - """ - Returns a single playlist matching the id in the query params. - """ - playlist = self.collection.find_one({"_id": ObjectId(id)}) - return convert_one(playlist) - - def get_playlist_by_name(self, name: str) -> dict: - """ - Returns a single playlist matching the name in the query params. - """ - playlist = self.collection.find_one({"name": name}) - return convert_one(playlist) - - @dataclass class Album: """ @@ -375,7 +60,41 @@ class Album: self.count = tags["count"] self.duration = tags["duration"] self.date = tags["date"] - self.artistimage = "http://10.5.8.182:8900/images/artists/" + tags["artistimage"] - self.image = "http://10.5.8.182:8900/images/thumbnails/" + tags["image"] + self.artistimage = ( + settings.IMG_ARTIST_URI + tags["artistimage"] + ) + self.image = settings.IMG_THUMB_URI + tags["image"] +def create_playlist_tracks(playlist_tracks: List) -> List[Track]: + """ + Creates a list of model.Track objects from a list of playlist track dicts. + """ + tracks: List[Track] = [] + + for t in playlist_tracks: + for track in api.TRACKS: + if ( + track.title == t["title"] + and track.artists == t["artists"] + and track.album == t["album"] + ): + tracks.append(track) + + return tracks + + +@dataclass +class Playlist: + playlistid: str + name: str + description: str + image: str + tracks: List[Track] + + def __init__(self, data): + self.playlistid = data["_id"]["$oid"] + self.name = data["name"] + self.description = data["description"] + self.image = "" + self.tracks = create_playlist_tracks(data["tracks"])