mirror of
https://github.com/Belphemur/CBZOptimizer.git
synced 2025-10-14 12:38:50 +02:00
@@ -18,8 +18,8 @@ var converterType constant.ConversionFormat
|
|||||||
func init() {
|
func init() {
|
||||||
command := &cobra.Command{
|
command := &cobra.Command{
|
||||||
Use: "optimize [folder]",
|
Use: "optimize [folder]",
|
||||||
Short: "Optimize all CBZ files in a folder recursively",
|
Short: "Optimize all CBZ/CBR files in a folder recursively",
|
||||||
Long: "Optimize all CBZ files in a folder recursively.\nIt will take all the different pages in the CBZ files and convert them to the given format.\nThe original CBZ files will be kept intact depending if you choose to override or not.",
|
Long: "Optimize all CBZ/CBR files in a folder recursively.\nIt will take all the different pages in the CBZ/CBR files and convert them to the given format.\nThe original CBZ/CBR files will be kept intact depending if you choose to override or not.",
|
||||||
RunE: ConvertCbzCommand,
|
RunE: ConvertCbzCommand,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ func init() {
|
|||||||
|
|
||||||
command.Flags().Uint8P("quality", "q", 85, "Quality for conversion (0-100)")
|
command.Flags().Uint8P("quality", "q", 85, "Quality for conversion (0-100)")
|
||||||
command.Flags().IntP("parallelism", "n", 2, "Number of chapters to convert in parallel")
|
command.Flags().IntP("parallelism", "n", 2, "Number of chapters to convert in parallel")
|
||||||
command.Flags().BoolP("override", "o", false, "Override the original CBZ files")
|
command.Flags().BoolP("override", "o", false, "Override the original CBZ/CBR files")
|
||||||
command.Flags().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
command.Flags().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
||||||
command.PersistentFlags().VarP(
|
command.PersistentFlags().VarP(
|
||||||
formatFlag,
|
formatFlag,
|
||||||
@@ -112,9 +112,12 @@ func ConvertCbzCommand(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !info.IsDir() && strings.HasSuffix(strings.ToLower(info.Name()), ".cbz") {
|
if !info.IsDir() {
|
||||||
|
fileName := strings.ToLower(info.Name())
|
||||||
|
if strings.HasSuffix(fileName, ".cbz") || strings.HasSuffix(fileName, ".cbr") {
|
||||||
fileChan <- path
|
fileChan <- path
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@@ -46,12 +46,14 @@ func TestConvertCbzCommand(t *testing.T) {
|
|||||||
t.Fatalf("testdata directory not found")
|
t.Fatalf("testdata directory not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy sample CBZ files from testdata to the temporary directory
|
// Copy sample CBZ/CBR files from testdata to the temporary directory
|
||||||
err = filepath.Walk(testdataDir, func(path string, info os.FileInfo, err error) error {
|
err = filepath.Walk(testdataDir, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !info.IsDir() && strings.HasSuffix(strings.ToLower(info.Name()), ".cbz") {
|
if !info.IsDir() {
|
||||||
|
fileName := strings.ToLower(info.Name())
|
||||||
|
if strings.HasSuffix(fileName, ".cbz") || strings.HasSuffix(fileName, ".cbr") {
|
||||||
destPath := filepath.Join(tempDir, info.Name())
|
destPath := filepath.Join(tempDir, info.Name())
|
||||||
data, err := os.ReadFile(path)
|
data, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -59,6 +61,7 @@ func TestConvertCbzCommand(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return os.WriteFile(destPath, data, info.Mode())
|
return os.WriteFile(destPath, data, info.Mode())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -78,7 +81,7 @@ func TestConvertCbzCommand(t *testing.T) {
|
|||||||
}
|
}
|
||||||
cmd.Flags().Uint8P("quality", "q", 85, "Quality for conversion (0-100)")
|
cmd.Flags().Uint8P("quality", "q", 85, "Quality for conversion (0-100)")
|
||||||
cmd.Flags().IntP("parallelism", "n", 2, "Number of chapters to convert in parallel")
|
cmd.Flags().IntP("parallelism", "n", 2, "Number of chapters to convert in parallel")
|
||||||
cmd.Flags().BoolP("override", "o", false, "Override the original CBZ files")
|
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().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
||||||
|
|
||||||
// Execute the command
|
// Execute the command
|
||||||
@@ -87,15 +90,48 @@ func TestConvertCbzCommand(t *testing.T) {
|
|||||||
t.Fatalf("Command execution failed: %v", err)
|
t.Fatalf("Command execution failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the results
|
// Track expected converted files for verification
|
||||||
|
expectedFiles := make(map[string]bool)
|
||||||
|
convertedFiles := make(map[string]bool)
|
||||||
|
|
||||||
|
// First pass: identify original files and expected converted filenames
|
||||||
err = filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
|
err = filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if info.IsDir() || !strings.HasSuffix(info.Name(), "_converted.cbz") {
|
if info.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
t.Logf("CBZ file found: %s", path)
|
fileName := strings.ToLower(info.Name())
|
||||||
|
if strings.HasSuffix(fileName, ".cbz") || strings.HasSuffix(fileName, ".cbr") {
|
||||||
|
if !strings.Contains(fileName, "_converted") {
|
||||||
|
// This is an original file, determine expected converted filename
|
||||||
|
baseName := strings.TrimSuffix(info.Name(), filepath.Ext(info.Name()))
|
||||||
|
expectedConverted := baseName + "_converted.cbz"
|
||||||
|
expectedFiles[expectedConverted] = false // false means not yet found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error identifying original files: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass: verify converted files exist and are properly converted
|
||||||
|
err = filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fileName := info.Name()
|
||||||
|
|
||||||
|
// Check if this is a converted file (should only be .cbz, never .cbr)
|
||||||
|
if strings.HasSuffix(fileName, "_converted.cbz") {
|
||||||
|
convertedFiles[fileName] = true
|
||||||
|
expectedFiles[fileName] = true // Mark as found
|
||||||
|
t.Logf("Archive file found: %s", path)
|
||||||
|
|
||||||
// Load the converted chapter
|
// Load the converted chapter
|
||||||
chapter, err := cbz.LoadChapter(path)
|
chapter, err := cbz.LoadChapter(path)
|
||||||
@@ -112,11 +148,24 @@ func TestConvertCbzCommand(t *testing.T) {
|
|||||||
if chapter.ConvertedTime.IsZero() {
|
if chapter.ConvertedTime.IsZero() {
|
||||||
t.Errorf("ConvertedTime is not set for chapter: %s", path)
|
t.Errorf("ConvertedTime is not set for chapter: %s", path)
|
||||||
}
|
}
|
||||||
t.Logf("CBZ file [%s] is converted: %s", path, chapter.ConvertedTime)
|
t.Logf("Archive file [%s] is converted: %s", path, chapter.ConvertedTime)
|
||||||
|
} else if strings.HasSuffix(fileName, "_converted.cbr") {
|
||||||
|
t.Errorf("Found incorrectly named converted file: %s (should be .cbz, not .cbr)", fileName)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error verifying converted files: %v", err)
|
t.Fatalf("Error verifying converted files: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify all expected files were found
|
||||||
|
for expectedFile, found := range expectedFiles {
|
||||||
|
if !found {
|
||||||
|
t.Errorf("Expected converted file not found: %s", expectedFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log summary
|
||||||
|
t.Logf("Found %d converted files", len(convertedFiles))
|
||||||
}
|
}
|
||||||
|
@@ -21,8 +21,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
command := &cobra.Command{
|
command := &cobra.Command{
|
||||||
Use: "watch [folder]",
|
Use: "watch [folder]",
|
||||||
Short: "Watch a folder for new CBZ files",
|
Short: "Watch a folder for new CBZ/CBR files",
|
||||||
Long: "Watch a folder for new CBZ files.\nIt will watch a folder for new CBZ files and optimize them.",
|
Long: "Watch a folder for new CBZ/CBR files.\nIt will watch a folder for new CBZ/CBR files and optimize them.",
|
||||||
RunE: WatchCommand,
|
RunE: WatchCommand,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ func init() {
|
|||||||
command.Flags().Uint8P("quality", "q", 85, "Quality for conversion (0-100)")
|
command.Flags().Uint8P("quality", "q", 85, "Quality for conversion (0-100)")
|
||||||
_ = viper.BindPFlag("quality", command.Flags().Lookup("quality"))
|
_ = viper.BindPFlag("quality", command.Flags().Lookup("quality"))
|
||||||
|
|
||||||
command.Flags().BoolP("override", "o", true, "Override the original CBZ files")
|
command.Flags().BoolP("override", "o", true, "Override the original CBZ/CBR files")
|
||||||
_ = viper.BindPFlag("override", command.Flags().Lookup("override"))
|
_ = viper.BindPFlag("override", command.Flags().Lookup("override"))
|
||||||
|
|
||||||
command.Flags().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
command.Flags().BoolP("split", "s", false, "Split long pages into smaller chunks")
|
||||||
@@ -107,7 +107,8 @@ func WatchCommand(_ *cobra.Command, args []string) error {
|
|||||||
for event := range events {
|
for event := range events {
|
||||||
log.Printf("[Event]%s, %v\n", event.Filename, event.Events)
|
log.Printf("[Event]%s, %v\n", event.Filename, event.Events)
|
||||||
|
|
||||||
if !strings.HasSuffix(strings.ToLower(event.Filename), ".cbz") {
|
filename := strings.ToLower(event.Filename)
|
||||||
|
if !strings.HasSuffix(filename, ".cbz") && !strings.HasSuffix(filename, ".cbr") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@ type OptimizeOptions struct {
|
|||||||
Split bool
|
Split bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimize optimizes a CBZ file using the specified converter.
|
// Optimize optimizes a CBZ/CBR file using the specified converter.
|
||||||
func Optimize(options *OptimizeOptions) error {
|
func Optimize(options *OptimizeOptions) error {
|
||||||
log.Printf("Processing file: %s\n", options.Path)
|
log.Printf("Processing file: %s\n", options.Path)
|
||||||
|
|
||||||
@@ -54,7 +54,16 @@ func Optimize(options *OptimizeOptions) error {
|
|||||||
// Write the converted chapter back to a CBZ file
|
// Write the converted chapter back to a CBZ file
|
||||||
outputPath := options.Path
|
outputPath := options.Path
|
||||||
if !options.Override {
|
if !options.Override {
|
||||||
|
// Handle both .cbz and .cbr files - strip the extension and add _converted.cbz
|
||||||
|
pathLower := strings.ToLower(options.Path)
|
||||||
|
if strings.HasSuffix(pathLower, ".cbz") {
|
||||||
outputPath = strings.TrimSuffix(options.Path, ".cbz") + "_converted.cbz"
|
outputPath = strings.TrimSuffix(options.Path, ".cbz") + "_converted.cbz"
|
||||||
|
} else if strings.HasSuffix(pathLower, ".cbr") {
|
||||||
|
outputPath = strings.TrimSuffix(options.Path, ".cbr") + "_converted.cbz"
|
||||||
|
} else {
|
||||||
|
// Fallback for other extensions - just add _converted.cbz
|
||||||
|
outputPath = options.Path + "_converted.cbz"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
err = cbz.WriteChapterToCBZ(convertedChapter, outputPath)
|
err = cbz.WriteChapterToCBZ(convertedChapter, outputPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user