From 7b788f7dc8f61b91130fef95f98d975ce138f6ae Mon Sep 17 00:00:00 2001 From: nessi Date: Thu, 13 Aug 2026 16:25:57 +0200 Subject: [PATCH] feat: add "Without German" tab to filter media missing German audio or subtitles Add new navigation tab showing count of movies and episodes without German tracks. Implement has_german_track() helper to check for German audio or subtitles. Filter movies and series to create missing_german_movies and missing_german_series lists passed to template. Add dedicated view section with tables for movies and series lacking German content, including empty state message. Update navigation translation logic --- app.py | 16 +++++++++++++++- templates/index.html | 9 +++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app.py b/app.py index bc42331..e7112db 100644 --- a/app.py +++ b/app.py @@ -153,6 +153,10 @@ def language_state(audios): if "Englisch" in names: return {"class":"bad", "label":"English only"} return {"class":"neutral", "label":"Andere"} +def has_german_track(row): + languages = row.get("audio_languages", []) + row.get("subtitle_languages", []) + return any(language.get("name") == "Deutsch" for language in languages) + def media_row(name, year, media_file, remote, local, extra=None): path = media_file.get("path") if media_file else None if not path and media_file and media_file.get("relativePath"): path = str(Path(media_file.get("basePath") or "") / media_file["relativePath"]) @@ -224,7 +228,17 @@ def index(): series = sonarr_groups() if any(row["pending"] for group in series for row in group["episodes"]): start_scan("sonarr") except Exception as exc: log.exception("Sonarr nicht erreichbar"); error = f"{error + ' | ' if error else ''}Sonarr: {exc}" - return render_template("index.html", rows=rows, series=series, error=error, sonarr_enabled=bool(SONARR_URL and SONARR_API_KEY), sab_enabled=bool(SAB_URL and SAB_API_KEY), radarr_media_path=RADARR_MEDIA_PATH, local_media_path=LOCAL_MEDIA_PATH, local_series_path=LOCAL_SERIES_PATH) + missing_german_movies = [row for row in rows if not has_german_track(row)] + missing_german_series = [] + for group in series: + episodes = [episode for episode in group["episodes"] if not has_german_track(episode)] + if episodes: + missing_german_series.append({**group, "episodes": episodes}) + return render_template("index.html", rows=rows, series=series, missing_german_movies=missing_german_movies, + missing_german_series=missing_german_series, error=error, + sonarr_enabled=bool(SONARR_URL and SONARR_API_KEY), sab_enabled=bool(SAB_URL and SAB_API_KEY), + radarr_media_path=RADARR_MEDIA_PATH, local_media_path=LOCAL_MEDIA_PATH, + local_series_path=LOCAL_SERIES_PATH) @app.post("/api/rescan") def api_rescan(): diff --git a/templates/index.html b/templates/index.html index 386ce01..538028a 100644 --- a/templates/index.html +++ b/templates/index.html @@ -6,7 +6,7 @@
Language Dashboard
Audio- und Untertitelspuren aus den Mediendateien
{% if error %}{% endif %} - +
Scan wird vorbereitet …Radarr: {{ radarr_media_path }}
@@ -16,6 +16,10 @@ {% if sonarr_enabled %}
{{ series|length }} SerienScan wird vorbereitet …Dashboard: {{ local_series_path }}
{% for group in series %}
{{ group.title }} ({{ group.year or '—' }}) · {{ group.episodes|length }} Episoden{% for r in group.episodes %}{% endfor %}
EpisodeQualityStatusAudioUntertitelVideoGröße
{{ r.title }}{{ r.quality }}{{ r.state.label }}
{% for l in r.audio_languages %}{{ l.flag }} {{ l.name }}{% else %}{% endfor %}
{% for l in r.subtitle_languages %}{{ l.flag }} {{ l.name }}{% else %}{% endfor %}
{{ r.video_codec }}{{ r.size }}
{% endfor %}
{% endif %} +
{{ missing_german_movies|length + (missing_german_series|map(attribute='episodes')|map('length')|sum) }} Einträge ohne DeutschKein deutsches Audio und keine deutschen Untertitel
+{% for r in missing_german_movies %}{% endfor %}
FilmQualitätStatusAudioUntertitelVideoGröße
{{ r.title }}{{ r.year or '' }}{{ r.quality }}Ohne Deutsch
{% for l in r.audio_languages %}{{ l.flag }} {{ l.name }}{% else %}{% endfor %}
{% for l in r.subtitle_languages %}{{ l.flag }} {{ l.name }}{% else %}{% endfor %}
{{ r.video_codec }}{{ r.size }}
+{% for group in missing_german_series %}
{{ group.title }} ({{ group.year or '—' }}) · {{ group.episodes|length }} Episoden ohne Deutsch{% for r in group.episodes %}{% endfor %}
EpisodeQualitätStatusAudioUntertitelVideoGröße
{{ r.title }}{{ r.quality }}Ohne Deutsch
{% for l in r.audio_languages %}{{ l.flag }} {{ l.name }}{% else %}{% endfor %}
{% for l in r.subtitle_languages %}{{ l.flag }} {{ l.name }}{% else %}{% endfor %}
{{ r.video_codec }}{{ r.size }}
{% endfor %} +{% if not missing_german_movies and not missing_german_series %}
Alle vorhandenen Filme und Episoden haben deutsches Audio oder deutsche Untertitel.
{% endif %}
{% if sab_enabled %}
Downloads werden geladen …SABnzbd …Geschwindigkeit: —
DownloadStatusFortschrittGröße / RestRestzeitQuelleSprache
Downloads werden geladen …
{% endif %}
@@ -30,6 +34,7 @@ document.querySelector('#rescan').onclick=async()=>{const b=document.querySelect