feat: library scan — probe seam + scan_library (have + monitored + followed)
Adds the AudioProbe seam (probe.py, _probe.py MutagenProbe with a lazy mutagen import, FakeAudioProbe) and scan_library, which walks /music, resolves each album against MusicBrainz (falling back to embedded tags when the folder name doesn't resolve), and idempotently records matched albums as have (LibraryItem), monitored (MonitoredRelease, fulfilled), and followed (WatchedArtist, autoMonitorFuture=false). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from typing import Callable
|
||||
|
||||
from lyra_worker.browser import ArtistHit, ReleaseGroupInfo
|
||||
from lyra_worker.probe import ProbeResult
|
||||
from lyra_worker.types import Candidate, DownloadResult, MBTarget, Quality
|
||||
|
||||
_QUALITIES = {
|
||||
@@ -81,3 +82,11 @@ class FakeMbBrowser:
|
||||
|
||||
def browse_release_groups(self, artist_mbid: str) -> list[ReleaseGroupInfo]:
|
||||
return list(self._releases.get(artist_mbid, []))
|
||||
|
||||
|
||||
class FakeAudioProbe:
|
||||
"""In-memory AudioProbe for tests."""
|
||||
def __init__(self, artist="", album="", fmt="FLAC", quality_class=3):
|
||||
self._r = ProbeResult(artist=artist, album=album, fmt=fmt, quality_class=quality_class)
|
||||
def probe(self, path: str) -> ProbeResult:
|
||||
return self._r
|
||||
|
||||
Reference in New Issue
Block a user