Added Last Chapter functionality to see how many more chapters you have, also kinda works as update Status bar

changed it to only load latest chapter instead of all chapters for manga
Added develop and release db from different locations
Added stopwatch for future performance improvement metrics
This commit is contained in:
Pablu23
2024-03-01 14:31:38 +01:00
parent 87ec7aa1a8
commit a8ba8728dc
9 changed files with 147 additions and 58 deletions

View File

@@ -0,0 +1,7 @@
//go:build Develop
package main
func getDbPath() string {
return "db.sqlite"
}

View File

@@ -9,44 +9,15 @@ import (
"os" "os"
"os/exec" "os/exec"
"os/signal" "os/signal"
"path/filepath"
"runtime" "runtime"
"time" "time"
) )
func main() { func main() {
dir, err := os.UserCacheDir() filePath := getDbPath()
if err != nil {
fmt.Println(nil)
return
}
dirPath := filepath.Join(dir, "MangaGetter")
filePath := filepath.Join(dirPath, "db.sqlite")
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
err = os.Mkdir(dirPath, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
}
if _, err := os.Stat(filePath); os.IsNotExist(err) {
f, err := os.Create(filePath)
if err != nil {
fmt.Println(err)
return
}
err = f.Close()
if err != nil {
fmt.Println(err)
return
}
}
db := database.NewDatabase(filePath, true) db := database.NewDatabase(filePath, true)
err = db.Open() err := db.Open()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return return

View File

@@ -0,0 +1,38 @@
//go:build !Develop
package main
import (
"os"
"path/filepath"
)
func getDbPath() string {
dir, err := os.UserCacheDir()
if err != nil {
panic(err)
}
dirPath := filepath.Join(dir, "MangaGetter")
filePath := filepath.Join(dirPath, "db.sqlite")
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
err = os.Mkdir(dirPath, os.ModePerm)
if err != nil {
panic(err)
}
}
if _, err := os.Stat(filePath); os.IsNotExist(err) {
f, err := os.Create(filePath)
if err != nil {
panic(err)
}
err = f.Close()
if err != nil {
panic(err)
}
}
return filePath
}

View File

@@ -195,28 +195,15 @@ func (dbMgr *Manager) load() error {
return err return err
} }
manga.Thumbnail = bytes.NewBuffer(thumbnail) manga.Thumbnail = bytes.NewBuffer(thumbnail)
latestChapter := db.QueryRow("SELECT Id, Url, Name, Number, TimeStampUnixEpoch FROM Chapter where MangaID = ? ORDER BY TimeStampUnixEpoch desc LIMIT 1", manga.Id)
chapter := Chapter{}
if err = latestChapter.Scan(&chapter.Id, &chapter.Url, &chapter.Name, &chapter.Number, &chapter.TimeStampUnix); err != nil {
return err
}
dbMgr.Chapters[chapter.Id] = &chapter
manga.LatestChapter = &chapter
dbMgr.Mangas[manga.Id] = &manga dbMgr.Mangas[manga.Id] = &manga
} }
rows, err = db.Query("SELECT * FROM Chapter")
if err != nil {
return err
}
for rows.Next() {
chapter := Chapter{}
var mangaID int
if err = rows.Scan(&chapter.Id, &mangaID, &chapter.Url, &chapter.Name, &chapter.Number, &chapter.TimeStampUnix); err != nil {
return err
}
chapter.Manga = dbMgr.Mangas[mangaID]
if dbMgr.Mangas[mangaID].LatestChapter == nil || dbMgr.Mangas[mangaID].LatestChapter.TimeStampUnix < chapter.TimeStampUnix {
dbMgr.Mangas[mangaID].LatestChapter = &chapter
}
dbMgr.Chapters[chapter.Id] = &chapter
}
return nil return nil
} }

View File

