fix(koreader): keep manual links to a different copy matched and suggest links

Report a linked copy whose bytes differ from the library file as positionIncompatible instead of
unmatched, so the plugin keeps the match, skips highlights without a failure and still syncs progress.
Treat a position-less place within a page as the same place and jump to the nearest page.
Suggest library books with the same title and authors for books to review, with bulk linking.
See docs/KOREADER_HASH_MATCHING.md.

Closes #1872
Closes #1919
This commit is contained in:
neon
2026-10-26 15:06:04 +00:00
parent 834da8c954
commit 1c27e5dd05
36 changed files with 1634 additions and 63 deletions
+24
View File
@@ -16,6 +16,30 @@ An explicit manual link takes precedence over automatic hash matches. Removing i
The existing API routes and response fields remain compatible. The file-timestamp component of the match-cache token uses a global indexed lookup, so another library's file changes can trigger extra match refreshes. History revisions and manual links remain scoped to the user's access. Manifest pagination continues across token changes.
## Links to a different copy
A manual link usually points a device copy at a library file with different bytes, such as a book
calibre sent to the device with its own metadata written in. Positions in that copy cannot be placed
in the library file, so the link syncs reading status, rating, reading time and progress as a
percentage, but not highlights, bookmarks or exact positions. Match-check marks such a match with
`positionCompatible: false`, and the highlight and bookmark exchanges list it under
`positionIncompatible`, never under `unmatched`: plugins read `unmatched` as "not in your library" and
drop the match. Plugin 2.0.0 ignores both fields, keeps the match and counts its skipped highlights as
uploaded; later plugins skip the exchange and say why.
A percentage-only place lands on a page boundary, so the plugin treats a remote place without a
position as the same place when it is within one page, and in page mode jumps to the nearest page
rather than the page below.
## Link suggestions
`GET /koreader/unmatched-books/suggestions` offers library books whose title and set of authors equal
a linkable book to review's, compared after folding only case, Unicode compatibility forms and
whitespace. It is read only and scoped like the rest of the user's library: accessible libraries,
content filters, present books, and a primary file that is not audio, because a link targets the
primary file. A title shared by two or more books, or by more books than are checked, is never offered
as a single suggestion. Nothing links until the user confirms through the ordinary link route.
## Historical recovery limit
The one-time backfill recovers delivered identities from retained KEPUB cache artifacts whose source identity is still verifiable. It cannot recover pre-fix temporary audioless outputs, over-limit conversions, or other delivered variants whose bytes have already been deleted. Those hashes need a manual link or another download. New deliveries use registration and durable retry instead of depending on retained artifacts.