Fixed Thumbnail Db Entry not loading, added favicon.ico, added going back to menu, if no more Chapters exist, added auto start of default browser with url, added dark mode to main Menu (doesnt save state), added Constructor for Server

This commit is contained in:
Pablu23
2024-02-26 12:09:00 +01:00
parent 23f96e0ab5
commit 8e6169430e
7 changed files with 149 additions and 27 deletions

View File

@@ -1,34 +1,59 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"net/http"
"os"
"os/signal"
"sync"
"mangaGetter/internal/database" "mangaGetter/internal/database"
"mangaGetter/internal/provider" "mangaGetter/internal/provider"
"mangaGetter/internal/server" "mangaGetter/internal/server"
"net/http"
"os"
"os/exec"
"os/signal"
"path/filepath"
"runtime"
"time"
) )
func main() { func main() {
db := database.NewDatabase("db.sqlite", true) dir, err := os.UserCacheDir()
err := db.Open()
if err != nil { if err != nil {
fmt.Println(nil)
return return
} }
s := server.Server{ dirPath := filepath.Join(dir, "MangaGetter")
ImageBuffers: make(map[string]*bytes.Buffer), filePath := filepath.Join(dirPath, "db.sqlite")
NextReady: make(chan bool),
PrevReady: make(chan bool), if _, err := os.Stat(dirPath); os.IsNotExist(err) {
Provider: &provider.Bato{}, err = os.Mkdir(dirPath, os.ModePerm)
DbMgr: &db, if err != nil {
Mutex: &sync.Mutex{}, 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)
err = db.Open()
if err != nil {
fmt.Println(err)
return
}
s := server.New(&provider.Bato{}, &db)
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt) signal.Notify(c, os.Interrupt)
@@ -48,6 +73,14 @@ func main() {
http.HandleFunc("POST /exit", s.HandleExit) http.HandleFunc("POST /exit", s.HandleExit)
http.HandleFunc("POST /delete", s.HandleDelete) http.HandleFunc("POST /delete", s.HandleDelete)
go func() {
time.Sleep(300 * time.Millisecond)
err := open("http://localhost:8000")
if err != nil {
fmt.Println(err)
}
}()
fmt.Println("Server starting...") fmt.Println("Server starting...")
err = http.ListenAndServe(":8000", nil) err = http.ListenAndServe(":8000", nil)
if err != nil { if err != nil {
@@ -56,6 +89,23 @@ func main() {
} }
} }
func open(url string) error {
var cmd string
var args []string
switch runtime.GOOS {
case "windows":
cmd = "cmd"
args = []string{"/c", "start"}
case "darwin":
cmd = "open"
default: // "linux", "freebsd", "openbsd", "netbsd"
cmd = "xdg-open"
}
args = append(args, url)
return exec.Command(cmd, args...).Start()
}
func Close(db *database.Manager) { func Close(db *database.Manager) {
fmt.Println("Attempting to save and close DB") fmt.Println("Attempting to save and close DB")
err := db.Save() err := db.Save()

View File

@@ -190,9 +190,11 @@ func (dbMgr *Manager) load() error {
for rows.Next() { for rows.Next() {
manga := Manga{} manga := Manga{}
if err = rows.Scan(&manga.Id, &manga.Title, &manga.TimeStampUnix, &manga.Thumbnail); err != nil { var thumbnail []byte
if err = rows.Scan(&manga.Id, &manga.Title, &manga.TimeStampUnix, &thumbnail); err != nil {
return err return err
} }
manga.Thumbnail = bytes.NewBuffer(thumbnail)
dbMgr.Mangas[manga.Id] = &manga dbMgr.Mangas[manga.Id] = &manga
} }

BIN
internal/server/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -212,13 +212,20 @@ func (s *Server) HandleNext(w http.ResponseWriter, r *http.Request) {
}(*s.PrevViewModel, s) }(*s.PrevViewModel, s)
} }
if s.NextViewModel == nil || s.NextSubUrl == "" {
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
err := s.DbMgr.Save()
if err != nil {
fmt.Println(err)
}
return
}
s.PrevViewModel = s.CurrViewModel s.PrevViewModel = s.CurrViewModel
s.CurrViewModel = s.NextViewModel s.CurrViewModel = s.NextViewModel
s.PrevSubUrl = s.CurrSubUrl s.PrevSubUrl = s.CurrSubUrl
s.CurrSubUrl = s.NextSubUrl s.CurrSubUrl = s.NextSubUrl
<-s.NextReady
go s.LoadNext() go s.LoadNext()
http.Redirect(w, r, "/current/", http.StatusTemporaryRedirect) http.Redirect(w, r, "/current/", http.StatusTemporaryRedirect)
@@ -236,13 +243,20 @@ func (s *Server) HandlePrev(w http.ResponseWriter, r *http.Request) {
}(*s.NextViewModel, s) }(*s.NextViewModel, s)
} }
if s.PrevViewModel == nil || s.PrevSubUrl == "" {
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
err := s.DbMgr.Save()
if err != nil {
fmt.Println(err)
}
return
}
s.NextViewModel = s.CurrViewModel s.NextViewModel = s.CurrViewModel
s.CurrViewModel = s.PrevViewModel s.CurrViewModel = s.PrevViewModel
s.NextSubUrl = s.CurrSubUrl s.NextSubUrl = s.CurrSubUrl
s.CurrSubUrl = s.PrevSubUrl s.CurrSubUrl = s.PrevSubUrl
<-s.PrevReady
go s.LoadPrev() go s.LoadPrev()
http.Redirect(w, r, "/current/", http.StatusTemporaryRedirect) http.Redirect(w, r, "/current/", http.StatusTemporaryRedirect)

