feat(importer): make NZB compression configurable and number only on collision (#679)#687
Merged
Merged
Conversation
…collision (#679) Persisted NZBs were always stored gzip-compressed (.nzb.gz) and always nested under a per-queue-ID subfolder (.nzbs/{category}/{id}/), which surfaced to users as files numbered 1, 2, 3 inside their category folders. - Add `import.compress_nzb` config option (default true = unchanged). When disabled, NZBs are kept as plain .nzb in their category folders. The one-time gzip migration is skipped while compression is off so it does not rewrite plain files. Reads already tolerate both extensions. - Drop the forced per-ID subfolder: save directly to .nzbs/{category}/{name}{ext} and only namespace with an `{id}-` filename prefix on collision (DB- and disk-aware), mirroring the failed-path convention. - Wire the option end-to-end: Go config + accessor, API response type, frontend ImportConfig types, and a "Compress Stored NZBs" toggle. Closes #679
On a failed rename (e.g. cross-device), leave the source NZB untouched and return an error so the import can retry, rather than risking a partial copy. Removes the now-unused copyFile fallback.
Mirror the existing nzbfile.GzExtension constant instead of a hardcoded ".nzb" literal in ensurePersistentNzb, centralizing NZB extension knowledge.
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.
What & why
Closes #679. Users reported that persisted NZBs were saved as numbered entries (
1,2,3…) and only as gzip.nzb.gz, rather than as plain.nzbin their category folders (Movies, Series, corrupted, etc.). Two behaviors ininternal/importercaused this:ensurePersistentNzbalways nested every successful NZB under a per-queue-ID subfolder.nzbs/{category}/{id}/. The{id}was the "number" users saw..nzb.gz, with a startup migration also rewriting any plain.nzb. There was no opt-out.Changes
import.compress_nzboption (*bool, defaulttrue= unchanged behavior) with aShouldCompressNzb()accessor. When disabled, NZBs are moved as plain.nzb(rename with copy+remove fallback) instead of gzip-compressed. The one-time gzip migration early-returns while compression is off so it won't rewrite plain files behind the user's back. Reads already tolerate both extensions vianzbfile.Open/ResolveOnDisk..nzbs/{category}/{name}{ext}. The per-ID disambiguation only kicks in when the destination is already taken, applied as an{id}-{name}filename prefix (kept in the category folder), mirroring the existing failed-path convention (uniqueFailedNzbPath). The collision check is both disk- and DB-aware so the UNIQUEimport_queue.nzb_pathconstraint still holds even afterDeleteCompletedNzbremoves a file. Extracted into a testablepersistentNzbPathhelper.ImportAPIResponsefield + mapping, frontendImportConfig/ImportUpdateRequesttypes, and a "Compress Stored NZBs" toggle inWorkersConfigSection.tsx.The failed path (
.nzbs/failed/{category}/) already numbered only on collision and needed no change.Reviewer notes
compress_nzb: true, so existing installs are unaffected; users opt into plain.nzb.{id}-filename prefix on collision is a deliberate choice (per request) consistent with the failed-folder behavior.Testing
TestPersistentNzbPathcovers free-destination (clean name) and collision (prefixed) cases for both extensions.go test -race ./internal/importer/... ./internal/config/... ./internal/api/...andgo vetpass.bun run check(biome) passes.