diff --git a/.gitattributes b/.gitattributes index fe2172f..f10d157 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,5 @@ -*.jpg filter=lfs diff=lfs merge=lfs -text *.mp3 filter=lfs diff=lfs merge=lfs -text *.lua filter=lfs diff=lfs merge=lfs -text -*.svg filter=lfs diff=lfs merge=lfs -text -*.png filter=lfs diff=lfs merge=lfs -text *.webp filter=lfs diff=lfs merge=lfs -text *.gif filter=lfs diff=lfs merge=lfs -text *.webm filter=lfs diff=lfs merge=lfs -text @@ -31,7 +28,3 @@ *.odt filter=lfs diff=lfs merge=lfs -text *.docx filter=lfs diff=lfs merge=lfs -text *.apk filter=lfs diff=lfs merge=lfs -text -*.ico filter=lfs diff=lfs merge=lfs -text -*.JXL filter=lfs diff=lfs merge=lfs -text -*.AVIF filter=lfs diff=lfs merge=lfs -text -*.PNG filter=lfs diff=lfs merge=lfs -text diff --git a/Containerfile b/Containerfile index 0e3bbb9..7a3c8c8 100644 --- a/Containerfile +++ b/Containerfile @@ -29,7 +29,7 @@ RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build \ RUN upx --best --ultra-brute bin/main RUN chmod +x bin/main -FROM cgr.dev/chainguard/static:latest +FROM git.jester-designs.com/riomoo/alisterbase:1.0.0 WORKDIR /app diff --git a/Containerfile.build b/Containerfile.build index f9fab6a..7747181 100644 --- a/Containerfile.build +++ b/Containerfile.build @@ -35,12 +35,15 @@ RUN echo "Building Linux binary..." && \ # Build Windows binary RUN echo "Building Windows binary..." && \ + echo 'IDI_ICON1 ICON "./app/gopherbook/static/images/favicon/favicon.ico"' > gopherbook.rc && \ + x86_64-w64-mingw32-windres gopherbook.rc -o ./app/gopherbook/gopherbook.syso && \ CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build \ -a \ -ldflags="-s -w" \ -trimpath \ -o bin/gopherbook-windows.exe ./app/gopherbook && \ - upx --best --ultra-brute bin/gopherbook-windows.exe + upx --best --ultra-brute bin/gopherbook-windows.exe && \ + rm ./app/gopherbook/gopherbook.syso gopherbook.rc # Verify binaries were created RUN ls -lh bin/ && \ diff --git a/Makefile b/Makefile index 11a28fe..797294d 100644 --- a/Makefile +++ b/Makefile @@ -2,4 +2,4 @@ build: go build -o bin/main ./app/gopherbook clean: - rm -rf watch etc library cache + rm -rf watch etc library cache binaries releases diff --git a/README.md b/README.md index 2766fdc..23e0389 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,21 @@ -# Gopherbook – Self-Hosted Comic Library & CBZ/CBT Reader +
+ +Description + +
+ +
+ +## 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 -[![Custom badge](https://img.shields.io/endpoint?style=for-the-badge&url=https%3A%2F%2Fshare.jester-designs.com%2Fview%2Fpil.json)](LICENSE) +[![Custom badge](https://git.jester-designs.com/riomoo/gopherbook/media/branch/main/docs/images/svgs/PIL.svg)](LICENSE) ## Features @@ -56,7 +66,16 @@ Then open http://localhost:8080 in your browser. ```bash git clone https://codeberg.org/riomoo/gopherbook.git cd gopherbook -./scripts-bash/run.sh +./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 ``` Then open http://localhost:12010 in your browser. @@ -186,6 +205,14 @@ 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 7ed7bae..9db9fd1 100644 --- a/app/gopherbook/main.go +++ b/app/gopherbook/main.go @@ -21,6 +21,7 @@ import ( "regexp" "sort" "strings" + "io/fs" "sync" "time" "runtime" @@ -39,6 +40,9 @@ 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"` @@ -135,6 +139,14 @@ 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) @@ -154,6 +166,7 @@ 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 { @@ -1599,7 +1612,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: 70}) + err = jpeg.Encode(out, img, &jpeg.Options{Quality: 85}) img = nil runtime.GC() @@ -1643,7 +1656,7 @@ func handleTags(w http.ResponseWriter, r *http.Request) { } if req.Color == "" { - req.Color = "#1f6feb" + req.Color = "#446B6E" } tagsMutex.Lock() @@ -1832,7 +1845,7 @@ func handleTryKnownPasswords(w http.ResponseWriter, r *http.Request) { tagData.Count++ tags[tag] = tagData } else { - tags[tag] = Tag{Name: tag, Color: "#1f6feb", Count: 1} + tags[tag] = Tag{Name: tag, Color: "#446B6E", Count: 1} } } tagsMutex.Unlock() @@ -1947,7 +1960,7 @@ func handleSetPassword(w http.ResponseWriter, r *http.Request) { tagData.Count++ tags[tag] = tagData } else { - tags[tag] = Tag{Name: tag, Color: "#1f6feb", Count: 1} + tags[tag] = Tag{Name: tag, Color: "#446B6E", Count: 1} } } tagsMutex.Unlock() @@ -2419,7 +2432,7 @@ func processComic(filePath, filename string, modTime time.Time) Comic { tagData.Count++ tags[tag] = tagData } else { - tags[tag] = Tag{Name: tag, Color: "#1f6feb", Count: 1} + tags[tag] = Tag{Name: tag, Color: "#446B6E", Count: 1} } } tagsMutex.Unlock() @@ -2481,7 +2494,7 @@ func loadComicMetadataLazy(comicID string) error { tagData.Count++ tags[tag] = tagData } else { - tags[tag] = Tag{Name: tag, Color: "#1f6feb", Count: 1} + tags[tag] = Tag{Name: tag, Color: "#446B6E", Count: 1} } } tagsMutex.Unlock() diff --git a/app/gopherbook/static/images/favicon/favicon.ico b/app/gopherbook/static/images/favicon/favicon.ico new file mode 100644 index 0000000..415e0c5 Binary files /dev/null and b/app/gopherbook/static/images/favicon/favicon.ico differ diff --git a/app/gopherbook/static/images/pngs/CutePose2.png b/app/gopherbook/static/images/pngs/CutePose2.png new file mode 100644 index 0000000..d4949e3 Binary files /dev/null and b/app/gopherbook/static/images/pngs/CutePose2.png differ diff --git a/app/gopherbook/static/images/pngs/LogoPose2.png b/app/gopherbook/static/images/pngs/LogoPose2.png new file mode 100644 index 0000000..4a96d50 Binary files /dev/null and b/app/gopherbook/static/images/pngs/LogoPose2.png differ diff --git a/app/gopherbook/templates/index.html b/app/gopherbook/templates/index.html index a501978..f2408ce 100644 --- a/app/gopherbook/templates/index.html +++ b/app/gopherbook/templates/index.html @@ -3,6 +3,7 @@ + Gopherbook