Skip to content

Fetch show posters and episode stills from TMDB - #303

Merged
tripsittr merged 1 commit into
mainfrom
tmdb-show-artwork
Oct 6, 2026
Merged

tripsittr merged 1 commit into
mainfrom
tmdb-show-artwork

Conversation

@tripsittr

Copy link
Copy Markdown
Owner

The real cause of the blank episode covers. My earlier fixes — the series-poster fallback (#299) and the client payload version — were both correct and both irrelevant: nothing had ever fetched any show artwork to display.

What I found

Tvdb writes episode stills and was the only source that did. It needs its own API key. Your server has tmdb_api_key set and tvdb_api_key empty, so nothing was fetching stills at all.

Meanwhile Tmdb::enrichEpisode() was requesting /tv/{id}/season/{n}/episode/{n} — the record that carries still_path — reading the name and air date off it, and discarding the image. The series path wrote no poster_path either, so the fallback I added in #299 had nothing to fall back to.

Both are now stored, from responses the source was already fetching. No extra API calls.

Backfill

Fixing the source only helps items enriched afterwards, and enrichment never re-runs on its own — an already-enriched episode keeps its empty cover for ever, which is every episode in the reported library.

library:show-artwork goes back for them. Series first, deliberately: an episode with no still of its own falls back to the series poster, so fetching posters first leaves every row showing something even where TMDB has no still. --dry-run writes nothing; no key is a hard refusal rather than a silent "filled 0 of 400".

Testing

9 new tests, 206 pass across show/artwork/enrichment/metadata. Each confirmed to fail against its target:

Mutation Caught by
still_path discarded an_episode_gets_its_still_from_tmdb, a_bare_path_becomes_a_full_url
poster_path discarded a_series_gets_its_poster_from_tmdb
overwrite guard removed existing_artwork_is_not_overwritten
dry run writes a_dry_run_writes_nothing
key check removed it_refuses_without_a_tmdb_key

For review

w780 is a judgement call. Large enough for a detail page at 3x, small enough that a sixty-episode list is not sixty full-resolution images. If you think stills should be smaller than posters, they can take different sizes.

Not verified against the real API. This machine has zero show rows and I have no TMDB key here, so every test uses a faked response shaped like TMDB's. The shape is from their documented schema, not from a live call — worth one real run on a5 (library:show-artwork --dry-run --limit=5 first) before trusting it over a large library.

Order of operations matters on deploy. The backfill should run after this merges, and the phone needs its full re-fetch (SoundChexiOS#91 has the payload-version change) before the covers appear on device.

Every episode row was a grey TV glyph. The renderer was right and the
series-poster fallback was right -- nothing had ever fetched any artwork.

Tvdb writes episode stills and was the only source that did, and it needs its
own API key. A server holding a TMDB key and no TVDB key had nothing fetching
stills at all, while Tmdb was requesting the very episode record that carries
still_path and throwing the image away. The series path wrote no poster_path
either, so the fallback had nothing to fall back to.

Both are stored now, from responses already being fetched, so no extra API
calls. Stored as full w780 URLs: TMDB returns a bare path that renders broken
if kept as-is, the same trap the TVDB source documents. Nothing overwrites a
cover that came with the file or one a person chose.

library:show-artwork backfills existing items, since enrichment does not re-run
on its own and an already-enriched episode keeps its empty cover for ever.
Series first, because the episodes fall back to the poster.
@tripsittr
tripsittr merged commit 54312b4 into main Oct 6, 2026
3 checks passed
@tripsittr
tripsittr deleted the tmdb-show-artwork branch October 6, 2026 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant