From b8d82e920c38850191a952fec524d3febea1fa56 Mon Sep 17 00:00:00 2001 From: Milan Nikolic Date: Wed, 24 Jun 2026 04:50:10 +0200 Subject: [PATCH] Fix comic chapters, issue #50 --- cbconvert_convert.go | 23 ++++++++++++++--------- cbconvert_func.go | 6 ++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/cbconvert_convert.go b/cbconvert_convert.go index df22714..c3afac1 100644 --- a/cbconvert_convert.go +++ b/cbconvert_convert.go @@ -123,7 +123,7 @@ func (c *Converter) convertArchive(ctx context.Context, fileName string) error { if isImage(pathName) { if c.Opts.NoConvert { - if err = copyFile(bytes.NewReader(data), c.workPath(filepath.Base(pathName))); err != nil { + if err = copyFile(bytes.NewReader(data), c.workPath(flatName(pathName))); err != nil { return fmt.Errorf("convertArchive: %w", err) } @@ -131,7 +131,7 @@ func (c *Converter) convertArchive(ctx context.Context, fileName string) error { } if cover == pathName && c.Opts.NoCover { - if err = copyFile(bytes.NewReader(data), c.workPath(filepath.Base(pathName))); err != nil { + if err = copyFile(bytes.NewReader(data), c.workPath(flatName(pathName))); err != nil { return fmt.Errorf("convertArchive: %w", err) } @@ -145,7 +145,7 @@ func (c *Converter) convertArchive(ctx context.Context, fileName string) error { } if c.Opts.NoRGB && !isGrayScale(img) { - if err = copyFile(bytes.NewReader(data), c.workPath(filepath.Base(pathName))); err != nil { + if err = copyFile(bytes.NewReader(data), c.workPath(flatName(pathName))); err != nil { return fmt.Errorf("convertArchive: %w", err) } @@ -163,7 +163,7 @@ func (c *Converter) convertArchive(ctx context.Context, fileName string) error { } if c.prefix == "" && !c.Opts.NoNonImage { - if err = copyFile(bytes.NewReader(data), c.workPath(filepath.Base(pathName))); err != nil { + if err = copyFile(bytes.NewReader(data), c.workPath(flatName(pathName))); err != nil { return fmt.Errorf("convertArchive: %w", err) } } @@ -206,13 +206,18 @@ func (c *Converter) convertDirectory(ctx context.Context, dirPath string) error return fmt.Errorf("convertDirectory: %w", ctx.Err()) } + rel, rerr := filepath.Rel(dirPath, img) + if rerr != nil { + rel = filepath.Base(img) + } + file, err := os.Open(img) if err != nil { return fmt.Errorf("convertDirectory: %w", err) } if isNonImage(img) && c.prefix == "" && !c.Opts.NoNonImage { - if err = copyFile(file, c.workPath(filepath.Base(img))); err != nil { + if err = copyFile(file, c.workPath(flatName(rel))); err != nil { return fmt.Errorf("convertDirectory: %w", err) } @@ -223,7 +228,7 @@ func (c *Converter) convertDirectory(ctx context.Context, dirPath string) error continue } else if isImage(img) { if c.Opts.NoConvert { - if err = copyFile(file, c.workPath(filepath.Base(img))); err != nil { + if err = copyFile(file, c.workPath(flatName(rel))); err != nil { return fmt.Errorf("convertDirectory: %w", err) } @@ -241,7 +246,7 @@ func (c *Converter) convertDirectory(ctx context.Context, dirPath string) error } if c.Opts.NoRGB && !isGrayScale(i) { - if err = copyFile(file, c.workPath(filepath.Base(img))); err != nil { + if err = copyFile(file, c.workPath(flatName(rel))); err != nil { return fmt.Errorf("convertDirectory: %w", err) } @@ -258,7 +263,7 @@ func (c *Converter) convertDirectory(ctx context.Context, dirPath string) error if i != nil { eg.Go(func() error { - return c.imageConvert(ctx, i, index, img) + return c.imageConvert(ctx, i, index, rel) }) } } @@ -296,7 +301,7 @@ func (c *Converter) imageConvert(ctx context.Context, img image.Image, index int var fileName string if pathName != "" { - fileName = c.workPath(fmt.Sprintf("%s.%s", baseNoExt(pathName), ext)) + fileName = c.workPath(fmt.Sprintf("%s.%s", flatName(strings.TrimSuffix(pathName, filepath.Ext(pathName))), ext)) } else { fileName = c.workPath(fmt.Sprintf("%03d.%s", index, ext)) } diff --git a/cbconvert_func.go b/cbconvert_func.go index b9917d2..7b7ae19 100644 --- a/cbconvert_func.go +++ b/cbconvert_func.go @@ -123,6 +123,12 @@ func baseNoExt(filename string) string { return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename)) } +// flatName flattens a path into a single collision-free name by replacing separators. +func flatName(name string) string { + name = strings.ReplaceAll(name, "\\", "/") + return strings.ReplaceAll(name, "/", "_") +} + // copyFile copies reader to file. func copyFile(reader io.Reader, filename string) error { err := os.MkdirAll(filepath.Dir(filename), 0755)