the open-show button rendered for youtube cards too; the click ran parseInt on the
youtube video id → ids starting with a digit became a small library id (e.g. 3 →
'3rd Rock from the Sun'), others became NaN → broken link. youtube cards now render a
real YouTube link for that button; movie/show/episode keep the open-detail button.
regression test pins the youtube branch.
- EPISODE downloads now show the specific episode: still + 'S02E05 · air date' + that
episode's own title + synopsis (was just the show synopsis). meta endpoint takes
?season=&episode= → engine.tmdb_season; show cast/logo stay as context.
- YOUTUBE drawer: big 16:9 thumbnail + channel · duration · views · upload date +
description. new yt-meta route → db.youtube_video_detail (cached duration/views).
- AVAILABILITY line: the chosen source's free-slot/queue/speed snapshot, stashed in
search_ctx at grab time (build_download_record) → 'Availability: ✓ free slot · queue 0
· 2.1 MB/s'.
drawer also reworked into clean youtube / episode / movie-show branches; first paint
shows 'Loading…' instead of flashing 'no synopsis'. tested.
drawer upgrades (the TMDB call we already make returns all this — just render it):
- FIX cast photos — used c.profile_url; the field is c.photo. now shows headshots.
- title LOGO header (falls back to text) + meta line (year · ⭐rating · runtime · network).
- tagline, director/creator, ▶ trailer link, and a 'Watch on' provider-logo row.
- meta endpoint widened to return logo/cast-photo/rating/runtime/crew/trailer/providers.
OMDb spam fix (the 'Request limit reached!' tracebacks):
- the new bulk schedule-refresh called refresh_show_art per show, which did an OMDb
ratings backfill each → blew the daily quota. refresh_show_art gains with_ratings;
the automation passes False (it only needs episode schedules).
- _backfill_ratings now latches _omdb_blocked on OMDbAuthError → one quiet warning +
stops calling OMDb for the rest of the process, instead of a traceback per show.
tested (cast/logo/trailer contract, no-ratings plumbing, the latch-off behavior).
click a card → it expands inline into a detail drawer (open state survives the
in-place re-patches via _expanded):
- big backdrop + synopsis + genres + a cast strip (photos/names/characters),
lazily fetched from TMDB by the grab's tmdb id (new /downloads/meta/<kind>/<id>
endpoint → engine.tmdb_full_detail). youtube shows channel + description instead.
- a facts grid: status, quality target, release, format, source+queue, size,
attempts, copyable dest path, full error.
- big actions: open in library / open on youtube / copy path / cancel / retry.
all type-themed (Cinema palette) and scoped to .vdpg-card. contract-tested + the
meta route is registered.
- per-type colour (movie=azure / TV=violet / youtube=red) on a left accent bar, the
status pill, the progress fill + quality chip — tell the three apart at a glance.
- bigger poster art + a type corner badge (reads even with a poster).
- status is now a coloured pill; queued/searching/importing get an indeterminate
shimmer instead of a frozen bar; 'Importing' + 'Import failed' surfaced with their
own context lines ('Moving into your library…').
- sidebar Downloads nav shows a live active-count badge, kept fresh off-page by a
light poll (skips the fetch while the page's own poll is running).
all scoped to .vdpg-card so the music downloads page is untouched. contract-tested.