From 3a24fc24b10ac902e16e0015dc131d69091ddfb5 Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Wed, 17 Jun 2026 11:59:39 -0700 Subject: [PATCH] YouTube worker: push status over the socket like the others (stop polling) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The date enricher was the odd one out — the dashboard polled /api/video/enrichment/youtube/status every 3s (flooding the access log) instead of using the shared WebSocket the other three workers push on. Now the existing _emit_video_enrichment_status_loop also emits 'enrichment:youtube' (same stats shape), and video-enrichment.js binds it on the socket alongside tmdb/tvdb/omdb. Removed the bespoke polling loop. One-time prime fetch on load stays (instant initial state); everything after is socket-driven. Consistent with the others. --- web_server.py | 8 ++++++++ webui/static/video/video-enrichment.js | 20 +++++++------------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/web_server.py b/web_server.py index 9dec4b81..b80ff17c 100644 --- a/web_server.py +++ b/web_server.py @@ -37271,6 +37271,14 @@ def _emit_video_enrichment_status_loop(): socketio.emit(f'enrichment:{svc}', w.get_stats()) except Exception as e: logger.debug(f"Error emitting video {svc} status: {e}") + # The YouTube date enricher is a standalone daemon (not an engine worker), + # but it reports the SAME stats shape — push it on the same socket so its + # dashboard orb listens like the others (no /enrichment/youtube/status poll). + try: + from core.video.youtube_enrichment import get_youtube_date_enricher + socketio.emit('enrichment:youtube', get_youtube_date_enricher().stats()) + except Exception as e: + logger.debug(f"Error emitting video youtube status: {e}") def _emit_tool_progress_loop(): diff --git a/webui/static/video/video-enrichment.js b/webui/static/video/video-enrichment.js index 418f8750..c87db590 100644 --- a/webui/static/video/video-enrichment.js +++ b/webui/static/video/video-enrichment.js @@ -14,9 +14,10 @@ (function () { 'use strict'; - var SERVICES = ['tmdb', 'tvdb', 'omdb']; // pushed over the shared socket - var POLLED = ['youtube']; // standalone daemon → light polling - var ALL = SERVICES.concat(POLLED); + // All four push status over the shared socket every 2s (server emits + // 'enrichment:') — including the standalone YouTube date enricher — so the + // browser never polls /api/video/enrichment//status. + var SERVICES = ['tmdb', 'tvdb', 'omdb', 'youtube']; function onVideoSide() { return document.body.getAttribute('data-side') === 'video'; @@ -74,13 +75,7 @@ // One-time fetch so the buttons aren't blank until the first socket push. function primeOnce() { - if (onVideoSide() && !document.hidden) ALL.forEach(pollOne); - } - // The YouTube date enricher isn't on the socket — poll it so its orb reflects - // activity (only while the video side is foregrounded). - function pollPolledLoop() { - if (onVideoSide() && !document.hidden) POLLED.forEach(pollOne); - setTimeout(pollPolledLoop, 3000); + if (onVideoSide() && !document.hidden) SERVICES.forEach(pollOne); } // Listen on the shared socket (set up by core.js) for the server-pushed @@ -112,7 +107,7 @@ } function init() { - ALL.forEach(function (svc) { + SERVICES.forEach(function (svc) { var b = btn(svc); if (b) b.addEventListener('click', function () { toggle(svc); }); }); @@ -123,8 +118,7 @@ }); } primeOnce(); // instant initial state - bindSocket(); // then the socket pushes updates for tmdb/tvdb/omdb - pollPolledLoop(); // ...and poll the youtube enricher + bindSocket(); // then the socket pushes updates for all four (incl. youtube) // Re-prime when the user returns to the tab (socket kept pushing, but a // quick fetch snaps the buttons current immediately). document.addEventListener('visibilitychange', function () {