fix: address copilot and coderabbit review feedback

- Use named returns for IsAlreadyConverted and WriteChapterToCBZ so
  errs.Capture defers propagate close errors to the caller.
- Add context.Context to IsAlreadyConverted and ExtractChapter for
  cancellation/timeout support; thread it from Optimize.
- Filter non-image files (__MACOSX, Thumbs.db, .DS_Store, etc.) and
  only extract supported image extensions in ExtractChapter.
- Validate TempDir is non-empty in ConvertChapter before creating output dir.
- Separate fatal conversion errors from PageIgnoredError in the WebP
  converter result aggregation so real failures aren't masked.
- Fix error message "failed to load chapter" → "failed to extract chapter".
- Use %w instead of %v in fmt.Errorf for proper error wrapping.
- Fix LoadChapter doc comment to match its actual behavior.
- Extract shared parseConvertedComment/parseConvertedCommentTime helpers
  to avoid duplicated zip-comment parsing logic.
- Convert tests to use testify assertions (assert/require) per guidelines.

Co-authored-by: Belphemur <197810+Belphemur@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-07-04 22:39:19 +00:00
committed by GitHub
co-authored by Belphemur
parent 5ae05e5f0c
commit 5e5cac4883
6 changed files with 216 additions and 256 deletions
+3 -3
View File
@@ -4,6 +4,8 @@ import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestIsValidFolder(t *testing.T) {
@@ -51,9 +53,7 @@ func TestIsValidFolder(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
path := tt.setup(t)
result := IsValidFolder(path)
if result != tt.expected {
t.Errorf("IsValidFolder(%q) = %v, want %v", path, result, tt.expected)
}
assert.Equal(t, tt.expected, result)
})
}
}
+18 -16
View File
@@ -41,7 +41,7 @@ func Optimize(options *OptimizeOptions) error {
Msg("Optimization parameters")
// Step 1: Fast conversion check before extracting (new requirement)
alreadyConverted, err := cbz.IsAlreadyConverted(options.Path)
alreadyConverted, err := cbz.IsAlreadyConverted(context.Background(), options.Path)
if err != nil {
log.Debug().Str("file", options.Path).Err(err).Msg("Conversion check failed, proceeding with extraction")
}
@@ -52,10 +52,22 @@ func Optimize(options *OptimizeOptions) error {
// Step 2: Extract chapter to disk
log.Debug().Str("file", options.Path).Msg("Extracting chapter")
chapter, err := cbz.ExtractChapter(options.Path)
// Create context for extraction (use timeout if configured)
var extractCtx context.Context
if options.Timeout > 0 {
var cancel context.CancelFunc
extractCtx, cancel = context.WithTimeout(context.Background(), options.Timeout)
defer cancel()
log.Debug().Str("file", options.Path).Dur("timeout", options.Timeout).Msg("Applying timeout")
} else {
extractCtx = context.Background()
}
chapter, err := cbz.ExtractChapter(extractCtx, options.Path)
if err != nil {
log.Error().Str("file", options.Path).Err(err).Msg("Failed to extract chapter")
return fmt.Errorf("failed to load chapter: %v", err)
return fmt.Errorf("failed to extract chapter: %w", err)
}
defer func() {
if cleanupErr := chapter.Cleanup(); cleanupErr != nil {
@@ -75,17 +87,7 @@ func Optimize(options *OptimizeOptions) error {
Msg("Chapter extracted successfully")
// Step 3: Convert pages file-to-file
var ctx context.Context
if options.Timeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(context.Background(), options.Timeout)
defer cancel()
log.Debug().Str("file", options.Path).Dur("timeout", options.Timeout).Msg("Applying timeout")
} else {
ctx = context.Background()
}
convertedChapter, err := options.ChapterConverter.ConvertChapter(ctx, chapter, options.Quality, options.Split, func(msg string, current uint32, total uint32) {
convertedChapter, err := options.ChapterConverter.ConvertChapter(extractCtx, chapter, options.Quality, options.Split, func(msg string, current uint32, total uint32) {
if current%10 == 0 || current == total {
log.Info().Str("file", chapter.FilePath).Uint32("current", current).Uint32("total", total).Msg("Converting")
} else {
@@ -98,7 +100,7 @@ func Optimize(options *OptimizeOptions) error {
log.Debug().Str("file", chapter.FilePath).Err(err).Msg("Page conversion error (non-fatal)")
} else {
log.Error().Str("file", chapter.FilePath).Err(err).Msg("Chapter conversion failed")
return fmt.Errorf("failed to convert chapter: %v", err)
return fmt.Errorf("failed to convert chapter: %w", err)
}
}
if convertedChapter == nil {
@@ -140,7 +142,7 @@ func Optimize(options *OptimizeOptions) error {
err = cbz.WriteChapterToCBZ(convertedChapter, outputPath)
if err != nil {
log.Error().Str("output_path", outputPath).Err(err).Msg("Failed to write converted chapter")
return fmt.Errorf("failed to write converted chapter: %v", err)
return fmt.Errorf("failed to write converted chapter: %w", err)
}
// If overriding a CBR file, delete the original