From 909df0cc83539f327da3fa2b256ba9dd6b611418 Mon Sep 17 00:00:00 2001 From: sbcrumb Date: Wed, 15 Oct 2025 09:55:28 -0400 Subject: [PATCH] web: update web interface for tv eps missing date --- VERSION | 2 +- api/routes.py | 7 ++++- api/web_routes.py | 59 +++++++++++++++++++++++++++++++++++++++ static/js/app.js | 70 +++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 130 insertions(+), 8 deletions(-) diff --git a/VERSION b/VERSION index b1b25a5..530cdd9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.2 +2.2.4 diff --git a/api/routes.py b/api/routes.py index f2fdfff..eb3705b 100644 --- a/api/routes.py +++ b/api/routes.py @@ -18,7 +18,7 @@ from api.models import ( from api.web_routes import ( get_movies_list, get_tv_series_list, get_series_episodes, get_series_sources, get_missing_dates_report, get_dashboard_stats, update_movie_date, update_episode_date, bulk_update_source, - get_movie_date_options, get_episode_date_options + get_movie_date_options, get_episode_date_options, debug_series_date_distribution ) @@ -1059,6 +1059,11 @@ def register_routes(app, dependencies: dict): """Get list of available episode sources for filtering""" return await get_series_sources(dependencies) + @app.get("/api/debug/series-date-distribution") + async def _debug_series_dates(): + """Debug endpoint showing TV series date distribution""" + return await debug_series_date_distribution(dependencies) + @app.get("/api/reports/missing-dates") async def _missing_dates_report(): """Get report of content missing dateadded""" diff --git a/api/web_routes.py b/api/web_routes.py index 0ff0b70..b18b630 100644 --- a/api/web_routes.py +++ b/api/web_routes.py @@ -209,6 +209,65 @@ async def get_series_sources(dependencies: dict): return {"sources": sources} +async def debug_series_date_distribution(dependencies: dict): + """Debug function to show TV series date distribution""" + db = dependencies["db"] + + with db.get_connection() as conn: + cursor = conn.cursor() + + # Get series with episode date statistics + cursor.execute(""" + SELECT + s.imdb_id, + s.path, + COUNT(e.episode) as total_episodes, + COUNT(CASE WHEN e.dateadded IS NOT NULL AND e.dateadded != '' THEN 1 END) as episodes_with_dates, + COUNT(CASE WHEN e.dateadded IS NULL OR e.dateadded = '' THEN 1 END) as episodes_without_dates + FROM series s + LEFT JOIN episodes e ON s.imdb_id = e.imdb_id + GROUP BY s.imdb_id, s.path + HAVING COUNT(e.episode) > 0 + ORDER BY total_episodes DESC + LIMIT 50 + """) + + series_stats = [] + complete_count = 0 + incomplete_count = 0 + none_count = 0 + + for row in cursor.fetchall(): + stats = dict(row) + total = stats['total_episodes'] + with_dates = stats['episodes_with_dates'] + without_dates = stats['episodes_without_dates'] + + if without_dates == 0: + category = "complete" + complete_count += 1 + elif with_dates == 0: + category = "none" + none_count += 1 + else: + category = "incomplete" + incomplete_count += 1 + + stats['category'] = category + stats['title'] = stats['path'].split('/')[-1] if stats['path'] else stats['imdb_id'] + series_stats.append(stats) + + return { + "series_sample": series_stats[:20], # First 20 for debugging + "distribution": { + "complete": complete_count, + "incomplete": incomplete_count, + "none": none_count, + "total": complete_count + incomplete_count + none_count + } + } + + async def get_series_episodes(dependencies: dict, imdb_id: str): """Get all episodes for a specific TV series""" db = dependencies["db"] diff --git a/static/js/app.js b/static/js/app.js index e398524..d1822a6 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -114,13 +114,16 @@ async function loadDashboard() { function updateDashboardStats() { if (!dashboardData) return; + // Debug: Log dashboard data to see what fields are available + console.log('Dashboard data received:', dashboardData); + const moviesTotal = dashboardData.movies_total || 0; const moviesWithDates = dashboardData.movies_with_dates || 0; - const moviesWithoutDates = dashboardData.movies_without_dates || 0; + const moviesWithoutDates = dashboardData.movies_without_dates || (moviesTotal - moviesWithDates); const episodesTotal = dashboardData.episodes_total || 0; const episodesWithDates = dashboardData.episodes_with_dates || 0; - const episodesWithoutDates = dashboardData.episodes_without_dates || 0; + const episodesWithoutDates = dashboardData.episodes_without_dates || (episodesTotal - episodesWithDates); document.getElementById('movies-total').textContent = moviesTotal; document.getElementById('movies-with-dates').textContent = `${moviesWithDates} with dates, ${moviesWithoutDates} without`; @@ -429,14 +432,39 @@ async function viewSeriesEpisodes(imdbId) { } function showEpisodesModal(data) { + // Calculate statistics + const totalEpisodes = data.episodes.length; + const episodesWithDates = data.episodes.filter(ep => ep.dateadded && ep.dateadded.trim() !== '').length; + const episodesWithoutDates = totalEpisodes - episodesWithDates; + const episodesWithVideo = data.episodes.filter(ep => ep.has_video_file).length; + const modalHtml = `