A drawer with two part types is one label, so the page, the preview, the
print loop and the PDF all work from plan_groups rather than iterating
the selection. The preview takes the parts that share a label, and the
page reports how much tape the run will use.
Printing redirected back to a bare tape page, so every option - rotation
most visibly - reverted to the default the moment you pressed Print.
Carry the chosen options through the redirect instead.
Also read tape_rotate_default so an untick can be made permanent in
Settings; it only applies to a fresh arrival, never over an explicit
choice on the page.
LIM configured no logging at all, so the instruction fetcher had no trail to follow. Adds a rotating file handler on the root logger plus two owner-only admin pages.
- Admin > Logs: filter by level, source and text; tracebacks kept with their error; auto-refresh, raw download, rotated-file browsing and rotate-now
- Admin > Logs > Brickset API calls: every outbound call recorded with method, params, caller, duration, result count and error, plus daily quota accounting (only getSets counts) and a comparison against getKeyUsageStats
- New owner concept (services/ownership.py): a single account, distinct from is_admin, since these pages expose other admins activity. Defaults to the first admin; flask owner show/set to change
- Services now log through module loggers; retention setting and pruning for call records
- New CLI: flask owner show/set, flask logs path/prune
- New table brickset_api_calls, created automatically at boot; LOG_* env vars, /data/logs in Docker
Downloads official instruction PDFs from LEGO, located via the Brickset API, one set per interval (10 minutes by default) so neither API gets hammered. Official sets only; MOCs are excluded throughout.
- New admin page at /admin/instruction-fetch: queue builder, pacing controls, live countdown and per-set job history
- Database-backed queue (instruction_fetch_jobs) and last-run timestamp, so pacing survives restarts
- Background worker thread, plus 'flask instructions queue/run/status' for Task Scheduler or cron
- SHA-256 dedupe (instructions.sha256), PDF header check, size cap and streaming downloads via temp files
- brickset_api: getInstructions2 by set number and getInstructions by setID (the old code sent a set number to the setID method); getSets params now proper JSON; getKeyUsageStats added
- Schema top-ups applied automatically at boot: new table plus instructions.sha256/source
- Docker: fetcher env vars passed through compose, no worker thread in the entrypoint bootstrap