diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go index 3bb0c35..450718b 100644 --- a/pkg/cli/cli.go +++ b/pkg/cli/cli.go @@ -1,12 +1,18 @@ package cli import ( + "errors" "flag" "fmt" + "io/ioutil" + "net/http" "os" + "path" "path/filepath" "sort" + "strconv" "strings" + "time" "code.fmartingr.dev/fmartingr/go-mangadex" "github.com/sirupsen/logrus" @@ -18,6 +24,49 @@ type CliOPtions struct { const defaultLogLevel string = "INFO" +func fileExists(filename string) bool { + info, err := os.Stat(filename) + if os.IsNotExist(err) { + return false + } + return !info.IsDir() +} + +func DownloadFile(url string, destinationPath string) error { + response, err := http.Get(url) + if err != nil { + logrus.Errorf("Error downloading page: %s", err) + return err + } + + if response.StatusCode != 200 { + logrus.Errorf("Status code not OK: %d", response.StatusCode) + return errors.New("Status code not 200") + } + + if response.Body != nil { + defer response.Body.Close() + } + + file, errOpen := os.Create(destinationPath) + if err != nil { + logrus.Errorf("Error opening file: %s", errOpen) + return errOpen + } + + defer file.Close() + + body, errBody := ioutil.ReadAll(response.Body) + if errBody != nil { + logrus.Errorf("Failing read body from response: %s", errBody) + return err + } + + file.Write(body) + + return nil +} + func Start() { logLevelFlag := flag.String("log-level", defaultLogLevel, "Log level") mangaIDFlag := flag.Int("manga-id", 0, "Manga ID to convert") @@ -56,7 +105,7 @@ func Start() { logrus.Infof("Found! %s", manga.Title) logrus.Infof("Getting chapter information...") - var mangaChapters []mangadex.MangaChapter + var mangaChapters []mangadex.MangaChapterList mangaGroups := map[int]mangadex.MangaGroup{} chapterParams := mangadex.NewGetChaptersParams() currentPage := 1 @@ -106,8 +155,9 @@ func Start() { logrus.Infof("Calculating Volumes...") - mangaVolumeChapter := map[string]mangadex.MangaChapter{} + mangaVolumeChapter := map[string]mangadex.MangaChapterList{} var mangaVolumeChapterKeys []string + //testTest := map[string]map[string]mangadex.MangaChapter{} for chapter := range mangaChapters { if !strings.Contains(mangaChapters[chapter].Chapter, ".") { @@ -116,6 +166,7 @@ func Start() { volumeChapterKey := fmt.Sprintf("%04s_%08s", mangaChapters[chapter].Volume, mangaChapters[chapter].Chapter) _, exists := mangaVolumeChapter[volumeChapterKey] if !exists { + //testTest[fmt.Sprintf("%04s", mangaChapters[chapter].Volume)][fmt.Sprintf("%08s", mangaChapters[chapter].Chapter)] = mangaChapters[chapter] logrus.Debugf("Collecting volume %4s chapter %4s from group %7d", mangaChapters[chapter].Volume, mangaChapters[chapter].Chapter, mangaChapters[chapter].Groups) mangaVolumeChapter[volumeChapterKey] = mangaChapters[chapter] mangaVolumeChapterKeys = append(mangaVolumeChapterKeys, volumeChapterKey) @@ -125,12 +176,62 @@ func Start() { logrus.Debugf("Sorting by volume and chapter") sort.Strings(mangaVolumeChapterKeys) + mangaOutputPath := filepath.Join(outputPath, manga.Title) for i := range mangaVolumeChapterKeys { - logrus.Info(mangaVolumeChapterKeys[i]) + chapter := mangaVolumeChapter[mangaVolumeChapterKeys[i]] + if chapter.Volume == "1" { + volumeOutputPath := filepath.Join(mangaOutputPath, fmt.Sprintf("%s - Volume %s", manga.Title, chapter.Volume)) + + logrus.Infof("Processing Volume %s Chapter %s", chapter.Volume, chapter.Chapter) + logrus.Tracef("Processing %s", mangaVolumeChapterKeys[i]) + + errMkdir := os.MkdirAll(volumeOutputPath, 0766) + if errMkdir != nil { + logrus.Fatalf("Error creating output directory: %s", errMkdir) + } + + chapterDetail, errChapterDetail := manga.GetChapter(strconv.Itoa(chapter.ID)) + if errChapterDetail != nil { + logrus.Errorf("Failed getting chapter detail: %s", errChapterDetail) + } + + for page := range chapterDetail.Pages { + logrus.Infof("Processing page %s", chapterDetail.Pages[page]) + extension := path.Ext(chapterDetail.Pages[page]) + pageDestinationPath := filepath.Join(volumeOutputPath, fmt.Sprintf("%s_%03d%s", mangaVolumeChapterKeys[i], page, extension)) + if !fileExists(pageDestinationPath) { + logrus.Tracef("Downloading page from %s", chapterDetail.Server+path.Join(chapterDetail.Hash, chapterDetail.Pages[page])) + logrus.Tracef("Downlading page to %s", pageDestinationPath) + errDownload := DownloadFile(chapterDetail.Server+path.Join(chapterDetail.Hash, chapterDetail.Pages[page]), pageDestinationPath) + if errDownload != nil { + logrus.Errorf("Error downloading page: %s", errDownload) + } + } + time.Sleep(100 * time.Millisecond) + } + + } + } + + covers, errCovers := manga.GetCovers() + if errCovers != nil { + logrus.Errorf("Error getting cover information: %s", errCovers) + } + + for cover := range covers { + if covers[cover].Volume == "1" { + extension := path.Ext(covers[cover].URL) + coverOutputPath := filepath.Join(mangaOutputPath, fmt.Sprintf("%s - Volume %s", manga.Title, covers[cover].Volume), fmt.Sprintf("0000%s", extension)) + if !fileExists(coverOutputPath) { + logrus.Tracef("Downloading cover from %s", covers[cover].URL) + logrus.Tracef("Writting cover to: %s", coverOutputPath) + errDownload := DownloadFile(covers[cover].URL, coverOutputPath) + if errDownload != nil { + logrus.Errorf("Error downloading cover: %s", errDownload) + } + } + time.Sleep(100 * time.Millisecond) + } } - // TODO: Build output directory structure: Output///_%4d.jpg - // TODO: Download chapters - // TODO: Store download status - // TODO: Download covers: Output// - Volume /0000.jpg // TODO: Zip folders into CBR files }