Live video on the AT Protocol
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 "stream.place/streamplace/pkg/streamplace"
13)
14
15type Block struct {
16 RKey string `gorm:"primaryKey;column:rkey"`
17 CID string `gorm:"column:cid"`
18 RepoDID string `json:"repoDID" gorm:"column:repo_did;index:idx_repo_did_subject_did,priority:1"`
19 Repo *Repo `json:"repo,omitempty" gorm:"foreignKey:DID;references:RepoDID"`
20 SubjectDID string `gorm:"column:subject_did;index:idx_repo_did_subject_did,priority:2"`
21 Record []byte
22 CreatedAt time.Time
23}
24
25func (b *Block) ToStreamplaceBlock() (*streamplace.Defs_BlockView, error) {
26 rec, err := lexutil.CborDecodeValue(b.Record)
27 if err != nil {
28 return nil, fmt.Errorf("error decoding feed post: %w", err)
29 }
30 block, ok := rec.(*bsky.GraphBlock)
31 if !ok {
32 return nil, fmt.Errorf("record is not a GraphBlock")
33 }
34 return &streamplace.Defs_BlockView{
35 LexiconTypeID: "place.stream.defs#blockView",
36 Blocker: &bsky.ActorDefs_ProfileViewBasic{
37 Did: b.RepoDID,
38 Handle: b.Repo.Handle,
39 },
40 Cid: b.CID,
41 IndexedAt: b.CreatedAt.Format(time.RFC3339),
42 Record: block,
43 Uri: fmt.Sprintf(`at://%s/app.bsky.graph.block/%s`, b.RepoDID, b.RKey),
44 }, nil
45}
46
47func (m *DBModel) CreateBlock(ctx context.Context, block *Block) error {
48 return m.DB.Create(block).Error
49}
50
51func (m *DBModel) DeleteBlock(ctx context.Context, rkey string) error {
52 return m.DB.Where("rkey = ?", rkey).Delete(&Block{}).Error
53}
54
55func (m *DBModel) GetBlock(ctx context.Context, rkey string) (*Block, error) {
56 var block Block
57 err := m.DB.Preload("Repo").Where("rkey = ?", rkey).First(&block).Error
58 if errors.Is(err, gorm.ErrRecordNotFound) {
59 return nil, nil
60 }
61 if err != nil {
62 return nil, err
63 }
64 return &block, nil
65}
66
67func (m *DBModel) GetUserBlock(ctx context.Context, userDID, subjectDID string) (*Block, error) {
68 var block Block
69 err := m.DB.Where("repo_did = ? AND subject_did = ?", userDID, subjectDID).First(&block).Error
70 if errors.Is(err, gorm.ErrRecordNotFound) {
71 return nil, nil
72 }
73 if err != nil {
74 return nil, err
75 }
76 return &block, nil
77}