feat: show subtitle quality score, provider, and sync/translate status on movie detail#3337
Closed
davidgut1982 wants to merge 6 commits into
Closed
Conversation
…ate From) Adds a translate_from field to language profile items so Bazarr can automatically translate a downloaded subtitle to a target language without manual intervention. Behaviour: - Providers are still searched first (translate_from is a parallel trigger) - When a source language subtitle is downloaded and the target language is still missing, translation is queued automatically via the job queue - Translated subtitles are immediately re-indexed so missing_subtitles is updated without waiting for the next scheduled scan - Backward compatible: translate_from defaults to null (disabled) Files changed: - bazarr/app/database.py: DB migration adds translate_from field - bazarr/subtitles/processing.py: post-download auto-translation hook - bazarr/subtitles/tools/translate/main.py: re-index after translation - frontend/src/types/api.d.ts: ProfileItem type extension - frontend/src/components/forms/ProfileEditForm.tsx: Translate From UI column Closes morpheus65535#3334 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ensures consistent 'series'/'movies' values are passed to translate_subtitles_file(), matching the convention used by the existing API endpoint handler. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Only trigger automatic subtitle translation when the source subtitle meets a minimum quality score (default: 90%). Prevents translating poorly-matched or badly-synced subtitles. - bazarr/app/config.py: translator.min_source_score setting (default 90) - subtitles/processing.py: check score before queuing translation - subtitles/wanted/movies.py: check history score for existing subs - subtitles/wanted/series.py: same for series - frontend: min score input in Settings -> Subtitles -> Translator Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ie detail Adds three new columns to the movie detail subtitle table: - Score badge (green ≥90%, yellow 70-89%, red <70%) - Provider name - Sync/translate status icons (reuses existing HistoryIcon) Data is sourced from the existing movie history API (useMovieHistory hook). History records are joined to subtitles by subtitles_path with null guards. Most recent download/upgrade record wins for score and provider. Sync (action=5) and translate (action=6) events shown as overlay icons. Phase 1: movies only. Episode support deferred (N+1 query concern). Closes morpheus65535#3336 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ScoreBadge: remove duplicate % (API already appends it) - historyMap: use first-wins (backend returns DESC, first = most recent) - historyMap: include action=2 (Manual downloads) for score display Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
61d0d03 to
0a92852
Compare
davidgut1982
added a commit
to davidgut1982/bazarr
that referenced
this pull request
May 21, 2026
…er/status columns (PR morpheus65535#3337) to LavX - Add translate_from field to Language.ProfileItem type - Add TranslateFromCell selector in ProfileEditForm - Add min_source_score Number control in Translator settings - Add history prop + Score/Provider/Status columns to Movies/Details/table - Preserve all LavX-specific SubtitleToolsMenu and navigation code
LavX
added a commit
to LavX/bazarr
that referenced
this pull request
May 27, 2026
* feat: port auto-translate from language profile (PR morpheus65535#3335) to LavX - Add translator.min_source_score config validator (default 90%) - Add translate_from field migration in upgrade_languages_profile_values - Add _trigger_auto_translation hook in processing.py - Add translate_from_map logic to wanted/movies.py and series.py * feat: port translate_from UI (PR morpheus65535#3335) and score/provider/status columns (PR morpheus65535#3337) to LavX - Add translate_from field to Language.ProfileItem type - Add TranslateFromCell selector in ProfileEditForm - Add min_source_score Number control in Translator settings - Add history prop + Score/Provider/Status columns to Movies/Details/table - Preserve all LavX-specific SubtitleToolsMenu and navigation code * fix: treat missing history as at-threshold for auto-translate When a source-language subtitle exists on disk but has no TableHistory/TableHistoryMovie row (manual placement or pre-tracking era), source_score_pct was 0 and auto-translation was silently skipped. Set source_score_pct = min_score in that case so translation proceeds instead of silently blocking. * fix: auto-translate forced guard, double-translate prevention, shared util - Fix forced-subtitle guard in _trigger_auto_translation: inspect the forced bool parameter instead of string-scanning downloaded_lang which never contains ':forced' - Write history entry before translate_subtitles_file in wanted-scan paths to prevent double-translation when async job has not completed before next scan cycle - Extract _find_existing_subtitle_path to shared wanted/utils.py to eliminate copy-paste divergence risk between series and movies paths - Hoist check_missing_languages() above profile-items loop in _trigger_auto_translation (called once instead of N times per item) Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * fix: wire double-translate guard query to correct language column The previous commit wrote history entries with language=target_lang but the guard query checked language=source_lang, so the guard could never find the written entry. Add explicit guard queries on TableHistory / TableHistoryMovie for action=6 AND language=target_lang before queuing translation, so post-restart re-queuing for completed translations is actually blocked. Also remove duplicate store_subtitles import in wanted/series.py. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * fix: guard query matches hi/forced language suffixes in translate dedup TableHistory.language stores 'fr:hi' or 'fr:forced' for hearing-impaired and forced-subtitle targets. The previous guard used an equality check on the bare lang_code ('fr') which never matched suffixed rows, allowing re-queuing of HI/forced auto-translations on every scan cycle. Change to .like(f'{lang_code}%') to match all suffix variants. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * fix: source score lookup matches :hi/:forced language suffixes (closes #142) The history query for source subtitle score used exact equality on the language column (e.g. 'en') but the DB stores 'en:hi' or 'en:forced' for HI/forced subtitle tracks. The query returned no rows for those cases, silently falling back to min_score instead of validating actual source quality. Change to .like(f"{translate_cfg['from']}%") to match all suffix variants, consistent with the identical pattern already used in the deduplication guard queries in the same files. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * chore: add pre-commit hooks (ruff, detect-secrets, standard checks) Adds .pre-commit-config.yaml with: - pre-commit-hooks: trailing whitespace, EOF fixer, YAML/JSON check, large-file guard (500 KB), debug-statement and merge-conflict detection - ruff (lint --fix) and ruff-format, respecting existing ruff.toml ruleset - detect-secrets with baseline covering 159 known findings in 52 files; future commits will only fail on *new* secrets Chains with the existing husky/pretty-quick frontend hook by appending a call to frontend/.husky/pre-commit after pre-commit runs in .git/hooks/pre-commit (required because core.hooksPath was pointing to husky's shim directory). Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * fix: address LavX PR #137 review feedback - Remove pre-logging of history action=6 before async translation job completes; translate services already write history on success, so pre-logging caused the duplicate guard to permanently skip failed jobs - Add path_replace_fn parameter to _find_existing_subtitle_path so caller passes path_mappings.path_replace / path_replace_movie; raw os.path.exists on DB-stored paths breaks Docker path-mapped setups - Convert f-string logging to % formatting to fix G004 lint failures in series.py, movies.py, and processing.py Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * fix: guard translate re-queue with jobs_queue pending check, clean up logging - Add jobs_queue in-memory dedup check before translate_subtitles_file so wanted-scan doesn't re-queue the same translation while an async job is already pending (complements the history guard which only fires after successful completion) - Remove redundant str(e) from logging.exception calls (traceback is already included automatically) - Use %.1f%% for min_score to match source_score_percent formatting Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * Add per-provider language settings * Invert provider language selection * Fix auto-translate media type and variant matching Follow-up to #137. Queues series translations as episodes and matches Translate From profile targets by exact language variant. * Fix embedded subtitle history upgrade handling (#154) Co-authored-by: david <david.gutowsky@gmail.com> * chore: prepare v2.3.1 draft release * docs: revise v2.3.1 draft notes * docs: add v2.3.1 codename * fix: track per-provider apply state and add Apply all in updates panel (#155) Applying one provider update used to flip every card's spinner because all cards shared a single useMutation isPending boolean. Track applying provider ids in local state so each card spins independently. Also add an Apply all button to the Available now header that fans out mutateAsync calls in parallel and settles once every apply finishes. * docs: rename v2.3.1 codename to Keystone, add hero sketch and PNG Drop the redundant "Bridge" suffix so v2.3.1 shares the Keystone codename with v2.3.0. New hero sketch (keystone-v2.3.1.html) varies seed and adds a teal accent for the auto-translate headline. --------- Co-authored-by: david <david.gutowsky@gmail.com> Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Owner
|
So, basically, you should read CONTRIBUTING.md and, once done, get back to your PR and explain us, in your words, what you're trying to achieve. This isn't acceptable use of AI by our standards. Please refrain from doing pure vibe coding. We won't be accepting this kind of PR. Feel free to reopen this PR when you're ready or open a new one cleaned and done by yourself. Until then, please respect our wishes. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #3336
Adds subtitle quality metadata to the movie detail view so users can see the quality of their downloaded subtitles at a glance — without inspecting the database.
New columns on the movie subtitle table
—if no historyopensubtitlescom,whisperai)Data is sourced from the existing movie history API (
useMovieHistoryhook — already in the codebase, already used inHistoryModal). No backend changes required.Implementation details
subtitles_pathwith full null guards (embedded tracks, delete events, etc.)action=1oraction=3) wins for score and provideraction=5) and translate (action=6) events shown as overlay icons via the existingHistoryIconcomponentScoreBadgeparses the pre-formatted score string already returned by the APIScope
Phase 1 (this PR): movies only. Episode support is deferred — the episode view renders a full series table where calling
useEpisodeHistoryper row creates an N+1 query problem. A follow-up PR will address this with a series-level history endpoint or lazy-load pattern.Files changed
frontend/src/pages/Movies/Details/index.tsxuseMovieHistorycall; passhistoryprop to tablefrontend/src/pages/Movies/Details/table.tsxScoreBadge,historyMap,statusMap, and 3 new columnsTesting
vite buildin 4.19s)—gracefully🤖 Generated with Claude Code