kennel #13

Merged
simponic merged 4 commits from kennel into main 2024-08-17 18:29:33 -04:00
5 changed files with 100 additions and 52 deletions
Showing only changes of commit 67bf0199e1 - Show all commits

View File

@ -1,9 +1,9 @@
package kennel package kennel
import ( import (
"encoding/json"
"log" "log"
"net/http" "net/http"
"strconv"
"strings" "strings"
"git.hatecomputers.club/hatecomputers/hatecomputers.club/adapters/files" "git.hatecomputers.club/hatecomputers/hatecomputers.club/adapters/files"
@ -151,23 +151,66 @@ func RemoveCatContinuation(fileAdapter files.FilesAdapter, catsPath string) func
} }
} }
func GetCatStateAtContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain { func RingContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain { return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
atLong, err := strconv.ParseInt(req.FormValue("at"), 10, 64) order := req.URL.Query().Get("order")
if order == "random" {
kennelCat, err := database.GetRandomKennelCat(context.DBConn)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
resp.WriteHeader(http.StatusInternalServerError)
return failure(context, req, resp)
}
http.Redirect(resp, req, kennelCat.Link, http.StatusFound)
return success(context, req, resp)
}
id := req.URL.Query().Get("id")
if id == "" {
resp.WriteHeader(http.StatusBadRequest) resp.WriteHeader(http.StatusBadRequest)
return failure(context, req, resp) return failure(context, req, resp)
} }
if order != "random" && order != "next" && order != "prev" {
kennelCat, err := database.GetKennelCat(context.DBConn, id)
if err != nil {
log.Println(err)
resp.WriteHeader(http.StatusNotFound)
return failure(context, req, resp)
}
http.Redirect(resp, req, kennelCat.Link, http.StatusFound)
return success(context, req, resp)
}
cats, err := database.GetKennelStateAt(context.DBConn, atLong) nextCat, err := database.GetNextKennelCat(context.DBConn, id, order == "next")
if err != nil { if err != nil {
log.Println(err) log.Println(err)
resp.WriteHeader(http.StatusInternalServerError) resp.WriteHeader(http.StatusInternalServerError)
return failure(context, req, resp) return failure(context, req, resp)
} }
(*context.TemplateData)["EncodedState"] = cats.EncodedState http.Redirect(resp, req, nextCat.Link, http.StatusFound)
return success(context, req, resp)
}
}
func GetKennelContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
cats, err := database.GetKennel(context.DBConn)
if err != nil {
log.Println(err)
resp.WriteHeader(http.StatusInternalServerError)
return failure(context, req, resp)
}
json, err := json.Marshal(cats)
if err != nil {
log.Println(err)
resp.WriteHeader(http.StatusInternalServerError)
return failure(context, req, resp)
}
resp.Header().Set("Content-Type", "application/json")
resp.Write(json)
return success(context, req, resp) return success(context, req, resp)
} }
} }

View File

