Skip to content

v2.0.2#785

Merged
ajslater merged 364 commits into
mainfrom
develop
Jun 22, 2026
Merged

v2.0.2#785
ajslater merged 364 commits into
mainfrom
develop

Conversation

@ajslater

Copy link
Copy Markdown
Owner
  • Fixes
    • The web UI now works under a reverse-proxy subpath: the live-update
      websocket, API calls, and cover images honor url_path_prefix instead of
      loading from the server root.

ajslater added 30 commits April 14, 2026 10:34
    Fix clear settings null bug, add global settings clear button

    - clearComicSettings was setting book.settings to null, causing
      Object.entries() to throw TypeError downstream in getBookSettings
    - Add null guard in getBookSettings as defense-in-depth
    - Add null guard in isClearDisabled computed
    - Add clearGlobalSettings action and clear button to Default Settings panel
    - Compare against READER_DEFAULTS to determine if global clear is disabled
ajslater and others added 29 commits June 14, 2026 21:02
The UNREAD filter used Q(bookmark=None), a multi-valued relationship
test for "comic has no bookmark from anyone" rather than "no bookmark
for me". Once any user finished a comic it dropped out of every other
user's (and anonymous visitors') unread view. UNREAD now negates the
per-user finished predicate (~(my_filter & finished=True)), compiling
to a per-user NOT-EXISTS subquery.

Also harden get_my_bookmark_filter: an anonymous visitor with no
established session_key resolved to `session_id IS NULL`, which matches
every authenticated user's bookmarks. Return a match-nothing filter
instead; a session key is minted only when a bookmark is written.

Adds tests/test_bookmark_filter_isolation.py covering cross-user and
anonymous isolation for READ/UNREAD/IN_PROGRESS.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Replace a stale `ty: ignore[no-matching-overload]` with an isinstance
guard so `settings` is a Mapping before `_copy_params_into`, clearing
the `invalid-argument-type` diagnostic from `make ty`.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Skipping super() left the class-level atomic from setUpTestData
uncommitted-but-unrolled-back, leaking the codex_init() "admin"
superuser into later test classes and causing UNIQUE constraint
failures (e.g. test_bookmark_filter_isolation) in full-suite runs.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Attribute the matched source for every matched comic and tidy the table
layout in the admin Online Tagging Status table.

- Source column was empty for re-tagged comics. They win via comicbox's
  stored-id fast path, which (until comicbox a556faa) emitted no AutoWritten
  event, so codex never learned the source. With merge_all_sources a comic
  can also be auto-written by both sources, so accumulate every winning
  source (deduped, order preserved) instead of last-event-wins:
  matched_source_by_path is now dict[Path, list[str]] and the snapshot row
  field becomes won_sources (a list).
- Render one success chip per matched source; em-dash when unattributed.
- Layout: the Comic column claims all slack (width 100% + the max-width:0
  cell trick) so the filename fills the space before truncating with an
  ellipsis (full path on hover); Status and Source shrink to fit their
  content, so Source is only as wide as the widest source cell present.

Requires comicbox emitting AutoWritten on the explicit-id and stored-id
fast-path wins (comicbox a556faa).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Give every .0 release a short hyphen-delimited title and convert the
existing ### flavor-subtitles to the same format.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Granian assigns url_path_prefix verbatim to the ASGI root_path, which
Django strips from the request path with removeprefix(). A value like
"codex" (no leading slash) never matches the "/codex/..." request path,
so path_info keeps the prefix, ServeStatic 500s on every static file,
and STATIC_URL / email verification links come out malformed.

Normalize the prefix to the root_path / SCRIPT_NAME convention (one
leading slash, no trailing slash) at the single read site, so "codex",
"/codex/", etc. all resolve to "/codex".

Co-Authored-By: Claude Opus 4.8 <[email protected]>
A bulk online-tag scan handed every comic to comicbox's search path, so
a comic codex already holds a Metron/Comic Vine issue id for was
re-searched (resolving the series by name and listing issues per
candidate) instead of fetched directly by that id.

run_session now runs _prefetch_stored_ids first: build_stored_id_map
reads numeric issue ids straight from the Identifier table (so it works
even when the id never round-tripped into the file), each identified
comic is fetched by explicit id in one API call, written through the
same BulkTagWriteTask path, and dropped from the search set. Prefetched
comics stay in path_to_pk so the status table shows them matched and
Resume skips them; unresolved ids fall back to search. Skipped on dry
runs and for sources without credentials.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
The v4 client hardcoded root-absolute paths ("/api/v4/", "/api/v4/ws"),
so under a reverse-proxy subpath (server.url_path_prefix, e.g. "/codex")
every API call 404'd and the websocket connected to "/api/v4/ws" without
the prefix. Channels' outermost URLRouter requires the path to start with
root_path, so it raised "No route found for path '/api/v4/ws'" on every
connect (GitHub #784).

Derive the API and WebSocket bases from window.CODEX.APP_PATH (which
Django already resolves with the prefix) via shared APP_BASE / V4_BASE
exports in api/v4/base.js, and consume them from notify, browser, reader,
and the two admin tabs that built cover/schema URLs by hand. At the server
root APP_PATH is "/", so the bases stay "/api/v4/..." — no regression.

Also drops a stray leading slash in getPDFInBrowserURL that produced a
protocol-relative "//api/v4/..." URL.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Move the subpath (url_path_prefix) frontend fix from v2.0.1 into a new
v2.0.2 section.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@ajslater ajslater merged commit f03796c into main Jun 22, 2026
4 checks passed
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.

1 participant