fix(dl): keep the --enrich original language after get_tracks

A service that sets title.language in get_tracks replaced the metadata language, so 'orig' picked the wrong audio. Video tags and original flags move to the enrich language with the title.
This commit is contained in:
imSp4rky
2026-10-02 20:06:56 -06:00
parent 73bdb98d3e
commit 825678a1c4
3 changed files with 75 additions and 1 deletions
@@ -0,0 +1,53 @@
from types import SimpleNamespace
from langcodes import Language
from unshackle.core.utilities import apply_original_language
class FakeTracks(SimpleNamespace):
def __iter__(self):
return iter([*self.videos, *self.audio])
def track(lang, original=False):
return SimpleNamespace(language=Language.get(lang) if lang else None, is_original_lang=original)
def title(language, videos=(), audio=()):
return SimpleNamespace(
language=Language.get(language) if language else None,
tracks=FakeTracks(videos=list(videos), audio=list(audio)),
)
def test_overrides_the_service_guess_and_its_videos():
t = title("es", videos=[track("es"), track("es")])
apply_original_language(t, Language.get("it"))
assert str(t.language) == "it"
assert [str(v.language) for v in t.tracks.videos] == ["it", "it"]
def test_videos_in_another_language_keep_it():
t = title("es", videos=[track("es"), track("ja"), track(None)])
apply_original_language(t, Language.get("it"))
assert [v.language and str(v.language) for v in t.tracks.videos] == ["it", "ja", None]
def test_no_service_language_keeps_video_tags():
t = title(None, videos=[track("en")])
apply_original_language(t, Language.get("it"))
assert str(t.language) == "it"
assert str(t.tracks.videos[0].language) == "en"
def test_original_flag_moves_to_the_enrich_language():
t = title("es", audio=[track("es-419", original=True), track("it-IT")])
apply_original_language(t, Language.get("it"))
assert [a.is_original_lang for a in t.tracks.audio] == [False, True]
def test_same_language_leaves_flags_alone():
t = title("it", videos=[track(None, original=True)])
apply_original_language(t, Language.get("it"))
assert t.tracks.videos[0].is_original_lang is True
+4 -1
View File
@@ -74,6 +74,7 @@ from unshackle.core.tracks.dv_fixup import apply_dv_fixup
from unshackle.core.tracks.hybrid import Hybrid
from unshackle.core.tracks.track import assert_fragments_decrypted, has_encrypted_sample_entry
from unshackle.core.utilities import (
apply_original_language,
as_requested,
declared_kwargs,
embedded_audio_langs,
@@ -1759,13 +1760,13 @@ class dl:
cache_region = service.current_region if hasattr(service, "current_region") else None
cache_account_hash = get_account_hash(service.credential) if hasattr(service, "credential") else None
enrich_lang: Optional[Language] = None
if self.enrich:
sample_title = titles[0] if hasattr(titles, "__getitem__") else titles
kind = "tv" if isinstance(sample_title, Episode) else "movie"
enrich_title: Optional[str] = None
enrich_year: Optional[int] = None
enrich_lang: Optional[Language] = None
enrich_result = providers.resolve_by_ids(
self.tmdb_id,
@@ -2099,6 +2100,8 @@ class dl:
try:
title.tracks.add(service.get_tracks(title), warn_only=True)
title.tracks.chapters = service.get_chapters(title)
if enrich_lang:
apply_original_language(title, enrich_lang)
except Exception as e:
if self.debug_logger:
self.debug_logger.log_error(
+18
View File
@@ -248,6 +248,24 @@ def embedded_audio_langs(videos: Sequence[Any], keep_videos: bool) -> list[str]:
return [video.data["audio_language"] for video in videos if video.data.get("audio_language")]
def apply_original_language(title: Any, language: Language) -> None:
"""
Make ``language`` the title's original language over the one the service set.
A service tags its videos and original-language flags with its own guess, so the videos that
carry that guess move to ``language`` and every track's flag is set again.
"""
guess = title.language
if guess == language:
return
for video in title.tracks.videos:
if guess and video.language == guess:
video.language = language
for track in title.tracks:
track.is_original_lang = bool(track.language and is_close_match(track.language, [language]))
title.language = language
def find_missing_langs(
requested: Sequence[str],
available: Sequence[Union[str, Language, None]],