View File

@@ -2,6 +2,7 @@ package server
import ( import (
"bytes" "bytes"
_ "embed"
"fmt" "fmt"
"io" "io"
"mangaGetter/internal/database" "mangaGetter/internal/database"
@@ -32,35 +33,51 @@ type Server struct {
IsLast bool IsLast bool
DbMgr *database.Manager DbMgr *database.Manager
}
// I'm not even sure if this helps. func New(provider provider.Provider, db *database.Manager) *Server {
// If you press next and then prev too fast you still lock yourself out s := Server{
NextReady chan bool ImageBuffers: make(map[string]*bytes.Buffer),
PrevReady chan bool Provider: provider,
DbMgr: db,
Mutex: &sync.Mutex{},
}
s.AddIco()
return &s
} }
func (s *Server) LoadNext() { func (s *Server) LoadNext() {
c, err := s.Provider.GetHtml(s.CurrSubUrl) c, err := s.Provider.GetHtml(s.CurrSubUrl)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
s.NextSubUrl = ""
s.NextViewModel = nil
return return
} }
next, err := s.Provider.GetNext(c) next, err := s.Provider.GetNext(c)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
s.NextSubUrl = ""
s.NextViewModel = nil
return return
} }
html, err := s.Provider.GetHtml(next) html, err := s.Provider.GetHtml(next)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
s.NextSubUrl = ""
s.NextViewModel = nil
return return
} }
imagesNext, err := s.AppendImagesToBuf(html) imagesNext, err := s.AppendImagesToBuf(html)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
s.NextSubUrl = ""
s.NextViewModel = nil
return return
} }
@@ -73,32 +90,38 @@ func (s *Server) LoadNext() {
full := strings.Replace(title, "-", " ", -1) + " - " + strings.Replace(chapter, "_", " ", -1) full := strings.Replace(title, "-", " ", -1) + " - " + strings.Replace(chapter, "_", " ", -1)
s.NextViewModel = &view.ImageViewModel{Images: imagesNext, Title: full} s.NextViewModel = &view.ImageViewModel{Images: imagesNext, Title: full}
s.NextSubUrl = next s.NextSubUrl = next
fmt.Println("Loaded next") fmt.Println("Loaded next")
s.NextReady <- true
} }
func (s *Server) LoadPrev() { func (s *Server) LoadPrev() {
c, err := s.Provider.GetHtml(s.CurrSubUrl) c, err := s.Provider.GetHtml(s.CurrSubUrl)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
s.PrevSubUrl = ""
s.PrevViewModel = nil
return return
} }
prev, err := s.Provider.GetPrev(c) prev, err := s.Provider.GetPrev(c)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
s.PrevSubUrl = ""
s.PrevViewModel = nil
return return
} }
html, err := s.Provider.GetHtml(prev) html, err := s.Provider.GetHtml(prev)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
s.PrevSubUrl = ""
s.PrevViewModel = nil
return return
} }
imagesNext, err := s.AppendImagesToBuf(html) imagesNext, err := s.AppendImagesToBuf(html)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
s.PrevSubUrl = ""
s.PrevViewModel = nil
return return
} }
@@ -114,7 +137,6 @@ func (s *Server) LoadPrev() {
s.PrevSubUrl = prev s.PrevSubUrl = prev
fmt.Println("Loaded prev") fmt.Println("Loaded prev")
s.PrevReady <- true
} }
func (s *Server) LoadCurr() { func (s *Server) LoadCurr() {
@@ -187,6 +209,16 @@ func (s *Server) AppendImagesToBuf(html string) ([]view.Image, error) {
return images, nil return images, nil
} }
//go:embed favicon.ico
var ico []byte
func (s *Server) AddIco() {
buf := bytes.NewBuffer(ico)
s.Mutex.Lock()
s.ImageBuffers["favicon.ico"] = buf
s.Mutex.Unlock()
}
func addFileToRam(url string) (*bytes.Buffer, error) { func addFileToRam(url string) (*bytes.Buffer, error) {
// Get the data // Get the data
resp, err := http.Get(url) resp, err := http.Get(url)

View File

@@ -3,7 +3,22 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Main Menu</title> <title>Main Menu</title>
<link href="/img/favicon.ico" rel="icon" type="image/x-icon">
<style> <style>
body {
padding: 25px;
background-color: white;
color: black;
font-size: 25px;
}
.dark-mode {
background-color: #171717;
color: white;
}
.button-36 { .button-36 {
background-image: linear-gradient(92.88deg, #455EB5 9.16%, #5643CC 43.89%, #673FD7 64.72%); background-image: linear-gradient(92.88deg, #455EB5 9.16%, #5643CC 43.89%, #673FD7 64.72%);
border-radius: 8px; border-radius: 8px;
@@ -90,6 +105,12 @@
</style> </style>
<script>
function myFunction() {
var element = document.body;
element.classList.toggle("dark-mode");
}
</script>
</head> </head>
<body> <body>
@@ -100,6 +121,7 @@
</label> </label>
<input type="submit" value="Open" class="button-36"> <input type="submit" value="Open" class="button-36">
</form> </form>
<button onclick="myFunction()">Toggle dark mode</button>
<table class="table"> <table class="table">
<tr> <tr>

View File

@@ -4,6 +4,8 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>{{.Title}}</title> <title>{{.Title}}</title>
<link href="/img/favicon.ico" rel="icon" type="image/x-icon">
<style> <style>
body {background-color: #171717} body {background-color: #171717}