feat: organized album directory and persistent /music bind-mount
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import re
|
||||
|
||||
from lyra_worker.types import MBTarget
|
||||
|
||||
_ILLEGAL = re.compile(r'[<>:"/\\|?*\x00-\x1f]')
|
||||
|
||||
|
||||
def safe_name(s: str) -> str:
|
||||
"""A filesystem-safe path component (single segment, no separators)."""
|
||||
cleaned = _ILLEGAL.sub("_", s).strip().strip(".").strip()
|
||||
return cleaned or "Unknown"
|
||||
|
||||
|
||||
def album_dir(dest_root: str, target: MBTarget) -> str:
|
||||
"""`{dest_root}/{safe artist}/{safe album}[ (year)]`."""
|
||||
album = safe_name(target.album)
|
||||
if target.year:
|
||||
album = f"{album} ({target.year})"
|
||||
return f"{dest_root}/{safe_name(target.artist)}/{album}"
|
||||
@@ -5,6 +5,7 @@ import psycopg
|
||||
|
||||
from lyra_worker.adapters.base import SourceAdapter
|
||||
from lyra_worker.confidence import score_confidence
|
||||
from lyra_worker.library import album_dir
|
||||
from lyra_worker.quality import quality_class
|
||||
from lyra_worker.ranker import rank_candidates
|
||||
from lyra_worker.types import Candidate, MBTarget
|
||||
@@ -150,7 +151,7 @@ def run_pipeline(
|
||||
# 4. download (fall-through)
|
||||
_set_state(conn, job_id, "downloading", "download")
|
||||
by_source = {a.name: a for a in adapters}
|
||||
dest = f"{dest_root}/{target.artist}/{target.album}"
|
||||
dest = album_dir(dest_root, target)
|
||||
winner = None
|
||||
result = None
|
||||
for candidate in ranked:
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
from lyra_worker.library import album_dir, safe_name
|
||||
from lyra_worker.types import MBTarget
|
||||
|
||||
|
||||
def test_safe_name_replaces_illegal_chars():
|
||||
assert safe_name("AC/DC") == "AC_DC"
|
||||
assert safe_name('a:b*c?"') == "a_b_c__"
|
||||
assert safe_name(" .Trailing. ") == "Trailing"
|
||||
assert safe_name("") == "Unknown"
|
||||
|
||||
|
||||
def test_album_dir_with_year():
|
||||
t = MBTarget(artist="John Mayer", album="Continuum", year=2006)
|
||||
assert album_dir("/music", t) == "/music/John Mayer/Continuum (2006)"
|
||||
|
||||
|
||||
def test_album_dir_without_year():
|
||||
t = MBTarget(artist="John Mayer", album="Continuum")
|
||||
assert album_dir("/music", t) == "/music/John Mayer/Continuum"
|
||||
|
||||
|
||||
def test_album_dir_sanitizes():
|
||||
t = MBTarget(artist="AC/DC", album="Back in Black", year=1980)
|
||||
assert album_dir("/music", t) == "/music/AC_DC/Back in Black (1980)"
|
||||
Reference in New Issue
Block a user