diff --git a/internal/epub/core.go b/internal/epub/core.go index 9bd788f..69e4c11 100644 --- a/internal/epub/core.go +++ b/internal/epub/core.go @@ -1,8 +1,10 @@ package epub import ( + "archive/zip" "fmt" "io/fs" + "os" "path/filepath" "runtime" "sort" @@ -122,6 +124,99 @@ func (e *EPub) Render(templateString string, data any) string { return result.String() } +func (e *EPub) Load(path string) *EPub { + fi, err := os.Stat(path) + if err != nil { + e.Error = err + return e + } + + if fi.IsDir() { + return e.LoadDir(path) + } + + switch ext := strings.ToLower(filepath.Ext(path)); ext { + case ".cbz": + e.LoadCBZ(path) + case ".cbr": + e.LoadCBR(path) + case ".pdf": + e.LoadPDF(path) + default: + e.Error = fmt.Errorf("unknown file format (%s): support .cbz, .cbr, .pdf", ext) + } + return e +} + +func (e *EPub) LoadCBZ(path string) *EPub { + r, err := zip.OpenReader(path) + if err != nil { + e.Error = err + } + + images := make([]*zip.File, 0) + for _, f := range r.File { + if f.FileInfo().IsDir() { + continue + } + if strings.ToLower(filepath.Ext(f.Name)) != ".jpg" { + continue + } + images = append(images, f) + } + if len(images) == 0 { + e.Error = fmt.Errorf("no images found") + r.Close() + return e + } + e.ImagesCount = len(images) + + type Todo struct { + Id int + FZ *zip.File + } + + todo := make(chan *Todo) + + e.ProcessingImages = func() chan *Image { + defer r.Close() + wg := &sync.WaitGroup{} + results := make(chan *Image) + for i := 0; i < runtime.NumCPU(); i++ { + wg.Add(1) + go func() { + defer wg.Done() + for task := range todo { + fmt.Println(task.FZ.Name) + // TODO + } + }() + } + go func() { + for i, fz := range images { + todo <- &Todo{i, fz} + } + close(todo) + wg.Wait() + close(results) + }() + + return results + } + + return e +} + +func (e *EPub) LoadCBR(path string) *EPub { + e.Error = fmt.Errorf("no implemented") + return e +} + +func (e *EPub) LoadPDF(path string) *EPub { + e.Error = fmt.Errorf("no implemented") + return e +} + func (e *EPub) LoadDir(dirname string) *EPub { images := make([]string, 0) err := filepath.WalkDir(dirname, func(path string, d fs.DirEntry, err error) error { @@ -188,11 +283,7 @@ func (e *EPub) LoadDir(dirname string) *EPub { } go func() { for i, path := range images { - if i == 0 { - todo <- &Todo{i, path} - } else { - todo <- &Todo{i, path} - } + todo <- &Todo{i, path} } close(todo) wg.Wait() @@ -214,7 +305,6 @@ func (e *EPub) GetParts() []*EpubPart { bar.Close() epubPart := make([]*EpubPart, 0) - cover := images[0] images = images[1:] if e.LimitMb == 0 { diff --git a/main.go b/main.go index 4040926..777cc3f 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "go-comic-converter/internal/epub" + "os" "path/filepath" "strings" ) @@ -86,24 +87,35 @@ func main() { if opt.Input == "" { fmt.Println("Missing input or output!") flag.Usage() - return + os.Exit(1) } if opt.Output == "" { - opt.Output = fmt.Sprintf("%s.epub", filepath.Clean(opt.Input)) + 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)]) + } } profile, profileMatch := Profiles[opt.Profile] if !profileMatch { fmt.Println("Profile doesn't exists!") flag.Usage() - return + os.Exit(1) } if opt.LimitMb > 0 && opt.LimitMb < 20 { fmt.Println("LimitMb should be 0 or >= 20") flag.Usage() - return + os.Exit(1) } if opt.Title == "" { @@ -119,10 +131,13 @@ func main() { SetLimitMb(opt.LimitMb). SetTitle(opt.Title). SetAuthor(opt.Author). - LoadDir(opt.Input). + Load(opt.Input). Write() if err != nil { - panic(err) + fmt.Printf("Error: %v\n", err) + os.Exit(1) } + + os.Exit(0) }