add a couple post endpoints + /timelines/home
This commit is contained in:
parent
dd72a1f4c1
commit
9f052dc9ef
24 changed files with 462 additions and 32 deletions
91
web/api/posts/create_post.go
Normal file
91
web/api/posts/create_post.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// TODO: federate post + push to websockets
|
||||
return api.DBPostToPost(post, blog), nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue