Repository navigation
fix: stop browsing from re-importing tagless comics and reloading the page (#992) - #993
Merged
Merged
Conversation
Hovering a browser card's tag button lazy-imports a comic whose has_metadata is false, i.e. metadata_imported_at and metadata_mtime are both NULL. metadata_mtime stays NULL for any archive with no embedded tags file. metadata_imported_at was only stamped by forced imports, so a library scan with "Import Tags on Library Scan" on (the default) read every comic but stamped none. On any install scanned since 0043, every comic without embedded tags read as un-imported. Each hover then forced an import that found nothing but still rewrote the row, purged and rebuilt the cover and broadcast LIBRARY_CHANGED, reloading the browser once per comic. - Stamp at finish whenever the pass read tags: forced, or the IMPORT_METADATA flag on. A flag-off scan still leaves rows NULL for the lazy importer. The flag read moves to FinishImporter so extract and finish share it. - Batch the stamp's path__in by IMPORTER_LINK_FK_BATCH_SIZE. First scans of large libraries now reach it, and a single IN list would exceed SQLite's default 32766-variable cap. - Migration 0060 backfills NULL rows with 0043's seed when the IMPORT_METADATA flag is on (a missing row counts as on). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A forced or lazy import of an unchanged comic, typically one with no embedded tags, still rewrote the row. The query phase kept it in UPDATE_COMICS with an empty diff "to set stat", so update_comics wrote the six always-update fields, purged and rebuilt the cover and bumped updated_at. TimestampUpdater then restamped its collections and finish broadcast LIBRARY_CHANGED, reloading every open browser. update_comics now skips a comic when the update would write nothing new: - no scalar diff and no FK link change remain after the query phase's pruning, so Force Update still relinks a wrong publisher; - no m2m link to create or delete, so a stray genre still gets the row write that re-syncs its search entry and timestamp; - no TagWriter series_attrs ride along; - presave derives the same stat, size, date, decade and age-rating index from the file on disk, so a replaced file with the same tags still updates and gets a new cover; - the chunk's update_all_fks changed no rows. FK bulk updates don't write updated_at, and the FK search re-sync only runs beside per-comic FTS entries. A corrected tag or collection row reaches the browser and the index only through the comics the import rewrites, so such a chunk keeps the old full update. With nothing written, counts stay zero, so finish neither clears caches nor broadcasts. The metadata_imported_at stamp is path-scoped and still lands. An import that rewrote no comics left the empty FTS inputs behind, because an operate with no entries returns before consuming them; import_search_index now drains them on exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #992: browsing a folder of CBR/CBZ files re-imports comics one at a time and reloads the page.
Cause
Hovering a browser card's (invisible) tag button lazy-imports a comic whose
has_metadatais false, i.e.metadata_imported_atandmetadata_mtimeare both NULL.metadata_mtimeis NULL for any archive with no embedded tags file.metadata_imported_atwas only stamped by forced imports. A library scan with Import Tags on Library Scan on (the default) read every comic but stamped none, so on any install scanned since 0043 every comic without embedded tags looked un-imported.Each hover then forced an import that found nothing new but still rewrote the row, purged and rebuilt the cover and broadcast LIBRARY_CHANGED. The browser reloaded once per comic, which matches the reporter's log line for line.
Changes
1. Stamp on tag-reading scans (
finish.py, migration 0060)_stamp_metadata_importednow runs when the pass read tags: forced, or the IMPORT_METADATA flag on. A flag-off scan still leaves rows NULL for the lazy importer.extract.pyandfinish.pyshare the flag read.path__inis batched byIMPORTER_LINK_FK_BATCH_SIZE. A first scan now reaches it with every path in the library.2. Skip no-op re-imports (
create/comics.py)update_comicsskips a comic only when all of these hold:series_attrsride along;presavederives the same stat and derived values from the file on disk;update_all_fkschanged no rows (newchunk_fks_updatedflag). FK bulk updates don't writeupdated_at, so a corrected tag or collection row reaches the browser and the search index only through a rewritten comic.With nothing written, finish neither clears caches nor broadcasts.
Also:
import_search_indexnow drains its empty inputs on exit.test_update_none's snapshots now expect no FTS update entry for the unchanged comic.Force Update of an unchanged comic no longer rebuilds its cover. Remove All Covers is still the way to regenerate covers.
Tests
tests/test_lazy_import_marker.pytests/importer/test_noop_update.py, all end to end:updated_atbump);finish.py; the two silent tests fail without the guard; the genre and designation tests fail without the m2m and FK-chunk checks.make fix,make lint,make ty,make complexityare clean.make test: 1753 passed, 1 xfailed; frontend 1033 passed.🤖 Generated with Claude Code