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:
@@ -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()
|
||||||
|
|||||||
@@ -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
BIN
internal/server/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user