Skip to content

v4.6.1 - #157

Merged
ajslater merged 423 commits into
mainfrom
develop
Jul 26, 2026
Merged

v4.6.1#157
ajslater merged 423 commits into
mainfrom
develop

Conversation

@ajslater

Copy link
Copy Markdown
Owner
  • Fixes
    • Hand-tagged identifier keys with a type prefix, like series:178012, now
      produce correct per-database URLs instead of embedding the prefix in an
      issue-shaped URL. Affected every source, notably ComicVine, Metron, Grand
      Comics Database, and League of Comic Geeks.
    • Hand-tagged ComicVine long codes like 4050-160294 are normalized to the
      bare id with the right URL.
    • source:type:key identifier strings in tags no longer drop the id number.
    • All URNs in a notes field are read as identifiers; previously only the
      first was.
    • Story arcs tagged online from Metron or ComicVine get web URLs.

ajslater and others added 28 commits July 19, 2026 01:23
- New AlternativeNumber and CommunityRating (AverageRating, RatingCount)
  tags; validate against the released v1.1 XSD and drop the v1.0 XSD.
- New native nested community_rating (average_rating, rating_count).
  ComicInfo CommunityRating and ComicBookInfo rating now map to it;
  critical_rating remains but no longer maps to any format.
- New native alternative_issue, an issue object parsed into name, number
  and suffix parts like issue. Metron API alt_number now maps to it
  instead of shoehorning into the issue suffix.
- Guard the metron write path so a count-only community_rating never
  emits an XSD-invalid CommunityRating without an AverageRating.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mokkari 4.2.0 added average_rating and rating_count to the Issue model.
Map them into the native community_rating block. Unrated issues (null
average, zero count) emit nothing, and a zero count is never passed
through to the minimum=1 native field where it would clamp up to 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
write_metadata() and BulkWriteItem accept delete_keys glom key paths,
layered onto general.delete_keys. Empty patch values are pruned on
schema load, so update-mode writes could never clear an existing tag;
delete_keys is the explicit clear mechanism. A pure-clear write may
pass an empty patch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extracted pdf pages were named from the archive type and only renamed if
the pdf reader reported the format it served. A reader that hands back a
page's embedded image instead of a one page pdf without reporting an
extension left jpeg data on disk named ".pdf".

Sniff the data's magic bytes at the pdf read boundary to fill in a format
the reader didn't report, so pages are named for what they contain. A
reported format still wins, so nothing that names correctly today changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
--extract-pages RANGE with --pdf-pages pdf (or the default pdf format)
now writes one merged pdf spanning the range instead of a file per page.

The --pdf-pages help table is derived from the installed pdffile's
PageFormat enum, so it can never advertise a value the CLI rejects, and
all five modes are documented.

Also stop counting a pdf's embedded metadata (e.g. an embedded
ComicInfo.xml) as a page, which inflated the page count and left a stray
file when extracting ranges.

Requires comicbox-pdffile 0.6.3 for the read_pdf page-range argument.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- RUF036: order None last in union return types
- PLC0414: keep the explicit re-export aliases with a targeted noqa
- ISC004: parenthesize an implicit string concatenation
- PLR0917: extend the TestParser noqa to cover its positional-arg count
- Split bin/roman.py _walk_tree's scan loop into a _scan_dir helper to
  drop its cognitive complexity below threshold

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Default conversion wrote raw .ppm pixmaps that no comic reader
(including comicbox itself) recognizes as pages, yielding a zero-page
book — and --delete-orig then removed the working original. Conversion
now defaults to pixmap_jpeg whole-page renders, which also apply pdf
display rotation.

--pdf-pages image wrote rotated pages as stored — sideways or upside
down for scans relying on /Rotate (or a rotated content-stream
placement) for display. Rotated image-dominant pages are now rendered
to match the displayed orientation (pdffile 0.6.3 classify); unrotated
pages still extract their original bytes untouched.

Also store converted page images uncompressed: the compression decision
ran before pdf pages gained their image suffix, so page images were
pointlessly deflated.

Ships as v4.5.1 alongside the pdf range extraction and page naming
fixes already in NEWS; version stays 4.5.1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The release ships as v4.5.0; both unreleased sections merge into one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
radon counts each assert as a branch, so the 10-assert core-fields test
ranked C (11). Group the scalar and nested-name checks into single dict
comparisons — rank B (6), same coverage, clearer failure diagnostics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
YesNoEnum was missing its YES member, so EnumBooleanField's truthy
coercion produced the string "Yes", failed the enum lookup, and got
swallowed by TrapExceptionsMeta. BlackAndWhite was dead in both
directions: monochrome could never be read from a comic nor written to
one, leaving the field impossible to set or clear. The member was
dropped in 04342a3 when YesNoField was rebased from BooleanField onto
EnumBooleanField.

Restore the original semantics: deserialize to a bool, with the schema's
Unknown meaning no value. An unset monochrome omits the tag rather than
writing Unknown, matching how every other absent field is treated.

Also fix the shared enum-boolean base, which mishandled False for Manga
as well: str(False) matched no enum member, and _serialize raised
AttributeError on any bool. Coercion now consults the enum vocabulary
first so multi-valued enums keep their extra members, then falls back to
reading the value as a boolean.

The tag had no test coverage, which is how this shipped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mokkari 4.3.0 added `alt_names` to its Series and IssueSeries schemas.
Map them to comicbox reprints, the same representation MetronInfo.xml's
Series/AlternativeNames already round-trip through.

ComicVine has exposed volume `aliases` all along and comicbox ignored
them. Map those too: `get()` injects them from the volume it already
fetches for the publisher, so no extra API call.

Alternative names also feed online matching. `s_series` scores best-of
over the candidate's primary name and its aliases, and the pre-call
volume filter keeps a volume when any alias clears the threshold, so a
comic filed under a localized title matches its canonical volume.
Aliases only ever widen the gate; they cannot drop a volume the primary
name would have kept.

Metron's search results carry no alternative names — mokkari's
BasicSeries lacks the field, unlike the IssueSeries on issue detail —
so its candidates score exactly as before. Reading them at match time
would cost an API call per candidate.

The contributing-signals gate counts alternative names as candidate
series data. Since s_series can now score from them alone, omitting
them would drop W_SERIES from the renormalization denominator and
inflate the remaining signals.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ajslater
ajslater merged commit 820a3a4 into main Jul 26, 2026
3 checks passed
@ajslater ajslater mentioned this pull request Jul 26, 2026
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.

2 participants