mirror of
https://github.com/gen2brain/cbconvert
synced 2025-10-14 18:48:51 +02:00
Add Cancel, split file
This commit is contained in:
875
cbconvert.go
875
cbconvert.go
File diff suppressed because it is too large
Load Diff
422
cbconvert_arch.go
Normal file
422
cbconvert_arch.go
Normal file
@@ -0,0 +1,422 @@
|
|||||||
|
package cbconvert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"archive/zip"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/gen2brain/go-unarr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// archiveSave saves workdir to CBZ archive.
|
||||||
|
func (c *Convertor) archiveSave(fileName string) error {
|
||||||
|
if c.Opts.Archive == "zip" {
|
||||||
|
return c.archiveSaveZip(fileName)
|
||||||
|
} else if c.Opts.Archive == "tar" {
|
||||||
|
return c.archiveSaveTar(fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// archiveSaveZip saves workdir to CBZ archive.
|
||||||
|
func (c *Convertor) archiveSaveZip(fileName string) error {
|
||||||
|
if c.OnCompress != nil {
|
||||||
|
c.OnCompress()
|
||||||
|
}
|
||||||
|
|
||||||
|
var zipName string
|
||||||
|
if c.Opts.Recursive {
|
||||||
|
err := os.MkdirAll(filepath.Join(c.Opts.OutDir, filepath.Dir(fileName)), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
zipName = filepath.Join(c.Opts.OutDir, filepath.Dir(fileName), fmt.Sprintf("%s%s.cbz", baseNoExt(fileName), c.Opts.Suffix))
|
||||||
|
} else {
|
||||||
|
zipName = filepath.Join(c.Opts.OutDir, fmt.Sprintf("%s%s.cbz", baseNoExt(fileName), c.Opts.Suffix))
|
||||||
|
}
|
||||||
|
|
||||||
|
zipFile, err := os.Create(zipName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
z := zip.NewWriter(zipFile)
|
||||||
|
|
||||||
|
files, err := os.ReadDir(c.Workdir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
r, err := os.ReadFile(filepath.Join(c.Workdir, file.Name()))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := file.Info()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
zipInfo, err := zip.FileInfoHeader(info)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
zipInfo.Method = zip.Deflate
|
||||||
|
w, err := z.CreateHeader(zipInfo)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(r)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = z.Close(); err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = zipFile.Close(); err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.RemoveAll(c.Workdir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveZip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// archiveSaveTar saves workdir to CBT archive.
|
||||||
|
func (c *Convertor) archiveSaveTar(fileName string) error {
|
||||||
|
if c.OnCompress != nil {
|
||||||
|
c.OnCompress()
|
||||||
|
}
|
||||||
|
|
||||||
|
var tarName string
|
||||||
|
if c.Opts.Recursive {
|
||||||
|
err := os.MkdirAll(filepath.Join(c.Opts.OutDir, filepath.Dir(fileName)), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tarName = filepath.Join(c.Opts.OutDir, filepath.Dir(fileName), fmt.Sprintf("%s%s.cbt", baseNoExt(fileName), c.Opts.Suffix))
|
||||||
|
} else {
|
||||||
|
tarName = filepath.Join(c.Opts.OutDir, fmt.Sprintf("%s%s.cbt", baseNoExt(fileName), c.Opts.Suffix))
|
||||||
|
}
|
||||||
|
|
||||||
|
tarFile, err := os.Create(tarName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tw := tar.NewWriter(tarFile)
|
||||||
|
|
||||||
|
files, err := os.ReadDir(c.Workdir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
r, err := os.ReadFile(filepath.Join(c.Workdir, file.Name()))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := file.Info()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
header, err := tar.FileInfoHeader(info, info.Name())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tw.WriteHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = tw.Write(r)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = tw.Close(); err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = tarFile.Close(); err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.RemoveAll(c.Workdir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSaveTar: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// archiveList lists contents of archive.
|
||||||
|
func (c *Convertor) archiveList(fileName string) ([]string, error) {
|
||||||
|
var contents []string
|
||||||
|
|
||||||
|
archive, err := unarr.NewArchive(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return contents, fmt.Errorf("archiveList: %w", err)
|
||||||
|
}
|
||||||
|
defer archive.Close()
|
||||||
|
|
||||||
|
contents, err = archive.List()
|
||||||
|
if err != nil {
|
||||||
|
return contents, fmt.Errorf("archiveList: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return contents, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// archiveComment returns ZIP comment.
|
||||||
|
func (c *Convertor) archiveComment(fileName string) (string, error) {
|
||||||
|
zr, err := zip.OpenReader(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("archiveComment: %w", err)
|
||||||
|
}
|
||||||
|
defer zr.Close()
|
||||||
|
|
||||||
|
return zr.Comment, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// archiveSetComment sets ZIP comment.
|
||||||
|
func (c *Convertor) archiveSetComment(fileName, commentBody string) error {
|
||||||
|
zr, err := zip.OpenReader(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
defer zr.Close()
|
||||||
|
|
||||||
|
zf, err := os.CreateTemp(os.TempDir(), "cbc")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpName := zf.Name()
|
||||||
|
defer os.Remove(tmpName)
|
||||||
|
|
||||||
|
zw := zip.NewWriter(zf)
|
||||||
|
err = zw.SetComment(commentBody)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range zr.File {
|
||||||
|
ir, err := item.OpenRaw()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
item := item
|
||||||
|
|
||||||
|
it, err := zw.CreateRaw(&item.FileHeader)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(it, ir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = zw.Close()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = zf.Close()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(tmpName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(fileName, data, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveSetComment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// archiveFileAdd adds file to archive.
|
||||||
|
func (c *Convertor) archiveFileAdd(fileName, newFileName string) error {
|
||||||
|
zr, err := zip.OpenReader(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
defer zr.Close()
|
||||||
|
|
||||||
|
zf, err := os.CreateTemp(os.TempDir(), "cbc")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpName := zf.Name()
|
||||||
|
defer os.Remove(tmpName)
|
||||||
|
|
||||||
|
zw := zip.NewWriter(zf)
|
||||||
|
|
||||||
|
for _, item := range zr.File {
|
||||||
|
if item.Name == newFileName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ir, err := item.OpenRaw()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
item := item
|
||||||
|
|
||||||
|
it, err := zw.CreateRaw(&item.FileHeader)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(it, ir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := os.Stat(newFileName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newData, err := os.ReadFile(newFileName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
zipInfo, err := zip.FileInfoHeader(info)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
zipInfo.Method = zip.Deflate
|
||||||
|
w, err := zw.CreateHeader(zipInfo)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(newData)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = zw.Close()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = zf.Close()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(tmpName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(fileName, data, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileAdd: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// archiveFileRemove removes files from archive.
|
||||||
|
func (c *Convertor) archiveFileRemove(fileName, pattern string) error {
|
||||||
|
zr, err := zip.OpenReader(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
defer zr.Close()
|
||||||
|
|
||||||
|
zf, err := os.CreateTemp(os.TempDir(), "cbc")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpName := zf.Name()
|
||||||
|
defer os.Remove(tmpName)
|
||||||
|
|
||||||
|
zw := zip.NewWriter(zf)
|
||||||
|
|
||||||
|
for _, item := range zr.File {
|
||||||
|
matched, err := filepath.Match(pattern, item.Name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if matched {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ir, err := item.OpenRaw()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
item := item
|
||||||
|
|
||||||
|
it, err := zw.CreateRaw(&item.FileHeader)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(it, ir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = zw.Close()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = zf.Close()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(tmpName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(fileName, data, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("archiveFileRemove: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
184
cbconvert_func.go
Normal file
184
cbconvert_func.go
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
package cbconvert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// imageToRGBA converts an image.Image to *image.RGBA.
|
||||||
|
func imageToRGBA(src image.Image) *image.RGBA {
|
||||||
|
if dst, ok := src.(*image.RGBA); ok {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
b := src.Bounds()
|
||||||
|
dst := image.NewRGBA(b)
|
||||||
|
draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)
|
||||||
|
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// imageToGray converts an image.Image to *image.Gray.
|
||||||
|
func imageToGray(src image.Image) *image.Gray {
|
||||||
|
if dst, ok := src.(*image.Gray); ok {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
b := src.Bounds()
|
||||||
|
dst := image.NewGray(b)
|
||||||
|
draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)
|
||||||
|
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// imagesFromPath returns list of found image files for given directory.
|
||||||
|
func imagesFromPath(path string) ([]string, error) {
|
||||||
|
var images []string
|
||||||
|
|
||||||
|
walkFiles := func(fp string, f os.FileInfo, err error) error {
|
||||||
|
if !f.IsDir() && f.Mode()&os.ModeType == 0 {
|
||||||
|
if f.Size() > 0 && (isImage(fp)) {
|
||||||
|
images = append(images, fp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return images, fmt.Errorf("imagesFromPath: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stat, err := os.Stat(f)
|
||||||
|
if err != nil {
|
||||||
|
return images, fmt.Errorf("imagesFromPath: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !stat.IsDir() && stat.Mode()&os.ModeType == 0 {
|
||||||
|
if isImage(f) {
|
||||||
|
images = append(images, f)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = filepath.Walk(f, walkFiles)
|
||||||
|
if err != nil {
|
||||||
|
return images, fmt.Errorf("imagesFromPath: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return images, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// imagesFromSlice returns list of found image files for given slice of files.
|
||||||
|
func imagesFromSlice(files []string) []string {
|
||||||
|
var images []string
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
if isImage(f) {
|
||||||
|
images = append(images, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return images
|
||||||
|
}
|
||||||
|
|
||||||
|
// isArchive checks if file is archive.
|
||||||
|
func isArchive(f string) bool {
|
||||||
|
var types = []string{".rar", ".zip", ".7z", ".tar", ".cbr", ".cbz", ".cb7", ".cbt"}
|
||||||
|
for _, t := range types {
|
||||||
|
if strings.ToLower(filepath.Ext(f)) == t {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isDocument checks if file is document.
|
||||||
|
func isDocument(f string) bool {
|
||||||
|
var types = []string{".pdf", ".xps", ".epub", ".mobi"}
|
||||||
|
for _, t := range types {
|
||||||
|
if strings.ToLower(filepath.Ext(f)) == t {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isImage checks if file is image.
|
||||||
|
func isImage(f string) bool {
|
||||||
|
var types = []string{".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".tif", ".webp", ".avif", ".jxl"}
|
||||||
|
for _, t := range types {
|
||||||
|
if strings.ToLower(filepath.Ext(f)) == t {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isNonImage checks for allowed files in archive.
|
||||||
|
func isNonImage(f string) bool {
|
||||||
|
var types = []string{".nfo", ".xml", ".txt"}
|
||||||
|
for _, t := range types {
|
||||||
|
if strings.ToLower(filepath.Ext(f)) == t {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isSize checks size of file.
|
||||||
|
func isSize(a, b int64) bool {
|
||||||
|
if a > 0 {
|
||||||
|
if b < int64(a)*(1024*1024) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// isGrayScale checks if image is grayscale.
|
||||||
|
func isGrayScale(img image.Image) bool {
|
||||||
|
model := img.ColorModel()
|
||||||
|
if model == color.GrayModel || model == color.Gray16Model {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// baseNoExt returns base name without extension.
|
||||||
|
func baseNoExt(filename string) string {
|
||||||
|
return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename))
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyFile copies reader to file.
|
||||||
|
func copyFile(reader io.Reader, filename string) error {
|
||||||
|
err := os.MkdirAll(filepath.Dir(filename), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("copyFile: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("copyFile: %w", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(file, reader)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("copyFile: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@@ -58,7 +58,6 @@ func main() {
|
|||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
go func() {
|
go func() {
|
||||||
for range c {
|
for range c {
|
||||||
fmt.Println("\naborting")
|
|
||||||
if err := os.RemoveAll(conv.Workdir); err != nil {
|
if err := os.RemoveAll(conv.Workdir); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
@@ -114,7 +113,7 @@ func main() {
|
|||||||
|
|
||||||
conv.OnCompress = func() {
|
conv.OnCompress = func() {
|
||||||
if !opts.Quiet {
|
if !opts.Quiet {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "Compressing %d of %d...\r", conv.CurrFile, conv.Nfiles)
|
fmt.Fprintf(os.Stderr, "Compressing %d of %d...\r", conv.CurrFile, conv.Nfiles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +155,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\r")
|
fmt.Fprintf(os.Stderr, "\r")
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseFlags parses command line flags.
|
// parseFlags parses command line flags.
|
||||||
@@ -228,34 +227,34 @@ func parseFlags() (cbconvert.Options, []string) {
|
|||||||
flag.NewFlagSet("version", flag.ExitOnError)
|
flag.NewFlagSet("version", flag.ExitOnError)
|
||||||
|
|
||||||
flag.Usage = func() {
|
flag.Usage = func() {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "Usage: %s <command> [<flags>] [file1 dir1 ... fileOrDirN]\n\n", filepath.Base(os.Args[0]))
|
fmt.Fprintf(os.Stderr, "Usage: %s <command> [<flags>] [file1 dir1 ... fileOrDirN]\n\n", filepath.Base(os.Args[0]))
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\nCommands:\n")
|
fmt.Fprintf(os.Stderr, "\nCommands:\n")
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n convert\n \tConvert archive or document\n\n")
|
fmt.Fprintf(os.Stderr, "\n convert\n \tConvert archive or document\n\n")
|
||||||
convert.VisitAll(func(f *flag.Flag) {
|
convert.VisitAll(func(f *flag.Flag) {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
})
|
})
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n")
|
fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n")
|
||||||
cover.VisitAll(func(f *flag.Flag) {
|
cover.VisitAll(func(f *flag.Flag) {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
})
|
})
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n thumbnail\n \tExtract cover thumbnail (freedesktop spec.)\n\n")
|
fmt.Fprintf(os.Stderr, "\n thumbnail\n \tExtract cover thumbnail (freedesktop spec.)\n\n")
|
||||||
thumbnail.VisitAll(func(f *flag.Flag) {
|
thumbnail.VisitAll(func(f *flag.Flag) {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
})
|
})
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n meta\n \tCBZ metadata\n\n")
|
fmt.Fprintf(os.Stderr, "\n meta\n \tCBZ metadata\n\n")
|
||||||
meta.VisitAll(func(f *flag.Flag) {
|
meta.VisitAll(func(f *flag.Flag) {
|
||||||
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
})
|
})
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n version\n \tPrint version\n\n")
|
fmt.Fprintf(os.Stderr, "\n version\n \tPrint version\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(os.Args) < 2 {
|
if len(os.Args) < 2 {
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "no command\n")
|
fmt.Fprintf(os.Stderr, "no command\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user