mirror of
https://github.com/gen2brain/cbconvert
synced 2025-10-14 02:28:51 +02:00
Add version and preview
This commit is contained in:
154
cbconvert.go
154
cbconvert.go
@@ -6,6 +6,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -25,7 +27,7 @@ import (
|
|||||||
"image/png"
|
"image/png"
|
||||||
|
|
||||||
"github.com/chai2010/webp"
|
"github.com/chai2010/webp"
|
||||||
_ "github.com/hotei/bmp" // allow bmp decoding
|
_ "github.com/hotei/bmp" // allow 4-bit bmp decoding
|
||||||
"github.com/strukturag/libheif/go/heif"
|
"github.com/strukturag/libheif/go/heif"
|
||||||
"golang.org/x/image/tiff"
|
"golang.org/x/image/tiff"
|
||||||
|
|
||||||
@@ -100,6 +102,8 @@ type Options struct {
|
|||||||
Thumbnail bool
|
Thumbnail bool
|
||||||
// CBZ metadata
|
// CBZ metadata
|
||||||
Meta bool
|
Meta bool
|
||||||
|
// Version
|
||||||
|
Version bool
|
||||||
// ZIP comment
|
// ZIP comment
|
||||||
Comment bool
|
Comment bool
|
||||||
// ZIP comment body
|
// ZIP comment body
|
||||||
@@ -166,7 +170,15 @@ type Convertor struct {
|
|||||||
type File struct {
|
type File struct {
|
||||||
Name string
|
Name string
|
||||||
Path string
|
Path string
|
||||||
Size int64
|
Stat os.FileInfo
|
||||||
|
SizeHuman string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image type.
|
||||||
|
type Image struct {
|
||||||
|
Image image.Image
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
SizeHuman string
|
SizeHuman string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,9 +302,10 @@ func (c *Convertor) convertArchive(fileName string) error {
|
|||||||
var img image.Image
|
var img image.Image
|
||||||
img, err = c.imageDecode(bytes.NewReader(data), pathName)
|
img, err = c.imageDecode(bytes.NewReader(data), pathName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
e := err
|
||||||
img, err = c.imDecode(bytes.NewReader(data), pathName)
|
img, err = c.imDecode(bytes.NewReader(data), pathName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("convertArchive: %w", err)
|
return fmt.Errorf("convertArchive: %w: %w", e, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,9 +404,15 @@ func (c *Convertor) convertDirectory(dirPath string) error {
|
|||||||
var i image.Image
|
var i image.Image
|
||||||
i, err = c.imageDecode(file, img)
|
i, err = c.imageDecode(file, img)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
e := err
|
||||||
|
_, err = file.Seek(0, io.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("convertDirectory: %w: %w", e, err)
|
||||||
|
}
|
||||||
|
|
||||||
i, err = c.imDecode(file, img)
|
i, err = c.imDecode(file, img)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("convertDirectory: %w", err)
|
return fmt.Errorf("convertDirectory: %w: %w", e, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,6 +536,10 @@ func (c *Convertor) imageTransform(img image.Image) image.Image {
|
|||||||
i = imaging.AdjustContrast(i, float64(c.Opts.Contrast))
|
i = imaging.AdjustContrast(i, float64(c.Opts.Contrast))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Opts.Grayscale {
|
||||||
|
i = imageToGray(i)
|
||||||
|
}
|
||||||
|
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,9 +575,10 @@ func (c *Convertor) imageLevel(img image.Image) (image.Image, error) {
|
|||||||
var i image.Image
|
var i image.Image
|
||||||
i, err = c.imageDecode(bytes.NewReader(blob), "levels")
|
i, err = c.imageDecode(bytes.NewReader(blob), "levels")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
e := err
|
||||||
i, err = c.imDecode(bytes.NewReader(blob), "levels")
|
i, err = c.imDecode(bytes.NewReader(blob), "levels")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("imageLevel: %w", err)
|
return nil, fmt.Errorf("imageLevel: %w: %w", e, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,10 +646,6 @@ func (c *Convertor) imageEncode(img image.Image, fileName string) error {
|
|||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
if c.Opts.Grayscale {
|
|
||||||
img = imageToGray(img)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch filepath.Ext(fileName) {
|
switch filepath.Ext(fileName) {
|
||||||
case ".png":
|
case ".png":
|
||||||
err = png.Encode(file, img)
|
err = png.Encode(file, img)
|
||||||
@@ -667,12 +687,6 @@ func (c *Convertor) imEncode(i image.Image, fileName string) error {
|
|||||||
return fmt.Errorf("imEncode: %w", err)
|
return fmt.Errorf("imEncode: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Opts.Grayscale {
|
|
||||||
if err := mw.TransformImageColorspace(imagick.COLORSPACE_GRAY); err != nil {
|
|
||||||
return fmt.Errorf("imEncode: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch filepath.Ext(fileName) {
|
switch filepath.Ext(fileName) {
|
||||||
case ".png":
|
case ".png":
|
||||||
if err := mw.SetImageFormat("PNG"); err != nil {
|
if err := mw.SetImageFormat("PNG"); err != nil {
|
||||||
@@ -1187,9 +1201,10 @@ func (c *Convertor) coverArchive(fileName string) (image.Image, error) {
|
|||||||
var img image.Image
|
var img image.Image
|
||||||
img, err = c.imageDecode(bytes.NewReader(data), cover)
|
img, err = c.imageDecode(bytes.NewReader(data), cover)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
e := err
|
||||||
img, err = c.imDecode(bytes.NewReader(data), cover)
|
img, err = c.imDecode(bytes.NewReader(data), cover)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("coverArchive: %w", err)
|
return nil, fmt.Errorf("coverArchive: %w: %w", e, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1232,9 +1247,15 @@ func (c *Convertor) coverDirectory(dir string) (image.Image, error) {
|
|||||||
var img image.Image
|
var img image.Image
|
||||||
img, err = c.imageDecode(file, cover)
|
img, err = c.imageDecode(file, cover)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
e := err
|
||||||
|
_, err = file.Seek(0, io.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("coverDirectory: %w: %w", e, err)
|
||||||
|
}
|
||||||
|
|
||||||
img, err = c.imDecode(file, cover)
|
img, err = c.imDecode(file, cover)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("coverDirectory: %w", err)
|
return nil, fmt.Errorf("coverDirectory: %w: %w", e, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1448,6 +1469,13 @@ func (c *Convertor) baseNoExt(filename string) string {
|
|||||||
return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename))
|
return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tempName generates a temporary name.
|
||||||
|
func (c *Convertor) tempName(prefix, suffix string) string {
|
||||||
|
randBytes := make([]byte, 16)
|
||||||
|
_, _ = rand.Read(randBytes)
|
||||||
|
return filepath.Join(os.TempDir(), prefix+hex.EncodeToString(randBytes)+suffix)
|
||||||
|
}
|
||||||
|
|
||||||
// copyFile copies reader to file.
|
// copyFile copies reader to file.
|
||||||
func (c *Convertor) copyFile(reader io.Reader, filename string) error {
|
func (c *Convertor) copyFile(reader io.Reader, filename string) error {
|
||||||
err := os.MkdirAll(filepath.Dir(filename), 0755)
|
err := os.MkdirAll(filepath.Dir(filename), 0755)
|
||||||
@@ -1487,8 +1515,8 @@ func (c *Convertor) Files(args []string) ([]File, error) {
|
|||||||
var file File
|
var file File
|
||||||
file.Name = filepath.Base(fp)
|
file.Name = filepath.Base(fp)
|
||||||
file.Path = fp
|
file.Path = fp
|
||||||
file.Size = f.Size()
|
file.Stat = f
|
||||||
file.SizeHuman = humanize.IBytes(uint64(file.Size))
|
file.SizeHuman = humanize.IBytes(uint64(f.Size()))
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1630,10 +1658,10 @@ func (c *Convertor) Cover(fileName string, fileInfo os.FileInfo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Thumbnail extracts thumbnail.
|
// Thumbnail extracts thumbnail.
|
||||||
func (c *Convertor) Thumbnail(fileName string, info os.FileInfo) error {
|
func (c *Convertor) Thumbnail(fileName string, fileInfo os.FileInfo) error {
|
||||||
c.CurrFile++
|
c.CurrFile++
|
||||||
|
|
||||||
cover, err := c.coverImage(fileName, info)
|
cover, err := c.coverImage(fileName, fileInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: %w", fileName, err)
|
return fmt.Errorf("%s: %w", fileName, err)
|
||||||
}
|
}
|
||||||
@@ -1691,10 +1719,10 @@ func (c *Convertor) Thumbnail(fileName string, info os.FileInfo) error {
|
|||||||
if err := mw.SetImageProperty("Thumb::URI", fURI); err != nil {
|
if err := mw.SetImageProperty("Thumb::URI", fURI); err != nil {
|
||||||
return fmt.Errorf("%s: %w", fileName, err)
|
return fmt.Errorf("%s: %w", fileName, err)
|
||||||
}
|
}
|
||||||
if err := mw.SetImageProperty("Thumb::MTime", strconv.FormatInt(info.ModTime().Unix(), 10)); err != nil {
|
if err := mw.SetImageProperty("Thumb::MTime", strconv.FormatInt(fileInfo.ModTime().Unix(), 10)); err != nil {
|
||||||
return fmt.Errorf("%s: %w", fileName, err)
|
return fmt.Errorf("%s: %w", fileName, err)
|
||||||
}
|
}
|
||||||
if err := mw.SetImageProperty("Thumb::Size", strconv.FormatInt(info.Size(), 10)); err != nil {
|
if err := mw.SetImageProperty("Thumb::Size", strconv.FormatInt(fileInfo.Size(), 10)); err != nil {
|
||||||
return fmt.Errorf("%s: %w", fileName, err)
|
return fmt.Errorf("%s: %w", fileName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1753,12 +1781,88 @@ func (c *Convertor) Meta(fileName string) (any, error) {
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preview returns image preview.
|
||||||
|
func (c *Convertor) Preview(fileName string, fileInfo os.FileInfo, width, height int) (Image, error) {
|
||||||
|
var img Image
|
||||||
|
|
||||||
|
i, err := c.coverImage(fileName, fileInfo)
|
||||||
|
if err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w", fileName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
i = c.imageTransform(i)
|
||||||
|
|
||||||
|
if c.Opts.LevelsInMin != 0 || c.Opts.LevelsInMax != 255 || c.Opts.LevelsGamma != 1.0 ||
|
||||||
|
c.Opts.LevelsOutMin != 0 || c.Opts.LevelsOutMax != 255 {
|
||||||
|
i, err = c.imageLevel(i)
|
||||||
|
if err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w", fileName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpName := c.tempName("cbc", "."+c.Opts.Format)
|
||||||
|
|
||||||
|
switch c.Opts.Format {
|
||||||
|
case "jpeg", "png", "tiff", "webp", "avif":
|
||||||
|
if err := c.imageEncode(i, tmpName); err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w", fileName, err)
|
||||||
|
}
|
||||||
|
case "bmp":
|
||||||
|
if err := c.imEncode(i, tmpName); err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w", fileName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stat, err := os.Stat(tmpName)
|
||||||
|
if err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w", fileName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
img.Width = i.Bounds().Dx()
|
||||||
|
img.Height = i.Bounds().Dy()
|
||||||
|
img.SizeHuman = humanize.IBytes(uint64(stat.Size()))
|
||||||
|
|
||||||
|
f, err := os.Open(tmpName)
|
||||||
|
if err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w", fileName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer os.Remove(tmpName)
|
||||||
|
|
||||||
|
dec, err := c.imageDecode(f, tmpName)
|
||||||
|
if err != nil {
|
||||||
|
e := err
|
||||||
|
_, err = f.Seek(0, io.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w: %w", tmpName, e, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dec, err = c.imDecode(f, tmpName)
|
||||||
|
if err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w: %w", tmpName, e, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = f.Close()
|
||||||
|
if err != nil {
|
||||||
|
return img, fmt.Errorf("%s: %w", fileName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if width != 0 && height != 0 {
|
||||||
|
dec = imaging.Fit(dec, width, height, filters[c.Opts.Filter])
|
||||||
|
}
|
||||||
|
|
||||||
|
img.Image = dec
|
||||||
|
|
||||||
|
return img, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Convert converts comic book.
|
// Convert converts comic book.
|
||||||
func (c *Convertor) Convert(fileName string, info os.FileInfo) error {
|
func (c *Convertor) Convert(fileName string, fileInfo os.FileInfo) error {
|
||||||
c.CurrFile++
|
c.CurrFile++
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case info.IsDir():
|
case fileInfo.IsDir():
|
||||||
if err := c.convertDirectory(fileName); err != nil {
|
if err := c.convertDirectory(fileName); err != nil {
|
||||||
return fmt.Errorf("%s: %w", fileName, err)
|
return fmt.Errorf("%s: %w", fileName, err)
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime/debug"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/gen2brain/cbconvert"
|
"github.com/gen2brain/cbconvert"
|
||||||
@@ -14,8 +15,43 @@ import (
|
|||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var appVersion string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if appVersion != "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.Main.Version != "" {
|
||||||
|
appVersion = info.Main.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, kv := range info.Settings {
|
||||||
|
if kv.Value == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if kv.Key == "vcs.revision" {
|
||||||
|
appVersion = kv.Value
|
||||||
|
if len(appVersion) > 10 {
|
||||||
|
appVersion = kv.Value[:10]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
opts, args := parseFlags()
|
opts, args := parseFlags()
|
||||||
|
|
||||||
|
if opts.Version {
|
||||||
|
fmt.Println(filepath.Base(os.Args[0]), appVersion)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
conv := cbconvert.New(opts)
|
conv := cbconvert.New(opts)
|
||||||
|
|
||||||
c := make(chan os.Signal, 2)
|
c := make(chan os.Signal, 2)
|
||||||
@@ -83,12 +119,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
stat, err := os.Stat(file.Path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case opts.Meta:
|
case opts.Meta:
|
||||||
ret, err := conv.Meta(file.Path)
|
ret, err := conv.Meta(file.Path)
|
||||||
@@ -105,14 +135,14 @@ func main() {
|
|||||||
|
|
||||||
continue
|
continue
|
||||||
case opts.Cover:
|
case opts.Cover:
|
||||||
if err := conv.Cover(file.Path, stat); err != nil {
|
if err := conv.Cover(file.Path, file.Stat); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
case opts.Thumbnail:
|
case opts.Thumbnail:
|
||||||
if err = conv.Thumbnail(file.Path, stat); err != nil {
|
if err = conv.Thumbnail(file.Path, file.Stat); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -120,7 +150,7 @@ func main() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := conv.Convert(file.Path, stat); err != nil {
|
if err := conv.Convert(file.Path, file.Stat); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -197,34 +227,32 @@ func parseFlags() (cbconvert.Options, []string) {
|
|||||||
meta.StringVar(&opts.FileAdd, "file-add", "", "Add file to archive")
|
meta.StringVar(&opts.FileAdd, "file-add", "", "Add file to archive")
|
||||||
meta.StringVar(&opts.FileRemove, "file-remove", "", "Remove file from archive (glob pattern, i.e. *.xml)")
|
meta.StringVar(&opts.FileRemove, "file-remove", "", "Remove file from archive (glob pattern, i.e. *.xml)")
|
||||||
|
|
||||||
convert.Usage = func() {
|
flag.NewFlagSet("version", flag.ExitOnError)
|
||||||
|
|
||||||
|
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", f.Name)
|
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n \t")
|
|
||||||
_, _ = 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", f.Name)
|
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n \t")
|
|
||||||
_, _ = 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", f.Name)
|
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n \t")
|
|
||||||
_, _ = 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", f.Name)
|
_, _ = fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "\n \t")
|
|
||||||
_, _ = 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")
|
_, _ = fmt.Fprintf(os.Stderr, "\n version\n \tPrint version\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(os.Args) < 2 {
|
if len(os.Args) < 2 {
|
||||||
@@ -262,10 +290,12 @@ func parseFlags() (cbconvert.Options, []string) {
|
|||||||
if !pipe {
|
if !pipe {
|
||||||
args = meta.Args()
|
args = meta.Args()
|
||||||
}
|
}
|
||||||
|
case "version":
|
||||||
|
opts.Version = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 && !opts.Version {
|
||||||
convert.Usage()
|
flag.Usage()
|
||||||
_, _ = fmt.Fprintf(os.Stderr, "no arguments\n")
|
_, _ = fmt.Fprintf(os.Stderr, "no arguments\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user