refactor(settings): drop jellyfin machine service + dead machine path fields

Slice 1 of jellyfin-service-registry. Jellyfin is configured exclusively
via the service registry now; the machine-level media_root/path_prefix
fields were dead duplicates of the global config.

- services/settings_store.py: DEFAULT_SERVICES no longer includes
  "jellyfin" (now ["monitoring", "files"]). Removed machine-level
  media_root/path_prefix from _default_local_machine, _row_to_machine,
  _normalize_machine_payload, _seed_local_machine, get_machine_config,
  and upsert_machine. _default_local_machine no longer reads global
  config, so the get_settings import is dropped.
- routers/settings.py: removed media_root/path_prefix from
  MonitoringMachineInput (dead API input; store already ignored them).

The global config remote_media_root/path_prefix properties + path_utils.py
are unchanged (files.py and media_index still use them for Jellyfin->SSH
path resolution). ruff clean; 239 backend tests pass.
This commit is contained in:
Developer
2026-06-24 14:38:47 +00:00
parent 38b2de54ff
commit 7107815a5c
13 changed files with 21 additions and 39 deletions
@@ -2,7 +2,7 @@
dir: backend/src/media_library_viewer_api/services
## role
Backend service layer providing business logic for media library management, including media indexing, backup monitoring, email notifications, SSH task execution, settings persistence, and security.
Backend service layer providing business logic for media library management, backup monitoring, email notifications, SSH task execution, encryption, and persistent settings storage.
## parent
index: backend/src/media_library_viewer_api/.pi-map.index.md
map: backend/src/media_library_viewer_api/.pi-map.md
File diff suppressed because one or more lines are too long
@@ -17,16 +17,14 @@ from typing import Any
import paramiko
from media_library_viewer_api.config import get_settings
from media_library_viewer_api.models.widgets import _validate_config_keys
DEFAULT_SETTINGS_PATH = Path(".cache/media_library_viewer/settings.sqlite")
LOCAL_MACHINE_ID = "local"
DEFAULT_SERVICES = ["monitoring", "files", "jellyfin"]
DEFAULT_SERVICES = ["monitoring", "files"]
def _default_local_machine() -> dict[str, Any]:
settings = get_settings()
return {
"id": LOCAL_MACHINE_ID,
"name": "This machine",
@@ -42,8 +40,6 @@ def _default_local_machine() -> dict[str, Any]:
"ssh_private_key": "",
"ssh_private_key_passphrase": "",
"password": "",
"media_root": settings.media_root,
"path_prefix": settings.path_prefix,
"node_exporter_enabled": False,
"node_exporter_port": 9100,
"node_exporter_scrape_host": "",
@@ -285,8 +281,6 @@ class SettingsStore:
"ssh_private_key_set": bool(data.get("ssh_private_key")),
"ssh_private_key_passphrase_set": bool(data.get("ssh_private_key_passphrase")),
"password_set": bool(data.get("password")),
"media_root": data.get("media_root", ""),
"path_prefix": data.get("path_prefix", ""),
"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", ""),
@@ -334,8 +328,6 @@ class SettingsStore:
if password in (None, ""):
password = (current or {}).get("password", "")
password = str(password or "")
media_root = _current_str("media_root")
path_prefix = _current_str("path_prefix")
node_exporter_enabled = bool(
payload.get("node_exporter_enabled")
if payload.get("node_exporter_enabled") is not None
@@ -365,8 +357,6 @@ class SettingsStore:
"ssh_private_key": ssh_private_key,
"ssh_private_key_passphrase": ssh_private_key_passphrase,
"password": password,
"media_root": media_root,
"path_prefix": path_prefix,
"node_exporter_enabled": node_exporter_enabled,
"node_exporter_port": node_exporter_port,
"node_exporter_scrape_host": node_exporter_scrape_host,
@@ -388,8 +378,6 @@ class SettingsStore:
"ssh_private_key": "",
"ssh_private_key_passphrase": "",
"password": "",
"media_root": machine["media_root"],
"path_prefix": machine["path_prefix"],
"node_exporter_enabled": machine["node_exporter_enabled"],
"node_exporter_port": machine["node_exporter_port"],
"node_exporter_scrape_host": machine["node_exporter_scrape_host"],
@@ -473,8 +461,6 @@ class SettingsStore:
"ssh_private_key": data.get("ssh_private_key", ""),
"ssh_private_key_passphrase": data.get("ssh_private_key_passphrase", ""),
"password": data.get("password", ""),
"media_root": data.get("media_root", ""),
"path_prefix": data.get("path_prefix", ""),
"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", ""),
@@ -512,8 +498,6 @@ class SettingsStore:
"ssh_private_key": machine["ssh_private_key"],
"ssh_private_key_passphrase": machine["ssh_private_key_passphrase"],
"password": machine["password"],
"media_root": machine["media_root"],
"path_prefix": machine["path_prefix"],
"node_exporter_enabled": machine["node_exporter_enabled"],
"node_exporter_port": machine["node_exporter_port"],
"node_exporter_scrape_host": machine["node_exporter_scrape_host"],