Add keyword browsing/filtering and expose alternate titles
CI / lint (push) Canceled after 0s
CI / typecheck (push) Canceled after 0s
CI / unit-tests (push) Canceled after 0s
CI / integration-tests (push) Canceled after 0s
CI / container-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
CI / lint (push) Canceled after 0s
CI / typecheck (push) Canceled after 0s
CI / unit-tests (push) Canceled after 0s
CI / integration-tests (push) Canceled after 0s
CI / container-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
Keywords were ingested and shown read-only on detail pages, but had no
directory (GET /keywords) or filter param -- the same gap genres had
before today. Mirrors the genre browse pattern exactly: repository,
service, route, plus a `keyword` filter on GET /movies and GET /series.
Alternate/translated titles ("Also Known As") were normalized down to
bare title strings and never written to MovieAlternateTitle/
SeriesAlternateTitle at all. Normalizer now captures country_code + type
per TMDb's actual shape; ingestion writes them; movie/series detail now
expose an alternate_titles list.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
e1a36ce227
commit
567b4ef068
@@ -96,6 +96,23 @@ def company_logo_artwork(logo_path: str | None) -> NormalizedArtwork | None:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class NormalizedAlternateTitle:
|
||||
title: str
|
||||
country_code: str | None
|
||||
type: str | None = None
|
||||
|
||||
|
||||
def _alternate_titles(entries: list[dict]) -> list[NormalizedAlternateTitle]:
|
||||
return [
|
||||
NormalizedAlternateTitle(
|
||||
title=t["title"], country_code=t.get("iso_3166_1") or None, type=t.get("type") or None
|
||||
)
|
||||
for t in entries
|
||||
if t.get("title")
|
||||
]
|
||||
|
||||
|
||||
# TMDb's per-country rating body isn't returned alongside a release_dates
|
||||
# certification or a content_ratings rating -- only the country and the
|
||||
# rating string itself are. This maps the handful of markets Aurora can
|
||||
@@ -216,7 +233,7 @@ class NormalizedMovie:
|
||||
adult: bool
|
||||
genres: list[str] = field(default_factory=list)
|
||||
keywords: list[str] = field(default_factory=list)
|
||||
alternate_titles: list[str] = field(default_factory=list)
|
||||
alternate_titles: list[NormalizedAlternateTitle] = field(default_factory=list)
|
||||
companies: list[NormalizedCompanyRef] = field(default_factory=list)
|
||||
cast: list[NormalizedPersonRef] = field(default_factory=list)
|
||||
crew: list[NormalizedPersonRef] = field(default_factory=list)
|
||||
@@ -419,7 +436,7 @@ def normalize_movie(raw: dict) -> NormalizedMovie:
|
||||
adult=bool(raw.get("adult", False)),
|
||||
genres=[g["name"] for g in raw.get("genres", [])],
|
||||
keywords=[k["name"] for k in keywords],
|
||||
alternate_titles=[t["title"] for t in alt_titles if t.get("title")],
|
||||
alternate_titles=_alternate_titles(alt_titles),
|
||||
companies=companies,
|
||||
cast=cast,
|
||||
crew=crew,
|
||||
@@ -567,7 +584,7 @@ class NormalizedSeries:
|
||||
vote_count: int | None
|
||||
genres: list[str] = field(default_factory=list)
|
||||
keywords: list[str] = field(default_factory=list)
|
||||
alternate_titles: list[str] = field(default_factory=list)
|
||||
alternate_titles: list[NormalizedAlternateTitle] = field(default_factory=list)
|
||||
networks: list[NormalizedCompanyRef] = field(default_factory=list)
|
||||
companies: list[NormalizedCompanyRef] = field(default_factory=list)
|
||||
creators: list[NormalizedPersonRef] = field(default_factory=list)
|
||||
@@ -748,7 +765,7 @@ def normalize_series(raw: dict) -> NormalizedSeries:
|
||||
vote_count=raw.get("vote_count"),
|
||||
genres=[g["name"] for g in raw.get("genres", [])],
|
||||
keywords=[k["name"] for k in keywords],
|
||||
alternate_titles=[t["title"] for t in alt_titles if t.get("title")],
|
||||
alternate_titles=_alternate_titles(alt_titles),
|
||||
networks=networks,
|
||||
companies=companies,
|
||||
creators=creators,
|
||||
|
||||
Reference in New Issue
Block a user