diff options
| author | Julian Hurst <ark@mansus.space> | 2025-04-14 01:49:03 +0200 |
|---|---|---|
| committer | Julian Hurst <ark@mansus.space> | 2025-04-14 01:49:03 +0200 |
| commit | 6b57b3f77cec3165ef2224b4345b2c23dbb89684 (patch) | |
| tree | 1f246c73fb9e0ab50d6252074260c8f6aca2be36 /main.go | |
| download | grimg-master.tar.gz | |
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 234 |
1 files changed, 234 insertions, 0 deletions
@@ -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)) +} |
