package createepub import ( "encoding/json" "fmt" "io" "log" "mangacrawler/mangacrawler" "net/http" "os" "os/user" "regexp" "strings" "github.com/go-shiori/go-epub" ) type MangaPlus struct { Data MangaRelationships `json:"data"` } type MangaRelationships struct { Rels []MangaRels `json:"relationships"` Attr MangaAttributes `json:"attributes"` } type MangaRels struct { Attributes MangaAuthor `json:"attributes"` Type string `json:"type"` } type MangaAuthor struct { Name string `json:"name"` File string `json:"fileName"` } type MangaAttributes struct { Desc MangaDesc `json:"description"` } type MangaDesc struct { En string `json:"en"` } func CreateEpub(mangaPath string, mangaTitle string, mangaId string) { var author MangaPlus url := "https://api.mangadex.org/manga/" + mangaId + "?includes[]=author&includes[]=cover_art" data := mangacrawler.GetJson(url) homepath, err := user.Current() if err != nil { panic(err) } if err := json.Unmarshal(data, &author); err != nil { panic(err) } fmt.Println("Downloading and adding cover page for EPUB") var coverPath string var coverFile string for _, rels := range author.Data.Rels { if rels.Type == "cover_art" { coverPath, coverFile = getCoverPage(mangaId, rels.Attributes.File, mangaPath) } } book := epub.NewEpub(mangaTitle) book.SetAuthor(author.Data.Rels[0].Attributes.Name) book.SetDescription(author.Data.Attr.Desc.En) bookCss, _ := book.AddCSS(strings.Join([]string{homepath.HomeDir, "mangas/EPUB", "epub.css"}, "/"), "") bookCover, _ := book.AddImage(coverPath, coverFile) book.SetCover(bookCover, "") fmt.Println("Cover page added") fmt.Println("Adding pages to EPUB. Each chapter is a section\nIf chapter title is available that will be used for section title") addPages(book, mangaPath, bookCss) fmt.Println("Writing EPUB to disk...") err = book.Write(strings.Join([]string{homepath.HomeDir, "mangas/EPUB", mangaTitle + ".epub"}, "/")) if err != nil { log.Fatal(err) } } func addPages(book *epub.Epub, mangaPath string, bookCss string) *epub.Epub { chapters, err := os.ReadDir(mangaPath) if err != nil { panic(err) } titleCompile, _ := regexp.Compile(`^[A-Za-z][^\d]`) bonusChapterCompile, _ := regexp.Compile(`^(z\d+)`) chapterIndexCompile, _ := regexp.Compile(`chapter0*(\d+)`) for _, chapter := range chapters { var section string if !strings.HasPrefix(chapter.Name(), "chapter") { continue } chapterNo := chapterIndexCompile.FindStringSubmatch(chapter.Name())[1] // fmt.Println(chapterNo) pages, _ := os.ReadDir(strings.Join([]string{mangaPath, chapter.Name()}, "/")) for i, page := range pages { var sectionBody string var subSectionBody string bookPage, _ := book.AddImage(strings.Join([]string{mangaPath, chapter.Name(), page.Name()}, "/"), page.Name()) if i == 0 { sectionBody = fmt.Sprintf("\n", bookPage) if len(chapter.Name()) > 10 { titleMatch := titleCompile.MatchString(chapter.Name()[11:]) bonusChapterMatch := bonusChapterCompile.MatchString(chapter.Name()[11:]) if bonusChapterMatch && len(chapter.Name()) > 13 { bonusChapterNo := bonusChapterCompile.FindStringSubmatch(chapter.Name()[11:]) section, err = book.AddSection(sectionBody, "Chapter "+chapterNo+strings.Replace(bonusChapterNo[1], "z", ".", 1)+": "+chapter.Name()[14:], "", bookCss) if err != nil { panic(err) } } else if bonusChapterMatch { bonusChapterNo := bonusChapterCompile.FindStringSubmatch(chapter.Name()[11:]) section, err = book.AddSection(sectionBody, "Chapter "+chapterNo+strings.Replace(bonusChapterNo[1], "z", ".", 1), "", bookCss) if err != nil { panic(err) } } else if titleMatch { section, err = book.AddSection(sectionBody, "Chapter "+chapterNo+": "+chapter.Name()[11:], "", bookCss) if err != nil { panic(err) } } } else { section, err = book.AddSection(sectionBody, "Chapter "+chapterNo, "", bookCss) if err != nil { panic(err) } } } else { subSectionBody = fmt.Sprintf("\n", bookPage) _, _ = book.AddSubSection(section, subSectionBody, "", "", bookCss) } } } return book } func getCoverPage(mangaId string, coverFile string, mangaPath string) (string, string) { _, err := os.Stat(strings.Join([]string{mangaPath, coverFile}, "/")) if err == nil { return strings.Join([]string{mangaPath, coverFile}, "/"), coverFile } url := strings.Join([]string{"https://uploads.mangadex.org/covers", mangaId, coverFile}, "/") result, err := http.Get(url) if err != nil { panic(err) } defer result.Body.Close() file, err := os.Create(strings.Join([]string{mangaPath, coverFile}, "/")) if err != nil { panic(err) } _, err = io.Copy(file, result.Body) if err != nil { panic(err) } file.Close() return strings.Join([]string{mangaPath, coverFile}, "/"), coverFile }