Files
Lyra/worker/lyra_worker/registry.py
T
Jonathan 4907d0d5a4 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>
2026-07-11 17:00:33 +02:00

50 lines
1.8 KiB
Python

from lyra_worker._mbbrowser import MusicBrainzBrowser
from lyra_worker._musicbrainz import MusicBrainzResolver
from lyra_worker._mutagen import MutagenTagger
from lyra_worker._probe import MutagenProbe
from lyra_worker.adapters._slskd import SlskdClient
from lyra_worker.adapters._streamrip import StreamripClient
from lyra_worker.adapters._ytdlp import YtDlpClient
from lyra_worker.adapters.base import SourceAdapter
from lyra_worker.adapters.qobuz import QobuzAdapter
from lyra_worker.adapters.soulseek import SoulseekAdapter
from lyra_worker.adapters.youtube import YouTubeAdapter
from lyra_worker.browser import MbBrowser
from lyra_worker.probe import AudioProbe
from lyra_worker.resolver import MbResolver
from lyra_worker.tagger import Tagger
def build_adapters(config: dict) -> list[SourceAdapter]:
"""Real source adapters, best-tier first, filtered to those that are configured.
An adapter is included only if its health() is true (Qobuz needs credentials,
Soulseek needs an slskd URL + API key). YouTube needs no config.
"""
candidates: list[SourceAdapter] = [
QobuzAdapter(StreamripClient(config)),
SoulseekAdapter(SlskdClient(config)),
YouTubeAdapter(YtDlpClient()),
]
return [a for a in candidates if a.health()]
def build_resolver() -> MbResolver:
"""The MusicBrainz resolver used to canonicalize requests in intake."""
return MusicBrainzResolver()
def build_tagger() -> Tagger:
"""The tagger that writes canonical metadata onto downloaded files."""
return MutagenTagger()
def build_browser() -> MbBrowser:
"""The MusicBrainz browser used by the background monitor."""
return MusicBrainzBrowser()
def build_probe() -> AudioProbe:
"""The audio probe used by the library scan."""
return MutagenProbe()