Skip to content

fix: keep library records in sync after file conversion - #161

Open
bbutlerau wants to merge 2 commits into
pullboxapp:developfrom
bbutlerau:fix/file-convert-syncs-library-record
Open

bbutlerau wants to merge 2 commits into
pullboxapp:developfrom
bbutlerau:fix/file-convert-syncs-library-record

Conversation

@bbutlerau

Copy link
Copy Markdown

Summary

The standalone Convert utility (file_convert) converts a tracked file, moves the original to trash, and leaves the LibraryFile row on the old path. Afterwards:

  • the record points at a file that no longer exists;
  • the converted .cbz is untracked;
  • later utilities cannot find metadata for it. Mass Convert logs No metadata available from unknown for <file>, skipping step 2.

I hit this converting six .cbr issues of one series; the records stayed on the .cbr paths and I had to repoint them by hand. The Mass Convert pipeline already syncs the record in apply_item_result; the standalone executor had no equivalent.

Related Issues

None filed.

Changes

  • FileConverterExecutor.apply_item_result: after a completed conversion, move the tracked record to the converted path (name, format, size, modified time), via the existing _sync_converted_file_record helper. Untracked files and failed items are left alone.
  • FileConverterExecutor.apply_rollback_result: after a successful rollback, point the record back at the restored original. The rollback executor already looks this hook up on the original executor.
  • _sync_converted_file_record now takes the format from the target path's suffix instead of always writing CBZ, so a rollback to a .cbr is not recorded as CBZ. Conversions still produce CBZ, so forward behaviour is unchanged. This also corrects the same case for Mass Convert rollbacks, which use the helper.

Checklist

  • Tests pass locally for the touched areas (tests/utilities/test_file_converter.py, test_mass_convert_pipeline.py, test_error_recovery.py, tests/unit/test_library_convert_service.py, test_referenced_utility_guards.py, and the rollback tests). The new record-sync tests fail on develop without the change.
  • Lint clean (ruff check src/ tests/)
  • Type check clean for the touched files (mypy --strict on file_converter.py and library_convert_service.py). A full-tree run in my environment reports errors on untouched develop too, so I am relying on CI for the full check.
  • Format clean (ruff format --check src/ tests/)
  • New code has test coverage
  • Documentation updated (not applicable)
  • Commit messages use documented conventional prefixes
  • CHANGELOG.md updated: left for release prep, per the contributing guide

Screenshots

No UI changes.

🤖 Generated with Claude Code

@DeusExTaco

Copy link
Copy Markdown
Contributor

@bbutlerau
This is definitely worth fixing. A successful conversion shouldn’t leave the library record pointing at the original file.
I found one case the new sync logic still misses: CBZ → CBZ repacking. The filename stays the same, so the helper returns early, but the file itself has changed. I reproduced a successful repack where the file size changed and the database kept the old size.
Could you update the helper to refresh the tracked file attributes even when the path doesn’t change, and add tests for same-path repacking and its rollback? Please make sure the cached hash is invalidated when the contents change too.
This branch also conflicts with current develop. When rebasing, please retain the existing hash invalidation and conversion-recovery protections in library_convert_service.
Once those changes are pushed, I’d be happy to take another look. The core fix makes sense; I just want the same-path case covered as well.

bbutlerau and others added 2 commits October 3, 2026 12:12
The standalone convert utility converts a tracked file, moves the
original to trash and leaves the LibraryFile row on the old path. The
record then references a file that no longer exists, the converted file
is untracked, and later utilities cannot find metadata for it (Mass
Convert reports "No metadata available from unknown").

Update the record after a completed conversion, as the mass convert
pipeline already does, and point it back on rollback. The shared sync
helper now takes the format from the target path so a rollback to a CBR
is not recorded as CBZ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E9gUFQEryh4gDJRKvjNUZM
A CBZ -> CBZ repack keeps the file name but rewrites the archive, and the
sync skipped it because the path had not changed, leaving the old size,
modified time and cached hash on the record. The record is now refreshed
whenever a conversion or its rollback completes, whether or not the path
moved; the shared helper already clears the cached hash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E9gUFQEryh4gDJRKvjNUZM
@bbutlerau
bbutlerau force-pushed the fix/file-convert-syncs-library-record branch from 814592a to 791b7af Compare October 3, 2026 02:13
@bbutlerau

Copy link
Copy Markdown
Author

Thanks, good catch on the same-path repack. Updated:

  • Same-path conversions: _sync_library_record no longer returns early when the path is unchanged. After a CBZ → CBZ repack the record's size and modified time are refreshed and the cached file_hash is cleared, using the shared _sync_converted_file_record helper. The same happens when the repack is rolled back. In that case the log reads "Refreshed library record: " instead of "Updated library record: a -> b".
  • Tests: added test_same_path_repack_refreshes_the_library_record and test_same_path_repack_rollback_refreshes_the_library_record. Each rewrites the archive in place with a different size and seeds a stale hash. Both fail without the change.
  • Rebase onto develop: the only conflict was in _sync_converted_file_record. I kept develop's file_hash = None alongside the suffix-derived format, and the conversion-recovery and hash-invalidation code in library_convert_service is otherwise develop's as-is.

The same-path fix is in a separate commit on top (791b7af).

This branch has not been deployed

No deployments
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