summaryrefslogtreecommitdiffstats
path: root/roseh.moe.go
diff options
context:
space:
mode:
Diffstat (limited to 'roseh.moe.go')
-rw-r--r--roseh.moe.go104
1 files changed, 63 insertions, 41 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index 48f93b6..d9a948b 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -30,7 +30,6 @@ import (
"net/http/httputil"
"net/url"
"os"
- "path"
"path/filepath"
"slices"
"strconv"
@@ -922,8 +921,9 @@ var (
)
type metArtIndexTemplateArgsGirl struct {
- URL string
- Name string
+ Name string
+ URL string
+ CoverID int64
}
type metArtIndexTemplateArgs struct {
@@ -947,7 +947,7 @@ func (h *metArtIndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var girls []metArtIndexTemplateArgsGirl
for rows.Next() {
var girl metArtIndexTemplateArgsGirl
- if err := rows.Scan(&girl.Name); err != nil {
+ if err := rows.Scan(&girl.Name, &girl.CoverID); err != nil {
log.Printf("Warning: list girls: %s", err)
http.Error(w, "internal error", http.StatusInternalServerError)
return
@@ -1081,14 +1081,18 @@ func (h *metArtGirlPreviewHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
if !stupidCache(w, r) {
return
}
- name := strings.ReplaceAll(r.PathValue("girl"), "-", " ")
+ id, err := strconv.ParseInt(strings.TrimSuffix(r.PathValue("photo"), ".jpeg"), 10, 64)
+ if err != nil {
+ notFound(w, r)
+ return
+ }
var path, filename string
- if err := h.s.findPreview.QueryRow(name).Scan(&path, &filename); err != nil {
+ if err := h.s.findPhoto.QueryRow(id).Scan(&path, &filename); err != nil {
if err == sql.ErrNoRows {
notFound(w, r)
return
}
- log.Printf("Warning: find preview photo: %s", err)
+ log.Printf("Warning: find photo: %s", err)
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
@@ -1128,7 +1132,6 @@ var (
type metArtSetTemplateArgs struct {
Name string
- URL string
Photos []int64
}
@@ -1140,33 +1143,46 @@ func (h *metArtSetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !stupidCache(w, r) {
return
}
- setID, setName, ok := strings.Cut(r.PathValue("set"), "-")
- if !ok {
- notFound(w, r)
- return
- }
+ setID, _, _ := strings.Cut(r.PathValue("set"), "-")
id, err := strconv.ParseInt(setID, 10, 64)
if err != nil {
notFound(w, r)
return
}
- rows, err := h.s.listPhotosForSet.Query(id)
- if err != nil {
- log.Printf("Warning: list set photos: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
+ wg := new(sync.WaitGroup)
+ var setName string
+ var setErr error
+ wg.Go(func() {
+ setErr = h.s.setName.QueryRow(id).Scan(&setName)
+ })
var photos []int64
- for rows.Next() {
- var photoID int64
- if err := rows.Scan(&photoID); err != nil {
- log.Printf("Warning: list set photos: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
+ var photosErr error
+ wg.Go(func() {
+ rows, err := h.s.listPhotosForSet.Query(id)
+ if err != nil {
+ photosErr = err
+ return
+ }
+ for rows.Next() {
+ var photoID int64
+ if err := rows.Scan(&photoID); err != nil {
+ photosErr = err
+ return
+ }
+ photos = append(photos, photoID)
+ }
+ if err := rows.Err(); err != nil {
+ photosErr = err
return
}
- photos = append(photos, photoID)
+ })
+ wg.Wait()
+ if err := setErr; err != nil {
+ log.Printf("Error: find set name: %s", err)
+ http.Error(w, "internal error", http.StatusInternalServerError)
+ return
}
- if err := rows.Err(); err != nil {
+ if err := photosErr; err != nil {
log.Printf("Warning: list set photos: %s", err)
http.Error(w, "internal error", http.StatusInternalServerError)
return
@@ -1175,7 +1191,7 @@ func (h *metArtSetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
notFound(w, r)
return
}
- if err := metArtSetTemplate.Execute(w, metArtSetTemplateArgs{Name: strings.ReplaceAll(setName, "-", " "), URL: path.Join(r.PathValue("girl"), r.PathValue("set")), Photos: photos}); err != nil {
+ if err := metArtSetTemplate.Execute(w, metArtSetTemplateArgs{Name: setName, Photos: photos}); err != nil {
log.Printf("Warning: mart set: %s", err)
}
}
@@ -1204,7 +1220,6 @@ func (p *jellyfinReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
type stmts struct {
listGirls *sql.Stmt
findPhoto *sql.Stmt
- findPreview *sql.Stmt
girlName *sql.Stmt
listSetsForGirl *sql.Stmt
setName *sql.Stmt
@@ -1214,7 +1229,18 @@ type stmts struct {
func prepareStatements(db *sql.DB) (*stmts, error) {
s := new(stmts)
var err error
- s.listGirls, err = db.Prepare("SELECT name FROM girls ORDER BY substr(name, instr(name, ' ')+1), name")
+ s.listGirls, err = db.Prepare(`
+ SELECT
+ girls.name,
+ (
+ SELECT cover_photo_id
+ FROM sets
+ WHERE sets.girl_id = girls.girl_id
+ ORDER BY date ASC, sets.name ASC LIMIT 1
+ )
+ FROM girls
+ ORDER BY substr(girls.name, instr(girls.name, ' ')+1), girls.name
+ `)
if err != nil {
return nil, err
}
@@ -1222,10 +1248,6 @@ func prepareStatements(db *sql.DB) (*stmts, error) {
if err != nil {
return nil, err
}
- s.findPreview, err = db.Prepare("SELECT path, filename FROM girls JOIN sets USING (girl_id) JOIN photos ON photo_id = cover_photo_id WHERE girls.name = ? ORDER BY date ASC, sets.name ASC LIMIT 1")
- if err != nil {
- return nil, err
- }
s.girlName, err = db.Prepare("SELECT name FROM girls WHERE girl_id = ?")
if err != nil {
return nil, err
@@ -1271,7 +1293,7 @@ func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /{$}", index)
- mux.HandleFunc("GET /games/", gamesIndex)
+ mux.HandleFunc("GET /games/{$}", gamesIndex)
mux.HandleFunc("GET /games/pong", pong)
mux.HandleFunc("GET /games/rms", stallmanShooter)
mux.HandleFunc("GET /qr.png", qrHandler)
@@ -1282,17 +1304,17 @@ func main() {
mux.HandleFunc("POST /login", login)
mux.HandleFunc("GET /notepad", notepad)
mux.HandleFunc("POST /notepad", autosave)
- mux.HandleFunc("GET /cmd/", cmdIndex)
+ mux.HandleFunc("GET /cmd/{$}", cmdIndex)
mux.HandleFunc("GET /cmd/{cmd}", cmd)
- mux.HandleFunc("GET /pkg/", pkgIndex)
+ mux.HandleFunc("GET /pkg/{$}", pkgIndex)
mux.HandleFunc("GET /pkg/{pkg}", pkg)
mux.Handle("GET /code/", http.StripPrefix("/code/", http.FileServer(http.Dir(*codeDir))))
mux.Handle("GET /nezuko/", &nezukoHandler{http.StripPrefix("/nezuko/", http.FileServer(http.Dir(*nezuko)))})
- mux.Handle("GET /mart/", &metArtIndexHandler{stmts})
- mux.Handle("GET /mart/{girl}/", &metArtGirlHandler{stmts})
- mux.Handle("GET /mart/{girl}/preview.jpeg", &metArtGirlPreviewHandler{stmts})
- mux.Handle("GET /mart/{girl}/{set}/", &metArtSetHandler{stmts})
- mux.Handle("GET /mart/{girl}/{set}/{photo}", &metArtPhotoHandler{stmts})
+ mux.Handle("GET /mart/{$}", &metArtIndexHandler{stmts})
+ mux.Handle("GET /mart/{girl}/{$}", &metArtGirlHandler{stmts})
+ mux.Handle("GET /mart/{girl}/{set}", &metArtSetHandler{stmts})
+ mux.Handle("GET /mart/photos/{photo}", &metArtPhotoHandler{stmts})
+ mux.Handle("GET /mart/photos/preview/{photo}", &metArtGirlPreviewHandler{stmts})
mux.HandleFunc("GET /static/", static)
mux.HandleFunc("GET /favicon.ico", favicon)
apiMux := http.NewServeMux()