All formats

comicbox

LanguagePython (3.11+)
LicenseLGPL-3.0
Repositorygithub.com/ajslater/comicbox
Documentationcomicbox.readthedocs.io
Depends onPython packages (py7zr, rarfile, Pillow, marshmallow, ...); the unrar binary for CBR
Read / writeyes / converts to CBZ (7z archives can't be rewritten; writing metadata produces a CBZ)

comicbox is a comic book library and command line tool. It opens CBZ, CBR, CB7, CBT and PDF comics, finds the page images, picks the cover, and reads every common metadata format: ComicInfo.xml, MetronInfo.xml, ComicBookInfo, CoMet and metadata parsed from the file name. It merges them into one normalized dictionary. It’s the metadata engine of the Codex comic server. CB7 support uses py7zr (pure Python), so no external tool is needed.

comicbox doesn’t write 7z archives. When you write metadata to a CB7 file, it repacks the comic as a CBZ next to the original. comicbox sorts pages by case-insensitive name, not natural order, so zero-padded names (001.jpg) matter.

Installation#

Shell
pip install comicbox
# with PDF support
pip install "comicbox[pdf]"

Basic usage: pages, cover and metadata#

Python
from comicbox.box import Comicbox

with Comicbox("Batman 001.cb7") as cb:
    print(cb.get_file_type())          # "CB7"
    print(cb.get_page_count(), "pages")
    for name in cb.get_page_filenames():
        print(name)

    md = cb.to_dict()["comicbox"]      # merged metadata from all sources
    print(md.get("series", {}).get("name"), md.get("issue", {}).get("name"), md.get("title"))

    cover = cb.get_cover_page()        # bytes of the cover image
    with open("cover.jpg", "wb") as f:
        f.write(cover)

get_cover_page() honors a FrontCover page in ComicInfo.xml and falls back to the first page.

How to read a page by index#

Python
with Comicbox("comic.cb7") as cb:
    data = cb.get_page_by_index(0)                     # bytes, or None if out of range
    name = cb.get_pagename(0)                          # file name inside the archive
    for page in cb.get_pages(page_from=0, page_to=4):  # first five pages, as bytes
        print(len(page))

How to get ComicInfo.xml as XML#

to_string serializes the merged metadata in any supported format:

Python
from comicbox.box import Comicbox
from comicbox.formats import MetadataFormats

with Comicbox("comic.cb7") as cb:
    print(cb.to_string(MetadataFormats.COMIC_INFO))   # ComicInfo.xml text
    print(cb.to_string(MetadataFormats.METRON_INFO))  # MetronInfo.xml text

How to write metadata (converts to CBZ)#

write_metadata merges a patch into the existing metadata. For a CB7 file it writes a new CBZ and reports its path in final_path; the original file is left in place:

Python
from comicbox.write import write_metadata

result = write_metadata(
    "Batman 001.cb7",
    {"series": {"name": "Batman"}, "publisher": {"name": "DC Comics"}},
    formats=["COMIC_INFO"],
)
print(result.written, result.final_path)   # True Batman 001.cbz

comicbox.predict.predict_write_destination(path) tells you where a write would land before doing it.

Command line#

Shell
comicbox -p comic.cb7                     # print merged metadata
comicbox -X --dest-path ./out comic.cb7   # extract the cover
comicbox -x 0:5 --dest-path ./out comic.cb7  # extract pages 0-5
comicbox -z comic.cb7                     # convert to CBZ, keeping metadata

Tips#