~cytrogen/kobo-manga

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
cce44433 — HallowDem 4 days ago
feat(utils): shared parse_chapter_range + sanitize_filename

Used by CLI, web download handler, and background task worker.
d07d4ccd — HallowDem 4 days ago
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
46071cdd — HallowDem 4 days ago
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.
4e504823 — HallowDem 7 days ago master
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.