fix folder count

+ fix: file count when you have similar folder names
+ enforce trailing / on track folder paths
This commit is contained in:
mungai-njoroge
2024-04-07 19:19:48 +03:00
parent 14f3479baa
commit 4b04b8b155
5 changed files with 45 additions and 12 deletions
+3
View File
@@ -39,6 +39,9 @@ The REST API exposed by your Swing Music server
In endpoints that request multiple lists of items, this represents the number of items to return for each list. In endpoints that request multiple lists of items, this represents the number of items to return for each list.
#### Other infos
- In the folders endpoint, you can request `'$home'` to get the root directories.
--- ---
[MIT License](https://github.com/swing-opensource/swingmusic?tab=MIT-1-ov-file#MIT-1-ov-file) | Copyright (c) {datetime.datetime.now().year} [Mungai Njoroge](https://mungai.vercel.app) [MIT License](https://github.com/swing-opensource/swingmusic?tab=MIT-1-ov-file#MIT-1-ov-file) | Copyright (c) {datetime.datetime.now().year} [Mungai Njoroge](https://mungai.vercel.app)
+5 -3
View File
@@ -23,7 +23,9 @@ api = APIBlueprint("folder", __name__, url_prefix="/folder", abp_tags=[tag])
class FolderTree(BaseModel): class FolderTree(BaseModel):
folder: str = Field("$home", description="The folder to things from") folder: str = Field(
"$home", example="$home", description="The folder to things from"
)
tracks_only: bool = Field(False, description="Whether to only get tracks") tracks_only: bool = Field(False, description="Whether to only get tracks")
@@ -62,10 +64,10 @@ def get_folder_tree(body: FolderTree):
# Remember, the trailing slash is removed in the client. # Remember, the trailing slash is removed in the client.
req_dir += "/" req_dir += "/"
else: else:
req_dir = "/" + req_dir + "/" if not req_dir.startswith("/") else req_dir + "/" req_dir = "/" + req_dir if not req_dir.startswith("/") else req_dir
res = GetFilesAndDirs(req_dir, tracks_only=tracks_only)() res = GetFilesAndDirs(req_dir, tracks_only=tracks_only)()
res['folders'] = sorted(res['folders'], key=lambda i: i.name) res["folders"] = sorted(res["folders"], key=lambda i: i.name)
return res return res
+28 -9
View File
@@ -25,6 +25,18 @@ def create_folder(path: str, trackcount=0, foldercount=0) -> Folder:
) )
def get_first_child_from_path(root: str, maybe_child: str):
"""
Given a root path and a path, returns the first child from the root path.
"""
if not maybe_child.startswith(root) or maybe_child == root:
return None
children = maybe_child.replace(root, "")
first = Path(children).parts[0]
return os.path.join(root, first)
def get_folders(paths: list[str]): def get_folders(paths: list[str]):
""" """
Filters out folders that don't have any tracks and Filters out folders that don't have any tracks and
@@ -33,24 +45,27 @@ def get_folders(paths: list[str]):
count_dict = { count_dict = {
"tracks": {path: 0 for path in paths}, "tracks": {path: 0 for path in paths},
# folders are immediate children of the root folder # folders are immediate children of the root folder
"folders": {path: 0 for path in paths}, "folders": {path: set() for path in paths},
} }
for track in TrackStore.tracks: for track in TrackStore.tracks:
for path in paths: for path in paths:
if track.folder.startswith(path):
count_dict["tracks"][path] += 1
# increment folder count by counting the number of slashes
print("slash count", track.folder.count("/"), path.count("/")) # a child path should be longer than the root path
if track.folder.count("/") == path.count("/"): if len(track.folder) >= len(path) and track.folder.startswith(path):
count_dict["folders"][path] += 1 count_dict["tracks"][path] += 1
# counting subfolders
p = get_first_child_from_path(path, track.folder)
if p:
count_dict["folders"][path].add(p)
folders = [ folders = [
{ {
"path": path, "path": path,
"trackcount": count_dict["tracks"][path], "trackcount": count_dict["tracks"][path],
"foldercount": count_dict["folders"][path], "foldercount": len(count_dict["folders"][path]),
} }
for path in paths for path in paths
] ]
@@ -92,7 +107,11 @@ class GetFilesAndDirs:
ext = os.path.splitext(entry.name)[1].lower() ext = os.path.splitext(entry.name)[1].lower()
if entry.is_dir() and not entry.name.startswith("."): if entry.is_dir() and not entry.name.startswith("."):
dirs.append(win_replace_slash(entry.path)) dir = win_replace_slash(entry.path)
# add a trailing slash to the folder path
# to avoid matching a folder starting with the same name as the root path
# eg. .../Music and .../Music VideosI
dirs.append(os.path.join(dir, ""))
elif entry.is_file() and ext in SUPPORTED_FILES: elif entry.is_file() and ext in SUPPORTED_FILES:
files.append(win_replace_slash(entry.path)) files.append(win_replace_slash(entry.path))
+3
View File
@@ -90,6 +90,9 @@ def get_recently_played(limit=7):
if is_home_dir: if is_home_dir:
folder = os.path.expanduser("~") folder = os.path.expanduser("~")
# print(folder)
# folder = os.path.join("/", folder, "")
# print(folder)
count = len([t for t in TrackStore.tracks if t.folder == folder]) count = len([t for t in TrackStore.tracks if t.folder == folder])
items.append( items.append(
{ {
+6
View File
@@ -1,4 +1,5 @@
from dataclasses import dataclass from dataclasses import dataclass
import os
from pathlib import Path from pathlib import Path
from app.settings import SessionVarKeys, get_flag from app.settings import SessionVarKeys, get_flag
@@ -61,6 +62,11 @@ class Track:
self.last_mod = int(self.last_mod) self.last_mod = int(self.last_mod)
self.date = int(self.date) self.date = int(self.date)
# add a trailing slash to the folder path
# to avoid matching a folder starting with the same name as the root path
# eg. .../Music and .../Music Videos
self.folder = os.path.join(self.folder, "")
if self.artists is not None: if self.artists is not None:
artists = split_artists(self.artists) artists = split_artists(self.artists)
new_title = self.title new_title = self.title