diff --git a/core/video/enrichment/backfill.py b/core/video/enrichment/backfill.py index f0b4b6e8..0e491ae0 100644 --- a/core/video/enrichment/backfill.py +++ b/core/video/enrichment/backfill.py @@ -99,6 +99,7 @@ def _norm_title(s): # ── base worker (lifecycle + loop + status; mirrors VideoEnrichmentWorker) ──── class VideoBackfillWorker: is_ratings = False + requires_key = False # True for workers gated on an API key (vs a keyless toggle) def __init__(self, db, service, display_name, interval=1.0): self.db = db @@ -259,6 +260,7 @@ class VideoBackfillWorker: "percent": round(done / total * 100) if total else 0} return { "enabled": self.enabled, + "needs_key": self.requires_key, # key-gated → "Not configured"; keyless → "Disabled" "running": running, "paused": self.paused or cooling, "idle": idle, @@ -379,6 +381,7 @@ def _fa_first(j, *keys): class FanartWorker(VideoBackfillWorker): BASE = "https://webservice.fanart.tv/v3" + requires_key = True def __init__(self, db): super().__init__(db, "fanart", "fanart.tv", interval=1.0) @@ -451,6 +454,7 @@ class FanartWorker(VideoBackfillWorker): # ── OpenSubtitles (free key) — subtitle-language availability ───────────────── class OpenSubtitlesWorker(VideoBackfillWorker): BASE = "https://api.opensubtitles.com/api/v1" + requires_key = True def __init__(self, db): super().__init__(db, "opensubtitles", "OpenSubtitles", interval=1.5) @@ -521,6 +525,7 @@ class OpenSubtitlesWorker(VideoBackfillWorker): # ── Trakt (free API key) — community audience rating + vote count ───────────── class TraktWorker(VideoBackfillWorker): BASE = "https://api.trakt.tv" + requires_key = True def __init__(self, db): super().__init__(db, "trakt", "Trakt", interval=1.0) diff --git a/core/video/enrichment/worker.py b/core/video/enrichment/worker.py index 819eb741..63c4af82 100644 --- a/core/video/enrichment/worker.py +++ b/core/video/enrichment/worker.py @@ -290,6 +290,7 @@ class VideoEnrichmentWorker: "percent": round(done / total * 100) if total else 0} return { "enabled": self.enabled, + "needs_key": True, # matchers (TMDB/TVDB/OMDb) always require an API key "running": running, "paused": self.paused or cooling, # cooldown reads as paused in the UI "idle": idle, diff --git a/tests/test_video_backfill.py b/tests/test_video_backfill.py index 8fdbfa52..74fa6dd7 100644 --- a/tests/test_video_backfill.py +++ b/tests/test_video_backfill.py @@ -173,7 +173,7 @@ def test_nokey_workers_enabled_by_default_and_toggle(db): def test_get_stats_shape_matches_matcher_worker(db): _seed_video(db) stats = RydWorker(db).get_stats() - assert set(stats) == {"enabled", "running", "paused", "idle", "current_item", + assert set(stats) == {"enabled", "needs_key", "running", "paused", "idle", "current_item", "note", "cooldown", "stats", "progress", "breakdown"} assert set(stats["stats"]) == {"matched", "not_found", "errors", "pending"} diff --git a/webui/static/video/video-enrichment-manager.js b/webui/static/video/video-enrichment-manager.js index aa82a0c1..9e5a4883 100644 --- a/webui/static/video/video-enrichment-manager.js +++ b/webui/static/video/video-enrichment-manager.js @@ -89,7 +89,11 @@ } function statusInfo(s) { - if (!s || !s.enabled) return { cls: 'disabled', label: 'Not configured' }; + // Keyless workers that are simply toggled off read "Disabled", not the + // key-implying "Not configured". + if (!s || !s.enabled) { + return { cls: 'disabled', label: (s && s.needs_key === false) ? 'Disabled' : 'Not configured' }; + } if (s.running && !s.paused && !s.idle) return { cls: 'running', label: 'Running' }; if (s.paused) return { cls: 'paused', label: 'Paused' }; if (s.idle) return { cls: 'idle', label: 'Complete' }; @@ -106,7 +110,7 @@ return t ? Math.round(m / t * 100) : 0; } function railSub(s, id) { - if (!s || !s.enabled) return 'Not configured'; + if (!s || !s.enabled) return (s && s.needs_key === false) ? 'Off — enable in Settings' : 'Not configured'; if (id === 'youtube') { if (s.running && s.current_item && s.current_item.name) return s.current_item.name; if (s.queued) return s.queued + ' queued'; diff --git a/webui/static/video/video-enrichment.js b/webui/static/video/video-enrichment.js index 877b91ce..c017224c 100644 --- a/webui/static/video/video-enrichment.js +++ b/webui/static/video/video-enrichment.js @@ -43,7 +43,7 @@ var tip = document.querySelector('[data-video-enrich-tooltip="' + svc + '"]'); if (!tip) return; - var status = !d.enabled ? 'Not configured' + var status = !d.enabled ? (d.needs_key === false ? 'Disabled' : 'Not configured') : d.idle ? 'Complete' : (d.running && !d.paused) ? 'Running' : d.paused ? 'Paused' : 'Idle';