`core/media_server/` package with the Protocol contract that every media server client (Plex, Jellyfin, Navidrome, SoulSync standalone) satisfies, plus the registry that holds them. Required methods conservatively limited to the four every server truly implements today: is_connected, ensure_connection, get_all_artists, get_all_album_ids. Other generic methods (search_tracks, trigger_library_scan, get_recently_added_albums, etc.) are listed as OPTIONAL — present on most servers but not all (SoulSync has no library-scan API since it walks the filesystem directly; Jellyfin uses a different search shape). Phase B's engine adapters route around the gaps with per-server fallback instead of forcing every client to declare a no-op stub. Same registry shape as the download plugin registry — single source of truth for which servers exist + name resolution. Adding a 5th server (Subsonic, Emby, etc.) becomes one register call plus the new client class. 5 conformance tests pin every server class implements every required method. Plan doc at docs/media-server-engine-refactor-plan.md. Pure additive — no consumer routes through the contract or registry yet. Suite still green (1921 passed).
23 lines
1 KiB
Python
23 lines
1 KiB
Python
"""Media server engine — central dispatch for the per-server clients
|
|
(Plex, Jellyfin, Navidrome, SoulSync standalone).
|
|
|
|
Companion to the download engine refactor — same architectural
|
|
shape applied to the read-side of the library. The orchestrator
|
|
historically had 33+ ``if active_server == 'plex' / 'jellyfin' /
|
|
...`` dispatch sites in web_server.py. This package replaces those
|
|
with a single ``MediaServerEngine.method()`` call per operation.
|
|
|
|
Per-server clients keep their protocol-specific work (Plex's
|
|
PlexAPI SDK, Jellyfin's REST endpoints, Navidrome's OpenSubsonic
|
|
API, SoulSync's filesystem walk). The engine just routes by
|
|
``active_server`` config + provides a uniform shape for the calls
|
|
``web_server.py`` makes generically.
|
|
|
|
See ``docs/media-server-engine-refactor-plan.md`` for the full
|
|
phased plan.
|
|
"""
|
|
|
|
from core.media_server.contract import MediaServerClient
|
|
from core.media_server.registry import MediaServerRegistry, build_default_registry
|
|
|
|
__all__ = ["MediaServerClient", "MediaServerRegistry", "build_default_registry"]
|