package main import ( "flag" "fmt" "go-comic-converter/internal/epub" "os" "path/filepath" "strings" ) type Profile struct { Code string Description string Width int Height int } var Profiles = []Profile{ // Kindle {"K1", "Kindle 1", 600, 670}, {"K11", "Kindle 11", 1072, 1448}, {"K2", "Kindle 2", 600, 670}, {"K34", "Kindle Keyboard/Touch", 600, 800}, {"K578", "Kindle", 600, 800}, {"KDX", "Kindle DX/DXG", 824, 1000}, {"KPW", "Kindle Paperwhite 1/2", 758, 1024}, {"KV", "Kindle Paperwhite 3/4/Voyage/Oasis", 1072, 1448}, {"KPW5", "Kindle Paperwhite 5/Signature Edition", 1236, 1648}, {"KO", "Kindle Oasis 2/3", 1264, 1680}, {"KS", "Kindle Scribe", 1860, 2480}, // Kobo {"KoMT", "Kobo Mini/Touch", 600, 800}, {"KoG", "Kobo Glo", 768, 1024}, {"KoGHD", "Kobo Glo HD", 1072, 1448}, {"KoA", "Kobo Aura", 758, 1024}, {"KoAHD", "Kobo Aura HD", 1080, 1440}, {"KoAH2O", "Kobo Aura H2O", 1080, 1430}, {"KoAO", "Kobo Aura ONE", 1404, 1872}, {"KoN", "Kobo Nia", 758, 1024}, {"KoC", "Kobo Clara HD/Kobo Clara 2E", 1072, 1448}, {"KoL", "Kobo Libra H2O/Kobo Libra 2", 1264, 1680}, {"KoF", "Kobo Forma", 1440, 1920}, {"KoS", "Kobo Sage", 1440, 1920}, {"KoE", "Kobo Elipsa", 1404, 1872}, } var ProfilesIdx = map[string]int{} func init() { for i, p := range Profiles { ProfilesIdx[p.Code] = i } } type Option struct { Input string Output string Profile string Author string Title string Quality int NoCrop bool LimitMb int } func (o *Option) String() string { var desc string var width, height int if i, ok := ProfilesIdx[o.Profile]; ok { profile := Profiles[i] desc = profile.Description width = profile.Width height = profile.Height } limitmb := "nolimit" if o.LimitMb > 0 { limitmb = fmt.Sprintf("%d Mb", o.LimitMb) } return fmt.Sprintf(`Go Comic Converter Options: Input : %s Output : %s Profile : %s - %s - %dx%d Author : %s Title : %s Quality : %d Crop : %v LimitMb : %s `, o.Input, o.Output, o.Profile, desc, width, height, o.Author, o.Title, o.Quality, !o.NoCrop, limitmb, ) } func main() { availableProfiles := make([]string, 0) for _, p := range Profiles { availableProfiles = append(availableProfiles, fmt.Sprintf( " - %-7s ( %9s ) - %s", p.Code, fmt.Sprintf("%dx%d", p.Width, p.Height), p.Description, )) } opt := &Option{} flag.StringVar(&opt.Input, "input", "", "Source of comic to convert: directory, cbz, zip, cbr, rar, pdf") flag.StringVar(&opt.Output, "output", "", "Output of the epub: (default [INPUT].epub)") flag.StringVar(&opt.Profile, "profile", "", fmt.Sprintf("Profile to use: \n%s", strings.Join(availableProfiles, "\n"))) flag.StringVar(&opt.Author, "author", "GO Comic Converter", "Author of the epub") flag.StringVar(&opt.Title, "title", "", "Title of the epub") flag.IntVar(&opt.Quality, "quality", 85, "Quality of the image") flag.BoolVar(&opt.NoCrop, "nocrop", false, "Disable cropping") flag.IntVar(&opt.LimitMb, "limitmb", 0, "Limit size of the ePub: Default nolimit (0), Minimum 20") flag.Parse() if opt.Input == "" { fmt.Println("Missing input or output!") flag.Usage() os.Exit(1) } if opt.Output == "" { fi, err := os.Stat(opt.Input) if err != nil { fmt.Println(err) flag.Usage() os.Exit(1) } if fi.IsDir() { opt.Output = fmt.Sprintf("%s.epub", filepath.Clean(opt.Input)) } else { ext := filepath.Ext(opt.Input) opt.Output = fmt.Sprintf("%s.epub", opt.Input[0:len(opt.Input)-len(ext)]) } } profileIdx, profileMatch := ProfilesIdx[opt.Profile] if !profileMatch { fmt.Println("Profile doesn't exists!") flag.Usage() os.Exit(1) } profile := Profiles[profileIdx] if opt.LimitMb > 0 && opt.LimitMb < 20 { fmt.Println("LimitMb should be 0 or >= 20") flag.Usage() os.Exit(1) } if opt.Title == "" { opt.Title = filepath.Base(opt.Input) } fmt.Println(opt) if err := epub.NewEpub(&epub.EpubOptions{ Input: opt.Input, Output: opt.Output, LimitMb: opt.LimitMb, Title: opt.Title, Author: opt.Author, ImageOptions: &epub.ImageOptions{ ViewWidth: profile.Width, ViewHeight: profile.Height, Quality: opt.Quality, Crop: !opt.NoCrop, }, }).Write(); err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) } os.Exit(0) }