modularize src

+ merge main.py and manage.py
+ move start logic to swingmusic/__main__.py
+ add a run.py on the project root
This commit is contained in:
cwilvx
2025-05-25 20:35:54 +03:00
parent 76fc97e088
commit 86fabcd5e3
171 changed files with 658 additions and 627 deletions
+133
View File
@@ -0,0 +1,133 @@
import os
from pathlib import Path
from swingmusic.lib.sortlib import sort_folders, sort_tracks
from swingmusic.logger import log
from swingmusic.models import Folder
from swingmusic.serializers.track import serialize_tracks
from swingmusic.utils.filesystem import SUPPORTED_FILES
from swingmusic.store.folder import FolderStore
from swingmusic.utils.wintools import win_replace_slash
def create_folder(path: str, trackcount=0) -> Folder:
"""
Creates a folder object from a path.
"""
folder = Path(path)
return Folder(
name=folder.name,
path=win_replace_slash(str(folder)) + "/",
is_sym=folder.is_symlink(),
trackcount=trackcount,
)
def get_folders(paths: list[str]):
"""
Filters out folders that don't have any tracks and
returns a list of folder objects.
"""
folders = FolderStore.count_tracks_containing_paths(paths)
return [
create_folder(f["path"], f["trackcount"])
for f in folders
if f["trackcount"] > 0
]
def get_files_and_dirs(
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.
Can recursively call itself to skip through empty folders.
"""
# TODO: Replace os.path with pathlib
try:
entries = os.scandir(path)
except FileNotFoundError:
return {
"path": path,
"tracks": [],
"folders": [],
}
dirs, files = [], []
for entry_ in entries:
entry = Path(entry_.path)
ext = entry.suffix.lower()
if entry.is_dir() and not entry.name.startswith("."):
dir = (entry / "").as_posix()
# 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(dir)
elif entry.is_file() and ext in SUPPORTED_FILES:
files.append(entry.as_posix())
files_ = []
for file in files:
try:
files_.append(
{
"path": file,
"time": os.path.getmtime(file),
}
)
except OSError as e:
log.error(e)
files_.sort(key=lambda f: f["time"])
files = [f["path"] for f in files_]
tracks = []
if files:
if limit == -1:
limit = len(files)
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,
# skip through empty folders.
# Call recursively with the first folder in the list.
return get_files_and_dirs(
folders[0].path,
start=start,
limit=limit,
tracksortby=tracksortby,
foldersortby=foldersortby,
tracksort_reverse=tracksort_reverse,
foldersort_reverse=foldersort_reverse,
tracks_only=tracks_only,
skip_empty_folders=True,
)
return {
"path": path,
"tracks": serialize_tracks(tracks),
"folders": folders,
"total": len(files),
}