v4.0.21 — Kobo cover aspect-ratio padding
Suggested release title:
v4.0.21 — pad book covers to Kobo screen aspect ratio (no more white sleeves)
Release body
A new optional admin toggle that pads covers server-side to the Kobo device's native aspect ratio so the e-reader stops white-letterboxing tall publisher covers on the home screen and the sleep cover. Off by default; opt-in under Admin → Configuration → Kobo sync.
Get it
docker pull ghcr.io/new-usemame/calibre-web-nextgen:v4.0.21
Same volume layout as v4.0.20; no migration. Four new admin settings auto-add via the existing _migrate_table ALTER TABLE pattern on first boot.
Why
Kobo e-readers fit covers to the screen and pad the mismatched dimension with white bars. Most publisher cover art is roughly 2:3 (≈0.667), but modern Kobo screens are roughly 3:4:
| Device family | Pixels | Aspect (W/H) |
|---|---|---|
| Libra Color / Libra 2 | 1264 × 1680 | 0.7524 |
| Clara HD / 2E / BW / Colour | 1072 × 1448 | 0.7403 |
Result: a typical 1500×2250 cover renders with white sleeves on the left and right of the home screen and the sleep cover. Looks cheap. Now you can pad once on the server and the device sees an already-on-target image.
What
- New checkbox Admin → Configuration → Kobo sync → Pad book covers to Kobo screen aspect ratio
- Target aspect dropdown: Libra Color/2 (default), Clara family, 3:4 generic, 2:3 publisher
- Five fill modes:
- Edge mirror (default) — clones outer edges + flops them into the pad area, looks like the artwork extends naturally
- Edge blur — soft bokeh border (clones edge, stretches across pad area, blurs heavily)
- Solid: most-common color — histogram-mode after 8-color quantize
- Solid: average color — mean of source pixels
- Solid: custom color — admin-supplied hex
- Original cover files on disk are never modified. Padding is a serve-time transformation, cached in
/config/thumbnails/keyed bybook_uuid + resolution + src_mtime + settings_hash. CoverImageIdgets a-p<settings_hash>suffix when padding is enabled, so devices re-fetch covers when the operator changes settings — no manual cache clear needed.- No new dependencies (Wand was already pinned).
Validation
- 27 unit tests (pure-functional, run anywhere) + 17 Wand-gated tests (run in container against real ImageMagick) — all green.
- End-to-end on the deployed instance: a 1112×1680 (2:3) cover served to a Libra Color URL pattern (
/kobo/.../1264/1680/...) returns 1264×1680 padded output (within 0.005 of target ratio) for all five fill modes. - Cache hits verified: re-fetching with same settings returns the same path with mtime preserved.
- Cache invalidation verified: switching fill modes produces new files with different
settings_hash; switchingmanual_colorwhile in a non-manual mode does NOT bust the cache. - Boot test: container restart auto-migrates the four new columns, app serves traffic on /login → 200, settings render in the admin form correctly.
What this release does not do
- No per-user override (global admin setting only)
- No live preview in admin (toggle, sync, look at device)
- No support for non-Kobo readers — web UI handles arbitrary aspect natively, OPDS readers display many shapes, KOReader handles aspect itself