feat(i18n): the server's closed English vocabularies named in the reader's language (E30 S2)

- lib/vocab + the `vocab` locale area: TMDB crew jobs and departments, auto-tags (D1 A: the data
  stays English, the catalog is named at its one source, useTags), built-in download profiles,
  YouTube topics; held key-for-key to the backend's own lists by backendIds.contract.
- Countries by ISO code: TMDB parse stores {code, name}; rows stored before are coded from TMDB's
  own country list in one request (run_enrich); Intl names them, historic codes (YU, SU, XI…)
  from the catalog.
- Player tracks named from the language tag, forced/SDH flags and codec tail, not Plex's
  server-language displayTitle; no invented "Audio N" on the server.
- Download lifecycle notices (shared / expiring / expired / evicted) named from data; the share
  notice carries the title.
- Scheduler: the job result rides along as data and is named per key (dashboard + run notice).
- Invite status named; a render crash's notice no longer shows the engine's English message.
- Fix: YouTube links …/wiki/Humour, the tagger looked for "Humor" — Comedy never came from a topic.
This commit is contained in:
2026-09-29 21:21:19 +02:00
parent f6298d29af
commit f3a85916ec
50 changed files with 1475 additions and 94 deletions
+69 -2
View File
@@ -49,7 +49,7 @@ MOVIE_PAYLOAD = {
],
},
"production_companies": [{"name": "Paramount"}, {"name": "Alfran"}],
"production_countries": [{"name": "United States of America"}],
"production_countries": [{"iso_3166_1": "US", "name": "United States of America"}],
"recommendations": {
"results": [
{
@@ -126,7 +126,8 @@ def test_parse_movie_pulls_all_fields():
},
] # the Gaffer is filtered; the two Coppola jobs survive (dedup is by name+job)
assert d["studios"] == ["Paramount", "Alfran"]
assert d["production_countries"] == ["United States of America"]
# E30: the code beside the English name, so the client can name the country in the reader's language.
assert d["production_countries"] == [{"code": "US", "name": "United States of America"}]
assert [r["tmdb_id"] for r in d["recommendations"]] == [240, 999]
assert d["backdrops"] == ["/bd1.jpg", "/bd2.jpg"]
# cast + crew names → tmdb person ids for the plex_people foundation
@@ -429,3 +430,69 @@ def test_resolve_recs_matches_by_media_type_not_bare_id(db):
}
assert hit[900]["in_library"] is True and hit[900]["rating_key"] == "m900"
assert hit[500]["in_library"] is True and hit[500]["rating_key"] == "s500"
# ---- E30: countries by ISO code -----------------------------------------------------------------
class FakeCountries(FakeTmdb):
"""TMDB's /configuration/countries, counting the requests."""
def __init__(self):
super().__init__()
self.calls = 0
def countries(self):
self.calls += 1
return [
{"iso_3166_1": "US", "english_name": "United States of America"},
{"iso_3166_1": "YU", "english_name": "Yugoslavia"},
]
def test_countries_stored_before_codes_get_them_from_tmdbs_list(db):
lib = _lib(db)
old = PlexItem(
rating_key="m1",
library_id=lib.id,
kind="movie",
title="Old",
production_countries=["Yugoslavia", "Atlantis"],
tmdb_enriched_at=datetime.now(timezone.utc),
)
show_lib = _lib(db, key="2", kind="show")
show = PlexShow(
rating_key="s1",
library_id=show_lib.id,
title="Show",
production_countries=["United States of America"],
)
new = PlexItem(
rating_key="m2",
library_id=lib.id,
kind="movie",
title="New",
production_countries=[{"code": "US", "name": "United States of America"}],
)
db.add_all([old, show, new])
db.commit()
# Served before the backfill: the bare name, with no code — never a crash on the old shape.
assert tmdb.serve_block(db, old, lang="hu")["production_countries"] == [
{"code": None, "name": "Yugoslavia"},
{"code": None, "name": "Atlantis"},
]
fake = FakeCountries()
assert tmdb.backfill_country_codes(db, fake) == 2
db.refresh(old)
db.refresh(show)
assert old.production_countries == [
{"code": "YU", "name": "Yugoslavia"},
{"code": None, "name": "Atlantis"}, # not in TMDB's list → no code, the name kept
]
assert show.production_countries == [{"code": "US", "name": "United States of America"}]
# Nothing left to code: no request at all.
assert tmdb.backfill_country_codes(db, fake) == 0
assert fake.calls == 1