From cfb9977532c0a92a3856c283dcf524f9babbec98 Mon Sep 17 00:00:00 2001 From: Developer Date: Tue, 23 Jun 2026 12:54:27 +0000 Subject: [PATCH] chore: remove dead machine-level Jellyfin/Jellyseerr fields Follow-up #1 to the service-registry change. Jellyfin/Jellyseerr now resolve from the service registry, so the machine-level app fields are dead config. - dependencies.py: drop dead _jellyseerr_client_for; simplify _resolve_machine to SSH-only. - settings_store.py + routers/settings.py: remove jellyfin_*/jellyseerr_* from machine default config, get_machine_config, normalization, row mappers, and MachineInput. - frontend types + Settings.tsx: drop the fields and the Jellyfin/Jellyseerr form sections + service options. - Update frontend test fixtures. Existing DB rows may still carry these keys in config_json; they are inert and drop on the next machine save. Verification: backend ruff clean, pytest 222; frontend lint 0 errors, build success, 70 tests. --- CHANGELOG.md | 10 ++ .../media_library_viewer_api/dependencies.py | 25 +--- .../routers/settings.py | 5 - .../services/settings_store.py | 41 ------ frontend/src/pages/Settings.tsx | 124 +----------------- frontend/src/pages/__tests__/Actions.test.tsx | 5 - .../src/pages/__tests__/FileBrowser.test.tsx | 5 - frontend/src/pages/__tests__/Media.test.tsx | 5 - .../src/pages/__tests__/Settings.test.tsx | 5 - frontend/src/types/index.ts | 10 -- 10 files changed, 17 insertions(+), 218 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b74dad..f2d1e8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,3 +54,13 @@ All notable changes to Manage. Breaking changes are marked with **BREAKING**. - Machine-level Jellyfin/Jellyseerr app config still powers the Media/Users/Files pages. Migrating those onto the service registry is a separate follow-up change (see `openspec/changes/service-registry/design.md` §12.5). + +## Follow-up #1 — remove dead machine Jellyfin/Jellyseerr fields + +With Jellyfin/Jellyseerr now resolved from the service registry, the machine-level +Jellyfin/Jellyseerr fields are dead config. Removed from `dependencies.py` (dead +`_jellyseerr_client_for`; `_resolve_machine` simplified to SSH-only), +`services/settings_store.py`, `routers/settings.py` (`MachineInput`), frontend +types, the `Settings.tsx` form, and frontend test fixtures. Existing DB rows may +still carry these keys in `config_json`; they are inert and get dropped on the +next machine save. No data migration required. diff --git a/backend/src/media_library_viewer_api/dependencies.py b/backend/src/media_library_viewer_api/dependencies.py index 9ccc256..ed390a4 100644 --- a/backend/src/media_library_viewer_api/dependencies.py +++ b/backend/src/media_library_viewer_api/dependencies.py @@ -81,21 +81,6 @@ def _jellyfin_client_for(cache_key: tuple[str, str, str]) -> JellyfinClient: return JellyfinClient(url, api_key) -@lru_cache(maxsize=32) -def _jellyseerr_client_for(cache_key: tuple[str, str]) -> JellyseerrClient | None: - machine_id, url = cache_key - if not url: - return None - settings = get_settings_store().get_machine_config(machine_id) if machine_id else None - api_key = (settings or {}).get("jellyseerr_api_key") if settings else "" - if not api_key: - return None - logger.info( - "Creating Jellyseerr client machine_id=%s url=%s", machine_id or "", url.rstrip("/") or "" - ) - return JellyseerrClient(url, api_key) - - @lru_cache(maxsize=32) def _ssh_client_for( cache_key: tuple[str, str, str, int, str, str | None, str | None, str | None, str | None], @@ -154,6 +139,10 @@ def _ssh_client_for( def _resolve_machine(service: str, request: Request | None = None) -> dict[str, Any] | None: + """Resolve an SSH/Files machine for the given transport service. + + Jellyfin/Jellyseerr are resolved against the service registry, not here. + """ store = get_settings_store() machine_id = _request_machine_id(request) if machine_id: @@ -161,11 +150,7 @@ def _resolve_machine(service: str, request: Request | None = None) -> dict[str, if machine and (service in machine.get("services", []) or service == "ssh"): return machine return machine - if service == "jellyfin": - machines = store.list_machines_for_service("jellyfin") - elif service == "jellyseerr": - machines = [m for m in store.list_machines_for_service("jellyfin") if m.get("jellyseerr_url")] - elif service == "ssh": + if service == "ssh": machines = store.list_machines_for_service("files") or store.list_machines_for_service("monitoring") else: machines = store.list_machines_for_service(service) diff --git a/backend/src/media_library_viewer_api/routers/settings.py b/backend/src/media_library_viewer_api/routers/settings.py index 4b88025..66bcb0c 100644 --- a/backend/src/media_library_viewer_api/routers/settings.py +++ b/backend/src/media_library_viewer_api/routers/settings.py @@ -43,11 +43,6 @@ class MonitoringMachineInput(BaseModel): password: str = "" media_root: str = "" path_prefix: str = "" - jellyfin_url: str = "" - jellyfin_user_id: str = "" - jellyfin_api_key: str = "" - jellyseerr_url: str = "" - jellyseerr_api_key: str = "" notes: str = "" diff --git a/backend/src/media_library_viewer_api/services/settings_store.py b/backend/src/media_library_viewer_api/services/settings_store.py index 5cd2c81..2df41b2 100644 --- a/backend/src/media_library_viewer_api/services/settings_store.py +++ b/backend/src/media_library_viewer_api/services/settings_store.py @@ -44,11 +44,6 @@ def _default_local_machine() -> dict[str, Any]: "password": "", "media_root": settings.media_root, "path_prefix": settings.path_prefix, - "jellyfin_url": "", - "jellyfin_user_id": "", - "jellyfin_api_key": "", - "jellyseerr_url": "", - "jellyseerr_api_key": "", "node_exporter_enabled": False, "node_exporter_port": 9100, "node_exporter_scrape_host": "", @@ -306,11 +301,6 @@ class SettingsStore: "password_set": bool(data.get("password")), "media_root": data.get("media_root", ""), "path_prefix": data.get("path_prefix", ""), - "jellyfin_url": data.get("jellyfin_url", ""), - "jellyfin_user_id": data.get("jellyfin_user_id", ""), - "jellyfin_api_key_set": bool(data.get("jellyfin_api_key")), - "jellyseerr_url": data.get("jellyseerr_url", ""), - "jellyseerr_api_key_set": bool(data.get("jellyseerr_api_key")), "node_exporter_enabled": bool(data.get("node_exporter_enabled", False)), "node_exporter_port": int(data.get("node_exporter_port", 9100) or 9100), "node_exporter_scrape_host": data.get("node_exporter_scrape_host", ""), @@ -360,17 +350,6 @@ class SettingsStore: password = str(password or "") media_root = _current_str("media_root") path_prefix = _current_str("path_prefix") - jellyfin_url = _current_str("jellyfin_url") - jellyfin_user_id = _current_str("jellyfin_user_id") - jellyfin_api_key = payload.get("jellyfin_api_key") - if jellyfin_api_key in (None, ""): - jellyfin_api_key = (current or {}).get("jellyfin_api_key", "") - jellyfin_api_key = str(jellyfin_api_key or "") - jellyseerr_url = _current_str("jellyseerr_url") - jellyseerr_api_key = payload.get("jellyseerr_api_key") - if jellyseerr_api_key in (None, ""): - jellyseerr_api_key = (current or {}).get("jellyseerr_api_key", "") - jellyseerr_api_key = str(jellyseerr_api_key or "") node_exporter_enabled = bool( payload.get("node_exporter_enabled") if payload.get("node_exporter_enabled") is not None @@ -402,11 +381,6 @@ class SettingsStore: "password": password, "media_root": media_root, "path_prefix": path_prefix, - "jellyfin_url": jellyfin_url, - "jellyfin_user_id": jellyfin_user_id, - "jellyfin_api_key": jellyfin_api_key, - "jellyseerr_url": jellyseerr_url, - "jellyseerr_api_key": jellyseerr_api_key, "node_exporter_enabled": node_exporter_enabled, "node_exporter_port": node_exporter_port, "node_exporter_scrape_host": node_exporter_scrape_host, @@ -430,11 +404,6 @@ class SettingsStore: "password": "", "media_root": machine["media_root"], "path_prefix": machine["path_prefix"], - "jellyfin_url": machine["jellyfin_url"], - "jellyfin_user_id": machine["jellyfin_user_id"], - "jellyfin_api_key": machine["jellyfin_api_key"], - "jellyseerr_url": machine["jellyseerr_url"], - "jellyseerr_api_key": machine["jellyseerr_api_key"], "node_exporter_enabled": machine["node_exporter_enabled"], "node_exporter_port": machine["node_exporter_port"], "node_exporter_scrape_host": machine["node_exporter_scrape_host"], @@ -520,11 +489,6 @@ class SettingsStore: "password": data.get("password", ""), "media_root": data.get("media_root", ""), "path_prefix": data.get("path_prefix", ""), - "jellyfin_url": data.get("jellyfin_url", ""), - "jellyfin_user_id": data.get("jellyfin_user_id", ""), - "jellyfin_api_key": data.get("jellyfin_api_key", ""), - "jellyseerr_url": data.get("jellyseerr_url", ""), - "jellyseerr_api_key": data.get("jellyseerr_api_key", ""), "node_exporter_enabled": bool(data.get("node_exporter_enabled", False)), "node_exporter_port": int(data.get("node_exporter_port", 9100) or 9100), "node_exporter_scrape_host": data.get("node_exporter_scrape_host", ""), @@ -564,11 +528,6 @@ class SettingsStore: "password": machine["password"], "media_root": machine["media_root"], "path_prefix": machine["path_prefix"], - "jellyfin_url": machine["jellyfin_url"], - "jellyfin_user_id": machine["jellyfin_user_id"], - "jellyfin_api_key": machine["jellyfin_api_key"], - "jellyseerr_url": machine["jellyseerr_url"], - "jellyseerr_api_key": machine["jellyseerr_api_key"], "node_exporter_enabled": machine["node_exporter_enabled"], "node_exporter_port": machine["node_exporter_port"], "node_exporter_scrape_host": machine["node_exporter_scrape_host"], diff --git a/frontend/src/pages/Settings.tsx b/frontend/src/pages/Settings.tsx index ef61022..bd3aa93 100644 --- a/frontend/src/pages/Settings.tsx +++ b/frontend/src/pages/Settings.tsx @@ -52,8 +52,6 @@ import { Textarea } from "@/components/ui/textarea"; const SERVICE_OPTIONS = [ { value: "monitoring", label: "Monitoring" }, { value: "files", label: "Files" }, - { value: "jellyfin", label: "Jellyfin" }, - { value: "jellyseerr", label: "Jellyseerr" }, { value: "nextcloud", label: "Nextcloud" }, ]; @@ -114,7 +112,7 @@ function emptyMachine( name: mode === "local" ? "This machine" : "", mode, enabled: true, - services: mode === "local" ? ["monitoring", "files", "jellyfin"] : [], + services: mode === "local" ? ["monitoring", "files"] : [], host: "", port: 22, username: "", @@ -126,11 +124,6 @@ function emptyMachine( password: "", media_root: "", path_prefix: "", - jellyfin_url: "", - jellyfin_user_id: "", - jellyfin_api_key: "", - jellyseerr_url: "", - jellyseerr_api_key: "", notes: "", }; } @@ -169,8 +162,6 @@ function MachineEditor({ const isLocal = draft.mode === "local"; const selectedSSHKey = sshKeys.find((key) => key.id === draft.ssh_key_id); const enabledServices = draft.services.length; - const hasJellyfin = draft.services.includes("jellyfin"); - const hasJellyseerr = draft.services.includes("jellyseerr"); const placeholderIfSet = (isSet: boolean | undefined) => isSet ? "Set, not shown" : undefined; return ( @@ -398,99 +389,6 @@ function MachineEditor({ /> - {hasJellyfin && ( - <> -
- -
-
- - - setDraft((current) => ({ - ...current, - jellyfin_url: e.target.value, - })) - } - /> - -
-
- - - setDraft((current) => ({ - ...current, - jellyfin_user_id: e.target.value, - })) - } - /> - -
-
- - - setDraft((current) => ({ - ...current, - jellyfin_api_key: e.target.value, - })) - } - /> - -
- - )} - {hasJellyseerr && ( - <> -
- -
-
- - - setDraft((current) => ({ - ...current, - jellyseerr_url: e.target.value, - })) - } - /> - -
-
- - - setDraft((current) => ({ - ...current, - jellyseerr_api_key: e.target.value, - })) - } - /> - -
- - )} {isLocal && (
@@ -538,7 +436,7 @@ function MachineEditor({ ) : null} - {!isLocal && !hasJellyfin && ( + {!isLocal && enabledServices === 0 && ( SSH machines usually need monitoring or files enabled. @@ -584,13 +482,6 @@ function MachineEditor({ )}
)} - {hasJellyseerr && !draft.jellyseerr_url && ( - - - Jellyseerr is enabled, but no URL is configured yet. - - - )} ); @@ -1146,11 +1037,6 @@ export function Settings() { ssh_private_key_passphrase: "", password: "", media_root: machine.media_root, - jellyfin_url: machine.jellyfin_url, - jellyfin_user_id: machine.jellyfin_user_id, - jellyfin_api_key: "", - jellyseerr_url: machine.jellyseerr_url, - jellyseerr_api_key: "", notes: machine.notes, }, machine, @@ -1237,12 +1123,6 @@ export function Settings() { ssh_private_key_passphrase: "", password: "", media_root: selectedMachine.media_root, - jellyfin_url: selectedMachine.jellyfin_url, - jellyfin_user_id: - selectedMachine.jellyfin_user_id, - jellyfin_api_key: "", - jellyseerr_url: selectedMachine.jellyseerr_url, - jellyseerr_api_key: "", notes: selectedMachine.notes, }, selectedMachine, diff --git a/frontend/src/pages/__tests__/Actions.test.tsx b/frontend/src/pages/__tests__/Actions.test.tsx index 1d90289..1d849df 100644 --- a/frontend/src/pages/__tests__/Actions.test.tsx +++ b/frontend/src/pages/__tests__/Actions.test.tsx @@ -48,11 +48,6 @@ function machine( password_set: false, media_root: "", path_prefix: "", - jellyfin_url: "", - jellyfin_user_id: "", - jellyfin_api_key_set: false, - jellyseerr_url: "", - jellyseerr_api_key_set: false, notes: "", ...overrides, } as MonitoringMachine; diff --git a/frontend/src/pages/__tests__/FileBrowser.test.tsx b/frontend/src/pages/__tests__/FileBrowser.test.tsx index 52dd6b2..98ee6f2 100644 --- a/frontend/src/pages/__tests__/FileBrowser.test.tsx +++ b/frontend/src/pages/__tests__/FileBrowser.test.tsx @@ -30,11 +30,6 @@ function machineFixture( password_set: false, media_root: "", path_prefix: "", - jellyfin_url: "", - jellyfin_user_id: "", - jellyfin_api_key_set: false, - jellyseerr_url: "", - jellyseerr_api_key_set: false, notes: "", ...overrides, }; diff --git a/frontend/src/pages/__tests__/Media.test.tsx b/frontend/src/pages/__tests__/Media.test.tsx index 516c1bb..af0889a 100644 --- a/frontend/src/pages/__tests__/Media.test.tsx +++ b/frontend/src/pages/__tests__/Media.test.tsx @@ -34,11 +34,6 @@ function machineFixture( password_set: false, media_root: "", path_prefix: "", - jellyfin_url: "", - jellyfin_user_id: "", - jellyfin_api_key_set: false, - jellyseerr_url: "", - jellyseerr_api_key_set: false, notes: "", ...overrides, }; diff --git a/frontend/src/pages/__tests__/Settings.test.tsx b/frontend/src/pages/__tests__/Settings.test.tsx index ce56ca3..6fb4e23 100644 --- a/frontend/src/pages/__tests__/Settings.test.tsx +++ b/frontend/src/pages/__tests__/Settings.test.tsx @@ -53,11 +53,6 @@ function localMachine( password_set: false, media_root: "/mnt/media", path_prefix: "", - jellyfin_url: "", - jellyfin_user_id: "", - jellyfin_api_key_set: false, - jellyseerr_url: "", - jellyseerr_api_key_set: false, notes: "Primary node", ...overrides, } as MonitoringMachine; diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index edf671d..0abc939 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -175,11 +175,6 @@ export interface MonitoringMachine { password_set: boolean; media_root: string; path_prefix: string; - jellyfin_url: string; - jellyfin_user_id: string; - jellyfin_api_key_set: boolean; - jellyseerr_url: string; - jellyseerr_api_key_set: boolean; notes: string; } @@ -200,11 +195,6 @@ export interface MonitoringMachineInput { password: string; media_root: string; path_prefix: string; - jellyfin_url: string; - jellyfin_user_id: string; - jellyfin_api_key: string; - jellyseerr_url: string; - jellyseerr_api_key: string; notes: string; }