@@ -109,9 +109,24 @@ func (b *Bato) GetTitleIdAndChapterId(url string) (titleId int, chapterId int, e
return t, c, err return t, c, err
} }
//func (b *Bato) GetChapterList(url string) (chapterIds []int, err error) { func (b *Bato) GetChapterList(subUrl string) (subUrls []string, err error) {
// reg, err := regexp.Compile(`<div class="space-x-1">.*?<a href="(.*?)" .*?>Chapter (\d*)</a>`)
//} if err != nil {
return nil, err
}
html, err := b.GetHtml(subUrl)
if err != nil {
return nil, err
}
subUrls = make([]string, 0)
matches := reg.FindAllStringSubmatch(html, -1)
for _, match := range matches {
subUrls = append(subUrls, match[1])
}
return subUrls, nil
}
func (b *Bato) GetThumbnail(subUrl string) (thumbnailUrl string, err error) { func (b *Bato) GetThumbnail(subUrl string) (thumbnailUrl string, err error) {
url := fmt.Sprintf("https://bato.to/title/%s", subUrl) url := fmt.Sprintf("https://bato.to/title/%s", subUrl)

View File

@@ -8,4 +8,5 @@ type Provider interface {
GetTitleAndChapter(url string) (title string, chapter string, err error) GetTitleAndChapter(url string) (title string, chapter string, err error)
GetTitleIdAndChapterId(url string) (titleId int, chapterId int, err error) GetTitleIdAndChapterId(url string) (titleId int, chapterId int, err error)
GetThumbnail(mangaId string) (thumbnailUrl string, err error) GetThumbnail(mangaId string) (thumbnailUrl string, err error)
GetChapterList(url string) (urls []string, err error)
} }

View File

@@ -52,19 +52,56 @@ func (s *Server) HandleMenu(w http.ResponseWriter, _ *http.Request) {
mangaViewModels := make([]view.MangaViewModel, l) mangaViewModels := make([]view.MangaViewModel, l)
counter := 0 counter := 0
n := time.Now().UnixNano()
var thumbNs int64 = 0
var titNs int64 = 0
//TODO: Change all this to be more performant
for _, manga := range all { for _, manga := range all {
title := cases.Title(language.English, cases.Compact).String(strings.Replace(manga.Title, "-", " ", -1)) title := cases.Title(language.English, cases.Compact).String(strings.Replace(manga.Title, "-", " ", -1))
t1 := time.Now().UnixNano()
thumbnail, err := s.LoadThumbnail(manga.Id) thumbnail, err := s.LoadThumbnail(manga.Id)
//TODO: Add default picture instead of not showing Manga at all
if err != nil { if err != nil {
continue continue
} }
manga.Thumbnail = s.ImageBuffers[thumbnail] manga.Thumbnail = s.ImageBuffers[thumbnail]
t2 := time.Now().UnixNano()
thumbNs += t2 - t1
t1 = time.Now().UnixNano()
// This is very slow
l, err := s.Provider.GetChapterList("/title/" + strconv.Itoa(manga.Id))
if err != nil {
continue
}
le := len(l)
_, c, err := s.Provider.GetTitleAndChapter(l[le-1])
if err != nil {
continue
}
chapterNumberStr := strings.Replace(c, "ch_", "", 1)
i, err := strconv.Atoi(chapterNumberStr)
if err != nil {
continue
}
t2 = time.Now().UnixNano()
titNs += t2 - t1
mangaViewModels[counter] = view.MangaViewModel{ mangaViewModels[counter] = view.MangaViewModel{
ID: manga.Id, ID: manga.Id,
Title: title, Title: title,
Number: manga.LatestChapter.Number, Number: manga.LatestChapter.Number,
LastNumber: i,
// I Hate this time Format... 15 = hh, 04 = mm, 02 = DD, 01 = MM, 06 == YY // I Hate this time Format... 15 = hh, 04 = mm, 02 = DD, 01 = MM, 06 == YY
LastTime: time.Unix(manga.TimeStampUnix, 0).Format("15:04 (02-01-06)"), LastTime: time.Unix(manga.TimeStampUnix, 0).Format("15:04 (02-01-06)"),
Url: manga.LatestChapter.Url, Url: manga.LatestChapter.Url,
@@ -73,10 +110,21 @@ func (s *Server) HandleMenu(w http.ResponseWriter, _ *http.Request) {
counter++ counter++
} }
fmt.Printf("Loading Thumbnails took %d ms\n", (thumbNs)/1000000)
fmt.Printf("Loading latest Chapter took %d ms\n", (titNs)/1000000)
nex := time.Now().UnixNano()
fmt.Printf("Creating Viewmodels took %d ms\n", (nex-n)/1000000)
n = time.Now().UnixNano()
slices.SortStableFunc(mangaViewModels, func(a, b view.MangaViewModel) int { slices.SortStableFunc(mangaViewModels, func(a, b view.MangaViewModel) int {
return cmp.Compare(a.Title, b.Title) return cmp.Compare(a.Title, b.Title)
}) })
nex = time.Now().UnixNano()
fmt.Printf("Sorting took %d ms\n", (nex-n)/1000000)
menuViewModel := view.MenuViewModel{ menuViewModel := view.MenuViewModel{
Mangas: mangaViewModels, Mangas: mangaViewModels,
} }
@@ -117,7 +165,31 @@ func (s *Server) HandleExit(w http.ResponseWriter, r *http.Request) {
return return
} }
fmt.Println("Cleaned out of scope Last")
http.Redirect(w, r, "/", http.StatusTemporaryRedirect) http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
go func() {
s.Mutex.Lock()
if s.PrevViewModel != nil {
for _, img := range s.PrevViewModel.Images {
delete(s.ImageBuffers, img.Path)
}
}
if s.CurrViewModel != nil {
for _, img := range s.CurrViewModel.Images {
delete(s.ImageBuffers, img.Path)
}
}
if s.NextViewModel != nil {
for _, img := range s.NextViewModel.Images {
delete(s.ImageBuffers, img.Path)
}
}
s.Mutex.Unlock()
}()
} }
func (s *Server) HandleCurrent(w http.ResponseWriter, _ *http.Request) { func (s *Server) HandleCurrent(w http.ResponseWriter, _ *http.Request) {
@@ -279,9 +351,6 @@ func (s *Server) HandleNewQuery(w http.ResponseWriter, r *http.Request) {
url := fmt.Sprintf("/title/%s", sub) url := fmt.Sprintf("/title/%s", sub)
s.Mutex.Lock()
s.ImageBuffers = make(map[string]*bytes.Buffer)
s.Mutex.Unlock()
s.CurrSubUrl = url s.CurrSubUrl = url
s.PrevSubUrl = "" s.PrevSubUrl = ""
s.NextSubUrl = "" s.NextSubUrl = ""

View File

@@ -138,7 +138,7 @@
</a> </a>
</td> </td>
<td class="table-left">{{.Title}}</td> <td class="table-left">{{.Title}}</td>
<td>{{.Number}}</td> <td>{{.Number}} / {{.LastNumber}}</td>
<td>{{.LastTime}}</td> <td>{{.LastTime}}</td>
<td> <td>
<a href="/new/{{.Url}}}"> <a href="/new/{{.Url}}}">

View File

@@ -14,6 +14,7 @@ type MangaViewModel struct {
ID int ID int
Title string Title string
Number int Number int
LastNumber int
LastTime string LastTime string
Url string Url string
ThumbnailUrl string ThumbnailUrl string