Video Discover: split Top 10 today into Movies + TV Shows (Netflix-style)
The mixed /trending/all chart is movie-heavy — TV was nearly absent (only 1 of the top 10 was a show). Split it like Netflix: 'Top 10 today' now holds two ranked rails, Movies and TV Shows, from the dedicated /trending/movie/day and /trending/tv/day charts (full 10 of each). - client.trending(window, kind): single-type charts force the kind into _disc_map (those endpoints omit media_type). - engine.trending(window, kind): kind in the cache key. - /discover/list: key=trending_movies_today / trending_tv_today, both treated as single un-paged charts; inherit the same hide-owned + ranked rendering. - frontend: one 'Top 10 today' group, two ranked shelves titled Movies / TV Shows (group header carries the 'Top 10' framing).
This commit is contained in:
parent
e7552d3c62
commit
877a86c9b0
4 changed files with 31 additions and 16 deletions
|
|
@ -322,7 +322,11 @@ def register_routes(bp):
|
|||
if key == "trending":
|
||||
return eng.trending()
|
||||
if key == "trending_today":
|
||||
return eng.trending(window="day") # the ranked 'Top 10 today' chart
|
||||
return eng.trending(window="day") # the ranked 'Top 10 today' chart (mixed)
|
||||
if key == "trending_movies_today":
|
||||
return eng.trending(window="day", kind="movie") # split 'Top 10 Movies Today'
|
||||
if key == "trending_tv_today":
|
||||
return eng.trending(window="day", kind="show") # split 'Top 10 TV Shows Today'
|
||||
if key:
|
||||
return eng.discover_curated(key, page=p)
|
||||
return eng.discover_filter(
|
||||
|
|
@ -360,7 +364,7 @@ def register_routes(bp):
|
|||
# thread-safe) so digging 20 pages deep costs ~4 page-latencies, not 20.
|
||||
need_fill = hide_owned or bool(prefer_langs)
|
||||
target = 20 if need_fill else 0
|
||||
if key in ("trending", "trending_today"):
|
||||
if key in ("trending", "trending_today", "trending_movies_today", "trending_tv_today"):
|
||||
consume(fetch(page)) # a single fixed chart; never paged
|
||||
elif not need_fill:
|
||||
for offset in range(pages): # no filtering: respect requested page count
|
||||
|
|
|
|||
|
|
@ -447,16 +447,22 @@ class TMDBClient:
|
|||
"poster": (self.PROFILE + it["profile_path"]) if it.get("profile_path") else None})
|
||||
return out
|
||||
|
||||
def trending(self, window="week"):
|
||||
"""Trending movies + shows this week — fills the search page when idle and
|
||||
the Discover hero slideshow (hence backdrops via _disc_map)."""
|
||||
def trending(self, window="week", kind=None):
|
||||
"""Trending titles. ``kind`` None = mixed movies + shows (/trending/all — the
|
||||
search-idle filler + Discover hero slideshow, hence backdrops via _disc_map).
|
||||
``kind`` 'movie' / 'show' hit the dedicated single-type charts (/trending/movie,
|
||||
/trending/tv) that power the split 'Top 10 Movies / TV Shows Today' rails.
|
||||
Single-type endpoints omit media_type, so the kind is forced into _disc_map."""
|
||||
if not self.api_key:
|
||||
return []
|
||||
import requests
|
||||
r = requests.get(self.BASE + "/trending/all/" + window,
|
||||
params={"api_key": self.api_key}, timeout=15)
|
||||
path = ("/trending/movie/" if kind == "movie"
|
||||
else "/trending/tv/" if kind == "show"
|
||||
else "/trending/all/") + window
|
||||
r = requests.get(self.BASE + path, params={"api_key": self.api_key}, timeout=15)
|
||||
r.raise_for_status()
|
||||
return self._disc_map((r.json() or {}).get("results"), None)[:20]
|
||||
forced = kind if kind in ("movie", "show") else None
|
||||
return self._disc_map((r.json() or {}).get("results"), forced)[:20]
|
||||
|
||||
# ── discover (browse TMDB by curated list / genre / year / decade) ────────
|
||||
def _disc_map(self, results, kind):
|
||||
|
|
|
|||
|
|
@ -310,19 +310,21 @@ class VideoEnrichmentEngine:
|
|||
return []
|
||||
return self._stamp_owned(results)
|
||||
|
||||
def trending(self, window="week") -> list:
|
||||
def trending(self, window="week", kind=None) -> list:
|
||||
"""Trending titles, annotated owned/not. ``window='day'`` is the real-time
|
||||
daily chart (the iconic 'Top 10 today' row); 'week' is the steadier hero/idle
|
||||
feed. Order is preserved, so the caller can render rank numbers."""
|
||||
daily chart (the iconic 'Top 10 today' rows); 'week' is the steadier hero/idle
|
||||
feed. ``kind`` None = mixed; 'movie'/'show' = the dedicated single-type charts
|
||||
(split 'Top 10 Movies / TV Shows Today'). Order is preserved for rank numbers."""
|
||||
w = self.workers.get("tmdb")
|
||||
if not w or not w.enabled:
|
||||
return []
|
||||
window = "day" if window == "day" else "week"
|
||||
ck = ("trending", window)
|
||||
kind = kind if kind in ("movie", "show") else None
|
||||
ck = ("trending", window, kind)
|
||||
cached = self._cache_get(ck)
|
||||
if cached is None:
|
||||
try:
|
||||
cached = w.client.trending(window=window) or []
|
||||
cached = w.client.trending(window=window, kind=kind) or []
|
||||
self._cache_put(ck, cached, ttl=3600)
|
||||
except Exception:
|
||||
logger.exception("video trending failed")
|
||||
|
|
|
|||
|
|
@ -49,8 +49,11 @@
|
|||
}
|
||||
|
||||
// ── the rail stack (personalized + curated + genre + decade) ──────────────
|
||||
// The iconic ranked "Top 10 today" row — daily TMDB trending, rendered with rank numbers.
|
||||
var TOP10 = { title: 'Top 10 Today', q: 'key=trending_today&lang=any', ranked: true };
|
||||
// The iconic ranked "Top 10 today" rows — split Movies / TV like Netflix, so TV
|
||||
// isn't drowned out by the movie-heavy mixed chart. Daily TMDB trending, rank numbers.
|
||||
// (Titles are terse because the group header already says "Top 10 today".)
|
||||
var TOP10_MOVIES = { title: 'Movies', q: 'key=trending_movies_today&lang=any', ranked: true };
|
||||
var TOP10_TV = { title: 'TV Shows', q: 'key=trending_tv_today&lang=any', ranked: true };
|
||||
var CURATED = [
|
||||
{ title: 'Trending This Week', q: 'key=trending' },
|
||||
{ title: 'Popular Movies', q: 'key=popular_movies' },
|
||||
|
|
@ -155,7 +158,7 @@
|
|||
// keep those group ids. Order of this array IS the on-screen order.
|
||||
return [
|
||||
{ id: 'foryou', label: 'For you', rails: foryou },
|
||||
{ id: 'topten', label: 'Top 10 today', rails: [TOP10] },
|
||||
{ id: 'topten', label: 'Top 10 today', rails: [TOP10_MOVIES, TOP10_TV] },
|
||||
{ id: 'new', label: 'New & noteworthy', rails: NEW_RAILS },
|
||||
{ id: 'collection', label: 'Finish your collection', rails: [] },
|
||||
{ id: 'taste', label: 'More of what you like', rails: taste },
|
||||
|
|
|
|||
Loading…
Reference in a new issue