package posts import ( "net/http" "git.sleepycat.moe/sam/mercury/internal/database" "git.sleepycat.moe/sam/mercury/internal/database/sql" "git.sleepycat.moe/sam/mercury/internal/utils" "git.sleepycat.moe/sam/mercury/web/api" "github.com/go-chi/chi/v5" "github.com/go-chi/render" "github.com/oklog/ulid/v2" "github.com/rs/zerolog/log" ) type createPostParams struct { Content string `json:"content"` Visibility database.PostVisibility `json:"visibility"` } func (p createPostParams) Validate(cfg database.Config) bool { if p.Content == "" { // TODO: allow empty content if the post has attachments return false } if p.Visibility == "" { return false } if utils.StringLength(p.Content) > cfg.PostCharacterLimit { return false } switch p.Visibility { case database.PublicVisibility, database.UnlistedVisibility, database.FollowersVisibility, database.DirectVisibility: default: return false } // everything checks out return true } func (app *App) Create(w http.ResponseWriter, r *http.Request) (api.Post, error) { ctx := r.Context() token, _ := app.TokenFromContext(ctx) var req createPostParams err := render.Decode(r, &req) if err != nil { return api.Post{}, api.Error{Code: api.ErrBadRequest} } if !req.Validate(app.DBConfig.Get()) { return api.Post{}, api.Error{Code: api.ErrBadRequest} } blogID, err := ulid.Parse(chi.URLParam(r, "blogID")) if err != nil { return api.Post{}, api.Error{Code: api.ErrBlogNotFound} } conn, err := app.Database.Acquire(ctx) if err != nil { log.Err(err).Msg("acquiring connection") return api.Post{}, err } defer conn.Release() blog, err := app.Blog(conn).ByID(ctx, blogID) if err != nil { if err == sql.ErrNotFound { return api.Post{}, api.Error{Code: api.ErrBlogNotFound} } log.Err(err).Msg("fetching blog") return api.Post{}, err } acct, err := app.Account(conn).ByID(ctx, blog.AccountID) if err != nil { log.Err(err).Msg("fetching account") return api.Post{}, err } if blog.AccountID != token.UserID { return api.Post{}, api.Error{Code: api.ErrNotYourObject} } // create post post, err := app.Post(conn).Create(ctx, blog, req.Content, req.Visibility) if err != nil { log.Err(err).Msg("creating post") return api.Post{}, err } go app.Processor.HandlePost(post) return api.DBPostToPost(post, blog, acct), nil }