diff --git a/web/debug/posts.go b/web/debug/posts.go new file mode 100644 index 0000000..211d67f --- /dev/null +++ b/web/debug/posts.go @@ -0,0 +1,91 @@ +package webdebug + +import ( + "database/sql" + "encoding/json" + "errors" + "fmt" + "net/http" + + httputils "git.mstar.dev/mstar/goutils/http" + "git.mstar.dev/mstar/goutils/sliceutils" + "github.com/rs/zerolog/log" + "gorm.io/gorm" + + "git.mstar.dev/mstar/linstrom/storage-new/dbgen" + "git.mstar.dev/mstar/linstrom/storage-new/models" + webshared "git.mstar.dev/mstar/linstrom/web/shared" +) + +func postAs(w http.ResponseWriter, r *http.Request) { + type Inbound struct { + Username string `json:"username"` + Content string `json:"content"` + } + dec := json.NewDecoder(r.Body) + data := Inbound{} + err := dec.Decode(&data) + if err != nil { + httputils.HttpErr(w, 0, "json decode failed", http.StatusBadRequest) + return + } + user, err := dbgen.User.GetByUsername(data.Username) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + httputils.HttpErr(w, 0, "no user with that name", http.StatusNotFound) + } else { + log.Error().Err(err).Str("name", data.Username).Msg("Failed to find user") + } + return + } + n := dbgen.Note + note := models.Note{ + Creator: *user, + CreatorId: user.ID, + RawContent: data.Content, + Remote: false, + ContentWarning: sql.NullString{Valid: false}, + RepliesTo: sql.NullString{Valid: false}, + Quotes: sql.NullString{Valid: false}, + AccessLevel: models.NOTE_TARGET_PUBLIC, + OriginId: 1, + } + n.Select( + n.CreatorId, + n.RawContent, + n.Remote, + n.ContentWarning, + n.RepliesTo, + n.Quotes, + n.AccessLevel, + n.OriginId, + ).Create(¬e) +} + +func notesFrom(w http.ResponseWriter, r *http.Request) { + username := r.FormValue("username") + user, err := dbgen.User.GetByUsername(username) + if err != nil { + log.Error().Err(err).Str("name", username).Msg("Failed to get user") + httputils.HttpErr(w, 0, "failed to get user", http.StatusInternalServerError) + return + } + notes, err := dbgen.Note.GetNotesPaged(user.ID, 0, uint8(models.NOTE_TARGET_PUBLIC)) + if err != nil { + log.Error().Err(err).Str("name", username).Msg("Failed to get notes") + httputils.HttpErr(w, 0, "failed to get notes", http.StatusInternalServerError) + return + } + publicNotes := sliceutils.Map(notes, func(t models.Note) webshared.Note { + n := webshared.Note{} + n.FromModel(&t) + return n + }) + jsonNotes, err := json.Marshal(publicNotes) + if err != nil { + log.Error().Err(err).Msg("Failed to marshal notes") + httputils.HttpErr(w, 0, "failed to marshal", http.StatusInternalServerError) + return + } + fmt.Fprint(w, string(jsonNotes)) +} diff --git a/web/shared/Note.go b/web/shared/Note.go new file mode 100644 index 0000000..1e7548b --- /dev/null +++ b/web/shared/Note.go @@ -0,0 +1,57 @@ +package webshared + +import ( + "time" + + "git.mstar.dev/mstar/linstrom/shared" + "git.mstar.dev/mstar/linstrom/storage-new/models" +) + +type Note struct { + // ---- Section public data + ID string `json:"id"` + CreatedAt time.Time `json:"created_at"` + CreatorId string `json:"creator_id"` + ServerId uint `json:"server_id"` + RawContent string `json:"raw_content"` + ContentWarning *string `json:"content_warning"` + RepliesToId *string `json:"replies_to_id"` + QuotesId *string `json:"quotes_id"` + AccessLevel uint8 `json:"access_level"` +} + +// Compile time interface implementation enforcement +var _ shared.Clonable = &Note{} +var _ shared.Sanitisable = &Note{} + +func (note *Note) Sanitize() { +} + +func (note *Note) Clone() shared.Clonable { + tmp := *note + return &tmp +} + +func (n *Note) FromModel(m *models.Note) { + n.ID = m.ID + n.CreatedAt = m.CreatedAt + n.CreatorId = m.CreatorId + n.ServerId = m.OriginId + n.RawContent = m.RawContent + if m.ContentWarning.Valid { + n.ContentWarning = &m.ContentWarning.String + } else { + n.ContentWarning = nil + } + if m.RepliesTo.Valid { + n.RepliesToId = &m.RepliesTo.String + } else { + n.RepliesToId = nil + } + if m.Quotes.Valid { + n.QuotesId = &m.Quotes.String + } else { + n.QuotesId = nil + } + n.AccessLevel = uint8(m.AccessLevel) +}