feat(metadata): write-to-file — embedded EPUB OPF + Calibre sidecars
Phase 5a of the metadata-writer feature: the book editor gains a "Write to file" action (admin) that persists the item's CURRENT database metadata into the artifact on disk, so the library stays portable to Calibre and other apps — the thing Save alone can't do. Dispatch (services/metadata_writer.go): EPUB/KEPUB gets its embedded OPF spliced in place (fresh dc:* block generated inside the ORIGINAL metadata open tag; manifest/spine/guide untouched; every other zip entry copied byte-identical in original order so mimetype stays first and STORED; original dc:identifiers preserved — the package's unique-identifier must keep resolving). Everything else takes a Calibre-style sidecar: metadata.opf when the book is ALONE in its directory (Calibre's own convention — round-trips through Calibre too), <basename>.opf when siblings share the folder, so one book's sidecar can never poison dir-mates' scans (the scanner now reads both, basename first). Safety contract: temp file + atomic rename — the original is never truncated on failure; the generated OPF is unit-tested to ROUND-TRIP through the scanner's own parser (write side and read side can never disagree); metadata_overrides are deliberately kept (file and DB agree after the write; overrides still guard against stale sidecars). The endpoint re-extracts inline (RescanMediaItem) and reports rescan failure separately — a failed rescan doesn't undo the write. SHA-256 changes are inherent and documented for users (Kobo/KOReader re-key). UI: the metadata editor modal carries the file path as a data attribute; the button confirms before mutating, labels the target (embedded vs sidecar) and toasts the outcome. Integration tests pin the 403, missing-file error, EPUB embed + post-write rescan title, the lone-book metadata.opf case, and the shared-dir <basename>.opf case with no dir-scoped litter.
This commit is contained in:
1 parent
61e5f47ec0
commit
eaf1b2c8dd
13 files changed
+1591
-413
No files matched your search
@@ -298,6 +298,27 @@ A: Calibre Web uses the same `metadata.opf` files, so yes - Bookhoard can scan a
|
||||
|
||||
A: Bookhoard has its own sorting logic and doesn't import Calibre sort fields. This allows for consistent sorting across all books.
|
||||
|
||||
## Writing metadata back to files (admin)
|
||||
|
||||
The book page's metadata editor has a **Write to file** action alongside
|
||||
Save. Save updates Bookhoard's database only; Write to file persists the
|
||||
currently saved values into the artifact on disk, then re-extracts so
|
||||
everything stays in sync:
|
||||
|
||||
- **EPUB/KEPUB** — the OPF embedded in the book is rewritten in place
|
||||
(cover, chapters and reading position are untouched). The file's
|
||||
checksum changes, so device syncs (Kobo, KOReader) re-key the book on
|
||||
their next sync.
|
||||
- **Everything else** (PDF, comics, folder books, audio until tag
|
||||
writing ships) — a Calibre-style sidecar is written next to the file:
|
||||
`metadata.opf` when the book is alone in its folder (Calibre's own
|
||||
convention, so Calibre reads it too), or `<filename>.opf` when several
|
||||
books share a folder, so one book's sidecar can never leak onto its
|
||||
neighbours.
|
||||
|
||||
The write mirrors exactly what the scanner reads back, and the original
|
||||
file is never touched if anything fails (temp file + atomic rename).
|
||||
|
||||
## Resources
|
||||
|
||||
- [Calibre Website](https://calibre-ebook.com/)
|
||||
|
||||
Reference in new issue
Block a user