Skip to content

Add downloaded ebooks through Calibre when the root folder is a Calibre library - #314

Draft
jtruland wants to merge 3 commits into
Chaptarr:developfrom
jtruland:fix/calibre-download-import-upstream
Draft

jtruland wants to merge 3 commits into
Chaptarr:developfrom
jtruland:fix/calibre-download-import-upstream

Conversation

@jtruland

Copy link
Copy Markdown

Ready for review. It is opened as a draft only because of the repository's one-open-PR limit for contributors without write access; my other open PR is #283. Please treat it as ready, or I can mark it ready once #283 is resolved.

Description

A download imported into a root folder marked as a Calibre library is copied into the library folder instead of being added through the Calibre content server. Calibre never sees the book: it is missing from metadata.db and from Calibre-Web, and it sits in a folder without Calibre's (id) suffix.

The cause is that download and manual imports go through ImportApprovedBooks, which always transfers the file with IMoveBookFiles. The Calibre path (CalibreProxy.AddAndConvert) only exists in UpgradeMediaFileService, which this import route never reaches.

This PR adds a small routing step in ImportApprovedBooks. When the destination Chaptarr would choose for an ebook falls inside a root folder with IsCalibreLibrary and Calibre settings, the file goes to AddAndConvert, the same call UpgradeMediaFileService uses. Calibre picks the folder, and SetFields records Calibre's path on the BookFile. In that case:

  • tag writing and release extras are skipped, because Calibre owns the folder;
  • relocating an already-tracked file keeps the existing path;
  • audiobooks and non-Calibre root folders are unchanged.

A second commit makes removing the downloaded source file best-effort once Calibre has accepted the book. If that delete failed the import used to fail, leaving the book in Calibre without a Chaptarr record; a retry then added it to Calibre a second time.

This is deliberately narrow. #132 covers much more (deletion propagation, duplicate reaping, metadata push, cover reconciliation). This PR only stops downloads from bypassing Calibre, so it can land on its own whatever happens with #132.

Fixes #205

Database Migration

NO

How was this tested?

  • Chaptarr.Core.Test: 3040 passed, 0 failed (3035 on develop plus 5 new). The new ImportApprovedBooksCalibreDestinationFixture covers:
    • an ebook bound for a Calibre-library root is routed to Calibre;
    • a plain root folder uses the normal transfer;
    • a Calibre root without settings uses the normal transfer;
    • audiobooks are never routed to Calibre.
  • Live, Docker on Debian 13: v0.9.965 plus this change, with a root folder at /data/calibre/library backed by a linuxserver/calibre content server on port 8181.
    • Before the change, imported EPUBs landed as loose files (for example Diana Jones/Howl's Moving Castle/dw2o9q31.epub) and metadata.db gained no rows.
    • After the change, the same EPUB imported from a download folder was added through the content server as Calibre book 2764 at Diana Wynne Jones/Howl's Moving Castle (2764)/. A rescan then linked the Chaptarr book file to that path.

The third commit null-guards CalibreProxy.SetFields. It dereferenced series links, edition images, genres and ratings without null checks. A book with no genres or series links threw ArgumentNullException after Calibre had already accepted the file, so the import failed and a retry added the book a second time. A regression test covers it; the test fails on develop at the same line as the production crash.

Disclosure

This bug was found, diagnosed, fixed and tested by Claude Code running Claude Opus 5.5, working on my own instance at my direction. I reviewed the change and deployed it to my server, where it has run since 2026-10-03.

🤖 Generated with Claude Code

jtruland and others added 3 commits October 3, 2026 13:05
…re library

ImportApprovedBooks always moved or copied the file with the book file
mover, so a download imported into a root folder marked as a Calibre
library bypassed the content server: the book never reached metadata.db
and Calibre/Calibre-Web could not see it (issue Chaptarr#205).

When the import destination for an ebook resolves to a Calibre library
root with settings, hand the file to CalibreProxy.AddAndConvert instead,
as UpgradeMediaFileService already does. Calibre picks the folder and
SetFields records its path on the BookFile. Tag writing and release
extras are skipped for these files because Calibre owns the folder.
Relocations of already-tracked files keep the existing path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Once AddAndConvert succeeds the book is in Calibre. Treating a failed
delete of the download as a failed import left the book untracked, and
a retry would add a duplicate to Calibre. Log a warning instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CalibreProxy.SetFields runs after the book is already in Calibre. It
dereferenced series links, edition images, genres and ratings without
null checks, so a book with no genres or series links threw
ArgumentNullException at OrderBy and failed the whole import, leaving
the book in Calibre with no Chaptarr record (a retry then added it
twice). Treat absent metadata as empty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Download imports to a Calibre root folder skip Calibre and copy the file directly

1 participant