Commit Graph
6 Commits
Author SHA1 Message Date
john-okeefe 9467bdb2bd fix(sync): link fresh books via read-only SHA-256 resolve before first pull
Downloading a book from OPDS and opening it for the first time left the
plugin without a cached bookhoard UUID, so it bootstrapped the book's
identity by pushing once. That push carried the device's first-page
position, which the server stored as a real progress update for a book
that could be mid-read from another source — tripping the cross-source
conflict detector and clobbering genuine progress before the first pull
could deliver it. Until the conflict was resolved on the web, the device
could not pull the correct progress at all.

- onReaderReady now always pulls first; a pull no longer delegates to a
  push to learn the book's identity
- new _linkBookThenPull: resolves the UUID with a read-only
  GET /api/sync/koreader/resolve?sha256= call (BookhoardAPI:resolveBook),
  caches it in the document sidecar, then performs the pull — the
  device's position is never transmitted
- the legacy push-bootstrap survives only as a background fallback for
  books the server does not know by hash (404, sideloaded); interactive
  pulls are told to push explicitly instead

Requires the server-side resolve endpoint (bookhoard feat(sync): add
read-only KOReader book resolve endpoint).
2026-08-22 09:57:16 -04:00
john-okeefe 9d7b0f689f feat: implement bidirectional annotation sync and delete propagation
Bring the plugin to feature parity with the server's annotation sync
system. Previously annotations were push-only (and even that was broken
because the server ignored inline annotations in progress pushes).

ANNOTATION PULL (server → device):
  - Add applyServerAnnotations() method called from _doGetProgress
    after progress handling
  - Parses annotations.highlights, annotations.notes, and
    annotations.bookmarks from GetMetadata response
  - Matches incoming annotations against local bookmarks by pos0
    (start position) to detect existing entries
  - New entries are inserted with correct KOReader bookmark format:
    page, pos0, pos1, datetime, text, notes, color, chapter
  - Existing entries with changed content are updated (LWW: server
    version is authoritative since the server already resolved conflicts)
  - Respects sync_highlights, sync_notes, sync_bookmarks toggles for
    inbound sync, not just outbound
  - Triggers onSortBookmarks + saveSettings on change for persistence

DELETE PROPAGATION:
  - Parses annotations.deleted_highlights and annotations.deleted_bookmarks
    from GetMetadata response
  - Each entry contains device_sync_data (pos0, datetime, page) from the
    original device push
  - Matches local bookmarks by pos0 and removes them
  - Deleted highlights only remove entries that have text (to avoid
    removing plain bookmarks at the same position)

CLEANUP:
  - Fix BookhoardAPI.lua: rename pcall return _ to err for clarity
    (was functional but misleading variable name)
  - Remove dead code: unused getLibrary() and syncBookmarks() API methods
  - Remove sync_endpoints field (stored from registration response but
    never read by any code)
2026-07-29 14:49:41 -04:00
john-okeefe 1cef347e9c Fix: require json.util with dot notation not slash 2026-05-30 10:31:12 -04:00
john-okeefe 618793a075 Fix JSON encoding: force empty tables to encode as arrays
Lua's json.encode produces {} for empty tables instead of [].
Use json.util.InitArray to mark tables as arrays so they encode
correctly as [] for authors, bookmarks, highlights, notes, and books.
2026-05-30 10:24:56 -04:00
john-okeefe b931d668e2 Fix pcall return value handling in HTTP client
pcall wraps socket.http.request returns as:
  true, 1, status_code, headers, status_line

The old code captured '1' as the status code instead of
the actual HTTP status. Added '_' to skip the first return.
2026-05-29 21:48:29 -04:00
john-okeefe 9d2310d87e Initial KOReader plugin: progress sync, annotations, device registration
Full feature set:
- In-plugin device registration with approval polling
- Reading progress sync (push on page update/close/suspend, pull on open/resume)
- Bookmark, highlight, and note sync via batch annotation collection
- Configurable sync behavior (silent/prompt/disable for forward/backward)
- OPDS catalog setup helper
- SHA-256 book hashing with doc_settings cache
- Debounced API calls with periodic push scheduling
2026-05-29 20:27:50 -04:00