@ -173,9 +173,14 @@ func MakeServer(argv *args.Arguments, dbConn *sql.DB) *http.Server {
LogRequestContinuation(requestContext, r, w)(auth.VerifySessionContinuation, FailurePassingContinuation)(hcaptcha.CaptchaVerificationContinuation, hcaptcha.CaptchaVerificationContinuation)(guestbook.SignGuestbookContinuation, FailurePassingContinuation)(guestbook.ListGuestbookContinuation, guestbook.ListGuestbookContinuation)(hcaptcha.CaptchaArgsContinuation, hcaptcha.CaptchaArgsContinuation)(template.TemplateContinuation("guestbook.html", true), template.TemplateContinuation("guestbook.html", true))(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation) LogRequestContinuation(requestContext, r, w)(auth.VerifySessionContinuation, FailurePassingContinuation)(hcaptcha.CaptchaVerificationContinuation, hcaptcha.CaptchaVerificationContinuation)(guestbook.SignGuestbookContinuation, FailurePassingContinuation)(guestbook.ListGuestbookContinuation, guestbook.ListGuestbookContinuation)(hcaptcha.CaptchaArgsContinuation, hcaptcha.CaptchaArgsContinuation)(template.TemplateContinuation("guestbook.html", true), template.TemplateContinuation("guestbook.html", true))(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
}) })
mux.HandleFunc("GET /kennel", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("GET /kennel/", func(w http.ResponseWriter, r *http.Request) {
requestContext := makeRequestContext() requestContext := makeRequestContext()
LogRequestContinuation(requestContext, r, w)(auth.VerifySessionContinuation, FailurePassingContinuation)(kennel.GetCatStateAtContinuation, FailurePassingContinuation)(template.TemplateContinuation("kennel_enc.json", false), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation) LogRequestContinuation(requestContext, r, w)(kennel.GetKennelContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
})
mux.HandleFunc("GET /kennel/cat", func(w http.ResponseWriter, r *http.Request) {
requestContext := makeRequestContext()
LogRequestContinuation(requestContext, r, w)(kennel.RingContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
}) })
mux.HandleFunc("GET /kennel/cats", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("GET /kennel/cats", func(w http.ResponseWriter, r *http.Request) {

View File

@ -93,6 +93,49 @@ func DeleteKennelCat(db *sql.DB, catID string) error {
return nil return nil
} }
func GetRandomKennelCat(dbConn *sql.DB) (*KennelCat, error) {
log.Println("getting random kennel cat")
row := dbConn.QueryRow("SELECT * FROM kennel_cat ORDER BY RANDOM() LIMIT 1")
var cat KennelCat
err := row.Scan(&cat.ID, &cat.Name, &cat.UserID, &cat.Link, &cat.Description, &cat.Spritesheet, &cat.CreatedAt)
if err != nil {
return nil, err
}
return &cat, nil
}
func GetNextKennelCat(dbConn *sql.DB, lastID string, next bool) (*KennelCat, error) {
log.Println("getting next kennel cat")
operation := ">"
sorted := "ASC"
if !next {
operation = "<"
sorted = "DESC"
}
row := dbConn.QueryRow("SELECT * FROM kennel_cat WHERE id "+operation+" ? ORDER BY id "+sorted+" LIMIT 1", lastID)
var cat KennelCat
err := row.Scan(&cat.ID, &cat.Name, &cat.UserID, &cat.Link, &cat.Description, &cat.Spritesheet, &cat.CreatedAt)
if err != nil {
if next {
// loop "back" to the first in the ring
row = dbConn.QueryRow("SELECT * FROM kennel_cat ORDER BY id ASC LIMIT 1")
} else {
// loop "forward" to the first in the ring
row = dbConn.QueryRow("SELECT * FROM kennel_cat ORDER BY id DESC LIMIT 1")
}
err = row.Scan(&cat.ID, &cat.Name, &cat.UserID, &cat.Link, &cat.Description, &cat.Spritesheet, &cat.CreatedAt)
}
if err != nil {
return nil, err
}
return &cat, nil
}
func GetKennel(dbConn *sql.DB) ([]KennelCat, error) { func GetKennel(dbConn *sql.DB) ([]KennelCat, error) {
log.Println("getting kennel") log.Println("getting kennel")
@ -114,37 +157,3 @@ func GetKennel(dbConn *sql.DB) ([]KennelCat, error) {
return cats, nil return cats, nil
} }
func GetLatestKennelState(dbConn *sql.DB) (*KennelState, error) {
log.Println("getting kennel state")
row := dbConn.QueryRow("SELECT * FROM kennel_state ORDER BY at DESC LIMIT 1")
var state KennelState
err := row.Scan(&state.At, &state.EncodedState)
if err != nil {
return nil, err
}
return &state, nil
}
func GetKennelStateAt(dbConn *sql.DB, at int64) (*KennelState, error) {
log.Println("getting kennel state at", at)
row := dbConn.QueryRow("SELECT * FROM kennel_state WHERE at = ?", at)
var state KennelState
err := row.Scan(&state.At, &state.EncodedState)
if err != nil {
return nil, err
}
return &state, nil
}
func SaveKennelState(dbConn *sql.DB, state *KennelState) (*KennelState, error) {
log.Println("saving kennel state")
_, err := dbConn.Exec("INSERT OR REPLACE INTO kennel_state (at, state) VALUES (?, ?)", state.At, state.EncodedState)
if err != nil {
return nil, err
}
return state, nil
}

View File

@ -179,14 +179,6 @@ func MigrateKennel(dbConn *sql.DB) (*sql.DB, error) {
return dbConn, err return dbConn, err
} }
_, err = dbConn.Exec(`CREATE TABLE IF NOT EXISTS kennel_state (
at LONG INTEGER PRIMARY KEY,
encoded_state TEXT NOT NULL
);`)
if err != nil {
return dbConn, err
}
return dbConn, nil return dbConn, nil
} }

View File

@ -1 +0,0 @@
{{ define "content" }}{{ .EncodedState }}{{ end }}