Apply the Cin-1 / Cin-2 pattern from the download refactor PR to the media server engine PR before review. Cin-1 — explicit inheritance: - PlexClient, JellyfinClient, NavidromeClient, SoulSyncClient now explicitly inherit MediaServerClient instead of relying on structural typing alone. Pre-change a reader of plex_client.py had no way to know the class was supposed to satisfy the contract. - Removed the engine + registry re-exports from core/media_server/__init__.py to break the circular import that the inheritance change introduced (importing the package now triggered a chain that loaded clients before their base class resolved). Submodules import directly: from core.media_server.engine import MediaServerEngine, etc. - Conformance test now also asserts isinstance() / issubclass() against MediaServerClient — drift in any class fails at the test boundary instead of at runtime. Cin-2 — generic accessors + singleton: - engine.configured_clients() — replaces the legacy per-server `if X and X.is_connected(): clients[name] = X` chains in web_server.py. - engine.reload_config(name=None) — generic dispatch, so callers pass the server name instead of reaching for plex_client.reload_config() directly. - get_media_server_engine() / set_media_server_engine() singleton factory matching the get_metadata_engine() / get_download_orchestrator() shape. web_server.py boots via set_media_server_engine(...) so factory + global handle share state. - 7 new tests pin the accessors + singleton behaviour.
33 lines
1.4 KiB
Python
33 lines
1.4 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.
|
|
|
|
Note: only ``MediaServerClient`` is re-exported here. The engine +
|
|
registry are NOT — importing the registry triggers eager imports
|
|
of every per-server client class, and those clients now inherit
|
|
``MediaServerClient`` (Cin-1), so re-exporting them here would
|
|
form a circular import the moment a client tried to resolve its
|
|
base class. Import them directly from their submodules:
|
|
from core.media_server.engine import MediaServerEngine
|
|
from core.media_server.registry import build_default_registry
|
|
"""
|
|
|
|
from core.media_server.contract import MediaServerClient
|
|
|
|
__all__ = [
|
|
"MediaServerClient",
|
|
]
|