Spaces:
Paused
Paused
Commit History
-
Add cache restart-persistence and 7-day cleanup job
FTA77001ad3b12
-
Add unconditional diagnostic logging around upsert_meta_db to trace missing image_meta rows
FTA77003aa6553
-
Track api_key_id on cache entries; admin preview uses correct per-key settings
FTA7700bb0b9d3
-
fix(image): preserve client error status from cache under concurrent requests
PNRxAImage requests are de-duplicated through moka's `try_get_with`, which returns the init closure's error as `Arc<AppError>`. On concurrent calls for the same key, moka hands every waiter a *clone* of that `Arc`, so `Arc::try_unwrap` fails (strong count > 1) and the `Err` arm collapsed the error to `AppError::Other` — a 500. The visible symptom was a spurious 500 in prod: status=500 Internal Server Error error=id not found: no logo available A single request for a title with no logo correctly returns 404; it only flipped to 500 when several identical requests raced (the inflight herd), which is exactly when the Arc is shared. The poster and episode serve paths had the same bug. Add `AppError::from_cached`, which moves the error out when it is the sole owner and otherwise rebuilds the client-facing variants by reference so the HTTP status is preserved; only genuinely-internal variants collapse to `Other`. Use it at all three image serve sites, and replace the hand-rolled equivalent…62f0fc0 -
fix(cache): align backdrop edge-inset clamp between cache key and render
PNRxAedge_inset_cache_suffix used the raw inset while render_backdrop_sync clamped to 100 (not the MAX_EDGE_INSET of 50 enforced elsewhere). An out-of-range value could mint a cache key the renderer would never reproduce. Clamp both to clamp_edge_inset so the key and the rendered output can never diverge.8946944
-
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: 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 -
feat: migrate existing cache keys for badge shape/background (v003)
PNRxAAdding the shape/background suffixes orphaned every previously cached image. Add a v003 data upgrade that rewrites existing image_meta cache keys and cache filenames, inserting the defaults (.shr.bgd — rounded, default background) immediately after the badge size token, so existing renders stay valid instead of being regenerated. - Reorder the poster suffix so shape/background always sit right after the badge size (before the optional split token), giving the migration a single uniform anchor across all image types. - DB + filesystem steps mirror v001/v002; idempotent via an '.bg' guard and the upgrades table. Covered by unit tests (filename rewriting) and integration tests (DB + filesystem across all image types). - Update v002's full-pipeline test expectations, which now also run v003.1367f50 -
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
-
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 main
PNRxA5fac6c0
-
fix(serve): do not fetch ratings when ratings are disabled
YagUber9ef1115
-
initial trakt implementation
PNRxA7f22b24
-
support language regions, fixes #20
PNRxAbaf86b2 -
additional configuration options for backdrops
PNRxA41b3b51
-
add support for episode ratings, closes #5
PNRxA76b8a0b
-
large refactor to prioritise tmdb logos and backdrops, then fall back to
PNRxAfanart, fixes #10094c13f
-
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
-
remove fallback placeholder behavior, accept param as no-op for rpdb
PNRxAcompatibility1464c42
-
add badge size option, improve settings layout
PNRxA4b9bf53
-
deduplicate image handlers and rename poster modules to image
PNRxA0c21886