kennel #13
			
				
			
		
		
		
	|  | @ -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) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -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) { | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1 +0,0 @@ | |||
| {{ define "content" }}{{ .EncodedState }}{{ end }} | ||||
		Loading…
	
		Reference in New Issue