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:
Jonathan
2026-07-11 17:00:33 +02:00
parent af67d01aa2
commit 4907d0d5a4
7 changed files with 279 additions and 0 deletions
+9
View File
@@ -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