diff --git a/TODO.md b/TODO.md index 820ca4e2..21050db2 100644 --- a/TODO.md +++ b/TODO.md @@ -59,8 +59,8 @@ - Replace the DbManager class with cls.execute() - Paginate the following endpoints: + 1. Folder tracks - 2. Playlist tracks + 2. Playlist tracks ⭐ - -- When you update a playlist, update the store as well! \ No newline at end of file +- When you update a playlist, update the store as well! diff --git a/app/api/playlist.py b/app/api/playlist.py index f1da68d2..fe382785 100644 --- a/app/api/playlist.py +++ b/app/api/playlist.py @@ -81,13 +81,12 @@ def get_artist_trackhashes(artisthash: str): def format_custom_playlist(playlist: models.Playlist, tracks: list[models.Track]): - duration = sum(t.duration for t in tracks) - - playlist.duration = duration + playlist.duration = sum(t.duration for t in tracks) + playlist.count = len(tracks) return { "info": serialize_for_card(playlist), - "tracks": tracks, + "tracks": serialize_tracks(tracks), } @@ -354,6 +353,7 @@ def remove_tracks_from_playlist( # } PlaylistTable.remove_from_playlist(path.playlistid, body.tracks) + PlaylistStore.remove_from_playlist(path.playlistid, body.tracks) return {"msg": "Done"}, 200 diff --git a/app/lib/home/recentlyadded.py b/app/lib/home/recentlyadded.py index ba99c8d1..a3216830 100644 --- a/app/lib/home/recentlyadded.py +++ b/app/lib/home/recentlyadded.py @@ -1,15 +1,13 @@ from datetime import datetime -from pprint import pprint from time import time -from app.db.libdata import AlbumTable, ArtistTable, TrackTable from app.lib.playlistlib import get_first_4_images from app.models.playlist import Playlist from app.models.track import Track -# from app.store.tracks import TrackStore -# from app.store.albums import AlbumStore -# from app.store.artists import ArtistStore +from app.store.tracks import TrackStore +from app.store.albums import AlbumStore +from app.store.artists import ArtistStore from app.serializers.track import serialize_track from app.serializers.album import album_serializer @@ -89,21 +87,21 @@ def create_track(t: Track): # INFO: Keys: folder, tracks, time (timestamp) -group_type = dict[str, list[Track], float] +# group_type = dict[str, str | list[Track] | float] -def check_folder_type(group_: group_type): +def check_folder_type(group_: dict): # check if all tracks in group have the same albumhash # if so, return "album" - key = group_["folder"] - tracks = group_["tracks"] - time = group_["time"] + key: str = group_["folder"] + tracks: list[Track] = group_["tracks"] + time: float = group_["time"] print(f"Checking folder: {key}") print(f"Tracks: {len(tracks)}") - existing_artist_hashes: set[str] = set(ArtistTable.get_all_hashes(time)) - existing_album_hashes: set[str] = set(AlbumTable.get_all_hashes(time)) + existing_artist_hashes: set[str] = set(ArtistStore.artistmap.keys()) + existing_album_hashes: set[str] = set(AlbumStore.albummap.keys()) if len(tracks) == 1: entry = create_track(tracks[0]) @@ -112,13 +110,14 @@ def check_folder_type(group_: group_type): is_album, albumhash, _ = check_is_album_folder(tracks) if is_album: - album = AlbumTable.get_album_by_albumhash(albumhash) + # album = AlbumTable.get_album_by_albumhash(albumhash) + entry = AlbumStore.albummap.get(albumhash) - if album is None: + if entry is None: return None album = album_serializer( - album, + entry.album, to_remove={ "genres", "og_title", @@ -141,12 +140,12 @@ def check_folder_type(group_: group_type): is_artist, artisthash, trackcount = check_is_artist_folder(tracks) if is_artist: - artist = ArtistTable.get_artist_by_hash(artisthash) + entry = ArtistStore.artistmap.get(artisthash) - if artist is None: + if entry is None: return None - artist = serialize_for_card(artist) + artist = serialize_for_card(entry.artist) artist["trackcount"] = trackcount artist["help_text"] = ( "NEW ARTIST" if artisthash not in existing_artist_hashes else "NEW MUSIC" @@ -200,7 +199,7 @@ def get_recently_added_items(limit: int = 7): print(f"Time taken to get tracks: {then - now}") groups = group_track_by_folders(tracks, {}) # print(groups) - last_trackcount: int = len(tracks) + # last_trackcount: int = len(tracks) # while len(groups.keys()) < limit and last_trackcount > 0: # distracks = get_recently_added_tracks(start=len(tracks), limit=100) @@ -223,8 +222,6 @@ def get_recently_added_items(limit: int = 7): } ) - pprint(f"😅😅😅😅😅😅😅😅😅😅😅😅😅😅😅😅 {grouplist[0]['len']}") - # sort groups by last modified date grouplist = sorted(grouplist, key=lambda group: group["time"], reverse=True) @@ -267,16 +264,14 @@ def get_recently_added_playlist(limit: int = 100): except IndexError: return playlist, [] - playlist.last_updated = date_string_to_time_passed(create_new_date(date)) - + playlist._last_updated = date_string_to_time_passed(create_new_date(date)) images = get_first_4_images(tracks=tracks) playlist.images = images - playlist.set_count(len(tracks)) + playlist.duration = sum(t.duration for t in tracks) + playlist.count = len(tracks) return playlist, tracks -def get_recently_added_tracks(start: int = 0, limit: int = 100): - # tracks = sorted(TrackStore.tracks, key=lambda t: t.created_date, reverse=True) - return TrackTable.get_recently_added(start, limit) - # return tracks[:limit] +def get_recently_added_tracks(start: int = 0, limit: int | None = 100): + return TrackStore.get_recently_added(start, limit) diff --git a/app/lib/home/recentlyplayed.py b/app/lib/home/recentlyplayed.py index a89cb92e..1f45761c 100644 --- a/app/lib/home/recentlyplayed.py +++ b/app/lib/home/recentlyplayed.py @@ -1,18 +1,13 @@ from datetime import datetime import os -from app.db.libdata import AlbumTable, ArtistTable, TrackTable from app.db.userdata import FavoritesTable, ScrobbleTable -from app.models.logger import TrackLog - -# from app.db.sqlite.logger.tracks import SQLiteTrackLogger as db -# from app.db.sqlite.playlists import SQLitePlaylistMethods as pdb -# from app.db.sqlite.favorite import SQLiteFavoriteMethods as fdb from app.models.playlist import Playlist from app.serializers.track import serialize_track from app.serializers.album import album_serializer from app.lib.playlistlib import get_first_4_images from app.store.folder import FolderStore +from app.store.playlists import PlaylistStore from app.utils.dates import ( create_new_date, date_string_to_time_passed, @@ -22,14 +17,13 @@ from app.serializers.artist import serialize_for_card from app.serializers.playlist import serialize_for_card as serialize_playlist from app.lib.home.recentlyadded import get_recently_added_playlist -# from app.store.albums import AlbumStore -# from app.store.tracks import TrackStore -# from app.store.artists import ArtistStore +from app.store.albums import AlbumStore +from app.store.tracks import TrackStore +from app.store.artists import ArtistStore def get_recently_played(limit=7): # TODO: Paginate this - # entries = db.get_all() entries = ScrobbleTable.get_all(0, 200) items = [] added = set() @@ -43,16 +37,13 @@ def get_recently_played(limit=7): if len(items) >= limit: break - # entry = TrackLog(*entry) - if entry.source in added: continue added.add(entry.source) if entry.type == "album": - # album = AlbumStore.get_album_by_hash(entry.type_src) - album = AlbumTable.get_album_by_albumhash(entry.type_src) + album = AlbumStore.get_album_by_hash(entry.type_src) if album is None: continue @@ -80,8 +71,7 @@ def get_recently_played(limit=7): continue if entry.type == "artist": - # artist = ArtistStore.get_artist_by_hash(entry.type_src) - artist = ArtistTable.get_artist_by_hash(entry.type_src) + artist = ArtistStore.get_artist_by_hash(entry.type_src) if artist is None: continue @@ -132,7 +122,6 @@ def get_recently_played(limit=7): continue if entry.type == "playlist": - continue is_custom = entry.type_src in [i["name"] for i in custom_playlists] # is_recently_added = entry.type_src == "recentlyadded" @@ -159,7 +148,8 @@ def get_recently_played(limit=7): ) continue - playlist = pdb.get_playlist_by_id(entry.type_src) + # playlist = pdb.get_playlist_by_id(entry.type_src) + playlist = PlaylistStore.get_playlist_by_id(entry.type_src) if playlist is None: continue @@ -195,13 +185,12 @@ def get_recently_played(limit=7): ) continue - # track = TrackStore.get_tracks_by_trackhashes([entry.trackhash])[0] - track = TrackTable.get_track_by_trackhash(entry.trackhash) + t = TrackStore.trackhashmap.get(entry.trackhash) - if track is None: + if t is None: continue - track = serialize_track(track) + track = serialize_track(t.get_best()) track["help_text"] = "track" track["time"] = timestamp_to_time_passed(entry.timestamp) @@ -225,12 +214,11 @@ def get_recently_played_playlist(limit: int = 100): trackhashes=[], ) - tracks = TrackTable.get_recently_played(limit) + tracks = TrackStore.get_recently_played(limit) date = datetime.fromtimestamp(tracks[0].lastplayed) - playlist.last_updated = date_string_to_time_passed(create_new_date(date)) + playlist._last_updated = date_string_to_time_passed(create_new_date(date)) images = get_first_4_images(tracks=tracks) playlist.images = images - playlist.count = len(tracks) return playlist, tracks diff --git a/app/store/albums.py b/app/store/albums.py index 76ab76c9..b7e97d16 100644 --- a/app/store/albums.py +++ b/app/store/albums.py @@ -125,11 +125,9 @@ class AlbumStore: """ Returns an album by its hash. """ - for album in cls.albums: - if album.albumhash == albumhash: - return album - - return None + entry = cls.albummap.get(albumhash) + if entry is not None: + return entry.album @classmethod def get_albums_by_hashes(cls, albumhashes: Iterable[str]) -> list[Album]: diff --git a/app/store/playlists.py b/app/store/playlists.py index 11151706..c74827f8 100644 --- a/app/store/playlists.py +++ b/app/store/playlists.py @@ -1,3 +1,4 @@ +from operator import index from app.db.userdata import PlaylistTable from app.lib.playlistlib import get_first_4_images from app.models.playlist import Playlist @@ -11,9 +12,12 @@ class PlaylistEntry: self.playlist.clear_lists() if not playlist.has_image: - self.playlist.images = get_first_4_images( - TrackStore.get_tracks_by_trackhashes(self.trackhashes) - ) + self.rebuild_images() + + def rebuild_images(self): + self.playlist.images = get_first_4_images( + TrackStore.get_tracks_by_trackhashes(self.trackhashes) + ) class PlaylistStore: @@ -48,3 +52,23 @@ class PlaylistStore: @classmethod def add_playlist(cls, playlist: Playlist): cls.playlistmap[str(playlist.id)] = PlaylistEntry(playlist) + + @classmethod + def get_playlist_by_id(cls, id: str): + entry = cls.playlistmap.get(id) + + if entry is not None: + return entry.playlist + + @classmethod + def remove_from_playlist(cls, pid: str, tracks: list[dict[str, str]]): + playlist = cls.playlistmap.get(pid) + + if not playlist: + return + + for track in tracks: + if playlist.trackhashes.index(track["trackhash"]) == track["index"]: + playlist.trackhashes.remove(track["trackhash"]) + + playlist.rebuild_images() \ No newline at end of file diff --git a/app/store/tracks.py b/app/store/tracks.py index 65e5a1fb..a5905e15 100644 --- a/app/store/tracks.py +++ b/app/store/tracks.py @@ -350,3 +350,20 @@ class TrackStore: predicate=predicate, including_duplicates=True, ) + + @classmethod + def get_recently_added(cls, start: int, limit: int | None): + """ + Returns the most recently added tracks. + """ + tracks = cls.get_flat_list() + + if limit is None: + return sorted(tracks, key=lambda x: x.last_mod, reverse=True)[start:] + + return sorted(tracks, key=lambda x: x.last_mod, reverse=True)[start:limit] + + @classmethod + def get_recently_played(cls, limit: int): + tracks = cls.get_flat_list() + return sorted(tracks, key=lambda x: x.lastplayed, reverse=True)[:limit]