fix(release): refresh tech_string after enrich_from_probe

enrich_from_probe fills None fields on ParsedRelease (quality, source,
codec, audio_*, languages) but left tech_string at its parser-time
value — so the filename builders (movie_folder_name, episode_filename,
…) saw stale tech tokens even after a successful probe.

Re-derive tech_string the same way the parser does — quality.source.codec
joined by dots, skipping None — at the end of enrich_from_probe. Token-
level values still win because enrich only fills None fields.

Four new tests in TestTechString cover: enrichment rebuilds it,
existing source survives, no-info input leaves it untouched, fully
empty parsed produces ''.
This commit is contained in:
2026-05-20 09:26:09 +02:00
parent 03aa844d7d
commit e79ca462b8
3 changed files with 54 additions and 0 deletions
+8
View File
@@ -15,6 +15,14 @@ callers).
## [Unreleased]
### Fixed
- **`enrich_from_probe` now refreshes `tech_string`** after filling
`quality` / `source` / `codec`. Previously the field stayed at its
parser-time value, so filename builders saw stale tech tokens even
after a successful probe. New `TestTechString` class in
`tests/application/test_enrich_from_probe.py` locks the behavior.
### Added
- **`inspect_release` orchestrator + `InspectedResult` VO**
@@ -80,3 +80,10 @@ def enrich_from_probe(parsed: ParsedRelease, info: MediaInfo) -> None:
for lang in info.audio_languages:
if lang.lower() != "und" and lang.upper() not in existing:
parsed.languages.append(lang)
# Re-derive tech_string so filename builders see the enriched
# quality/source/codec. Built the same way as in the parser pipeline:
# the non-None parts joined by dots, in order.
parsed.tech_string = ".".join(
p for p in (parsed.quality, parsed.source, parsed.codec) if p
)
@@ -210,3 +210,42 @@ class TestLanguages:
p = _bare()
enrich_from_probe(p, MediaInfo())
assert p.languages == []
# --------------------------------------------------------------------------- #
# tech_string #
# --------------------------------------------------------------------------- #
class TestTechString:
"""tech_string drives the filename builders; it must be re-derived
whenever quality / source / codec change."""
def test_rebuilt_from_filled_quality_and_codec(self):
p = _bare()
enrich_from_probe(
p, _info_with_video(width=1920, height=1080, codec="hevc")
)
assert p.quality == "1080p"
assert p.codec == "x265"
assert p.tech_string == "1080p.x265"
def test_keeps_existing_source_when_enriching(self):
# Token-level source must stay; probe fills only None fields.
p = _bare(source="BluRay")
enrich_from_probe(
p, _info_with_video(width=1920, height=1080, codec="hevc")
)
assert p.tech_string == "1080p.BluRay.x265"
def test_unchanged_when_no_enrichable_video_info(self):
# No video info → nothing to fill → tech_string stays as it was.
p = _bare(quality="2160p", source="WEB-DL", codec="x265")
p.tech_string = "2160p.WEB-DL.x265"
enrich_from_probe(p, MediaInfo())
assert p.tech_string == "2160p.WEB-DL.x265"
def test_empty_when_nothing_known(self):
p = _bare()
enrich_from_probe(p, MediaInfo())
assert p.tech_string == ""