Quiblo wiki

Code reference · Source

:source:tmdb

The optional film and series information client, and the key it spends.

dev.quiblo.source.tmdb

Off unless the user supplies a key, and the key is theirs. That asymmetry shapes everything here: getting a panel throttled makes our app slow, while getting their key throttled affects everything else they use it for.

There is no batch endpoint, so the per-title request shape is forced rather than chosen.

sealed interfaceTmdbAnswer

Found, NoMatch, or Refused — and the last two are not the same thing.

Three outcomes rather than a nullable record, and the distinction between the last two is the whole reason the type exists: "nothing matches this title" is an answer, and "I could not ask" is not. They used to be the same null.

That conflation is harmless while browsing — a poster shows no score for a minute — and ruinous in bulk. A scan tripping a rate limit half way through would otherwise write tens of thousands of rows saying "matches nothing", each cached for a fortnight, and the search screen would report a described catalogue with no genres in it.

A cache may hold answers. It may never hold failures.

metadataOrNull()Collapses the three back to two for screens, which render a missing plot and an unreachable host identically.

enumTmdbRefusal

RATE_LIMITED, KEY_REJECTED, UNAVAILABLE — the only detail a caller can act on.

Waiting fixes the first, nothing fixes the second, and the third is worth retrying later. Three outcomes because those are three different things to tell a viewer.

classTmdbRateLimiter

A token bucket: burst of 16, refilling one per 125 ms.

The same shape as PanelRateLimiter, and the same negative-balance detail, for the same hard-won reason. Sitting on the client means every path pays it — a poster tile, a detail screen, and a scan walking thirty thousand titles alike.

It is also the scan's pacing. A worker that cannot get a token simply waits here, so the scanner needs no throttle of its own.

classTmdbClient

Search and detail lookups against the service.

Returns a TmdbAnswer rather than a nullable, so a caller cannot accidentally treat a refusal as an absence. A record notes whether only the search step ran: a poster tile needs a score, a detail screen needs everything, and recording which was fetched lets a tile be satisfied by one request and a detail screen upgrade the same row.

objectcleanedForSearch / yearInTitle

Turns a provider title into something a metadata service can match.

Strips quality tags, language prefixes and release years from names that were never meant to be searched. Also the key the cache is stored under, and the comparison the genre filter makes — which is why that filter runs off the main thread.