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
-
Tune LOGO_AREA_HEIGHT 260 -> 150 for larger on-screen badge proportion
FTA77000786ba9
-
Fix logo badge size inconsistency: fixed-height logo box
FTA77000d4041b
-
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 -
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 -
fix: add padding around content at pill badge rounded ends
PNRxAPills (badge_shape=pill) fully round their long-axis ends, which left the label/value crowding the caps. Add scaled padding at those ends — left/right for horizontal badges, top/bottom for vertical — applied only to pills, so rounded badges are unchanged.4f091a3 -
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 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
-
redact api keys in logs, limit image decode size, fix ip extraction, add
PNRxAreferrer-policy headerbe73249
-
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
-
adjust horizontal padding for text label image
PNRxAb8ff786
-
add badge size option, improve settings layout
PNRxA4b9bf53 -
increase font size, update example images script, fix logos getting
PNRxAcropped on landingpage, optimise landing pages at build timef4d58d4
-
deduplicate image handlers and rename poster modules to image
PNRxA0c21886