Skip to content

Making the files portable

Every other comic reader — Komga, Kavita, ComicRack, YACReader, Chunky, Panels — reads ComicInfo.xml from inside the archive. None of them has a library-import format; they scan directories. So the way to move a library elsewhere is to make the files describe themselves, and then point the other application at them.

Write metadata to file on a comic's page does that: it rebuilds the CBZ with a ComicInfo.xml carrying everything Longbox knows. In bulk:

python -m app.cli tag --dry-run     # see what would be written
python -m app.cli tag

Reading state, favourites and your own rating are deliberately not written. They belong to an account, not to a file that may be copied or shared.

Converting CBR to CBZ

python -m app.cli convert --dry-run
python -m app.cli convert

Worth doing regardless of portability. RAR is proprietary: it needs unar installed on the server, cannot be written to at all (so CBR files can never be tagged), and is slower to seek. The images inside are identical either way — conversion copies each one across byte for byte, with no re-encoding.

Originals are kept unless you pass --delete-original, so a rescan will find them again until you remove them.

How the rewriting is done

Both operations are careful with files you own:

  • Never in place. A new archive is built beside the original, opened, and compared page by page against what went in. Only then is it moved over the top. A crash halfway leaves the original untouched.
  • Never lossy. Images are copied between containers unchanged — never re-encoded, resized or recompressed. They are stored rather than deflated in the new zip, since they are already compressed.
  • Nothing left stale. The stored size, both hashes and any cached pages are refreshed, so a verify run stays clean and the reader cannot serve pages from the file that used to be there.

PDF and EPUB are refused rather than half-handled: neither carries ComicInfo.xml, and converting them would mean re-encoding every page.

On the Docker deployment the comics volume is mounted read-only, which is the right default for a catalogue but blocks both of these. Remount it read-write if you want to use them, and take a backup first.

CBR files need a RAR tool

RAR is a proprietary format and Python cannot unpack it alone, so a CBR is opened by trying several tools in order until one works: 7-Zip first (the most dependable RAR5 reader), then the rarfile package via unar/unrar, then bsdtar. The Docker image installs unar, which handles both RAR4 and RAR5 on its own — 7-Zip is not required there. On a bare-metal install:

sudo apt install unar

Installing 7-Zip (p7zip-full on Debian/Ubuntu) as well is not required but is not wasted either: it becomes the first thing tried, and a file one tool struggles with still has two more chances rather than one. Without any of these, CBRs fail to import with a message naming what was tried and why each failed, rather than failing silently. Everything else needs no external tools.

CB7 needs no external binary either: py7zr is tried first (it is in requirements.txt), with the 7-Zip CLI as a fallback if that fails. It is worth knowing that 7-Zip is a solid format: entries share one compression stream, so pulling out a single page costs nearly as much as pulling out all of them. Longbox therefore expands a CB7 once, on first read, into a temporary directory that lasts as long as the file is open — to disk rather than memory, since a long comic runs to hundreds of megabytes. Converting CB7 to CBZ removes that cost permanently, and the images are copied across untouched.

PDF support needs pymupdf, which is in requirements.txt but has no wheel for Python 3.14 yet. On 3.14 the app still runs; PDFs import without covers or page counts. Python 3.12 gets full PDF support.