summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorJulian Hurst <ark@mansus.space>2025-04-14 01:49:03 +0200
committerJulian Hurst <ark@mansus.space>2025-04-14 01:49:03 +0200
commit6b57b3f77cec3165ef2224b4345b2c23dbb89684 (patch)
tree1f246c73fb9e0ab50d6252074260c8f6aca2be36 /main.go
downloadgrimg-6b57b3f77cec3165ef2224b4345b2c23dbb89684.tar.gz
Initial commitHEADmaster
Diffstat (limited to 'main.go')
-rw-r--r--main.go234
1 files changed, 234 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..abc64e0
--- /dev/null
+++ b/main.go
@@ -0,0 +1,234 @@
+package main
+
+import (
+ "net/http"
+ "log"
+ "embed"
+ "html/template"
+ "os"
+ "io/fs"
+ "strconv"
+ "path/filepath"
+ "sync"
+)
+
+//go:embed templates
+var tmplFS embed.FS
+
+type img struct {
+ Path string
+ Name string
+}
+
+var imgs map[string][]img = make(map[string][]img)
+
+var lock sync.RWMutex
+
+func serve(w http.ResponseWriter, data interface{}, funcMap template.FuncMap, views ...string) {
+ aviews := []string{"templates/base.html"}
+ aviews = append(aviews, views...)
+ t, err := template.New("base.html").Funcs(funcMap).ParseFS(tmplFS, aviews...)
+ if err != nil {
+ log.Fatal(err)
+ }
+ if err := t.Execute(w, data); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func index(w http.ResponseWriter, r *http.Request) {
+ q := r.URL.Query()
+ meltee := q.Get("meltee")
+ char := q.Get("char")
+ set := q.Get("set")
+
+ if meltee == "" || char == "" || set == "" {
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ fillimgs(meltee, char, set)
+
+ start := 0
+ end := min(start + 10, len(imgs))
+ funcMap := template.FuncMap {
+ "isLast": func(i int, imgs []img) bool {
+ return i == len(imgs) - 1
+ },
+ }
+ p := filepath.Join(meltee, char, set)
+ lock.RLock()
+ defer lock.RUnlock()
+ serve(w, struct {
+ Page int
+ Meltee string
+ Char string
+ Set string
+ Imgs []img
+ IsLastPage bool
+ }{
+ 1,
+ meltee,
+ char,
+ set,
+ imgs[p][start:end],
+ end == len(imgs[p]),
+ }, funcMap, "templates/index.html", "templates/img.html")
+}
+
+
+func getimgs(w http.ResponseWriter, r *http.Request) {
+ lock.RLock()
+ defer lock.RUnlock()
+ q := r.URL.Query()
+ page := q.Get("page")
+ meltee := q.Get("meltee")
+ char := q.Get("char")
+ set := q.Get("set")
+
+ if meltee == "" || char == "" || set == "" {
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ p := filepath.Join(meltee, char, set)
+
+ ipage, err := strconv.Atoi(page)
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ start := ipage * 10
+ end := min(start + 10, len(imgs[p]))
+
+ if start < 0 || end > len(imgs[p]) {
+ log.Println(start, end, len(imgs[p]))
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ funcMap := template.FuncMap {
+ "isLast": func(i int, imgs []img) bool {
+ return i == len(imgs) - 1
+ },
+ }
+
+ t, err := template.New("imgs_stub.html").Funcs(funcMap).ParseFS(tmplFS, "templates/imgs_stub.html", "templates/img.html")
+ if err != nil {
+ log.Fatal(err)
+ }
+ info := struct {
+ Page int
+ Meltee string
+ Char string
+ Set string
+ Imgs []img
+ IsLastPage bool
+ }{
+ ipage + 1,
+ meltee,
+ char,
+ set,
+ imgs[p][start:end],
+ end == len(imgs[p]),
+ }
+ if err := t.Execute(w, info); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func meltees(w http.ResponseWriter, r *http.Request) {
+ files, err := os.ReadDir("static/imgs")
+ if err != nil {
+ log.Fatal(err)
+ }
+ serve(w, files, nil, "templates/meltees.html")
+}
+
+func chars(w http.ResponseWriter, r *http.Request) {
+ q := r.URL.Query()
+ meltee := q.Get("meltee")
+ if meltee == "" {
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ files, err := os.ReadDir(filepath.Join("static/imgs", meltee))
+ if err != nil {
+ log.Fatal(err)
+ }
+ serve(w, struct {
+ Items []fs.DirEntry
+ Meltee string
+ }{
+ files,
+ meltee,
+ }, nil, "templates/chars.html")
+}
+
+func sets(w http.ResponseWriter, r *http.Request) {
+ q := r.URL.Query()
+ meltee := q.Get("meltee")
+ char := q.Get("char")
+ if meltee == "" || char == "" {
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ p := filepath.Join("static/imgs", meltee, char)
+ files, err := os.ReadDir(p)
+ if err != nil {
+ log.Fatal(err)
+ }
+ serve(w, struct {
+ Items []fs.DirEntry
+ Meltee string
+ Char string
+ }{
+ files,
+ meltee,
+ char,
+ }, nil, "templates/sets.html")
+}
+
+func fillimgs(meltee string, char string, set string) {
+ lock.Lock()
+ defer lock.Unlock()
+ pa := filepath.Join(meltee, char, set)
+ _, ok := imgs[pa]
+ if ok {
+ return
+ }
+ imgs[pa] = nil
+ d := os.DirFS(".")
+ p := filepath.Join("static/imgs", meltee, char, set)
+ fs.WalkDir(d, p, func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ log.Fatal(err)
+ }
+ info, err := d.Info()
+ if err != nil {
+ log.Fatal(err)
+ }
+ if info.IsDir() {
+ return nil
+ }
+ imgs[pa] = append(imgs[pa], img {
+ path,
+ d.Name(),
+ })
+ return nil
+ })
+ log.Println(imgs)
+}
+
+func main() {
+ mux := http.NewServeMux()
+
+ mux.HandleFunc("/", meltees)
+ mux.HandleFunc("/imgs", getimgs)
+ mux.HandleFunc("/chars", chars)
+ mux.HandleFunc("/chars/sets", sets)
+ mux.HandleFunc("/chars/sets/imgs", index)
+
+ mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
+ log.Println("listening on 8080")
+ log.Fatal(http.ListenAndServe(":8080", mux))
+}