Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
063f2d2
fix(frontend): send passwordConfirm from profile change-password (#793)
ajslater Jul 3, 2026
3020d67
update deps and version to v2.1.1. bump news
ajslater Jul 3, 2026
27783ee
test(frontend): work around vitest/valid-expect false positive on exp…
ajslater Jul 4, 2026
4963ad9
update deps
ajslater Jul 4, 2026
2462a41
fix(onlinetag): drop dead effort option; model Metron's fewer requests
ajslater Jul 4, 2026
8245efa
trim news
ajslater Jul 4, 2026
6591384
Merge branch 'main' into develop
ajslater Jul 4, 2026
a1845af
refactor(onlinetag): derive source list + issue-id parser from comicbox
ajslater Jul 4, 2026
cd84ed9
fix(onlinetag): scope the match-mode request-count hint to Comic Vine
ajslater Jul 4, 2026
9980c04
fix(fs): don't let one unreadable folder crash the library scan
ajslater Jul 4, 2026
42b7fe9
update deps
ajslater Jul 4, 2026
dfbf390
update version to 2.1.2
ajslater Jul 4, 2026
1d06607
fix typechecking
ajslater Jul 4, 2026
07ffa2a
news for v2.1.2
ajslater Jul 4, 2026
ed38cb5
format
ajslater Jul 4, 2026
a41eede
Squashed commit of the following:
ajslater Jul 4, 2026
8ebc051
update deps
ajslater Jul 4, 2026
08eadba
refactor(onlinetag): extract resume-param sanitizer to cut complexity
ajslater Jul 4, 2026
227cea4
fix(onlinetag): reference defined constant in match-mode hint
ajslater Jul 4, 2026
76a7d3b
Merge branch 'main' into develop
ajslater Jul 4, 2026
97c62aa
update deps
ajslater Jul 7, 2026
f7abf7d
fix(settings): nest comicbox loglevel/delete_keys under general section
ajslater Jul 11, 2026
da257b0
fix(onlinetag): resolve prompts against current DB path, surface appl…
ajslater Jul 11, 2026
a5f37d8
update deps and format
ajslater Jul 11, 2026
e45ef90
Native OIDC single sign-on (Admin Auth tab) (#798)
ajslater Jul 13, 2026
d03666d
bump version 2.2.0
ajslater Jul 13, 2026
698164c
bump news
ajslater Jul 13, 2026
2de8473
update deps and comicbox
ajslater Jul 13, 2026
9243b5e
adapt ComicVine credential check to simyan v3 (comicbox 4.1.1)
ajslater Jul 13, 2026
4c97679
update deps
ajslater Jul 13, 2026
e6bb026
test(onlinetag): assert merge flag is forwarded, not comicbox's arith…
ajslater Jul 13, 2026
19f7b1b
Merge branch 'main' into develop
ajslater Jul 13, 2026
c7dc81f
update deps
ajslater Jul 19, 2026
cb98ea0
v2.2.1: show Metron account rate limits live (comicbox 4.3.0 / mokkar…
ajslater Jul 19, 2026
b3ec559
update deps
ajslater Jul 22, 2026
86b8403
v2.2.1: community ratings replace critical rating (comicbox 4.4.0)
ajslater Jul 22, 2026
04a7b2d
Merge branch 'main' into develop
ajslater Jul 22, 2026
4f7e516
update deps
ajslater Jul 24, 2026
f7ceb6c
v2.2.2: fix rotated pdf page serving (comicbox-pdffile 0.6.3)
ajslater Jul 24, 2026
8086c4c
update deps, including comicbox 4.5.0
ajslater Jul 24, 2026
00c3a99
Fix silent no-op when clearing tag editor fields
ajslater Jul 22, 2026
172a8c9
Fix lint errors from the ruff 0.16 upgrade
ajslater Jul 24, 2026
f1c8405
update comicbox
ajslater Jul 24, 2026
8be22e5
Clear monochrome by deleting the tag, not writing false
ajslater Jul 24, 2026
6b29b63
Merge branch 'main' into develop
ajslater Jul 24, 2026
1acc942
update devenv and deps
ajslater Jul 25, 2026
d358c22
update claude rules about telemetry
ajslater Jul 25, 2026
10d87b0
Fix anonymous stats sending and report what codex grew into
ajslater Jul 26, 2026
9b102cd
update deps
ajslater Jul 26, 2026
a92236d
Support comicbox 4.6.0 series alternative names
ajslater Jul 26, 2026
265f7fa
update deps and devenv
ajslater Jul 26, 2026
5d5b3bd
bump news for comicbox 4.6.1
ajslater Jul 26, 2026
3b500ae
update devenv
ajslater Jul 26, 2026
646fe38
fix cron double enqueue of telemeter task
ajslater Jul 27, 2026
c014acb
test crond double enqueu fix
ajslater Jul 27, 2026
7c65e0d
test telmemeter logging fixes
ajslater Jul 27, 2026
7574042
Merge branch 'main' into develop
ajslater Jul 27, 2026
4bec196
feat(api): reintroduce Swagger UI at /api/v4/
ajslater Jul 27, 2026
8650305
v2.2.4
ajslater Jul 27, 2026
1d0fc47
sub api v3 for v4
ajslater Jul 27, 2026
8fbf7e1
feat(tagging): authenticate to Metron with an API key
ajslater Jul 29, 2026
31d81d2
update deps
ajslater Jul 29, 2026
0dd3e51
feat(tagging): remove the custom URL fields for Metron & Comic Vine
ajslater Jul 29, 2026
0f412f8
fix(tests): clear the two outstanding ty errors
ajslater Jul 29, 2026
f740fff
Merge branch 'main' into develop
ajslater Jul 29, 2026
2a1a170
feat(tagging): present Metron as an API key source & warn on legacy l…
ajslater Jul 29, 2026
7a09ccd
update devenv
ajslater Jul 30, 2026
0c2a0a7
update deps
ajslater Aug 1, 2026
5732a22
fix(importer): import a renamed comic's new tags instead of failing
ajslater Aug 1, 2026
e39ce40
v2.2.5
ajslater Aug 1, 2026
25d1a6d
feat(tagging): combine online search and tag-by-id into one pass
ajslater Aug 2, 2026
97c65d6
update deps
ajslater Aug 2, 2026
f54e70b
style(news): prettier wrap the online tagging entry
ajslater Aug 2, 2026
178a05d
Merge branch 'main' into develop
ajslater Aug 2, 2026
f0b513f
feat(tagging): restore the custom URL for Comic Vine
ajslater Aug 4, 2026
25e4c7e
bump version and update deps
ajslater Aug 4, 2026
97a08ee
bump dockerfile source version
ajslater Aug 4, 2026
e5dec10
granian 2.8.0
ajslater Aug 4, 2026
7a6ee38
update deps
ajslater Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ sibling `cfg` boilerplate system. Key fragments: `codex.mk`, `django.mk`,

### Key Libraries

- **Backend:** Django 6, Channels 4.2, DRF 3.16, Granian 2.7, comicbox (comic
- **Backend:** Django 6, Channels 4.2, DRF 3.16, Granian 2.8, comicbox (comic
parsing), Pillow, django-cachalot, loguru
- **Frontend:** Vue 3.5, Vite 8, Vuetify 4, Pinia 3, xior
- **Database:** SQLite + WAL + FTS5 full-text search
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ RUN set -eux \
&& rm -f /tmp/${CODEX_WHEEL}

# ---- Stage 4: final (production image) ------------------------------------
FROM ghcr.io/ajslater/python-debian:3.14.4-slim-trixie_0 AS final
FROM ghcr.io/ajslater/python-debian:3.14.6-slim-trixie_0 AS final
ARG CODEX_VERSION=dev
LABEL org.opencontainers.image.title="Codex" \
org.opencontainers.image.description="Codex Comic Server" \
Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ width: 128px;
border-radius: 128px;
" />

## v2.2.6

- Features
- The Comic Vine custom URL is back, for tagging against a Comic Vine proxy
or mirror. URLs discarded by v2.2.4 must be entered again. Metron Cloud's
stays gone; it never did anything.

## v2.2.5

- Features
Expand Down
36 changes: 22 additions & 14 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions codex/librarian/onlinetag/credential_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ def _validate_comicvine(creds: OnlineCredentials) -> ValidationResult:
"cache_expiry": DO_NOT_CACHE,
"ratelimit_path": tmp_path / "ratelimits.sqlite",
}
if creds.comicvine_url:
kwargs["base_url"] = creds.comicvine_url
cv = Comicvine(**kwargs)
try:
cv.list_publishers(params={"limit": "1"}, max_results=1)
Expand Down
5 changes: 4 additions & 1 deletion codex/librarian/onlinetag/explicit_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ def _build_auth_source(
user=credentials.metron_user,
password=credentials.metron_password,
)
return OnlineSourceCredentials(key=credentials.comicvine_key)
return OnlineSourceCredentials(
key=credentials.comicvine_key,
url=credentials.comicvine_url,
)


def build_explicit_id_config(
Expand Down
1 change: 1 addition & 0 deletions codex/librarian/onlinetag/session_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def _build_credentials(self) -> OnlineCredentials | None:
metron_user=defaults.metron_user or "",
metron_password=defaults.metron_password or "",
comicvine_key=defaults.comicvine_key or "",
comicvine_url=defaults.comicvine_url or "",
)

@staticmethod
Expand Down
3 changes: 2 additions & 1 deletion codex/librarian/telemeter/admin_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def _default_sources(defaults: ComicboxTaggingDefaults) -> dict[str, int]:


def get_tagging_stats() -> dict[str, Any]:
"""Report the online tagging defaults. Never the credentials."""
"""Report the online tagging defaults. Never the credentials or the url."""
defaults = ComicboxTaggingDefaults.objects.first()
if not defaults:
return {}
Expand All @@ -160,6 +160,7 @@ def get_tagging_stats() -> dict[str, Any]:
defaults.metron_key or (defaults.metron_user and defaults.metron_password)
),
"has_comicvine_credentials": bool(defaults.comicvine_key),
"comicvine_url_set": bool(defaults.comicvine_url),
}


Expand Down
29 changes: 29 additions & 0 deletions codex/migrations/0052_comicboxtaggingdefaults_comicvine_url.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Generated by Django 6.0.7 on 2026-08-03 12:00."""

from django.db import migrations, models


class Migration(migrations.Migration):
"""
Restore the custom Comic Vine URL override removed by 0051.

Only the Comic Vine half comes back. comicbox passes the url through to
simyan's ``base_url``, so pointing tagging at a Comic Vine proxy or mirror
works. Metron's twin stays gone: mokkari hardcodes its API endpoint and
comicbox warns that the url is ignored.

0051 dropped the column outright, so any URL saved before it is
unrecoverable — admins re-enter it.
"""

dependencies = [
("codex", "0051_remove_comicboxtaggingdefaults_urls"),
]

operations = [
migrations.AddField(
model_name="comicboxtaggingdefaults",
name="comicvine_url",
field=models.URLField(blank=True, default="", max_length=256),
),
]
5 changes: 5 additions & 0 deletions codex/models/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ class PromptsModeChoices(TextChoices):
metron_user = EncryptedCharField()
metron_password = EncryptedCharField()
comicvine_key = EncryptedCharField()
# Points simyan at a Comic Vine proxy or mirror instead of the public API.
# Not a secret, and the admin form echoes it back as a placeholder, so it
# stays a plain URLField. Metron has no twin: mokkari hardcodes its
# endpoint, so a custom URL there was always a no-op.
comicvine_url = URLField(max_length=256, blank=True, default="")

# Active session id + pending prompts used to live here. They are
# transient operational state — they only matter while a tagging
Expand Down
3 changes: 2 additions & 1 deletion codex/serializers/admin/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class StatsTaggingSerializer(Serializer):
"""
Online Tagging Defaults.

Credentials report only whether they are configured.
Credentials and the Comic Vine url report only whether they are configured.
"""

default_match_mode = CharField(required=False, read_only=True)
Expand All @@ -183,6 +183,7 @@ class StatsTaggingSerializer(Serializer):
default_format_count = IntegerField(required=False, read_only=True)
has_metron_credentials = BooleanField(required=False, read_only=True)
has_comicvine_credentials = BooleanField(required=False, read_only=True)
comicvine_url_set = BooleanField(required=False, read_only=True)


class StatsAuthSerializer(Serializer):
Expand Down
4 changes: 4 additions & 0 deletions codex/serializers/admin/tagging.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class TaggingValidateRequestSerializer(Serializer):
)
metron_key = CharField(required=False, allow_blank=True)
comicvine_key = CharField(required=False, allow_blank=True)
comicvine_url = CharField(required=False, allow_blank=True)


class TaggingRateLimitWindowSerializer(Serializer):
Expand Down Expand Up @@ -207,6 +208,9 @@ class Meta(BaseModelSerializer.Meta):
"merge_all_sources",
"metron_key",
"comicvine_key",
# Not a secret, so unlike the keys this reads back: the form shows
# the saved url as its placeholder.
"comicvine_url",
"metron_key_set",
"comicvine_key_set",
"has_metron_credentials",
Expand Down
9 changes: 5 additions & 4 deletions codex/user_data/restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ def _build_tagging_defaults(row) -> dict[str, Any]:
"metron_user": "",
"metron_password": "",
"comicvine_key": "",
"comicvine_url": "",
}
# ``sqlite3.Row`` raises on a missing column, so skip what a sidecar
# predating a column doesn't carry (e.g. metron_key) and let the model
Expand All @@ -386,10 +387,10 @@ def _build_tagging_defaults(row) -> dict[str, Any]:
defaults["default_sources"] = json.loads(row["default_sources"] or "[]")
defaults["delete_original"] = bool(row["delete_original"])
# ``active_session_id`` / ``active_prompts`` used to be on this row before
# they moved to the Django cache as transient state, and ``metron_url`` /
# ``comicvine_url`` before the custom URL overrides were removed. Older
# sidecar backups still carry those columns — since this comprehension
# walks ``coalesced`` rather than the row, they are silently ignored.
# they moved to the Django cache as transient state, and ``metron_url``
# before that no-op override was removed for good. Older sidecar backups
# still carry those columns — since this comprehension walks ``coalesced``
# rather than the row, they are silently ignored.
return defaults


Expand Down
1 change: 1 addition & 0 deletions codex/user_data/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ CREATE TABLE IF NOT EXISTS tagging_defaults (
metron_user TEXT NOT NULL DEFAULT '',
metron_password TEXT NOT NULL DEFAULT '',
comicvine_key TEXT NOT NULL DEFAULT '',
comicvine_url TEXT NOT NULL DEFAULT '',
updated_at TEXT
);

Expand Down
1 change: 1 addition & 0 deletions codex/user_data/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ def serialize_tagging_defaults(
"metron_user": defaults.metron_user or "",
"metron_password": defaults.metron_password or "",
"comicvine_key": defaults.comicvine_key or "",
"comicvine_url": defaults.comicvine_url or "",
"updated_at": _datetime_str(getattr(defaults, "updated_at", None)),
},
)
1 change: 1 addition & 0 deletions codex/views/admin/tagging_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"metron_user",
"metron_password",
"comicvine_key",
"comicvine_url",
)


Expand Down
Loading