mStar
599874c486
Fixed note rendering due to bad user header TODO: It's a stupid bandaid, replace with proper formatter once it works Remove test stuff Some spacing in the colours for readability CreateNoteRemote header added
140 lines
4.6 KiB
Go
140 lines
4.6 KiB
Go
package storage
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
"gitlab.com/mstarongitlab/linstrom/util"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Note represents an ActivityPub note
|
|
// ActivityPub notes can be quite a few things, depending on fields provided.
|
|
// A survey, a reply, a quote of another note, etc
|
|
// And depending on the origin server of a note, they are treated differently
|
|
// with for example rendering or available actions
|
|
// This struct attempts to contain all information necessary for easily working with a note
|
|
type Note struct {
|
|
ID string `gorm:"primarykey"` // Make ID a string (uuid) for other implementations
|
|
CreatedAt time.Time // When this entry was created
|
|
UpdatedAt time.Time // When this entry was last updated
|
|
// When this entry was deleted (for soft deletions)
|
|
// Soft delete means that this entry still exists in the db, but gorm won't include it anymore unless specifically told to
|
|
// If not null, this entry is marked as deleted
|
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
|
// Creator Account // `gorm:"foreignKey:CreatorId;references:ID"` // Account that created the post
|
|
CreatorId string
|
|
Remote bool // Whether the note is originally a remote one and just "cached"
|
|
// Raw content of the note. So without additional formatting applied
|
|
// Might already have formatting applied beforehand from the origin server
|
|
RawContent string
|
|
ContentWarning *string // Content warnings of the note, if it contains any
|
|
Attachments []string `gorm:"serializer:json"` // List of Ids for mediaFiles
|
|
Emotes []string `gorm:"serializer:json"` // Emotes used in that message
|
|
RepliesTo *string // Url of the message this replies to
|
|
Quotes *string // url of the message this note quotes
|
|
AccessLevel NoteAccessLevel // Where to send this message to (public, home, followers, dm)
|
|
Pings []string `gorm:"serializer:json"` // Who is being tagged in this message. Also serves as DM targets
|
|
OriginServer string // Url of the origin server. Also the primary key for those
|
|
Tags []string `gorm:"serializer:json"` // Hashtags
|
|
}
|
|
|
|
func (s *Storage) FindNoteById(id string) (*Note, error) {
|
|
defer util.Untrace(util.Trace(&log.Logger))
|
|
note := &Note{}
|
|
cacheNote, err := s.cacheNoteIdToData(id)
|
|
switch err {
|
|
case nil:
|
|
return cacheNote, nil
|
|
// Empty case, not found in cache means check db
|
|
case errCacheNotFound:
|
|
default:
|
|
return nil, err
|
|
}
|
|
switch err {
|
|
|
|
}
|
|
err = s.db.Find(note, id).Error
|
|
switch err {
|
|
case nil:
|
|
if err = s.cache.Set(cacheNoteIdToNotePrefix+id, note); err != nil {
|
|
log.Warn().Err(err).Str("note-id", id).Msg("Failed to place note in cache")
|
|
}
|
|
return note, nil
|
|
case gorm.ErrRecordNotFound:
|
|
return nil, ErrEntryNotFound
|
|
default:
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
func (s *Storage) FindNotesByFuzzyContent(fuzzyContent string) ([]Note, error) {
|
|
defer util.Untrace(util.Trace(&log.Logger))
|
|
notes := []Note{}
|
|
// TODO: Figure out if cache can be used here too
|
|
err := s.db.Where("raw_content LIKE %?%", fuzzyContent).Find(notes).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return notes, nil
|
|
}
|
|
|
|
func (s *Storage) FindNotesByAuthorHandle(handle string) ([]Note, error) {
|
|
defer util.Untrace(util.Trace(&log.Logger))
|
|
acc, err := s.FindAccountByFullHandle(handle)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("account with handle %s not found: %w", handle, err)
|
|
}
|
|
return s.FindNotesByAuthorId(acc.ID)
|
|
}
|
|
|
|
func (s *Storage) FindNotesByAuthorId(id string) ([]Note, error) {
|
|
defer util.Untrace(util.Trace(&log.Logger))
|
|
notes := []Note{}
|
|
err := s.db.Where("creator = ?", id).Find(notes).Error
|
|
switch err {
|
|
case nil:
|
|
return notes, nil
|
|
case gorm.ErrRecordNotFound:
|
|
return nil, ErrEntryNotFound
|
|
default:
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
func (s *Storage) UpdateNote(note *Note) error {
|
|
defer util.Untrace(util.Trace(&log.Logger))
|
|
if note == nil || note.ID == "" {
|
|
return ErrInvalidData
|
|
}
|
|
err := s.db.Save(note).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = s.cache.Set(cacheNoteIdToNotePrefix+note.ID, note)
|
|
if err != nil {
|
|
log.Warn().
|
|
Err(err).
|
|
Msg("Failed to update note into cache. Cache and db might be out of sync, a force sync is recommended")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Storage) CreateNoteLocal() (*Note, error) {
|
|
defer util.Untrace(util.Trace(&log.Logger))
|
|
// TODO: Think of good arguments and implement me
|
|
panic("not implemented")
|
|
}
|
|
|
|
func (s *Storage) CreateNoteRemote() (*Note, error) {
|
|
defer util.Untrace(util.Trace(&log.Logger))
|
|
// TODO: Think of good arguments and implement me
|
|
panic("not implemented")
|
|
}
|
|
|
|
func (s *Storage) DeleteNote(id string) {
|
|
defer util.Untrace(util.Trace(&log.Logger))
|
|
s.cache.Delete(cacheNoteIdToNotePrefix + id)
|
|
s.db.Delete(Note{ID: id})
|
|
}
|