mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
ade8759191
+ ignore src files in scans
155 lines
4.5 KiB
Python
155 lines
4.5 KiB
Python
import pathlib
|
|
from pathlib import Path
|
|
import logging
|
|
|
|
from swingmusic.lib.sortlib import sort_folders, sort_tracks
|
|
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
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
def create_folder(path: str, trackcount=0) -> Folder:
|
|
"""
|
|
Creates a folder object from a path.
|
|
"""
|
|
folder = Path(path)
|
|
|
|
return Folder(
|
|
name=folder.name,
|
|
path=folder.as_posix() + "/",
|
|
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: pathlib.Path,
|
|
start: int,
|
|
limit: int,
|
|
tracksortby: str,
|
|
foldersortby: str,
|
|
tracksort_reverse: bool,
|
|
foldersort_reverse: bool,
|
|
tracks_only: bool = False,
|
|
skip_empty_folders=True,
|
|
) -> dict[str: list|int|str]:
|
|
"""
|
|
Scan folder for files and folders.
|
|
Will only return files in `swingmusic.utils.filesystem.SUPPORTED_FILES`.
|
|
If `skip_empty_folders` is True
|
|
|
|
:param path:
|
|
:param start:
|
|
:param limit:
|
|
:param tracksortby:
|
|
:param foldersortby:
|
|
:param tracksort_reverse:
|
|
:param foldersort_reverse:
|
|
:param tracks_only: If True, will only return tracks with no folders
|
|
:param skip_empty_folders: If True, will call recursively and skip empty folders until >0 supported file found.
|
|
:returns: List of tracks and folders in that immediate path.
|
|
"""
|
|
|
|
path = pathlib.Path(path)
|
|
|
|
# if file or non-existent
|
|
if not path.exists() or not path.is_dir():
|
|
return {
|
|
"path": path.as_posix(),
|
|
"tracks": [],
|
|
"folders": [],
|
|
"total": 0
|
|
}
|
|
|
|
|
|
# iter through all folders
|
|
# add files with supported suffix
|
|
# ignore hidden folder
|
|
dirs, files = [], []
|
|
for entry in path.iterdir():
|
|
ext = entry.suffix.lower()
|
|
|
|
if entry.is_dir() and not entry.stem.startswith("."):
|
|
dirs.append((entry / "").as_posix())
|
|
# only append as posix for FolderStore and sort_folder function
|
|
# TODO: rework everything to support pathlib
|
|
# 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
|
|
|
|
elif entry.is_file() and ext in SUPPORTED_FILES:
|
|
files.append(entry)
|
|
|
|
# sort files by most recent
|
|
# TODO: rework if realy needed.
|
|
files_with_mtime = []
|
|
for file in files:
|
|
try:
|
|
files_with_mtime.append(
|
|
{
|
|
"path": file.as_posix(),
|
|
"time": file.lstat().st_mtime,
|
|
}
|
|
)
|
|
except OSError as e:
|
|
log.error(e)
|
|
|
|
files_with_mtime.sort(key=lambda f: f["time"])
|
|
files = [f["path"] for f in files_with_mtime]
|
|
|
|
# if supported files were found
|
|
# convert files to tracks
|
|
tracks = []
|
|
if len(files) > 0:
|
|
if limit == -1:
|
|
limit = len(files)
|
|
|
|
# only return tracks already indexed by us
|
|
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.as_posix(),
|
|
"tracks": serialize_tracks(tracks),
|
|
"folders": folders,
|
|
"total": len(files),
|
|
}
|