diff --git a/app/api/playlist.py b/app/api/playlist.py index 4ab9fa1e..71beb52b 100644 --- a/app/api/playlist.py +++ b/app/api/playlist.py @@ -53,11 +53,12 @@ def insert_playlist(name: str, image: str = None): return None -def get_path_trackhashes(path: str): +def get_path_trackhashes(path: str, tracksortby: str, reverse: bool): """ Returns a list of trackhashes in a folder. """ tracks = TrackStore.get_tracks_in_path(path) + tracks = sort_tracks(tracks, key=tracksortby, reverse=reverse) return [t.trackhash for t in tracks] @@ -152,6 +153,10 @@ class AddItemToPlaylistBody(BaseModel): description="The type of item to add", examples=["tracks", "folder", "album", "artist"], ) + sortoptions: dict = Field( + default=None, + description="The sort options for the tracks", + ) itemhash: str = Field(..., description="The hash of the item to add") @@ -165,11 +170,12 @@ def add_item_to_playlist(path: PlaylistIDPath, body: AddItemToPlaylistBody): itemtype = body.itemtype itemhash = body.itemhash playlist_id = path.playlistid + sortoptions = body.sortoptions if itemtype == "tracks": trackhashes = itemhash.split(",") elif itemtype == "folder": - trackhashes = get_path_trackhashes(itemhash) + trackhashes = get_path_trackhashes(itemhash, sortoptions.get("tracksortby") or 'default', sortoptions.get("tracksortreverse") or False) elif itemtype == "album": trackhashes = get_album_trackhashes(itemhash) elif itemtype == "artist": @@ -378,6 +384,10 @@ class SavePlaylistAsItemBody(BaseModel): itemtype: str = Field(..., description="The type of item", example="tracks") playlist_name: str = Field(..., description="The name of the playlist") itemhash: str = Field(..., description="The hash of the item to save") + sortoptions: dict = Field( + default=dict(), + description="The sort options for the tracks", + ) @api.post("/save-item") @@ -390,6 +400,7 @@ def save_item_as_playlist(body: SavePlaylistAsItemBody): itemtype = body.itemtype playlist_name = body.playlist_name itemhash = body.itemhash + sortoptions = body.sortoptions if PlaylistTable.check_exists_by_name(playlist_name): return {"error": "Playlist already exists"}, 409 @@ -397,7 +408,7 @@ def save_item_as_playlist(body: SavePlaylistAsItemBody): if itemtype == "tracks": trackhashes = itemhash.split(",") elif itemtype == "folder": - trackhashes = get_path_trackhashes(itemhash) + trackhashes = get_path_trackhashes(itemhash, sortoptions.get("tracksortby") or 'default', sortoptions.get("tracksortreverse") or False) elif itemtype == "album": trackhashes = get_album_trackhashes(itemhash) elif itemtype == "artist": diff --git a/app/lib/sortlib.py b/app/lib/sortlib.py index 8ca9a1f9..65419d43 100644 --- a/app/lib/sortlib.py +++ b/app/lib/sortlib.py @@ -1,6 +1,6 @@ from itertools import groupby import os -from pprint import pprint +from typing import Callable from app.lib.albumslib import sort_by_track_no from app.models.folder import Folder from app.models.track import Track @@ -14,25 +14,24 @@ def sort_tracks(tracks: list[Track], key: str, reverse: bool = False): if key == "default": return tracks - sortfunc = lambda x: getattr(x, key) - + sortfunc: Callable[[Track], str] = lambda track: getattr(track, key) if key == "artists" or key == "albumartists": - sortfunc = lambda x: getattr(x, key)[0]["name"] + sortfunc = lambda track: getattr(track, key)[0]["name"] if key == "disc": # INFO: Group tracks into albums, then sort them by disc number. - tracks = sorted(tracks, key=lambda x: x.album) + tracks = sorted(tracks, key=lambda x: x.album.casefold()) groups = groupby(tracks, lambda x: x.albumhash) return flatten([sort_by_track_no(list(g)) for k, g in groups]) # INFO: sort tracks by title for a fallback value - tracks = sorted(tracks, key=lambda t: t.title) + tracks = sorted(tracks, key=lambda t: t.title.casefold()) if key == "title" and not reverse: return tracks - return sorted(tracks, key=sortfunc, reverse=reverse) + return sorted(tracks, key=lambda track: sortfunc(track).casefold(), reverse=reverse) def sort_folders(folders: list[Folder], key: str, reverse: bool = False): @@ -42,9 +41,9 @@ def sort_folders(folders: list[Folder], key: str, reverse: bool = False): if key == "default": return folders - sortfunc = lambda x: getattr(x, key) + sortfunc: Callable[[Folder], str | float] = lambda folder: getattr(folder, key) if key == "lastmod": - sortfunc = lambda x: os.path.getmtime(x.path) + sortfunc = lambda folder: os.path.getmtime(folder.path) return sorted(folders, key=sortfunc, reverse=reverse)