From 67bf0199e1f0ed7dacda51ef624d6f548eec61ae Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Sat, 17 Aug 2024 15:23:22 -0700 Subject: [PATCH] make it simpler and add Ord --- api/kennel/kennel.go | 57 +++++++++++++++++++++++++---- api/serve.go | 9 ++++- database/kennel.go | 77 ++++++++++++++++++++++----------------- database/migrate.go | 8 ---- templates/kennel_enc.json | 1 - 5 files changed, 100 insertions(+), 52 deletions(-) delete mode 100644 templates/kennel_enc.json diff --git a/api/kennel/kennel.go b/api/kennel/kennel.go index 60a898e..a68388d 100644 --- a/api/kennel/kennel.go +++ b/api/kennel/kennel.go @@ -1,9 +1,9 @@ package kennel import ( + "encoding/json" "log" "net/http" - "strconv" "strings" "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 { - atLong, err := strconv.ParseInt(req.FormValue("at"), 10, 64) - if err != nil { - log.Println(err) + order := req.URL.Query().Get("order") + + if order == "random" { + kennelCat, err := database.GetRandomKennelCat(context.DBConn) + if err != nil { + 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) 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 { log.Println(err) resp.WriteHeader(http.StatusInternalServerError) 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) } } diff --git a/api/serve.go b/api/serve.go index 2f08cf9..e205ce5 100644 --- a/api/serve.go +++ b/api/serve.go @@ -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) }) - mux.HandleFunc("GET /kennel", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("GET /kennel/", func(w http.ResponseWriter, r *http.Request) { 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) { diff --git a/database/kennel.go b/database/kennel.go index 7e9a557..91525db 100644 --- a/database/kennel.go +++ b/database/kennel.go @@ -93,6 +93,49 @@ func DeleteKennelCat(db *sql.DB, catID string) error { 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) { log.Println("getting kennel") @@ -114,37 +157,3 @@ func GetKennel(dbConn *sql.DB) ([]KennelCat, error) { 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 -} diff --git a/database/migrate.go b/database/migrate.go index 14766b6..0c8318c 100644 --- a/database/migrate.go +++ b/database/migrate.go @@ -179,14 +179,6 @@ func MigrateKennel(dbConn *sql.DB) (*sql.DB, error) { 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 } diff --git a/templates/kennel_enc.json b/templates/kennel_enc.json deleted file mode 100644 index 602dad1..0000000 --- a/templates/kennel_enc.json +++ /dev/null @@ -1 +0,0 @@ -{{ define "content" }}{{ .EncodedState }}{{ end }}