201 lines
6.4 KiB
Go
201 lines
6.4 KiB
Go
package kennel
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/adapters/files"
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/api/types"
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/database"
|
|
"git.hatecomputers.club/hatecomputers/hatecomputers.club/utils"
|
|
)
|
|
|
|
const MaxCatSize = 1024 * 100 // 60KB
|
|
const CatsPath = "cats/"
|
|
const CatsPrefix = "/uploads/cats/"
|
|
const DefaultCatSpritesheet = "/static/img/cat_spritesheets/default.gif"
|
|
const MaxUserCats = 15
|
|
|
|
func ListUserCatsContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
|
|
userID := context.User.ID
|
|
|
|
cats, err := database.GetUserKennelCats(context.DBConn, userID)
|
|
if err != nil {
|
|
log.Println(err)
|
|
resp.WriteHeader(http.StatusInternalServerError)
|
|
return failure(context, req, resp)
|
|
}
|
|
|
|
(*context.TemplateData)["Cats"] = cats
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func CreateCatContinuation(fileAdapter files.FilesAdapter, maxUserCats int, maxCatSize int, catsPath string, catsPrefix string, defaultCatSpritesheet string) func(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
return func(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
|
|
formErrors := types.BannerMessages{
|
|
Messages: []string{},
|
|
}
|
|
|
|
numCats, err := database.CountUserKennelCats(context.DBConn, context.User.ID)
|
|
if err != nil {
|
|
log.Println(err)
|
|
resp.WriteHeader(http.StatusInternalServerError)
|
|
return failure(context, req, resp)
|
|
}
|
|
if numCats >= maxUserCats {
|
|
formErrors.Messages = append(formErrors.Messages, "max cats reached for user")
|
|
}
|
|
|
|
err = req.ParseMultipartForm(int64(maxCatSize))
|
|
if err != nil {
|
|
formErrors.Messages = append(formErrors.Messages, "cat spritesheet too large")
|
|
}
|
|
|
|
catID := utils.RandomId()
|
|
spritesheetPath := catsPrefix + catID
|
|
|
|
if len(formErrors.Messages) == 0 {
|
|
file, _, err := req.FormFile("spritesheet")
|
|
if file != nil && err != nil {
|
|
formErrors.Messages = append(formErrors.Messages, "error uploading spritesheet")
|
|
} else if file != nil {
|
|
defer file.Close()
|
|
reader := http.MaxBytesReader(resp, file, int64(maxCatSize))
|
|
defer reader.Close()
|
|
|
|
_, err = fileAdapter.CreateFile(catsPath+catID, reader)
|
|
if err != nil {
|
|
log.Println(err)
|
|
formErrors.Messages = append(formErrors.Messages, "error saving spritesheet (is it too big?)")
|
|
}
|
|
} else if file == nil && err != nil {
|
|
spritesheetPath = defaultCatSpritesheet
|
|
}
|
|
}
|
|
|
|
link := req.FormValue("link")
|
|
description := req.FormValue("description")
|
|
name := req.FormValue("name")
|
|
|
|
cat := &database.KennelCat{
|
|
ID: catID,
|
|
UserID: context.User.ID,
|
|
Name: name,
|
|
Link: link,
|
|
Description: description,
|
|
Spritesheet: spritesheetPath,
|
|
}
|
|
formErrors.Messages = append(formErrors.Messages, validateCat(cat)...)
|
|
if len(formErrors.Messages) == 0 {
|
|
_, err := database.SaveKennelCat(context.DBConn, cat)
|
|
if err != nil {
|
|
log.Println(err)
|
|
formErrors.Messages = append(formErrors.Messages, "failed to save cat")
|
|
}
|
|
}
|
|
|
|
if len(formErrors.Messages) > 0 {
|
|
(*context.TemplateData)["Error"] = formErrors
|
|
(*context.TemplateData)["CatForm"] = cat
|
|
resp.WriteHeader(http.StatusBadRequest)
|
|
|
|
return failure(context, req, resp)
|
|
}
|
|
|
|
formSuccess := types.BannerMessages{
|
|
Messages: []string{"cat added."},
|
|
}
|
|
(*context.TemplateData)["Success"] = formSuccess
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
}
|
|
|
|
func RemoveCatContinuation(fileAdapter files.FilesAdapter, catsPath string) func(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
return func(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
|
|
catID := req.FormValue("id")
|
|
|
|
cat, err := database.GetKennelCat(context.DBConn, catID)
|
|
if err != nil {
|
|
log.Println(err)
|
|
resp.WriteHeader(http.StatusInternalServerError)
|
|
return failure(context, req, resp)
|
|
}
|
|
if cat == nil || cat.UserID != context.User.ID {
|
|
resp.WriteHeader(http.StatusUnauthorized)
|
|
return failure(context, req, resp)
|
|
}
|
|
|
|
err = database.DeleteKennelCat(context.DBConn, catID)
|
|
if err != nil {
|
|
log.Println(err)
|
|
resp.WriteHeader(http.StatusInternalServerError)
|
|
return failure(context, req, resp)
|
|
}
|
|
|
|
err = fileAdapter.DeleteFile(catsPath + catID)
|
|
if err != nil && fileAdapter.FileExists(catsPath+catID) {
|
|
log.Println(err)
|
|
resp.WriteHeader(http.StatusInternalServerError)
|
|
return failure(context, req, resp)
|
|
}
|
|
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
}
|
|
|
|
func GetCatStateAtContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
return func(success types.Continuation, failure types.Continuation) types.ContinuationChain {
|
|
at := req.FormValue("at")
|
|
if at == "" {
|
|
resp.WriteHeader(http.StatusBadRequest)
|
|
return failure(context, req, resp)
|
|
}
|
|
atLong, err := strconv.ParseInt(at, 10, 64)
|
|
if err != nil {
|
|
log.Println(err)
|
|
resp.WriteHeader(http.StatusBadRequest)
|
|
return failure(context, req, resp)
|
|
}
|
|
|
|
cats, err := database.GetKennelStateAt(context.DBConn, atLong)
|
|
if err != nil {
|
|
log.Println(err)
|
|
resp.WriteHeader(http.StatusInternalServerError)
|
|
return failure(context, req, resp)
|
|
}
|
|
|
|
(*context.TemplateData)["EncodedState"] = cats.EncodedState
|
|
return success(context, req, resp)
|
|
}
|
|
}
|
|
|
|
func validateCat(cat *database.KennelCat) []string {
|
|
errors := []string{}
|
|
|
|
if cat.Name == "" {
|
|
errors = append(errors, "name is required")
|
|
}
|
|
if cat.Link == "" {
|
|
errors = append(errors, "link is required")
|
|
}
|
|
if !strings.HasPrefix(cat.Link, "http://") && !strings.HasPrefix(cat.Link, "https://") {
|
|
errors = append(errors, "link must be a valid URL")
|
|
}
|
|
if cat.Description == "" {
|
|
errors = append(errors, "description is required")
|
|
}
|
|
if len(cat.Description) > 100 {
|
|
errors = append(errors, "description must be less than 100 characters")
|
|
}
|
|
|
|
return errors
|
|
}
|