4907d0d5a4
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>
50 lines
1.8 KiB
Python
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()
|