Live video on the AT Protocol
at eli/docker-linting 142 lines 4.4 kB view raw
1package model 2 3import ( 4 "context" 5 "errors" 6 "fmt" 7 "time" 8 9 "github.com/bluesky-social/indigo/api/bsky" 10 lexutil "github.com/bluesky-social/indigo/lex/util" 11 "gorm.io/gorm" 12) 13 14type FeedPost struct { 15 CID string `json:"cid" gorm:"primaryKey;column:cid"` 16 URI string `json:"uri"` 17 CreatedAt time.Time `json:"createdAt" gorm:"column:created_at;index:recent_replies"` 18 FeedPost *[]byte `json:"feedPost"` 19 RepoDID string `json:"repoDID" gorm:"column:repo_did"` 20 Repo *Repo `json:"repo,omitempty" gorm:"foreignKey:DID;references:RepoDID"` 21 Type string `json:"type" gorm:"column:type"` 22 ReplyRootCID *string `json:"replyRootCID,omitempty" gorm:"column:reply_root_cid"` 23 ReplyRoot *FeedPost `json:"replyRoot,omitempty" gorm:"foreignKey:cid;references:ReplyRootCID"` 24 ReplyRootRepoDID *string `json:"replyRootRepoDID,omitempty" gorm:"column:reply_root_repo_did;index:recent_replies"` 25 ReplyRootRepo *Repo `json:"replyRootRepo,omitempty" gorm:"foreignKey:DID;references:ReplyRootRepoDID"` 26 IndexedAt *time.Time `json:"indexedAt,omitempty" gorm:"column:indexed_at"` 27} 28 29func (fp *FeedPost) ToBskyPostView() (*bsky.FeedDefs_PostView, error) { 30 rec, err := lexutil.CborDecodeValue(*fp.FeedPost) 31 if err != nil { 32 return nil, fmt.Errorf("error decoding feed post: %w", err) 33 } 34 postView := bsky.FeedDefs_PostView{ 35 LexiconTypeID: "app.bsky.feed.defs#postView", 36 Cid: fp.CID, 37 Uri: fp.URI, 38 Author: &bsky.ActorDefs_ProfileViewBasic{ 39 Did: fp.RepoDID, 40 }, 41 Record: &lexutil.LexiconTypeDecoder{Val: rec}, 42 IndexedAt: fp.IndexedAt.UTC().Format(time.RFC3339Nano), 43 } 44 if fp.Repo != nil { 45 postView.Author.Handle = fp.Repo.Handle 46 } 47 return &postView, nil 48} 49 50func (m *DBModel) CreateFeedPost(ctx context.Context, post *FeedPost) error { 51 return m.DB.Create(post).Error 52} 53 54func (m *DBModel) ListFeedPosts() ([]FeedPost, error) { 55 posts := []FeedPost{} 56 err := m.DB.Find(&posts).Error 57 if err != nil { 58 return nil, fmt.Errorf("error retrieving chat posts: %w", err) 59 } 60 return posts, nil 61} 62func (m *DBModel) ListFeedPostsByType(feedType string, limit int, after int64) ([]FeedPost, error) { 63 if after == 0 { 64 after = time.Now().Add(48 * time.Hour).UnixMilli() 65 } 66 time := time.UnixMilli(after) 67 posts := []FeedPost{} 68 // exclude scumb.ag for now (so my dev streams don't show up) 69 err := m.DB.Where("type = ? AND created_at < ? AND repo_did != ?", feedType, time.UTC(), "did:plc:dkh4rwafdcda4ko7lewe43ml"). 70 Order("created_at DESC"). 71 Group("uri"). 72 Limit(limit). 73 Find(&posts).Error 74 if err != nil { 75 return nil, fmt.Errorf("error retrieving feed posts: %w", err) 76 } 77 return posts, nil 78} 79 80func (m *DBModel) GetFeedPost(cid string) (*FeedPost, error) { 81 post := FeedPost{} 82 err := m.DB.Where("CID = ?", cid).First(&post).Error 83 if errors.Is(err, gorm.ErrRecordNotFound) { 84 return nil, nil 85 } 86 if err != nil { 87 return nil, fmt.Errorf("error retrieving feed post: %w", err) 88 } 89 return &post, nil 90} 91 92func (m *DBModel) GetReplies(repoDID string) ([]*bsky.FeedDefs_PostView, error) { 93 posts := []FeedPost{} 94 err := m.DB. 95 Preload("Repo"). 96 Where("reply_root_repo_did = ? AND type = ?", repoDID, "reply"). 97 Limit(100). 98 Order("created_at DESC"). 99 Find(&posts).Error 100 if err != nil { 101 return nil, fmt.Errorf("error retrieving replies: %w", err) 102 } 103 bskyPosts := []*bsky.FeedDefs_PostView{} 104 for _, post := range posts { 105 bskyPost, err := post.ToBskyPostView() 106 if err != nil { 107 return nil, fmt.Errorf("error converting feed post to bsky post view: %w", err) 108 } 109 bskyPosts = append(bskyPosts, bskyPost) 110 } 111 return bskyPosts, nil 112} 113 114type StreamplaceFeedPostLivestream struct { 115 URL string `json:"url"` 116 Title string `json:"title"` 117} 118 119func (m *DBModel) GetLatestLivestream(repoDID string) (*bsky.FeedDefs_PostView, error) { 120 posts := []FeedPost{} 121 err := m.DB. 122 Preload("Repo"). 123 Where("type = ?", "livestream"). 124 Where("repo_did = ?", repoDID). 125 Limit(1). 126 Order("created_at DESC"). 127 Find(&posts).Error 128 if err != nil { 129 return nil, fmt.Errorf("error retrieving livestream: %w", err) 130 } 131 132 if len(posts) == 0 { 133 return nil, nil 134 } 135 136 view, err := posts[0].ToBskyPostView() 137 if err != nil { 138 return nil, fmt.Errorf("error converting feed post to bsky post view: %w", err) 139 } 140 141 return view, nil 142}