Video enrichment: add the 4 new workers to the dashboard header
- Dashboard header now shows fanart.tv / OpenSubtitles / YouTube Votes / SponsorBlock buttons alongside TMDB/TVDB/OMDb/YouTube (same chip + spinner + tooltip + click pause/resume + worker-orb animation). - Socket status loop now iterates ALL engine workers (matchers + backfill) instead of a hardcoded 3, so new buttons get live 2s status with no extra wiring. - video-enrichment.js SERVICES + video-worker-orbs.js WORKER_DEFS extended. header-actions already flex-wraps, so 8 buttons reflow cleanly.
This commit is contained in:
parent
6f14f15dd6
commit
530d6f181f
4 changed files with 74 additions and 6 deletions
|
|
@ -37257,17 +37257,16 @@ def _emit_video_enrichment_status_loop():
|
|||
the access log). No-op until the video engine is actually running, so this
|
||||
never spins it up on the music side."""
|
||||
from core.video.enrichment.engine import peek_video_enrichment_engine
|
||||
services = ('tmdb', 'tvdb', 'omdb')
|
||||
while not globals().get('IS_SHUTTING_DOWN', False):
|
||||
socketio.sleep(2)
|
||||
eng = peek_video_enrichment_engine()
|
||||
if eng is None:
|
||||
continue
|
||||
for svc in services:
|
||||
# Emit for EVERY registered worker (matchers + backfill: fanart / opensubtitles
|
||||
# / ryd / sponsorblock) so new dashboard buttons get live status with no extra
|
||||
# wiring here.
|
||||
for svc, w in (eng.workers or {}).items():
|
||||
try:
|
||||
w = eng.worker(svc)
|
||||
if w is None:
|
||||
continue
|
||||
socketio.emit(f'enrichment:{svc}', w.get_stats())
|
||||
except Exception as e:
|
||||
logger.debug(f"Error emitting video {svc} status: {e}")
|
||||
|
|
|
|||
|
|
@ -504,6 +504,70 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-enrich-container" style="--ve-accent: 228, 80, 154;">
|
||||
<button class="video-enrich-button" type="button" data-video-enrich="fanart" title="fanart.tv Artwork">
|
||||
<span class="video-enrich-glyph" aria-hidden="true">🎨</span>
|
||||
<span class="video-enrich-spinner" aria-hidden="true"></span>
|
||||
</button>
|
||||
<div class="video-enrich-tooltip" data-video-enrich-tooltip="fanart">
|
||||
<div class="tooltip-content">
|
||||
<div class="tooltip-header">fanart.tv Artwork</div>
|
||||
<div class="tooltip-body">
|
||||
<div class="tooltip-status">Status: <span data-video-enrich-status>Idle</span></div>
|
||||
<div class="tooltip-current" data-video-enrich-current>No active matches</div>
|
||||
<div class="tooltip-progress" data-video-enrich-progress>Progress: 0 / 0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-enrich-container" style="--ve-accent: 34, 160, 121;">
|
||||
<button class="video-enrich-button" type="button" data-video-enrich="opensubtitles" title="OpenSubtitles">
|
||||
<span class="video-enrich-glyph" aria-hidden="true">💬</span>
|
||||
<span class="video-enrich-spinner" aria-hidden="true"></span>
|
||||
</button>
|
||||
<div class="video-enrich-tooltip" data-video-enrich-tooltip="opensubtitles">
|
||||
<div class="tooltip-content">
|
||||
<div class="tooltip-header">OpenSubtitles</div>
|
||||
<div class="tooltip-body">
|
||||
<div class="tooltip-status">Status: <span data-video-enrich-status>Idle</span></div>
|
||||
<div class="tooltip-current" data-video-enrich-current>No active matches</div>
|
||||
<div class="tooltip-progress" data-video-enrich-progress>Progress: 0 / 0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-enrich-container" style="--ve-accent: 239, 68, 68;">
|
||||
<button class="video-enrich-button" type="button" data-video-enrich="ryd" title="YouTube Votes (Return YouTube Dislike)">
|
||||
<span class="video-enrich-glyph" aria-hidden="true">👍</span>
|
||||
<span class="video-enrich-spinner" aria-hidden="true"></span>
|
||||
</button>
|
||||
<div class="video-enrich-tooltip" data-video-enrich-tooltip="ryd">
|
||||
<div class="tooltip-content">
|
||||
<div class="tooltip-header">YouTube Votes</div>
|
||||
<div class="tooltip-body">
|
||||
<div class="tooltip-status">Status: <span data-video-enrich-status>Idle</span></div>
|
||||
<div class="tooltip-current" data-video-enrich-current>No active matches</div>
|
||||
<div class="tooltip-progress" data-video-enrich-progress>Progress: 0 / 0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-enrich-container" style="--ve-accent: 0, 180, 160;">
|
||||
<button class="video-enrich-button" type="button" data-video-enrich="sponsorblock" title="SponsorBlock">
|
||||
<span class="video-enrich-glyph" aria-hidden="true">⏭</span>
|
||||
<span class="video-enrich-spinner" aria-hidden="true"></span>
|
||||
</button>
|
||||
<div class="video-enrich-tooltip" data-video-enrich-tooltip="sponsorblock">
|
||||
<div class="tooltip-content">
|
||||
<div class="tooltip-header">SponsorBlock</div>
|
||||
<div class="tooltip-body">
|
||||
<div class="tooltip-status">Status: <span data-video-enrich-status>Idle</span></div>
|
||||
<div class="tooltip-current" data-video-enrich-current>No active matches</div>
|
||||
<div class="tooltip-progress" data-video-enrich-progress>Progress: 0 / 0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Reuses music's .em-manage-btn* classes verbatim so it's
|
||||
pixel-identical; wired by data-attribute (no inline
|
||||
handler) via video-enrichment.js, never music's. -->
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
// All four push status over the shared socket every 2s (server emits
|
||||
// 'enrichment:<svc>') — including the standalone YouTube date enricher — so the
|
||||
// browser never polls /api/video/enrichment/<svc>/status.
|
||||
var SERVICES = ['tmdb', 'tvdb', 'omdb', 'youtube'];
|
||||
var SERVICES = ['tmdb', 'tvdb', 'omdb', 'youtube',
|
||||
'fanart', 'opensubtitles', 'ryd', 'sponsorblock'];
|
||||
|
||||
function onVideoSide() {
|
||||
return document.body.getAttribute('data-side') === 'video';
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@
|
|||
{ sel: '[data-video-enrich="tvdb"]', color: [168, 85, 247], id: 'tvdb' },
|
||||
{ sel: '[data-video-enrich="omdb"]', color: [245, 197, 24], id: 'omdb' },
|
||||
{ sel: '[data-video-enrich="youtube"]', color: [255, 59, 59], id: 'youtube' },
|
||||
{ sel: '[data-video-enrich="fanart"]', color: [228, 80, 154], id: 'fanart' },
|
||||
{ sel: '[data-video-enrich="opensubtitles"]', color: [34, 160, 121], id: 'opensubtitles' },
|
||||
{ sel: '[data-video-enrich="ryd"]', color: [239, 68, 68], id: 'ryd' },
|
||||
{ sel: '[data-video-enrich="sponsorblock"]', color: [0, 180, 160], id: 'sponsorblock' },
|
||||
{ sel: '[data-video-manage-workers]', color: [168, 85, 247], hub: true },
|
||||
];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue