Spaces:
Paused
Paused
Commit History
-
Add cache restart-persistence and 7-day cleanup job
FTA77001ad3b12
-
Add retry-with-backoff (3 attempts, 1s/2s) to Cloudflare edge purge, given confirmed intermittent stalls
FTA77003b18611 -
Surface Cloudflare edge-purge failures instead of silently reporting success; relabel poster-origin audit count to avoid confusion with settings-staleness
FTA77000e78008
-
Reuse a single pooled IPv4-only client for Cloudflare purge calls instead of rebuilding one per request
FTA7700f3ac5bb
-
Rewrite Library staleness checker to use timestamp comparison instead of predicted cache_key matching, which false-positived on titles with partial rating-source availability (e.g. Letterboxd has no TV data)
FTA77007cb5dfa
-
Replace IPv4-only resolver with hickory-resolver (Ipv4Only strategy) to avoid combined A/AAAA lookup stalls
FTA7700d9f1add -
Add timing instrumentation to IPv4-only DNS resolver
FTA77004596802
-
Rearrange buttons in purge, refresh stale/duplicate entries
FTA770013e3b99 -
Add Library Cleanup: audit poster origin, soft-delete stale/duplicate entries
FTA77009b2515d
-
Silence unused client param warning in purge_cloudflare_tags
FTA7700ddea1ec -
Force IPv4-only client for Cloudflare purge (HF container IPv6 egress issue)
FTA77006303e9c -
Add Cloudflare edge-cache purge (Workers Cache + Cache-Tag)
FTA77000e00f39 -
Add Cloudflare edge-cache purge (Workers Cache + Cache-Tag)
FTA77001ecada6 -
Add live purge feature: catalogs + library, sourced from Stremio account API
FTA7700ef14e02
-
Add API alias column to admin image lists
FTA77006512c5c
-
Revert SLOW_RATINGS_MS diagnostic threshold back to 1000ms
FTA7700c8104e9 -
Temporarily lower SLOW_RATINGS_MS to 300 for provider latency diagnostic
FTA7700605b97d
-
fix(logging): strip API keys from upstream error URLs before logging
PNRxAreqwest embeds the full request URL — query string included — in both the Display and Debug of its errors. TMDB, OMDb, MDBList and fanart all pass their API key as a query parameter (`?api_key=…` / `?apikey=…`), so an upstream 404/timeout/decode error logged via `AppError::Api` leaked the key into the logs, e.g.: mdblist rating fetch failed: API error: HTTP status client error (404 Not Found) for url (https://api.mdblist.com/imdb/show/tt…?apikey=<KEY>) Sanitize the error object itself at the only two `AppError::Api` construction sites — the `From<reqwest::Error>` conversion (every `?`/`error_for_status()?`) and the direct build in `services::retry` — by dropping the URL's query string (`set_query(None)`). Scrubbing the stored error rather than one Display site also protects Debug output and the moka `Arc<AppError>` → `Other(_.to_string())` laundering paths in image::serve. Scheme/host/path are kept for debugging; the key is never in them. Trakt sends its key as a header, whic…937da1f -
fix(ratings): treat empty imdb_id as absent so the MDBList TMDB fallback fires
PNRxATMDB returns an empty string (not null) for titles with no IMDb cross-reference — exactly the anime/no-IMDb case issue #14's fallback targets. resolved.imdb_id was Some(""), which routed to the IMDb-keyed MDBList endpoint with a blank id, 404'd, and dropped every MDBList badge. Normalise empty ids to None at the source (id/mod.rs) and guard mdblist_lookup_for defensively. Also suppress zero-score MDBList sources (rt/popcorn/metacritic/trakt) for consistency with Ebert/aggregate/TMDB, and extract a pure, unit-tested trakt_badge() for the percent formatting.9f5255d
-
Merge pull request #53 from PNRxA/fix/anime-season-ratings
PNRxAfix: keep ratings for anime/IMDb-less titles via MDBList TMDB fallback (#14)4528a2b -
feat: add distance-from-edge inset setting for backdrop ratings
PNRxACloses #7. Some media players (e.g. Nuvio on Mac) reposition/crop backdrops and clip the rating badges. Add two independent per-key/global settings that inset the backdrop ratings inward from the anchored edge: - backdrop_edge_inset_x — horizontal inset (% of width), applies only to left/right positions - backdrop_edge_inset_y — vertical inset (% of height), applies only to top/bottom positions Centered axes ignore their inset, so a top-right position exposes "space from top" and "space from right", while "right" exposes only "space from right". Surfaced in the settings UI as conditional, edge-aware inputs and as edge_inset_x / edge_inset_y query params on the backdrop image and preview endpoints. The cache token (.eh{x}/.ev{y}) is emitted only when the position-gated value is non-zero, mirroring the existing optional .x1 (split) and .blur tokens, so default backdrop cache keys are unchanged and no cache-key migration is needed (only the additive DB columns, default 0).70cc48f -
change default poster fit to native (legacy passthrough)
PNRxAMake `native` (keep the source aspect ratio) the default for poster_fit instead of `cover`, so out-of-the-box rendering matches the prior behavior and 2:3 normalization (cover/pad/blur) is opt-in. The selection-side preference for ~2:3 source posters still applies by default. Because native emits an empty cache-key token, the default now reuses existing poster cache entries with no re-render. - db: default_poster_fit() -> Native; api_key_settings column default 'native' - web: form fallback + dropdown order (native first) - README: native is the default fit; restore source-ratio poster dimensions - tests updated for the new default1fdea6e -
feat: normalize poster aspect ratio to 2:3 (#15)
PNRxANon-2:3 source posters were served at their native aspect ratio, so downstream apps (Stremio addons, aiometadata) that place posters in fixed 2:3 containers cropped them — cutting off the title/logo art baked into the poster (issue #15). Two complementary fixes: - Render-side: a new `poster_fit` setting normalizes every poster to an exact 2:3 frame (e.g. 580x870 / 1280x1920 / 2000x3000). Modes: `cover` (default, center-crop), `pad` (solid letterbox), `blur` (blurred-fill bars), and `native` (legacy source-ratio passthrough). - Selection-side: among TMDB posters, prefer art near 2:3 before falling back to highest vote, so the chosen source usually needs little cropping. Configurable per-key, globally, and via the `?fit=` query param. Threaded through RenderSettings, the cache key (native emits no token so existing poster cache stays valid; the new default emits one), the api_key_settings DB column + migration, OpenAPI, and the admin UI (with live preview). Tests: poster fit …5283e2c -
fix: fall back to MDBList TMDB lookup when a title has no IMDb id
PNRxAAnime split into per-season catalog entries (and other titles TMDB knows but hasn't cross-referenced to IMDb) resolve without an imdb_id. Because every rating source except TMDB's own vote_average is looked up through the IMDb-keyed MDBList call, fetch_mdblist_ratings bailed out early — so those titles lost IMDb, RT, Metacritic, Trakt, Letterboxd, MyAnimeList, the MDBList score and Roger Ebert, leaving only the TMDB score. MDBList's /tmdb/{movie|show}/{tmdb_id} endpoint returns the same full rating set (including MyAnimeList), and tmdb_id is always present on a resolved id. Use it as a fallback when no imdb_id resolved, so these titles keep their badges. Note: this restores the (series-level) rating set; it does not make MAL per-season accurate — the id that reaches the service is always series-level (aiometadata/RPDB never encode a season number in the poster URL), so a single id cannot distinguish seasons. That would need a season-aware id type and is out of scope here. Refs #14579d735
-
fix: dedupe pill cache keys + disable ignored badge style control for pills
PNRxAPills always render as a horizontal lozenge, so badge style is overridden to horizontal at render time. Route both the renderer and the cache key through a single BadgeStyle::for_shape() helper so pill+vertical and pill+horizontal no longer produce two cache entries for identical output. UX: disable the Badge style select (and show a hint) when the badge shape is pill, in both the per-key settings form and the free-key try-it-out form, so users don't expect the orientation choice to take effect. Badge direction stays enabled — it still controls multi-badge stacking for pills.6387a43 -
fix: pills always render as a horizontal lozenge + a bit more top/bottom padding
PNRxA- A pill is a horizontal icon/label-left, value-right lozenge; vertical stacked pills look wrong, so pill shape now forces horizontal layout for every image type (logos/backdrops/episodes default to vertical style). - Give horizontal pills a little extra height for top/bottom breathing room.9052d8e -
Merge remote-tracking branch 'origin/main' into feat/badge-shape-background
PNRxA# Conflicts: # README.md # api/src/handlers/preview.rs # api/src/image/generate.rs # api/src/image/serve.rs # api/src/lib.rs # web/src/__tests__/components/RenderSettingsForm.spec.ts # web/src/components/RenderSettingsForm.vue # web/src/lib/api.tsc45d5f9
-
feat: split poster badges onto opposite sides (#18)
PNRxAAdd a per-poster `poster_badge_split` setting (query param `split`) that divides rating badges evenly across two opposite sides of the poster. The split axis follows the badge layout: a vertical column splits left/right, horizontal rows split top/bottom. With an odd number of badges the configured side keeps the extra one (4 -> 2+2, 3 -> 2+1); a single badge is never split. - Rendering: BadgePosition::split_anchors + overlay_poster_group on the poster render path; threaded through ImageParams/serve/preview. - Cache: the split contributes a key token only when enabled, so existing non-split cache keys and CDN settings hashes are unchanged. - Settings: new column + migration, per-key/global/free-key plumbing, `split` query-param override. - Web: settings-form checkbox with live preview, free-key "Try it out" control, API params, types, and README docs.6db0b76 -
feat: add pill-style badges and dark/transparent/no-background options (#19)
PNRxAAdd two orthogonal, per-image-type badge appearance settings: - badge_shape: rounded (default) | pill (fully rounded ends) - badge_background: default | dark | transparent | none These are plumbed through the full settings stack (per-key + global defaults, query-param overrides, cache keys) for posters, logos, backdrops, and episodes, and exposed in the admin/key settings forms and the public free-key "Try it out" form. Closes #19.c165e10 -
feat: add MDBList score and Roger Ebert rating sources (#42, #35)
PNRxAAdd two new rating sources, both sourced from the existing MDBList integration: - mdblist: MDBList's own 0-100 aggregate score (top-level `score` field), rendered as a bare integer to match MDBList's presentation (#42) - ebert: Roger Ebert's classic 0-4 star rating (the `rogerebert` entry in MDBList's ratings array; only `value` is populated), rendered as a bare decimal like IMDb/Letterboxd (#35) Both are wired through every layer: the RatingSource enum (label/key/ color/cache_char/canonical order), badge + icon rendering, validation, the default ratings order, the web settings UI, the landing page, and docs. The per-image ratings limit cap is raised 8 -> 10 to fit all sources. The MDBList response->badge mapping is extracted into a pure `mdblist_badges` fn with serde-level tests covering int/null `score` deserialization and 0/null value suppression. Icons: MDBList uses its official mark from Simple Icons (CC0); Roger Ebert uses a generic filled thumbs-up from Phosphor Icons …79c9393
-
fix: fold ratings_exclude into CDN settings_hash to prevent cache collisions
PNRxAThe CDN content-addressed settings_hash derived its ratings portion from the predicted ratings_cache_suffix, which pads the source list with all canonical sources before applying the exclusion and limit. When an excluded source fell beyond the rating limit in that all-present prediction (e.g. excluding `trakt` at limit 3 -> still `@mil`), two configs differing only in ratings_exclude collapsed to the same /c/{hash}/ URL. A title with partial source availability could then be served the wrong cached image (an excluded badge shown, or a badge missing). Hash a canonical, order-independent exclude token alongside the predicted suffix so configs differing only in ratings_exclude always hash differently, while semantically-equal excludes ("rt,tmdb" vs "tmdb,rt") still dedupe. The disk cache was unaffected (it keys off the actually rendered badges). Found via adversarial review.7015998 -
feat: add ratings_exclude setting to hide specific rating sources (#17)
PNRxAAdds a "ratings_exclude" setting (comma-separated rating source keys to drop from generated images) following the same global-default + per-API-key + query-override pattern as ratings_order. Closes #17. Exclusion is applied before ordering and limiting, so excluding a source you don't care about (e.g. Rotten Tomatoes critics) frees its badge slot for the next preferred source rather than leaving a gap. The exclusion list is folded into every cache-key suffix (ratings_cache_suffix, badges_suffix_from_available, and the CDN settings_hash), so two configurations differing only in their exclusions never collide in the cache. - Storage: new api_key_settings.ratings_exclude column via idempotent migration; empty default ("exclude nothing") keeps existing cache keys byte-identical. - API: ?ratings_exclude= query override (all image types) plus admin global, per-key admin, and self-service settings endpoints. - Web: "Exclude ratings" checkbox control in the settings form with live previe…f54670e -
Merge pull request #44 from PNRxA/feat/trakt
PNRxATrakt rating supportc7854de -
perf: resolve Trakt show IMDb ID lazily, quiet 404s
PNRxA- Only fetch show external_ids when Trakt is configured and the request is an episode, instead of on every episode resolution (removes an unconditional TMDB call + a duplicate /tv/{show} fetch) - Treat Trakt 404 as Ok(None) so absent titles/episodes don't log at warn - Dedup the three Trakt client methods via a shared get_rating helper8770f6d
-
fix backdrop default, add to free key ui, fixes #36
PNRxAe030eb4
-
fix Trakt episode lookup to use show IMDb ID instead of TMDB ID, DRY
PNRxAclient headers31e49e3
-
initial trakt implementation
PNRxA7f22b24
-
support language regions, fixes #20
PNRxAbaf86b2 -
additional configuration options for backdrops
PNRxA41b3b51 -
prioritise mdblist ratings
PNRxAeeec19f
-
add support for episode ratings, closes #5
PNRxA76b8a0b
-
large refactor to prioritise tmdb logos and backdrops, then fall back to
PNRxAfanart, fixes #10094c13f -
change 0 ratings to return no ratings instead of max ratings, fixes #11
PNRxA3a59cbc
-
show newest items first, fixes #8
PNRxAf5ef4f9 -
expose all customisation through url params, fixes #3
PNRxA0b7bef2
-
refactor to use explicit enum types instead of strings
PNRxAb8d53ae -
added support for official icons and made it the default
PNRxAbc616c9
-
change mdblist score type from i32 to f64 to handle float values
PNRxA8e142ce -
log provider errors
PNRxA56e9890
-
add badge size option, improve settings layout
PNRxA4b9bf53