feat(web): FastAPI UI and Kobo sync protocol endpoints
Progressive enhancement web app: works without JS (plain HTML forms + full
page reloads), upgrades to HTMX partial swaps + SSE task progress when JS
is available.
UI routes (app.py + templates/):
- / search homepage
- /search multi-source manga search (HTMX partial for results)
- /manga/{source}/{id} detail page with chapter list + download form
- /download enqueue background download task
- /tasks task list with live progress via SSE
- /api/cover cover proxy (handles anti-hotlink referer per source)
Background task manager (tasks.py):
- In-memory TaskStatus registry with up to MAX_FINISHED_TASKS cap
- cancel_task guards against pipelines that don't implement cancel_download
(current MangaPipeline is sync-only)
Kobo sync router (kobo_sync.py):
- Full sync protocol implementation compatible with Kobo firmware, cribbed
from calibre-web cps/kobo.py. Key gotchas documented inline:
* Format must be EPUB3FL (not KEPUB) for pre-paginated manga
* metadata endpoint must return [metadata] list, not bare dict
* mark_synced must fire on download, not on sync (no SyncToken delta)
* thumbnail endpoint extracts cover.jpg from KEPUB zip
- All endpoints guard on auth_token via kobo_devices table
Security fixes applied during review:
- log_all_requests middleware redacts /kobo/<token>/ before logging and
runs at DEBUG level so auth tokens don't end up in log files
- cancel_task uses getattr guard so pipelines missing cancel_download
don't crash with AttributeError
feat(utils): shared parse_chapter_range + sanitize_filename
Used by CLI, web download handler, and background task worker.
feat(db): add kobo_devices / kobo_sync_state tables and queries
- kobo_devices: auth_token -> device_id mapping for Kobo sync protocol
- kobo_sync_state: per-device pending/synced book queue
- make_book_id: deterministic UUID5 from KEPUB filename (Kobo format)
- register_device / enqueue_for_sync / get_pending_syncs / mark_synced
- backfill_existing_kepubs: scan output dir and queue into new device
chore(deps): add FastAPI web stack (fastapi/uvicorn/jinja2/python-multipart)
New web UI uses these deps; declare them in pyproject + lock so uv sync --frozen
actually installs a runnable environment.
Initial commit: kobo-manga pipeline
Automated manga download-convert-import pipeline for Kobo e-reader.
Plugin-based source architecture, concurrent download engine,
image processing, KEPUB conversion, and device transfer.