fix(importer): move single-file audiobooks into their folder on reorganize (#2894) - #2901
Merged
vavallee merged 2 commits intoOct 1, 2026
Merged
Conversation
…anize (vavallee#2894) A single-file audiobook tracked as the .m4b itself was given the templated folder path as its own destination, so Rename files turned Author/Title.m4b into a file named "Title (Year)" with no extension. Resolve a file row to <templated folder>/<its name>, mirroring the single-file import branch: join the book's own ebook folder (vavallee#2686), otherwise uniquify with the file's current folder treated as available so a file already in place stays a noop instead of moving to "Title (Year) (2)". The sidecar cleanup and write follow file vs folder rather than format. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Zikeji <me@zikeji.com>
zikeji
marked this pull request as ready for review
October 1, 2026 06:36
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…nstead of moving them again A file the old Rename files left on its folder path (named "Title (Year)" with no extension) used to read as a noop. With the file row fix it would instead be proposed as a move to "Title (Year) (2)/Title (Year)", burying the extensionless file in a new folder. Report it as an error naming the manual recovery and leave it in place. Also cover the stale sidecar cleanup for a lone audiobook file, apply the shared folder case end to end, and spell out the recovery steps and credit in the changelog fragment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fJcCVbNnKsmj2MAAMwWj9 Signed-off-by: vavallee <vavallee@protonmail.com>
Owner
|
Nice fix, the preview now matches what import does. One gap I hit: a file that's already been flattened (named |
| } | ||
|
|
||
| func isSingleFile(path string) bool { | ||
| info, err := os.Stat(path) |
vavallee
added a commit
that referenced
this pull request
Oct 1, 2026
…emplate (#2900) (#2905) With naming.audiobook_file_template set, a folder of tracks was renamed per track but a lone .m4b kept its source filename: the template was only read on the directory branch, and the single-file branch placed the file as filepath.Base(src). The single-file branch now renders the same template through the same renderer, via a new Renamer.AudiobookSingleFileName. {Part} renders empty when every {Part} sits in a #1127 conditional group, so "{Title}{ - Pt. Part:3}.{ext}" gives "Title.m4b". A bare {Part} keeps its glue outside the braces and an empty value would leave "Title - Part .m4b" (the default template), so such a template numbers the file as part 1. No template keeps the source name exactly as before. The same naming applies to: - a folder holding a single track, so the name does not depend on how the release was packed (the flatten namer now receives the track count); - Rename files (singleFileAudiobookDest from #2901) and the Fix Match destination preview, which share one Scanner helper with the import. The settings validator checked for the substring "{Part", which rejected every conditional form; it now asks the renderer whether a group carries a Part token. The drop folder (External mode) has its own placement that never used the file template and is unchanged. Claude-Session: https://claude.ai/code/session_016fJcCVbNnKsmj2MAAMwWj9 Signed-off-by: vavallee <vavallee@protonmail.com> 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.
Summary
Rename files gave a single-file audiobook its templated folder path as its own destination, so
Author/Title.m4bwas moved to a file namedAuthor/Title (Year).proposedPathForusedAudiobookDestDirfor every audiobook row, andmoveTrackedFilethen moved the file onto that path through the ebook branch.A file row now resolves to
<templated folder>/<its own name>, mirroring the single-file import branch:Title (Year)/was proposed as a move toTitle (Year) (2), which is where the(2)folders in my library came from.metadata.opflands inside the folder.Folder rows are unchanged.
PreviewImportDestinationsharesproposedPathFor, so the Fix Match preview for a single audiobook file now names<folder>/<file>instead of the folder. That's where the single-file import branch writes it, so the preview now matches the import.TestPreviewImportDestination_FormatHintWinsis updated to expect the file inside the folder; it still asserts the format hint routes to the audiobook root.Closes #2894
How it was verified
New tests in
internal/importer/reorganize_test.go, failing onmain(31ccc40):All 18
TestReorganize_*pass on this branch.End to end against an image built from this branch, using the repro from #2894 (flat
Stephen King/The Shining.m4b, library scan, Rename files):v1.39.0Stephen King/The Shining (1977)Stephen King/The Shining (1977)/The Shining.m4bThe Shining (1977), no extensionThe Shining (1977)/The Shining.m4bmetadata.opfnot a directorywarningnoopon the broken pathnoopon the correct pathFollow-ups (not in this PR)
A file already flattened by the old behaviour has lost its extension, and this doesn't restore it. Recovery stays manual: rename it back into a folder, deregister the old path, rescan.
Checklist
Signed-off-bythat matches its author (git commit -s), see Sign your work. Commits authored by a coding agent fail this check; author them as yourself.changelog.d/<issue-number>-<slug>.md, not an edit toCHANGELOG.md, see changelog.d/README.mddocs/DEPLOYMENT.mdupdated if env vars, config, or upgrade path changeddocs/updated if user-facing behaviour changedTHIRD_PARTY_LICENSES.mdis regeneratedNo docs change: the User Guide already says a reorganized library and a freshly imported one come out identical, and this makes that hold for single files.
Test plan
gofmt,go vet ./...,golangci-lint run(v2.11.4),govulncheck ./...on Go 1.26.6go test ./cmd/... ./internal/...cd web && npm run build(noweb/changes)