mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
feat: implement folder and folder track sorting
This commit is contained in:
+46
-5
@@ -23,11 +23,46 @@ api = APIBlueprint("folder", __name__, url_prefix="/folder", abp_tags=[tag])
|
||||
|
||||
|
||||
class FolderTree(BaseModel):
|
||||
folder: str = Field(
|
||||
"$home", example="$home", description="The folder to things from"
|
||||
folder: str = Field("$home", description="The folder to things from")
|
||||
tracksortby: str = Field(
|
||||
"default",
|
||||
description="""The field to sort tracks by. Options: [
|
||||
"default",
|
||||
"album",
|
||||
"albumartists",
|
||||
"artists",
|
||||
"bitrate",
|
||||
"date",
|
||||
"disc",
|
||||
"duration",
|
||||
"lastmod",
|
||||
"lastplayed",
|
||||
"playduration",
|
||||
"playcount",
|
||||
"title",
|
||||
]""",
|
||||
)
|
||||
tracksort_reverse: bool = Field(
|
||||
False,
|
||||
description="Whether to reverse the sort order of the tracks",
|
||||
)
|
||||
foldersortby: str = Field(
|
||||
"lastmod",
|
||||
description="""The field to sort folders by.
|
||||
Options: [
|
||||
"default",
|
||||
"name",
|
||||
"lastmod",
|
||||
"trackcount",
|
||||
]
|
||||
""",
|
||||
)
|
||||
foldersort_reverse: bool = Field(
|
||||
True,
|
||||
description="Whether to reverse the sort order of the folders",
|
||||
)
|
||||
start: int = Field(0, description="The start index")
|
||||
end: int = Field(50, description="The end index")
|
||||
limit: int = Field(50, description="The max number of items to return")
|
||||
tracks_only: bool = Field(False, description="Whether to only get tracks")
|
||||
|
||||
|
||||
@@ -69,9 +104,15 @@ def get_folder_tree(body: FolderTree):
|
||||
req_dir = "/" + req_dir if not req_dir.startswith("/") else req_dir
|
||||
|
||||
res = get_files_and_dirs(
|
||||
req_dir, start=body.start, end=body.end, tracks_only=tracks_only
|
||||
req_dir,
|
||||
start=body.start,
|
||||
limit=body.limit,
|
||||
tracks_only=tracks_only,
|
||||
tracksortby=body.tracksortby,
|
||||
foldersortby=body.foldersortby,
|
||||
tracksort_reverse=body.tracksort_reverse,
|
||||
foldersort_reverse=body.foldersort_reverse,
|
||||
)
|
||||
res["folders"] = sorted(res["folders"], key=lambda i: i.name)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
+24
-8
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from app.lib.sortlib import sort_folders, sort_tracks
|
||||
from app.logger import log
|
||||
from app.models import Folder
|
||||
from app.serializers.track import serialize_tracks
|
||||
@@ -11,7 +12,7 @@ from app.utils.wintools import win_replace_slash
|
||||
# from app.db.libdata import TrackTable as TrackDB
|
||||
|
||||
|
||||
def create_folder(path: str, trackcount=0, foldercount=0) -> Folder:
|
||||
def create_folder(path: str, trackcount=0) -> Folder:
|
||||
"""
|
||||
Creates a folder object from a path.
|
||||
"""
|
||||
@@ -22,7 +23,6 @@ def create_folder(path: str, trackcount=0, foldercount=0) -> Folder:
|
||||
path=win_replace_slash(str(folder)) + "/",
|
||||
is_sym=folder.is_symlink(),
|
||||
trackcount=trackcount,
|
||||
foldercount=foldercount,
|
||||
)
|
||||
|
||||
|
||||
@@ -46,14 +46,22 @@ def get_folders(paths: list[str]):
|
||||
"""
|
||||
folders = FolderStore.count_tracks_containing_paths(paths)
|
||||
return [
|
||||
create_folder(f["path"], f["trackcount"], foldercount=0)
|
||||
create_folder(f["path"], f["trackcount"])
|
||||
for f in folders
|
||||
if f["trackcount"] > 0
|
||||
]
|
||||
|
||||
|
||||
def get_files_and_dirs(
|
||||
path: str, start: int, end: int, tracks_only: bool = False, skip_empty_folders=True
|
||||
path: str,
|
||||
start: int,
|
||||
limit: int,
|
||||
tracksortby: str,
|
||||
foldersortby: str,
|
||||
tracksort_reverse: bool,
|
||||
foldersort_reverse: bool,
|
||||
tracks_only: bool = False,
|
||||
skip_empty_folders=True,
|
||||
):
|
||||
"""
|
||||
Given a path, returns a list of tracks and folders in that immediate path.
|
||||
@@ -102,14 +110,17 @@ def get_files_and_dirs(
|
||||
|
||||
tracks = []
|
||||
if files:
|
||||
if end == -1:
|
||||
end = len(files)
|
||||
if limit == -1:
|
||||
limit = len(files)
|
||||
|
||||
tracks = list(FolderStore.get_tracks_by_filepaths(files[start:end]))
|
||||
tracks = list(FolderStore.get_tracks_by_filepaths(files))
|
||||
tracks = sort_tracks(tracks, tracksortby, tracksort_reverse)
|
||||
tracks = tracks[start : start + limit]
|
||||
|
||||
folders = []
|
||||
if not tracks_only:
|
||||
folders = get_folders(dirs)
|
||||
folders = sort_folders(folders, foldersortby, foldersort_reverse)
|
||||
|
||||
if skip_empty_folders and len(folders) == 1 and len(tracks) == 0:
|
||||
# INFO: When we only have one folder and no tracks,
|
||||
@@ -118,7 +129,11 @@ def get_files_and_dirs(
|
||||
return get_files_and_dirs(
|
||||
folders[0].path,
|
||||
start=start,
|
||||
end=end,
|
||||
limit=limit,
|
||||
tracksortby=tracksortby,
|
||||
foldersortby=foldersortby,
|
||||
tracksort_reverse=tracksort_reverse,
|
||||
foldersort_reverse=foldersort_reverse,
|
||||
tracks_only=tracks_only,
|
||||
skip_empty_folders=True,
|
||||
)
|
||||
@@ -127,4 +142,5 @@ def get_files_and_dirs(
|
||||
"path": path,
|
||||
"tracks": serialize_tracks(tracks),
|
||||
"folders": folders,
|
||||
"total": len(files),
|
||||
}
|
||||
|
||||
+4
-11
@@ -14,17 +14,6 @@ from app.store.folder import FolderStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.threading import background
|
||||
|
||||
def load_and_map():
|
||||
key = str(time())
|
||||
FolderStore.load_filepaths()
|
||||
AlbumStore.load_albums(key)
|
||||
ArtistStore.load_artists(key)
|
||||
|
||||
map_scrobble_data()
|
||||
map_favorites()
|
||||
map_artist_colors()
|
||||
map_album_colors()
|
||||
|
||||
|
||||
class IndexEverything:
|
||||
def __init__(self) -> None:
|
||||
@@ -36,6 +25,10 @@ class IndexEverything:
|
||||
ArtistStore.load_artists(key)
|
||||
FolderStore.load_filepaths()
|
||||
|
||||
# map colors
|
||||
map_album_colors()
|
||||
map_artist_colors()
|
||||
|
||||
map_scrobble_data()
|
||||
map_favorites()
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
from itertools import groupby
|
||||
import os
|
||||
from pprint import pprint
|
||||
from app.lib.albumslib import sort_by_track_no
|
||||
from app.models.folder import Folder
|
||||
from app.models.track import Track
|
||||
from app.utils import flatten
|
||||
|
||||
|
||||
def sort_tracks(tracks: list[Track], key: str, reverse: bool = False):
|
||||
"""
|
||||
Sorts a list of tracks by a key.
|
||||
"""
|
||||
if key == "default":
|
||||
return tracks
|
||||
|
||||
sortfunc = lambda x: getattr(x, key)
|
||||
|
||||
if key == "artists" or key == "albumartists":
|
||||
sortfunc = lambda x: getattr(x, 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)
|
||||
groups = groupby(tracks, lambda x: x.albumhash)
|
||||
|
||||
return flatten([sort_by_track_no(list(g)) for k, g in groups])
|
||||
|
||||
return sorted(tracks, key=sortfunc, reverse=reverse)
|
||||
|
||||
|
||||
def sort_folders(folders: list[Folder], key: str, reverse: bool = False):
|
||||
"""
|
||||
Sorts a list of folders by a key.
|
||||
"""
|
||||
if key == "default":
|
||||
return folders
|
||||
|
||||
sortfunc = lambda x: getattr(x, key)
|
||||
|
||||
if key == "lastmod":
|
||||
sortfunc = lambda x: os.path.getmtime(x.path)
|
||||
|
||||
return sorted(folders, key=sortfunc, reverse=reverse)
|
||||
@@ -7,4 +7,3 @@ class Folder:
|
||||
path: str
|
||||
is_sym: bool = False
|
||||
trackcount: int = 0
|
||||
foldercount: int = 0
|
||||
|
||||
Reference in New Issue
Block a user