fix(plex): show-library collections get montage art too (A3)

The collection browse-tile montage queried only movie members, so show-library
collections (IMDb Popular, TMDb Trending, … in the TV library) rendered as bare colour
tiles. Union the art from PlexShow members as well (a collection lives in one library, so
exactly one side has art); fall back to the collection's own poster, then the colour hash.
Runtime stays movie-only (shows have no single duration).

Verified live: every collection now shows a montage (0 art-less tiles, was ~all the show
collections).

Gate: backend ruff clean, 5 collections tests (+ a show-collection art assertion).
This commit is contained in:
2026-08-23 03:57:20 +02:00
parent 37d11b602f
commit 14a44bff6e
2 changed files with 37 additions and 6 deletions
+14 -5
View File
@@ -11,6 +11,7 @@ from app.models import (
PlexCollection,
PlexItem,
PlexLibrary,
PlexShow,
User,
)
from app.plex import sync as plex_sync
@@ -95,17 +96,25 @@ def collections(
func.lower(PlexCollection.title),
)
).scalars().all()
# A montage of the top films per tile + the collection's total runtime (color hash + no-runtime is
# the client fallback for show-only / empty collections). Two grouped queries over the movie libs.
movie_ids, _show_ids = _content_libs(db)
# A montage of the top titles per tile + the collection's total runtime. Art unions MOVIE and SHOW
# members (a collection lives in one library, so exactly one side has art) — a show collection would
# otherwise render blank; the collection's own poster is the next fallback, then the colour hash.
# Runtime is movie-only (shows have no single duration).
movie_ids, show_ids = _content_libs(db)
keys = [c.rating_key for c in rows]
art = top_art_keys(db, PlexItem, movie_ids, PlexItem.collection_keys, keys, per=2)
art_m = top_art_keys(db, PlexItem, movie_ids, PlexItem.collection_keys, keys, per=2)
art_s = top_art_keys(db, PlexShow, show_ids, PlexShow.collection_keys, keys, per=2)
runtime = runtime_by_key(db, PlexItem, movie_ids, PlexItem.collection_keys, keys)
def _art(c: PlexCollection) -> list[str]:
member = art_m.get(c.rating_key) or art_s.get(c.rating_key)
return member or ([c.rating_key] if c.thumb_key else [])
return {
"collections": [
{
**_collection_card(c),
"art": art.get(c.rating_key, []),
"art": _art(c),
"total_runtime_s": runtime.get(c.rating_key, 0),
}
for c in rows