feat(plex): classify collection-strip source (franchise/imdb/tmdb/smart)

Derive a `source` bucket per collection from the already-synced title + smart
flag (no schema change, no re-sync): external list providers (IMDb/TMDb/TVDb/
Trakt) by leading token, Plex smart lists via the smart flag, everything else a
genuine "collection". Returned on each info-page collection strip so the client
can show/hide each type independently. Adds the stripSource labels (en/hu/de).
This commit is contained in:
npeter83 2026-07-06 06:49:43 +02:00
parent 418a874851
commit 8a8087ae99
5 changed files with 51 additions and 2 deletions

View file

@ -684,6 +684,22 @@ def person_image(u: str, _: User = Depends(current_user)) -> Response:
return _img_response(r.content, ct) return _img_response(r.content, ct)
# Known external list providers that seed Plex collections (via plextraktsync et al). A collection's
# "source" buckets the info-page strips so the user can show/hide each type independently (e.g. hide
# the noisy 'IMDb Popular'/'TMDb Trending' auto-lists but keep genuine franchise collections). Derived
# from the already-synced title/smart — no schema change, no re-sync. Unknown providers stay "collection".
_STRIP_PROVIDERS = ("imdb", "tmdb", "tvdb", "trakt")
def _collection_source(col: PlexCollection) -> str:
first = (col.title or "").strip().split(" ", 1)[0].lower()
if first in _STRIP_PROVIDERS:
return first
if col.smart:
return "smart"
return "collection"
def _collection_strips(db: Session, it: PlexItem, user_id: int) -> list[dict]: def _collection_strips(db: Session, it: PlexItem, user_id: int) -> list[dict]:
"""The collections this movie belongs to, each with its member titles (playable cards) — the """The collections this movie belongs to, each with its member titles (playable cards) — the
'Avatar Collection' strip on the info page. Pure local lookup (no Plex call).""" 'Avatar Collection' strip on the info page. Pure local lookup (no Plex call)."""
@ -714,7 +730,14 @@ def _collection_strips(db: Session, it: PlexItem, user_id: int) -> list[dict]:
PlexState.user_id == user_id, PlexState.item_id.in_(ids or [0]) PlexState.user_id == user_id, PlexState.item_id.in_(ids or [0])
) )
} }
out.append({"id": rk, "title": col.title, "items": [_movie_card(m, states.get(m.id)) for m in members]}) out.append(
{
"id": rk,
"title": col.title,
"source": _collection_source(col),
"items": [_movie_card(m, states.get(m.id)) for m in members],
}
)
return out return out

View file

@ -98,6 +98,14 @@
"customize": "Ansicht anpassen", "customize": "Ansicht anpassen",
"prefArtBg": "Dezenter Hintergrund", "prefArtBg": "Dezenter Hintergrund",
"prefCast": "Besetzung", "prefCast": "Besetzung",
"stripSource": {
"collection": "Sammlungen",
"imdb": "IMDb",
"tmdb": "TMDb",
"tvdb": "TVDb",
"trakt": "Trakt",
"smart": "Smart-Listen"
},
"openImdb": "Bei IMDb öffnen", "openImdb": "Bei IMDb öffnen",
"director": "Regie", "director": "Regie",
"cast": "Besetzung & Crew", "cast": "Besetzung & Crew",

View file

@ -98,6 +98,14 @@
"customize": "Customize view", "customize": "Customize view",
"prefArtBg": "Faint backdrop", "prefArtBg": "Faint backdrop",
"prefCast": "Cast & crew", "prefCast": "Cast & crew",
"stripSource": {
"collection": "Collections",
"imdb": "IMDb",
"tmdb": "TMDb",
"tvdb": "TVDb",
"trakt": "Trakt",
"smart": "Smart lists"
},
"openImdb": "Open on IMDb", "openImdb": "Open on IMDb",
"director": "Director", "director": "Director",
"cast": "Cast & crew", "cast": "Cast & crew",

View file

@ -98,6 +98,14 @@
"customize": "Nézet testreszabása", "customize": "Nézet testreszabása",
"prefArtBg": "Halvány háttér", "prefArtBg": "Halvány háttér",
"prefCast": "Szereplők", "prefCast": "Szereplők",
"stripSource": {
"collection": "Kollekciók",
"imdb": "IMDb",
"tmdb": "TMDb",
"tvdb": "TVDb",
"trakt": "Trakt",
"smart": "Smart listák"
},
"openImdb": "Megnyitás az IMDb-n", "openImdb": "Megnyitás az IMDb-n",
"director": "Rendező", "director": "Rendező",
"cast": "Szereplők & stáb", "cast": "Szereplők & stáb",

View file

@ -714,7 +714,9 @@ export interface PlexItemDetail {
episode_number?: number | null; episode_number?: number | null;
prev_id?: string | null; prev_id?: string | null;
next_id?: string | null; next_id?: string | null;
collections?: { id: string; title: string; items: PlexCard[] }[]; // `source` buckets the strip so each type can be shown/hidden independently on the info page:
// "collection" (genuine franchise), "imdb"/"tmdb"/"tvdb"/"trakt" (external auto-lists), "smart".
collections?: { id: string; title: string; source: string; items: PlexCard[] }[];
} }
export interface PlexCollection { export interface PlexCollection {
id: string; id: string;