-
-## Self-Hosted Comic Library & CBZ/CBT Reader
+# Gopherbook – Self-Hosted Comic Library & CBZ/CBT Reader
Gopherbook is a lightweight, single-binary, self-hosted web comic reader and library manager written in Go.
It is designed for people who want full control over their digital comic collection (CBZ/CBT files), including support for password-protected/encrypted archives, per-user libraries, tagging, automatic organization, and a clean modern reader.
-
-
## License
-[](LICENSE)
+[](LICENSE)
## Features
@@ -66,16 +56,7 @@ Then open http://localhost:8080 in your browser.
```bash
git clone https://codeberg.org/riomoo/gopherbook.git
cd gopherbook
-./scripts-bash/run-gb-container/run-podman.sh
-```
-
-or
-
-## If you want to use this with docker:
-```bash
-git clone https://codeberg.org/riomoo/gopherbook.git
-cd gopherbook
-./scripts-bash/run-gb-container/run-docker.sh
+./scripts-bash/run.sh
```
Then open http://localhost:12010 in your browser.
@@ -205,14 +186,6 @@ Pull requests are welcome! Especially:
Please open an issue first for bigger changes.
-## If you'd like to know about the new mascot Vinny
-
-- Check the Wiki!
-- **GitHub**: https://github.com/riomoo/gopherbook/wiki/Meet-Vinny
-- **GitGud**: https://gitgud.io/riomoo/gopherbook/-/wikis/Meet-Vinny
-- **JesterDesigns**: https://git.jester-designs.com/riomoo/gopherbook/wiki/Meet-Vinny
-
-
## Thanks / Credits
- yeka/zip – password-protected ZIP support in pure Go
diff --git a/app/gopherbook/main.go b/app/gopherbook/main.go
index 9db9fd1..7ed7bae 100644
--- a/app/gopherbook/main.go
+++ b/app/gopherbook/main.go
@@ -21,7 +21,6 @@ import (
"regexp"
"sort"
"strings"
- "io/fs"
"sync"
"time"
"runtime"
@@ -40,9 +39,6 @@ import (
//go:embed templates/index.html
var templateFS embed.FS
-//go:embed all:static
-var staticFS embed.FS
-
// ComicInfo represents the standard ComicInfo.xml metadata
type ComicInfo struct {
XMLName xml.Name `xml:"ComicInfo"`
@@ -139,14 +135,6 @@ func main() {
loadUsers()
initWatchFolders()
- // Create static sub-filesystem once
- staticSubFS, err := fs.Sub(staticFS, "static")
- if err != nil {
- log.Fatal(fmt.Errorf("failed to create static sub-filesystem: %w", err))
- }
-
- // Create handlers once and reuse
- staticHandler := http.FileServer(http.FS(staticSubFS))
http.HandleFunc("/api/register", handleRegister)
http.HandleFunc("/api/login", handleLogin)
@@ -166,7 +154,6 @@ func main() {
http.HandleFunc("/api/admin/delete-comic/", authMiddleware(handleDeleteComic))
http.HandleFunc("/api/watch-folder", authMiddleware(handleWatchFolder))
http.HandleFunc("/", serveUI)
- http.Handle("/static/", http.StripPrefix("/static/", staticHandler))
go func() {
for {
@@ -1612,7 +1599,7 @@ func saveJPEG(img image.Image, path string) error {
defer out.Close()
// Lower quality = smaller memory footprint during encoding
- err = jpeg.Encode(out, img, &jpeg.Options{Quality: 85})
+ err = jpeg.Encode(out, img, &jpeg.Options{Quality: 70})
img = nil
runtime.GC()
@@ -1656,7 +1643,7 @@ func handleTags(w http.ResponseWriter, r *http.Request) {
}
if req.Color == "" {
- req.Color = "#446B6E"
+ req.Color = "#1f6feb"
}
tagsMutex.Lock()
@@ -1845,7 +1832,7 @@ func handleTryKnownPasswords(w http.ResponseWriter, r *http.Request) {
tagData.Count++
tags[tag] = tagData
} else {
- tags[tag] = Tag{Name: tag, Color: "#446B6E", Count: 1}
+ tags[tag] = Tag{Name: tag, Color: "#1f6feb", Count: 1}
}
}
tagsMutex.Unlock()
@@ -1960,7 +1947,7 @@ func handleSetPassword(w http.ResponseWriter, r *http.Request) {
tagData.Count++
tags[tag] = tagData
} else {
- tags[tag] = Tag{Name: tag, Color: "#446B6E", Count: 1}
+ tags[tag] = Tag{Name: tag, Color: "#1f6feb", Count: 1}
}
}
tagsMutex.Unlock()
@@ -2432,7 +2419,7 @@ func processComic(filePath, filename string, modTime time.Time) Comic {
tagData.Count++
tags[tag] = tagData
} else {
- tags[tag] = Tag{Name: tag, Color: "#446B6E", Count: 1}
+ tags[tag] = Tag{Name: tag, Color: "#1f6feb", Count: 1}
}
}
tagsMutex.Unlock()
@@ -2494,7 +2481,7 @@ func loadComicMetadataLazy(comicID string) error {
tagData.Count++
tags[tag] = tagData
} else {
- tags[tag] = Tag{Name: tag, Color: "#446B6E", Count: 1}
+ tags[tag] = Tag{Name: tag, Color: "#1f6feb", Count: 1}
}
}
tagsMutex.Unlock()
diff --git a/app/gopherbook/static/images/favicon/favicon.ico b/app/gopherbook/static/images/favicon/favicon.ico
deleted file mode 100644
index 415e0c5..0000000
Binary files a/app/gopherbook/static/images/favicon/favicon.ico and /dev/null differ
diff --git a/app/gopherbook/static/images/pngs/CutePose2.png b/app/gopherbook/static/images/pngs/CutePose2.png
deleted file mode 100644
index d4949e3..0000000
Binary files a/app/gopherbook/static/images/pngs/CutePose2.png and /dev/null differ
diff --git a/app/gopherbook/static/images/pngs/LogoPose2.png b/app/gopherbook/static/images/pngs/LogoPose2.png
deleted file mode 100644
index 4a96d50..0000000
Binary files a/app/gopherbook/static/images/pngs/LogoPose2.png and /dev/null differ
diff --git a/app/gopherbook/templates/index.html b/app/gopherbook/templates/index.html
index f2408ce..a501978 100644
--- a/app/gopherbook/templates/index.html
+++ b/app/gopherbook/templates/index.html
@@ -3,7 +3,6 @@
-
Gopherbook