tavern/web/handler_notes.go

149 lines
3.7 KiB
Go

package web
import (
"fmt"
"net/http"
"time"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/ngerakines/tavern/errors"
"github.com/ngerakines/tavern/fed"
"github.com/ngerakines/tavern/job"
"github.com/ngerakines/tavern/storage"
)
func (h handler) dashboardNotes(c *gin.Context) {
session := sessions.Default(c)
ctx := c.Request.Context()
trans, transOK := c.Get("trans")
if !transOK {
panic("trans not found in context")
}
data := gin.H{
"flashes": getFlashes(session),
"Trans": trans,
}
user, err := h.storage.GetUserBySession(ctx, session)
if err != nil {
if errors.Is(err, errors.UserSessionNotFoundError{}) {
if err = appendFlashError(session, "Not Authenticated"); err != nil {
h.hardFail(c, errors.NewCannotSaveSessionError(err))
return
}
c.Redirect(http.StatusFound, "/")
return
}
h.hardFail(c, err)
return
}
data["user"] = user
if err = session.Save(); err != nil {
h.hardFail(c, err)
return
}
c.HTML(http.StatusOK, "dashboard_notes", data)
}
func (h handler) createNote(c *gin.Context) {
// "conversation":"tag:mastodon.social,2020-02-26:objectId=156298483:objectType=Conversation"
session := sessions.Default(c)
ctx := c.Request.Context()
user, err := h.storage.GetUserBySession(ctx, session)
if err != nil {
if errors.Is(err, errors.UserSessionNotFoundError{}) {
if err = appendFlashError(session, "Not Authenticated"); err != nil {
h.hardFail(c, errors.NewCannotSaveSessionError(err))
return
}
c.Redirect(http.StatusFound, "/")
return
}
h.hardFail(c, err)
return
}
content := c.PostForm("content")
if len(content) == 0 {
h.flashErrorOrFail(c, "/dashboard/network", fmt.Errorf("note is empty"))
return
}
actor := storage.NewActorID(user.Name, h.domain)
activityID := storage.NewV4()
activityURL := fmt.Sprintf("https://%s/activity/%s", h.domain, activityID)
now := time.Now()
publishedAt := now.Format("2006-01-02T15:04:05Z")
conversation := fmt.Sprintf("tag:%s,%s:objectId=%s:objectType=Conversation", h.domain, now.Format("2006-01-02"), activityID)
createNote := storage.EmptyPayload()
createNote["@context"] = "https://www.w3.org/ns/activitystreams"
createNote["actor"] = actor
createNote["id"] = activityURL
createNote["published"] = publishedAt
createNote["type"] = "Create"
createNote["to"] = []string{
"https://www.w3.org/ns/activitystreams#Public",
actor.Followers(),
}
note := storage.EmptyPayload()
note["attributedTo"] = actor
note["content"] = content
note["context"] = conversation
note["conversation"] = conversation
note["id"] = activityURL
note["published"] = publishedAt
note["summary"] = ""
note["to"] = "https://www.w3.org/ns/activitystreams#Public"
note["type"] = "Note"
note["url"] = activityURL
createNote["object"] = note
payload := createNote.Bytes()
err = h.storage.RecordActivity(ctx, activityID, activityURL, string(payload))
if err != nil {
h.flashErrorOrFail(c, "/dashboard/notes", err)
return
}
err = h.storage.WatchThread(ctx, user.ID, conversation)
if err != nil {
h.flashErrorOrFail(c, "/dashboard/notes", err)
return
}
err = h.storage.AddToUserFeed(ctx, user.ID, activityID)
if err != nil {
h.flashErrorOrFail(c, "/dashboard/notes", err)
return
}
err = h.storage.RecordUserActivity(ctx, storage.NewV4(), user.ID, activityID)
if err != nil {
h.flashErrorOrFail(c, "/dashboard/notes", err)
return
}
nc := fed.ActorClient{
HTTPClient: job.DefaultHTTPClient(),
Logger: h.logger,
}
err = nc.Broadcast(ctx, h.storage, storage.LocalActor{User: user, ActorID: storage.NewActorID(user.Name, h.domain)}, payload)
if err != nil {
h.flashErrorOrFail(c, "/dashboard/notes", err)
return
}
c.Redirect(http.StatusFound, "/dashboard/notes")
}