Add Creator Info + Fetching to JNC Module. Implement .cbz chapter generation
This commit is contained in:
parent
1661c7de42
commit
b36bc9b0b2
2 changed files with 345 additions and 49 deletions
49
jnc/jnc.go
49
jnc/jnc.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -90,7 +91,7 @@ type Volume struct {
|
||||||
Number int `json:"number"`
|
Number int `json:"number"`
|
||||||
OriginalPublisher string `json:"originalPublisher"`
|
OriginalPublisher string `json:"originalPublisher"`
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Creators []string `json:"creators"` // TODO: check, might not be correct
|
Creators Creators `json:"creators"` // TODO: check, might not be correct
|
||||||
hidden bool
|
hidden bool
|
||||||
ForumTopicId int `json:"forumTopicId"`
|
ForumTopicId int `json:"forumTopicId"`
|
||||||
Created string `json:"created"`
|
Created string `json:"created"`
|
||||||
|
@ -105,6 +106,28 @@ type Volume struct {
|
||||||
OnSale bool `json:"onSale"`
|
OnSale bool `json:"onSale"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Creators []Creator
|
||||||
|
|
||||||
|
type Creator struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
OriginalName string `json:"originalName "`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (creators *Creators) Contains(name string) bool {
|
||||||
|
return slices.ContainsFunc(*creators, func(c Creator) bool {
|
||||||
|
return c.Name == name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (creators *Creators) Get(name string) *Creator {
|
||||||
|
idx := slices.IndexFunc(*creators, func(c Creator) bool {
|
||||||
|
return c.Name == name
|
||||||
|
})
|
||||||
|
return &(*creators)[idx]
|
||||||
|
}
|
||||||
|
|
||||||
type VolumeAugmented struct {
|
type VolumeAugmented struct {
|
||||||
Info Volume
|
Info Volume
|
||||||
Downloads []Download
|
Downloads []Download
|
||||||
|
@ -367,6 +390,30 @@ func (jncApi *Api) FetchLibrarySeries() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FetchVolumeInfo retrieves additional Volume Info that was not returned when retrieving the entire Library
|
||||||
|
func (jncApi *Api) FetchVolumeInfo(volume Volume) (Volume, error) {
|
||||||
|
fmt.Println("Fetching Volume details...")
|
||||||
|
res, err := http.Get(ApiV2Url + "volumes/" + volume.Id + "?" + jncApi.ReturnFormat() + "&" + jncApi.AuthParam())
|
||||||
|
if err != nil {
|
||||||
|
return volume, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.StatusCode != 200 {
|
||||||
|
return volume, errors.New(res.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := io.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
return volume, err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(body, &volume)
|
||||||
|
if err != nil {
|
||||||
|
return volume, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return volume, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetLibrarySeries returns a list of unique series found in the User's library. Tags are only included if FetchLibrarySeries was previously called.
|
// GetLibrarySeries returns a list of unique series found in the User's library. Tags are only included if FetchLibrarySeries was previously called.
|
||||||
func (jncApi *Api) GetLibrarySeries() (seriesList []SerieAugmented, err error) {
|
func (jncApi *Api) GetLibrarySeries() (seriesList []SerieAugmented, err error) {
|
||||||
arr := make([]SerieAugmented, 0, len(jncApi._series))
|
arr := make([]SerieAugmented, 0, len(jncApi._series))
|
||||||
|
|
341
main.go
341
main.go
|
@ -3,7 +3,9 @@ package main
|
||||||
import (
|
import (
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"container/list"
|
"container/list"
|
||||||
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/beevik/etree"
|
"github.com/beevik/etree"
|
||||||
"io"
|
"io"
|
||||||
|
@ -14,6 +16,7 @@ import (
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Chapter struct {
|
type Chapter struct {
|
||||||
|
@ -23,6 +26,7 @@ type Chapter struct {
|
||||||
title string
|
title string
|
||||||
firstPage string
|
firstPage string
|
||||||
lastPage string
|
lastPage string
|
||||||
|
pages []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileWrapper struct {
|
type FileWrapper struct {
|
||||||
|
@ -64,7 +68,25 @@ func ClearScreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
downloadDir := "/home/neshura/Documents/Go Workspaces/Kavita Helper/"
|
interactive := false
|
||||||
|
if slices.Contains(os.Args, "-I") {
|
||||||
|
interactive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !interactive {
|
||||||
|
panic("automatic mode is not implemented yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
var downloadDir string
|
||||||
|
if slices.Contains(os.Args, "-d") {
|
||||||
|
idx := slices.Index(os.Args, "-d")
|
||||||
|
downloadDir = os.Args[idx+1]
|
||||||
|
if strings.LastIndex(downloadDir, "/") != len(downloadDir)-1 {
|
||||||
|
downloadDir = downloadDir + "/"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic("working directory not specified")
|
||||||
|
}
|
||||||
|
|
||||||
// initialize the J-Novel Club Instance
|
// initialize the J-Novel Club Instance
|
||||||
jnovel := jnc.NewJNC()
|
jnovel := jnc.NewJNC()
|
||||||
|
@ -192,10 +214,16 @@ func main() {
|
||||||
func HandleSeries(jnovel jnc.Api, serie jnc.SerieAugmented, downloadDir string, updatedOnly bool) {
|
func HandleSeries(jnovel jnc.Api, serie jnc.SerieAugmented, downloadDir string, updatedOnly bool) {
|
||||||
for v := range serie.Volumes {
|
for v := range serie.Volumes {
|
||||||
volume := serie.Volumes[v]
|
volume := serie.Volumes[v]
|
||||||
|
if updatedOnly {
|
||||||
if len(volume.Downloads) != 0 && volume.UpdateAvailable() {
|
if len(volume.Downloads) != 0 && volume.UpdateAvailable() {
|
||||||
downloadDir = PrepareSerieDirectory(serie, volume, downloadDir)
|
downloadDir = PrepareSerieDirectory(serie, volume, downloadDir)
|
||||||
HandleVolume(jnovel, serie, volume, downloadDir)
|
HandleVolume(jnovel, serie, volume, downloadDir)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
downloadDir = PrepareSerieDirectory(serie, volume, downloadDir)
|
||||||
|
HandleVolume(jnovel, serie, volume, downloadDir)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +328,6 @@ func DownloadAndProcessEpub(jnovel jnc.Api, serie jnc.SerieAugmented, volume jnc
|
||||||
}
|
}
|
||||||
|
|
||||||
if metadata.fileSet && navigation.fileSet {
|
if metadata.fileSet && navigation.fileSet {
|
||||||
println("breaking")
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,11 +337,104 @@ func DownloadAndProcessEpub(jnovel jnc.Api, serie jnc.SerieAugmented, volume jnc
|
||||||
switch FormatMetadataName[metadata.fileName] {
|
switch FormatMetadataName[metadata.fileName] {
|
||||||
case "manga":
|
case "manga":
|
||||||
{
|
{
|
||||||
|
comicInfoName := "ComicInfo.xml"
|
||||||
chapterList := GenerateMangaChapterList(navigation)
|
chapterList := GenerateMangaChapterList(navigation)
|
||||||
|
|
||||||
|
if chapterList.Len() == 0 {
|
||||||
|
fmt.Println("No chapters found, chapter name likely not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
basePath := downloadDirectory + volume.Info.Title + "/"
|
||||||
|
PrepareVolumeDirectory(basePath)
|
||||||
|
volume.Info, err = jnovel.FetchVolumeInfo(volume.Info)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
doc := etree.NewDocument()
|
||||||
|
reader, err := metadata.file.Open()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := doc.ReadFrom(reader); err != nil {
|
||||||
|
_ = reader.Close()
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
language := doc.FindElement("package/metadata/dc:language").Text()
|
||||||
|
|
||||||
for ch := chapterList.Front(); ch != nil; ch = ch.Next() {
|
for ch := chapterList.Front(); ch != nil; ch = ch.Next() {
|
||||||
chap := ch.Value.(Chapter)
|
chap := ch.Value.(Chapter)
|
||||||
fmt.Printf("[%s] %s: %s - %s\n", chap.chDisplay, chap.title, chap.firstPage, chap.lastPage)
|
|
||||||
|
zipPath := basePath + "Chapter " + chap.chDisplay + ".cbz"
|
||||||
|
|
||||||
|
newZipFile, err := os.Create(zipPath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newZip := zip.NewWriter(newZipFile)
|
||||||
|
|
||||||
|
for chapterPageIndex := range chap.pages {
|
||||||
|
chapterFile := chap.pages[chapterPageIndex]
|
||||||
|
|
||||||
|
epubFileIndex := slices.IndexFunc(epub.File, func(f *zip.File) bool {
|
||||||
|
fParts := strings.Split(f.Name, "/")
|
||||||
|
cParts := strings.Split(chapterFile, "/")
|
||||||
|
return fParts[len(fParts)-1] == cParts[len(cParts)-1]
|
||||||
|
})
|
||||||
|
|
||||||
|
epubFile := epub.File[epubFileIndex]
|
||||||
|
|
||||||
|
doc := etree.NewDocument()
|
||||||
|
reader, err := epubFile.Open()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := doc.ReadFrom(reader); err != nil {
|
||||||
|
_ = reader.Close()
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
imageFilePath := doc.FindElement("//html/body/svg/image").SelectAttr("href").Value
|
||||||
|
_ = reader.Close()
|
||||||
|
|
||||||
|
if imageFilePath[2:] == ".." {
|
||||||
|
fParts := strings.Split(epubFile.Name, "/")
|
||||||
|
imageFilePath = fParts[len(fParts)-2] + imageFilePath[2:len(imageFilePath)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
iParts := strings.Split(imageFilePath, "/")
|
||||||
|
imageFileIndex := slices.IndexFunc(epub.File, func(f *zip.File) bool {
|
||||||
|
fParts := strings.Split(f.Name, "/")
|
||||||
|
return fParts[len(fParts)-1] == iParts[len(iParts)-1]
|
||||||
|
})
|
||||||
|
|
||||||
|
imageFile := epub.File[imageFileIndex]
|
||||||
|
fileName := fmt.Sprintf("%020s", chapterPageIndex+1) + "." + strings.Split(iParts[len(iParts)-1], ".")[1]
|
||||||
|
|
||||||
|
err = addFileToZip(newZip, imageFile, fileName)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comicInfo, err := GenerateChapterMetadata(volume, serie, len(chap.pages), language)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = addBytesToZip(newZip, comicInfo, comicInfoName)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
epub.Close()
|
||||||
|
newZip.Close()
|
||||||
|
newZipFile.Close()
|
||||||
|
os.Remove(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "novel":
|
case "novel":
|
||||||
|
@ -416,65 +536,193 @@ func DownloadAndProcessEpub(jnovel jnc.Api, serie jnc.SerieAugmented, volume jnc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateChapterMetadata(volume jnc.VolumeAugmented, serie jnc.SerieAugmented, pageCount int, language string) ([]byte, error) {
|
||||||
|
comicInfo := ComicInfo{
|
||||||
|
XMLName: "ComicInfo",
|
||||||
|
XMLNS: "http://www.w3.org/2001/XMLSchema-instance",
|
||||||
|
XSI: "ComicInfo.xsd",
|
||||||
|
}
|
||||||
|
|
||||||
|
vInfo := volume.Info
|
||||||
|
sInfo := serie.Info
|
||||||
|
|
||||||
|
comicInfo.Series = sInfo.Title
|
||||||
|
comicInfo.Number = vInfo.Number
|
||||||
|
|
||||||
|
comicInfo.Count = -1 // TODO somehow fetch actual completion status
|
||||||
|
|
||||||
|
comicInfo.Summary = vInfo.Description
|
||||||
|
|
||||||
|
publishingTime, err := time.Parse(time.RFC3339, vInfo.Publishing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
comicInfo.Year = publishingTime.Year()
|
||||||
|
comicInfo.Month = int(publishingTime.Month())
|
||||||
|
comicInfo.Day = publishingTime.Day()
|
||||||
|
|
||||||
|
if vInfo.Creators.Contains("AUTHOR") {
|
||||||
|
comicInfo.Writer = vInfo.Creators.Get("AUTHOR").Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if vInfo.Creators.Contains("ILLUSTRATOR") {
|
||||||
|
comicInfo.Letterer = vInfo.Creators.Get("ILLUSTRATOR").Name
|
||||||
|
comicInfo.CoverArtist = vInfo.Creators.Get("ILLUSTRATOR").Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if vInfo.Creators.Contains("TRANSLATOR") {
|
||||||
|
comicInfo.Translator = vInfo.Creators.Get("TRANSLATOR").Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if vInfo.Creators.Contains("EDITOR") {
|
||||||
|
comicInfo.Editor = vInfo.Creators.Get("EDITOR").Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if vInfo.Creators.Contains("PUBLISHER") {
|
||||||
|
comicInfo.Publisher = vInfo.Creators.Get("PUBLISHER").Name
|
||||||
|
}
|
||||||
|
|
||||||
|
comicInfo.Tags = strings.Join(sInfo.Tags, ",")
|
||||||
|
comicInfo.PageCount = pageCount
|
||||||
|
comicInfo.Language = language
|
||||||
|
comicInfo.Format = "Comic" // JNC reports this as type in the epub file
|
||||||
|
|
||||||
|
return xml.Marshal(comicInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComicInfo struct {
|
||||||
|
XMLName string `xml:"ComicInfo"`
|
||||||
|
XMLNS string `xml:"xmlns,attr"`
|
||||||
|
XSI string `xml:"xsi,attr"`
|
||||||
|
Series string `xml:"Series"`
|
||||||
|
Number int `xml:"Number"`
|
||||||
|
Count int `xml:"Count"`
|
||||||
|
Summary string `xml:"Summary"`
|
||||||
|
Year int `xml:"Year"`
|
||||||
|
Month int `xml:"Month"`
|
||||||
|
Day int `xml:"Day"`
|
||||||
|
Writer string `xml:"Writer"`
|
||||||
|
Letterer string `xml:"Letterer"`
|
||||||
|
CoverArtist string `xml:"CoverArtist"`
|
||||||
|
Editor string `xml:"Editor"`
|
||||||
|
Translator string `xml:"Translator"`
|
||||||
|
Publisher string `xml:"Publisher"`
|
||||||
|
Tags string `xml:"Tags"`
|
||||||
|
PageCount int `xml:"PageCount"`
|
||||||
|
Language string `xml:"LanguageISO"`
|
||||||
|
Format string `xml:"Format"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func addBytesToZip(zipWriter *zip.Writer, fileBytes []byte, filename string) error {
|
||||||
|
reader := bytes.NewReader(fileBytes)
|
||||||
|
|
||||||
|
w, err := zipWriter.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := io.Copy(w, reader); err != nil {
|
||||||
|
return error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addFileToZip(zipWriter *zip.Writer, file *zip.File, filename string) error {
|
||||||
|
fileToZip, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
return error(err)
|
||||||
|
}
|
||||||
|
defer fileToZip.Close()
|
||||||
|
|
||||||
|
w, err := zipWriter.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := io.Copy(w, fileToZip); err != nil {
|
||||||
|
return error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PrepareVolumeDirectory(directory string) {
|
||||||
|
_, err := os.Stat(directory)
|
||||||
|
if err != nil {
|
||||||
|
err = os.Mkdir(directory, 0755)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func FinalizeChapters(chapters *list.List, pageList []*etree.Element) *list.List {
|
func FinalizeChapters(chapters *list.List, pageList []*etree.Element) *list.List {
|
||||||
fmt.Println("Finalizing Chapters")
|
fmt.Println("Finalizing Chapters")
|
||||||
|
|
||||||
lastPage := pageList[len(pageList)-1].SelectAttr("src").Value
|
|
||||||
|
|
||||||
sortedChapters := list.New()
|
sortedChapters := list.New()
|
||||||
|
|
||||||
|
var mainChapter Chapter
|
||||||
|
|
||||||
for ch := chapters.Back(); ch != nil; ch = ch.Prev() {
|
for ch := chapters.Back(); ch != nil; ch = ch.Prev() {
|
||||||
var newChapterData Chapter
|
|
||||||
currentChapter := ch.Value.(Chapter)
|
currentChapter := ch.Value.(Chapter)
|
||||||
|
|
||||||
if currentChapter.numberMain != -1 {
|
if currentChapter.numberMain != -1 {
|
||||||
newChapterData.title = currentChapter.title
|
// pages
|
||||||
newChapterData.firstPage = currentChapter.firstPage
|
if currentChapter.numberSub != 0 {
|
||||||
|
numberMain, numberSub := AnalyzeMainChapter(ch)
|
||||||
|
currentChapter.numberMain = numberMain
|
||||||
|
currentChapter.numberSub = numberSub
|
||||||
|
currentChapter.chDisplay = strconv.FormatInt(int64(currentChapter.numberMain), 10) + "." + strconv.FormatInt(int64(currentChapter.numberSub), 10)
|
||||||
} else {
|
} else {
|
||||||
mainChapter := GetLastValidChapterNumber(ch)
|
currentChapter.chDisplay = strconv.FormatInt(int64(currentChapter.numberMain), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentChapter.lastPage = pageList[len(pageList)-1].SelectAttr("src").Value
|
||||||
|
collecting := false
|
||||||
|
for p := range pageList {
|
||||||
|
page := pageList[p].SelectAttr("src").Value
|
||||||
|
if page == currentChapter.firstPage {
|
||||||
|
collecting = true
|
||||||
|
currentChapter.pages = append(currentChapter.pages, page)
|
||||||
|
} else if ch.Next() != nil && page == ch.Next().Value.(Chapter).firstPage {
|
||||||
|
currentChapter.lastPage = pageList[p-1].SelectAttr("src").Value
|
||||||
|
collecting = false
|
||||||
|
} else if collecting {
|
||||||
|
currentChapter.pages = append(currentChapter.pages, page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortedChapters.PushFront(currentChapter)
|
||||||
|
} else {
|
||||||
|
mainChapter = GetLastValidChapterNumber(ch)
|
||||||
|
|
||||||
for sch := sortedChapters.Front(); sch != nil; sch = sch.Next() {
|
for sch := sortedChapters.Front(); sch != nil; sch = sch.Next() {
|
||||||
if sch.Value.(Chapter).title == mainChapter.title {
|
if sch.Value.(Chapter).title == mainChapter.title {
|
||||||
newChapterData = sch.Value.(Chapter)
|
mainChapterData := sch.Value.(Chapter)
|
||||||
newChapterData.firstPage = currentChapter.firstPage
|
mainChapterData.firstPage = currentChapter.firstPage
|
||||||
sch.Value = newChapterData
|
|
||||||
|
collecting := false
|
||||||
|
pages := []string{}
|
||||||
|
for p := range pageList {
|
||||||
|
page := pageList[p].SelectAttr("src").Value
|
||||||
|
if page == currentChapter.firstPage {
|
||||||
|
collecting = true
|
||||||
|
pages = append(pages, page)
|
||||||
|
} else if ch.Next() != nil && page == ch.Next().Value.(Chapter).firstPage {
|
||||||
|
currentChapter.lastPage = pageList[p-1].SelectAttr("src").Value
|
||||||
|
collecting = false
|
||||||
|
} else if collecting {
|
||||||
|
pages = append(pages, page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mainChapterData.pages = append(pages, mainChapterData.pages...)
|
||||||
|
sch.Value = mainChapterData
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if currentChapter.numberSub != 0 {
|
|
||||||
numberMain, numberSub := AnalyzeMainChapter(ch)
|
|
||||||
|
|
||||||
newChapterData.numberMain = numberMain
|
|
||||||
newChapterData.numberSub = numberSub
|
|
||||||
} else {
|
|
||||||
newChapterData.numberMain = currentChapter.numberMain
|
|
||||||
newChapterData.numberSub = currentChapter.numberSub
|
|
||||||
}
|
|
||||||
|
|
||||||
if ch.Next() == nil {
|
|
||||||
newChapterData.lastPage = lastPage
|
|
||||||
} else {
|
|
||||||
var lastChapterPage string
|
|
||||||
for p := range pageList {
|
|
||||||
page := pageList[p]
|
|
||||||
if page.SelectAttr("src").Value == ch.Next().Value.(Chapter).firstPage {
|
|
||||||
lastChapterPage = pageList[p-1].SelectAttr("src").Value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newChapterData.lastPage = lastChapterPage
|
|
||||||
}
|
|
||||||
|
|
||||||
if newChapterData.numberSub != 0 {
|
|
||||||
newChapterData.chDisplay = strconv.FormatInt(int64(newChapterData.numberMain), 10) + "." + strconv.FormatInt(int64(newChapterData.numberSub), 10)
|
|
||||||
} else {
|
|
||||||
newChapterData.chDisplay = strconv.FormatInt(int64(newChapterData.numberMain), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
sortedChapters.PushFront(newChapterData)
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortedChapters
|
return sortedChapters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,7 +811,7 @@ func GenerateMangaChapterList(navigation FileWrapper) *list.List {
|
||||||
label := navChapter.FindElement("./navLabel/text").Text()
|
label := navChapter.FindElement("./navLabel/text").Text()
|
||||||
page := navChapter.FindElement("./content")
|
page := navChapter.FindElement("./content")
|
||||||
|
|
||||||
regex := "Chapter ([0-9]*)"
|
regex := "(?:Chapter|Episode) ([0-9]*)"
|
||||||
match, _ := regexp.MatchString(regex, label)
|
match, _ := regexp.MatchString(regex, label)
|
||||||
|
|
||||||
if match {
|
if match {
|
||||||
|
@ -587,6 +835,7 @@ func GenerateMangaChapterList(navigation FileWrapper) *list.List {
|
||||||
title: label,
|
title: label,
|
||||||
firstPage: page.SelectAttr("src").Value,
|
firstPage: page.SelectAttr("src").Value,
|
||||||
lastPage: "",
|
lastPage: "",
|
||||||
|
pages: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
chapters.PushBack(chapterData)
|
chapters.PushBack(chapterData)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue