diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/main.go b/main.go index 656b816..4fa807b 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,34 @@ +// Server entry point +// Copyright (C) 2022 Nguyễn Gia Phong +// +// This file is part of Phylactery. +// +// Phylactery is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Phylactery is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with Phylactery. If not, see <https://www.gnu.org/licenses/>. + package main import ( + "archive/zip" "embed" "html/template" "log" + "io" "net/http" "os" + "path" + "strconv" + "strings" ) //go:embed static/* @@ -14,14 +37,70 @@ var static embed.FS //go:embed templates/*.html var templates embed.FS +type Page struct { + Index int + Name string +} + +type Archive struct { + Path string + Title string + Entries []Page +} + func main() { http.Handle("/static/", http.FileServer(http.FS(static))) t, err := template.ParseFS(templates, "templates/*.html") if err != nil { log.Fatal(err) } + lib := os.Getenv("PHYLACTERY_LIBRARY") http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - t.ExecuteTemplate(w, "index.html", "Phylactery") + p := path.Clean(lib + r.URL.Path) + stat, err := os.Stat(p) + if err != nil { + http.NotFound(w, r) + return + } + + if stat.IsDir() { + // TODO + } + + // TODO: LRU caching + cbz, err := zip.OpenReader(p) + if err != nil { + http.Error(w, "invalid cbz", 406) + return + } + defer cbz.Close() + + r.ParseForm() + if entry, isImage := r.Form["entry"]; isImage { + i, err := strconv.Atoi(entry[0]) + if err != nil || i < 0 || i >= len(cbz.File) { + http.NotFound(w, r) + return + } + image, _ := cbz.File[i].Open() + defer image.Close() + io.Copy(w, image) + return + } + + var pages []Page + for i, f := range cbz.File { + image, _ := cbz.File[i].Open() + defer image.Close() + buf := make([]byte, 512) + n, _ := image.Read(buf) + mime := http.DetectContentType(buf[:n]) + if strings.HasPrefix(mime, "image/") { + pages = append(pages, Page{ i, f.Name }) + } + } + archive := Archive{ r.URL.Path, stat.Name(), pages } + t.ExecuteTemplate(w, "archive.html", archive) }) addr := os.Getenv("PHYLACTERY_ADDRESS") |