mirror of
https://github.com/Belphemur/CBZOptimizer.git
synced 2026-07-22 11:25:40 +02:00
feat(converter): add --keep-filenames flag to preserve original page filenames
Add a new `--keep-filenames` boolean flag (no shorthand, default false) on both `optimize` and `watch` commands. When enabled, page entries in the output CBZ preserve their original base filenames instead of being renumbered to `%04d` sequential indices. Extension is swapped on format conversion (e.g. `001.png` → `001.webp`), split pages get `-NN` suffixes on the original stem, and duplicate base names fall back to `<stem>_<index>.<ext>`. Watch mode supports the flag via the `keep-filenames` viper config key. Design: data-driven `OriginalName` field on `manga.PageFile`, set at extraction in `cbz_loader.ExtractChapter`. The `Converter` interface is unchanged. Flag off → behavior identical to before. Closes #216
This commit is contained in:
@@ -70,6 +70,19 @@ func setupSplitFlag(cmd *cobra.Command, defaultValue bool, bindViper bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// setupKeepFilenamesFlag sets up the keep-filenames flag for a command.
|
||||
//
|
||||
// Parameters:
|
||||
// - cmd: The Cobra command to add the keep-filenames flag to
|
||||
// - defaultValue: The default keep-filenames value
|
||||
// - bindViper: If true, binds the flag to viper for configuration file support
|
||||
func setupKeepFilenamesFlag(cmd *cobra.Command, defaultValue bool, bindViper bool) {
|
||||
cmd.Flags().Bool("keep-filenames", defaultValue, "Preserve original page filenames instead of renumbering to sequential indices")
|
||||
if bindViper {
|
||||
_ = viper.BindPFlag("keep-filenames", cmd.Flags().Lookup("keep-filenames"))
|
||||
}
|
||||
}
|
||||
|
||||
// setupTimeoutFlag sets up the timeout flag for a command.
|
||||
//
|
||||
// Parameters:
|
||||
@@ -96,5 +109,6 @@ func setupCommonFlags(cmd *cobra.Command, converterType *constant.ConversionForm
|
||||
setupQualityFlag(cmd, qualityDefault, bindViper)
|
||||
setupOverrideFlag(cmd, overrideDefault, bindViper)
|
||||
setupSplitFlag(cmd, splitDefault, bindViper)
|
||||
setupKeepFilenamesFlag(cmd, false, bindViper)
|
||||
setupTimeoutFlag(cmd, bindViper)
|
||||
}
|
||||
|
||||
@@ -73,6 +73,13 @@ func ConvertCbzCommand(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
log.Debug().Bool("split", split).Msg("Split parameter parsed")
|
||||
|
||||
keepFilenames, err := cmd.Flags().GetBool("keep-filenames")
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to parse keep-filenames flag")
|
||||
return fmt.Errorf("invalid keep-filenames value")
|
||||
}
|
||||
log.Debug().Bool("keep-filenames", keepFilenames).Msg("Keep-filenames parameter parsed")
|
||||
|
||||
timeout, err := cmd.Flags().GetDuration("timeout")
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to parse timeout flag")
|
||||
@@ -121,14 +128,15 @@ func ConvertCbzCommand(cmd *cobra.Command, args []string) error {
|
||||
log.Debug().Int("worker_id", workerID).Msg("Worker started")
|
||||
for path := range fileChan {
|
||||
log.Debug().Int("worker_id", workerID).Str("file_path", path).Msg("Worker processing file")
|
||||
err := utils2.Optimize(&utils2.OptimizeOptions{
|
||||
ChapterConverter: chapterConverter,
|
||||
Path: path,
|
||||
Quality: quality,
|
||||
Override: override,
|
||||
Split: split,
|
||||
Timeout: timeout,
|
||||
})
|
||||
err := utils2.Optimize(&utils2.OptimizeOptions{
|
||||
ChapterConverter: chapterConverter,
|
||||
Path: path,
|
||||
Quality: quality,
|
||||
Override: override,
|
||||
Split: split,
|
||||
KeepFilenames: keepFilenames,
|
||||
Timeout: timeout,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error().Int("worker_id", workerID).Str("file_path", path).Err(err).Msg("Worker encountered error")
|
||||
errMutex.Lock()
|
||||
|
||||
@@ -86,6 +86,7 @@ func TestConvertCbzCommand(t *testing.T) {
|
||||
cmd.Flags().IntP("parallelism", "n", 2, "Number of chapters to convert in parallel")
|
||||
cmd.Flags().BoolP("override", "o", false, "Override the original CBZ/CBR files")
|
||||
cmd.Flags().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
||||
cmd.Flags().Bool("keep-filenames", false, "Preserve original page filenames instead of renumbering to sequential indices")
|
||||
cmd.Flags().DurationP("timeout", "t", 0, "Maximum time allowed for converting a single chapter (e.g., 30s, 5m, 1h). 0 means no timeout")
|
||||
|
||||
// Execute the command
|
||||
@@ -197,6 +198,7 @@ func setupTestCommand(t *testing.T) (*cobra.Command, func()) {
|
||||
cmd.Flags().IntP("parallelism", "n", 1, "Number of chapters to convert in parallel")
|
||||
cmd.Flags().BoolP("override", "o", false, "Override the original CBZ/CBR files")
|
||||
cmd.Flags().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
||||
cmd.Flags().Bool("keep-filenames", false, "Preserve original page filenames instead of renumbering to sequential indices")
|
||||
cmd.Flags().DurationP("timeout", "t", 0, "Maximum time allowed for converting a single chapter")
|
||||
|
||||
// Reset converterType to default before test for consistency
|
||||
@@ -433,6 +435,7 @@ func TestConvertCbzCommand_ManyFiles_NoDeadlock(t *testing.T) {
|
||||
cmd.Flags().IntP("parallelism", "n", 2, "Number of chapters to convert in parallel")
|
||||
cmd.Flags().BoolP("override", "o", false, "Override the original CBZ/CBR files")
|
||||
cmd.Flags().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
||||
cmd.Flags().Bool("keep-filenames", false, "Preserve original page filenames instead of renumbering to sequential indices")
|
||||
cmd.Flags().DurationP("timeout", "t", 0, "Maximum time allowed for converting a single chapter")
|
||||
|
||||
converterType = constant.DefaultConversion
|
||||
@@ -535,6 +538,7 @@ func TestConvertCbzCommand_HighParallelism_NoDeadlock(t *testing.T) {
|
||||
cmd.Flags().IntP("parallelism", "n", 8, "Number of chapters to convert in parallel")
|
||||
cmd.Flags().BoolP("override", "o", false, "Override the original CBZ/CBR files")
|
||||
cmd.Flags().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
||||
cmd.Flags().Bool("keep-filenames", false, "Preserve original page filenames instead of renumbering to sequential indices")
|
||||
cmd.Flags().DurationP("timeout", "t", 0, "Maximum time allowed for converting a single chapter")
|
||||
|
||||
converterType = constant.DefaultConversion
|
||||
|
||||
@@ -65,6 +65,8 @@ func WatchCommand(_ *cobra.Command, args []string) error {
|
||||
|
||||
split := viper.GetBool("split")
|
||||
|
||||
keepFilenames := viper.GetBool("keep-filenames")
|
||||
|
||||
timeout := viper.GetDuration("timeout")
|
||||
|
||||
backfill := viper.GetBool("backfill")
|
||||
@@ -79,7 +81,7 @@ func WatchCommand(_ *cobra.Command, args []string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare converter: %w", err)
|
||||
}
|
||||
log.Info().Str("path", path).Bool("override", override).Uint8("quality", quality).Str("format", converterType.String()).Bool("split", split).Bool("backfill", backfill).Msg("Watching directory")
|
||||
log.Info().Str("path", path).Bool("override", override).Uint8("quality", quality).Str("format", converterType.String()).Bool("split", split).Bool("keep_filenames", keepFilenames).Bool("backfill", backfill).Msg("Watching directory")
|
||||
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
@@ -98,6 +100,7 @@ func WatchCommand(_ *cobra.Command, args []string) error {
|
||||
Quality: quality,
|
||||
Override: override,
|
||||
Split: split,
|
||||
KeepFilenames: keepFilenames,
|
||||
Timeout: timeout,
|
||||
})
|
||||
defer queue.Stop()
|
||||
|
||||
Reference in New Issue
Block a user