+1
-4
cmd/bigsky/main.go
+1
-4
cmd/bigsky/main.go
···
20
"github.com/bluesky-social/indigo/did"
21
"github.com/bluesky-social/indigo/events"
22
"github.com/bluesky-social/indigo/indexer"
23
-
"github.com/bluesky-social/indigo/notifs"
24
"github.com/bluesky-social/indigo/plc"
25
"github.com/bluesky-social/indigo/repomgr"
26
"github.com/bluesky-social/indigo/util"
···
449
450
evtman := events.NewEventManager(persister)
451
452
-
notifman := ¬ifs.NullNotifs{}
453
-
454
rf := indexer.NewRepoFetcher(db, repoman, cctx.Int("max-fetch-concurrency"))
455
456
-
ix, err := indexer.NewIndexer(db, notifman, evtman, cachedidr, rf, true, false, cctx.Bool("spidering"))
457
if err != nil {
458
return err
459
}
···
20
"github.com/bluesky-social/indigo/did"
21
"github.com/bluesky-social/indigo/events"
22
"github.com/bluesky-social/indigo/indexer"
23
"github.com/bluesky-social/indigo/plc"
24
"github.com/bluesky-social/indigo/repomgr"
25
"github.com/bluesky-social/indigo/util"
···
448
449
evtman := events.NewEventManager(persister)
450
451
rf := indexer.NewRepoFetcher(db, repoman, cctx.Int("max-fetch-concurrency"))
452
453
+
ix, err := indexer.NewIndexer(db, evtman, cachedidr, rf, true, false, cctx.Bool("spidering"))
454
if err != nil {
455
return err
456
}
+5
-34
indexer/indexer.go
+5
-34
indexer/indexer.go
···
14
"github.com/bluesky-social/indigo/events"
15
lexutil "github.com/bluesky-social/indigo/lex/util"
16
"github.com/bluesky-social/indigo/models"
17
-
"github.com/bluesky-social/indigo/notifs"
18
"github.com/bluesky-social/indigo/repomgr"
19
"github.com/bluesky-social/indigo/util"
20
"github.com/bluesky-social/indigo/xrpc"
···
31
type Indexer struct {
32
db *gorm.DB
33
34
-
notifman notifs.NotificationManager
35
-
events *events.EventManager
36
-
didr did.Resolver
37
38
Crawler *CrawlDispatcher
39
···
47
log *slog.Logger
48
}
49
50
-
func NewIndexer(db *gorm.DB, notifman notifs.NotificationManager, evtman *events.EventManager, didr did.Resolver, fetcher *RepoFetcher, crawl, aggregate, spider bool) (*Indexer, error) {
51
db.AutoMigrate(&models.FeedPost{})
52
db.AutoMigrate(&models.ActorInfo{})
53
db.AutoMigrate(&models.FollowRecord{})
···
56
57
ix := &Indexer{
58
db: db,
59
-
notifman: notifman,
60
events: evtman,
61
didr: didr,
62
doAggregations: aggregate,
···
424
if err := ix.db.Where("reposter = ? AND rkey = ?", evt.User, op.Rkey).Delete(&models.RepostRecord{}).Error; err != nil {
425
return err
426
}
427
-
428
-
ix.log.Warn("TODO: remove notifications on delete")
429
-
/*
430
-
if err := ix.notifman.RemoveRepost(ctx, fp.Author, rr.ID, evt.User); err != nil {
431
-
return nil, err
432
-
}
433
-
*/
434
-
435
case "app.bsky.feed.vote":
436
return ix.handleRecordDeleteFeedLike(ctx, evt, op)
437
case "app.bsky.graph.follow":
···
518
return nil, err
519
}
520
521
-
if err := ix.notifman.AddRepost(ctx, fp.Author, rr.ID, evt.User); err != nil {
522
-
return nil, err
523
-
}
524
-
525
case *bsky.FeedLike:
526
return nil, ix.handleRecordCreateFeedLike(ctx, rec, evt, op)
527
case *bsky.GraphFollow:
···
599
Cid: op.RecCid.String(),
600
}
601
if err := ix.db.Create(&fr).Error; err != nil {
602
-
return err
603
-
}
604
-
605
-
if err := ix.notifman.AddFollow(ctx, fr.Follower, fr.Target, fr.ID); err != nil {
606
return err
607
}
608
···
812
813
func (ix *Indexer) addNewPostNotification(ctx context.Context, post *bsky.FeedPost, fp *models.FeedPost, mentions []*models.ActorInfo) error {
814
if post.Reply != nil {
815
-
replyto, err := ix.GetPost(ctx, post.Reply.Parent.Uri)
816
if err != nil {
817
ix.log.Error("probably shouldn't error when processing a reply to a not-found post")
818
return err
819
}
820
-
821
-
if err := ix.notifman.AddReplyTo(ctx, fp.Author, fp.ID, replyto); err != nil {
822
-
return err
823
-
}
824
-
}
825
-
826
-
for _, mentioned := range mentions {
827
-
if err := ix.notifman.AddMention(ctx, fp.Author, fp.ID, mentioned.Uid); err != nil {
828
-
return err
829
-
}
830
}
831
832
return nil
833
}
834
835
func (ix *Indexer) addNewVoteNotification(ctx context.Context, postauthor models.Uid, vr *models.VoteRecord) error {
836
-
return ix.notifman.AddUpVote(ctx, vr.Voter, vr.Post, vr.ID, postauthor)
837
}
···
14
"github.com/bluesky-social/indigo/events"
15
lexutil "github.com/bluesky-social/indigo/lex/util"
16
"github.com/bluesky-social/indigo/models"
17
"github.com/bluesky-social/indigo/repomgr"
18
"github.com/bluesky-social/indigo/util"
19
"github.com/bluesky-social/indigo/xrpc"
···
30
type Indexer struct {
31
db *gorm.DB
32
33
+
events *events.EventManager
34
+
didr did.Resolver
35
36
Crawler *CrawlDispatcher
37
···
45
log *slog.Logger
46
}
47
48
+
func NewIndexer(db *gorm.DB, evtman *events.EventManager, didr did.Resolver, fetcher *RepoFetcher, crawl, aggregate, spider bool) (*Indexer, error) {
49
db.AutoMigrate(&models.FeedPost{})
50
db.AutoMigrate(&models.ActorInfo{})
51
db.AutoMigrate(&models.FollowRecord{})
···
54
55
ix := &Indexer{
56
db: db,
57
events: evtman,
58
didr: didr,
59
doAggregations: aggregate,
···
421
if err := ix.db.Where("reposter = ? AND rkey = ?", evt.User, op.Rkey).Delete(&models.RepostRecord{}).Error; err != nil {
422
return err
423
}
424
case "app.bsky.feed.vote":
425
return ix.handleRecordDeleteFeedLike(ctx, evt, op)
426
case "app.bsky.graph.follow":
···
507
return nil, err
508
}
509
510
case *bsky.FeedLike:
511
return nil, ix.handleRecordCreateFeedLike(ctx, rec, evt, op)
512
case *bsky.GraphFollow:
···
584
Cid: op.RecCid.String(),
585
}
586
if err := ix.db.Create(&fr).Error; err != nil {
587
return err
588
}
589
···
793
794
func (ix *Indexer) addNewPostNotification(ctx context.Context, post *bsky.FeedPost, fp *models.FeedPost, mentions []*models.ActorInfo) error {
795
if post.Reply != nil {
796
+
_, err := ix.GetPost(ctx, post.Reply.Parent.Uri)
797
if err != nil {
798
ix.log.Error("probably shouldn't error when processing a reply to a not-found post")
799
return err
800
}
801
}
802
803
return nil
804
}
805
806
func (ix *Indexer) addNewVoteNotification(ctx context.Context, postauthor models.Uid, vr *models.VoteRecord) error {
807
+
return nil
808
}
+1
-3
indexer/posts_test.go
+1
-3
indexer/posts_test.go
···
10
bsky "github.com/bluesky-social/indigo/api/bsky"
11
"github.com/bluesky-social/indigo/carstore"
12
"github.com/bluesky-social/indigo/events"
13
-
"github.com/bluesky-social/indigo/notifs"
14
"github.com/bluesky-social/indigo/plc"
15
"github.com/bluesky-social/indigo/repomgr"
16
"github.com/bluesky-social/indigo/util"
···
56
}
57
58
repoman := repomgr.NewRepoManager(cs, &util.FakeKeyManager{})
59
-
notifman := notifs.NewNotificationManager(maindb, repoman.GetRecord)
60
evtman := events.NewEventManager(events.NewMemPersister())
61
62
didr := testPLC(t)
63
64
rf := NewRepoFetcher(maindb, repoman, 10)
65
66
-
ix, err := NewIndexer(maindb, notifman, evtman, didr, rf, false, true, true)
67
if err != nil {
68
t.Fatal(err)
69
}
···
10
bsky "github.com/bluesky-social/indigo/api/bsky"
11
"github.com/bluesky-social/indigo/carstore"
12
"github.com/bluesky-social/indigo/events"
13
"github.com/bluesky-social/indigo/plc"
14
"github.com/bluesky-social/indigo/repomgr"
15
"github.com/bluesky-social/indigo/util"
···
55
}
56
57
repoman := repomgr.NewRepoManager(cs, &util.FakeKeyManager{})
58
evtman := events.NewEventManager(events.NewMemPersister())
59
60
didr := testPLC(t)
61
62
rf := NewRepoFetcher(maindb, repoman, 10)
63
64
+
ix, err := NewIndexer(maindb, evtman, didr, rf, false, true, true)
65
if err != nil {
66
t.Fatal(err)
67
}
-371
notifs/notifs.go
-371
notifs/notifs.go
···
1
-
package notifs
2
-
3
-
import (
4
-
"context"
5
-
"fmt"
6
-
"time"
7
-
8
-
appbskytypes "github.com/bluesky-social/indigo/api/bsky"
9
-
lexutil "github.com/bluesky-social/indigo/lex/util"
10
-
"github.com/bluesky-social/indigo/models"
11
-
"github.com/ipfs/go-cid"
12
-
cbg "github.com/whyrusleeping/cbor-gen"
13
-
"gorm.io/gorm"
14
-
"gorm.io/gorm/clause"
15
-
)
16
-
17
-
type NotificationManager interface {
18
-
GetNotifications(ctx context.Context, user models.Uid) ([]*appbskytypes.NotificationListNotifications_Notification, error)
19
-
GetCount(ctx context.Context, user models.Uid) (int64, error)
20
-
UpdateSeen(ctx context.Context, usr models.Uid, seen time.Time) error
21
-
AddReplyTo(ctx context.Context, user models.Uid, replyid uint, replyto *models.FeedPost) error
22
-
AddMention(ctx context.Context, user models.Uid, postid uint, mentioned models.Uid) error
23
-
AddUpVote(ctx context.Context, voter models.Uid, postid uint, voteid uint, postauthor models.Uid) error
24
-
AddFollow(ctx context.Context, follower, followed models.Uid, recid uint) error
25
-
AddRepost(ctx context.Context, op models.Uid, repost uint, reposter models.Uid) error
26
-
}
27
-
28
-
var _ NotificationManager = (*DBNotifMan)(nil)
29
-
30
-
type DBNotifMan struct {
31
-
db *gorm.DB
32
-
33
-
getRecord GetRecord
34
-
}
35
-
type GetRecord func(ctx context.Context, user models.Uid, collection string, rkey string, maybeCid cid.Cid) (cid.Cid, cbg.CBORMarshaler, error)
36
-
37
-
func NewNotificationManager(db *gorm.DB, getrec GetRecord) *DBNotifMan {
38
-
39
-
db.AutoMigrate(&NotifRecord{})
40
-
db.AutoMigrate(&NotifSeen{})
41
-
42
-
return &DBNotifMan{
43
-
db: db,
44
-
getRecord: getrec,
45
-
}
46
-
}
47
-
48
-
const (
49
-
NotifKindReply = 1
50
-
NotifKindMention = 2
51
-
NotifKindUpVote = 3
52
-
NotifKindFollow = 4
53
-
NotifKindRepost = 5
54
-
)
55
-
56
-
type NotifRecord struct {
57
-
gorm.Model
58
-
For models.Uid
59
-
Kind int64
60
-
Record uint
61
-
Who models.Uid
62
-
ReplyTo uint
63
-
}
64
-
65
-
type NotifSeen struct {
66
-
ID uint `gorm:"primarykey"`
67
-
Usr models.Uid `gorm:"uniqueIndex"`
68
-
LastSeen time.Time
69
-
}
70
-
71
-
type HydratedNotification struct {
72
-
Record any
73
-
IsRead bool
74
-
IndexedAt time.Time
75
-
Uri string
76
-
Cid string
77
-
Author *appbskytypes.ActorDefs_ProfileViewBasic
78
-
Reason string
79
-
ReasonSubject *string
80
-
}
81
-
82
-
func (nm *DBNotifMan) GetNotifications(ctx context.Context, user models.Uid) ([]*appbskytypes.NotificationListNotifications_Notification, error) {
83
-
var lastSeen time.Time
84
-
if err := nm.db.Model(NotifSeen{}).Where("usr = ?", user).Select("last_seen").Scan(&lastSeen).Error; err != nil {
85
-
return nil, err
86
-
}
87
-
88
-
var notifs []NotifRecord
89
-
if err := nm.db.Order("created_at desc").Find(¬ifs, "for = ?", user).Error; err != nil {
90
-
return nil, err
91
-
}
92
-
93
-
/*
94
-
Record any `json:"record" cborgen:"record"`
95
-
IsRead bool `json:"isRead" cborgen:"isRead"`
96
-
IndexedAt string `json:"indexedAt" cborgen:"indexedAt"`
97
-
Uri string `json:"uri" cborgen:"uri"`
98
-
Cid string `json:"cid" cborgen:"cid"`
99
-
Author *ActorRef_WithInfo `json:"author" cborgen:"author"`
100
-
Reason string `json:"reason" cborgen:"reason"`
101
-
ReasonSubject *string `json:"reasonSubject" cborgen:"reasonSubject"`
102
-
*/
103
-
104
-
out := []*appbskytypes.NotificationListNotifications_Notification{}
105
-
106
-
for _, n := range notifs {
107
-
hn, err := nm.hydrateNotification(ctx, &n, lastSeen)
108
-
if err != nil {
109
-
return nil, err
110
-
}
111
-
112
-
// TODO: muting
113
-
hn.Author.Viewer = &appbskytypes.ActorDefs_ViewerState{}
114
-
115
-
out = append(out, hn)
116
-
}
117
-
return out, nil
118
-
}
119
-
120
-
func (nm *DBNotifMan) hydrateNotification(ctx context.Context, nrec *NotifRecord, lastSeen time.Time) (*appbskytypes.NotificationListNotifications_Notification, error) {
121
-
122
-
switch nrec.Kind {
123
-
case NotifKindReply:
124
-
return nm.hydrateNotificationReply(ctx, nrec, lastSeen)
125
-
case NotifKindFollow:
126
-
return nm.hydrateNotificationFollow(ctx, nrec, lastSeen)
127
-
case NotifKindUpVote:
128
-
return nm.hydrateNotificationUpVote(ctx, nrec, lastSeen)
129
-
case NotifKindRepost:
130
-
return nm.hydrateNotificationRepost(ctx, nrec, lastSeen)
131
-
/*
132
-
case NotifKindMention:
133
-
return nm.hydrateNotificationMention(ctx, nrec, lastSeen)
134
-
*/
135
-
default:
136
-
return nil, fmt.Errorf("attempted to hydrate unknown notif kind: %d", nrec.Kind)
137
-
}
138
-
}
139
-
func (nm *DBNotifMan) getActor(ctx context.Context, act models.Uid) (*models.ActorInfo, error) {
140
-
var ai models.ActorInfo
141
-
if err := nm.db.First(&ai, "uid = ?", act).Error; err != nil {
142
-
return nil, err
143
-
}
144
-
145
-
return &ai, nil
146
-
}
147
-
148
-
func (nm *DBNotifMan) hydrateNotificationUpVote(ctx context.Context, nrec *NotifRecord, lastSeen time.Time) (*appbskytypes.NotificationListNotifications_Notification, error) {
149
-
var votedOn models.FeedPost
150
-
if err := nm.db.First(&votedOn, "id = ?", nrec.Record).Error; err != nil {
151
-
return nil, err
152
-
}
153
-
154
-
voter, err := nm.getActor(ctx, nrec.Who)
155
-
if err != nil {
156
-
return nil, err
157
-
}
158
-
159
-
var vote models.VoteRecord
160
-
if err := nm.db.First(&vote, "id = ?", nrec.Record).Error; err != nil {
161
-
return nil, err
162
-
}
163
-
164
-
_, rec, err := nm.getRecord(ctx, voter.Uid, "app.bsky.feed.vote", vote.Rkey, cid.Undef)
165
-
if err != nil {
166
-
return nil, fmt.Errorf("getting vote: %w", err)
167
-
}
168
-
169
-
postAuthor, err := nm.getActor(ctx, votedOn.Author)
170
-
if err != nil {
171
-
return nil, err
172
-
}
173
-
174
-
rsub := "at://" + postAuthor.Did + "/app.bsky.feed.post/" + votedOn.Rkey
175
-
176
-
return &appbskytypes.NotificationListNotifications_Notification{
177
-
Record: &lexutil.LexiconTypeDecoder{Val: rec},
178
-
IsRead: nrec.CreatedAt.Before(lastSeen),
179
-
IndexedAt: nrec.CreatedAt.Format(time.RFC3339),
180
-
Uri: "at://" + voter.Did + "/app.bsky.feed.vote/" + vote.Rkey,
181
-
Cid: vote.Cid,
182
-
Author: voter.ActorView(),
183
-
Reason: "vote",
184
-
ReasonSubject: &rsub,
185
-
}, nil
186
-
}
187
-
188
-
func (nm *DBNotifMan) hydrateNotificationRepost(ctx context.Context, nrec *NotifRecord, lastSeen time.Time) (*appbskytypes.NotificationListNotifications_Notification, error) {
189
-
var reposted models.FeedPost
190
-
if err := nm.db.First(&reposted, "id = ?", nrec.Record).Error; err != nil {
191
-
return nil, err
192
-
}
193
-
194
-
reposter, err := nm.getActor(ctx, nrec.Who)
195
-
if err != nil {
196
-
return nil, err
197
-
}
198
-
199
-
var repost models.RepostRecord
200
-
if err := nm.db.First(&repost, "id = ?", nrec.Record).Error; err != nil {
201
-
return nil, err
202
-
}
203
-
204
-
_, rec, err := nm.getRecord(ctx, reposter.Uid, "app.bsky.feed.repost", repost.Rkey, cid.Undef)
205
-
if err != nil {
206
-
return nil, fmt.Errorf("getting repost: %w", err)
207
-
}
208
-
209
-
postAuthor, err := nm.getActor(ctx, repost.Author)
210
-
if err != nil {
211
-
return nil, err
212
-
}
213
-
214
-
rsub := "at://" + postAuthor.Did + "/app.bsky.feed.post/" + reposted.Rkey
215
-
216
-
return &appbskytypes.NotificationListNotifications_Notification{
217
-
Record: &lexutil.LexiconTypeDecoder{Val: rec},
218
-
IsRead: nrec.CreatedAt.Before(lastSeen),
219
-
IndexedAt: nrec.CreatedAt.Format(time.RFC3339),
220
-
Uri: "at://" + reposter.Did + "/app.bsky.feed.repost/" + repost.Rkey,
221
-
Cid: repost.RecCid,
222
-
Author: reposter.ActorView(),
223
-
Reason: "repost",
224
-
ReasonSubject: &rsub,
225
-
}, nil
226
-
}
227
-
228
-
func (nm *DBNotifMan) hydrateNotificationReply(ctx context.Context, nrec *NotifRecord, lastSeen time.Time) (*appbskytypes.NotificationListNotifications_Notification, error) {
229
-
var fp models.FeedPost
230
-
if err := nm.db.First(&fp, "id = ?", nrec.Record).Error; err != nil {
231
-
return nil, err
232
-
}
233
-
234
-
var replyTo models.FeedPost
235
-
if err := nm.db.First(&replyTo, "id = ?", nrec.ReplyTo).Error; err != nil {
236
-
return nil, err
237
-
}
238
-
239
-
var author models.ActorInfo
240
-
if err := nm.db.First(&author, "id = ?", fp.Author).Error; err != nil {
241
-
return nil, err
242
-
}
243
-
244
-
var opAuthor models.ActorInfo
245
-
if err := nm.db.First(&opAuthor, "id = ?", replyTo.Author).Error; err != nil {
246
-
return nil, err
247
-
}
248
-
249
-
_, rec, err := nm.getRecord(ctx, author.Uid, "app.bsky.feed.post", fp.Rkey, cid.Undef)
250
-
if err != nil {
251
-
return nil, err
252
-
}
253
-
254
-
rsub := "at://" + opAuthor.Did + "/app.bsky.feed.post/" + replyTo.Rkey
255
-
256
-
return &appbskytypes.NotificationListNotifications_Notification{
257
-
Record: &lexutil.LexiconTypeDecoder{Val: rec},
258
-
IsRead: nrec.CreatedAt.Before(lastSeen),
259
-
IndexedAt: nrec.CreatedAt.Format(time.RFC3339),
260
-
Uri: "at://" + author.Did + "/app.bsky.feed.post/" + fp.Rkey,
261
-
Cid: fp.Cid,
262
-
Author: author.ActorView(),
263
-
Reason: "reply",
264
-
ReasonSubject: &rsub,
265
-
}, nil
266
-
}
267
-
268
-
func (nm *DBNotifMan) hydrateNotificationFollow(ctx context.Context, nrec *NotifRecord, lastSeen time.Time) (*appbskytypes.NotificationListNotifications_Notification, error) {
269
-
var frec models.FollowRecord
270
-
if err := nm.db.First(&frec, "id = ?", nrec.Record).Error; err != nil {
271
-
return nil, err
272
-
}
273
-
274
-
var follower models.ActorInfo
275
-
if err := nm.db.First(&follower, "id = ?", nrec.Who).Error; err != nil {
276
-
return nil, err
277
-
}
278
-
279
-
_, rec, err := nm.getRecord(ctx, follower.Uid, "app.bsky.graph.follow", frec.Rkey, cid.Undef)
280
-
if err != nil {
281
-
return nil, err
282
-
}
283
-
284
-
return &appbskytypes.NotificationListNotifications_Notification{
285
-
Record: &lexutil.LexiconTypeDecoder{Val: rec},
286
-
IsRead: nrec.CreatedAt.Before(lastSeen),
287
-
IndexedAt: nrec.CreatedAt.Format(time.RFC3339),
288
-
Uri: "at://" + follower.Did + "/app.bsky.graph.follow/" + frec.Rkey,
289
-
Cid: frec.Cid,
290
-
Author: follower.ActorView(),
291
-
Reason: "follow",
292
-
}, nil
293
-
294
-
}
295
-
296
-
func (nm *DBNotifMan) GetCount(ctx context.Context, user models.Uid) (int64, error) {
297
-
// TODO: sql count is inefficient
298
-
var lseen time.Time
299
-
if err := nm.db.Model(NotifSeen{}).Where("usr = ?", user).Select("last_seen").Scan(&lseen).Error; err != nil {
300
-
return 0, err
301
-
}
302
-
303
-
var c int64
304
-
//seen := nm.db.Model(NotifSeen{}).Where("usr = ?", user).Select("last_seen")
305
-
if err := nm.db.Model(NotifRecord{}).Where("for = ? AND created_at > ?", user, lseen).Count(&c).Error; err != nil {
306
-
return 0, err
307
-
}
308
-
309
-
return c, nil
310
-
}
311
-
312
-
func (nm *DBNotifMan) UpdateSeen(ctx context.Context, usr models.Uid, seen time.Time) error {
313
-
if err := nm.db.Clauses(clause.OnConflict{
314
-
Columns: []clause.Column{{Name: "usr"}},
315
-
DoUpdates: clause.AssignmentColumns([]string{"last_seen"}),
316
-
}).Create(NotifSeen{
317
-
Usr: usr,
318
-
LastSeen: seen,
319
-
}).Error; err != nil {
320
-
return err
321
-
}
322
-
323
-
return nil
324
-
}
325
-
326
-
func (nm *DBNotifMan) AddReplyTo(ctx context.Context, user models.Uid, replyid uint, replyto *models.FeedPost) error {
327
-
return nm.db.Create(&NotifRecord{
328
-
Kind: NotifKindReply,
329
-
For: replyto.Author,
330
-
Who: user,
331
-
ReplyTo: replyto.ID,
332
-
Record: replyid,
333
-
}).Error
334
-
}
335
-
336
-
func (nm *DBNotifMan) AddMention(ctx context.Context, user models.Uid, postid uint, mentioned models.Uid) error {
337
-
return nm.db.Create(&NotifRecord{
338
-
For: mentioned,
339
-
Kind: NotifKindMention,
340
-
Record: postid,
341
-
Who: user,
342
-
}).Error
343
-
}
344
-
345
-
func (nm *DBNotifMan) AddUpVote(ctx context.Context, voter models.Uid, postid uint, voteid uint, postauthor models.Uid) error {
346
-
return nm.db.Create(&NotifRecord{
347
-
For: postauthor,
348
-
Kind: NotifKindUpVote,
349
-
ReplyTo: postid,
350
-
Record: voteid,
351
-
Who: voter,
352
-
}).Error
353
-
}
354
-
355
-
func (nm *DBNotifMan) AddFollow(ctx context.Context, follower, followed models.Uid, recid uint) error {
356
-
return nm.db.Create(&NotifRecord{
357
-
Kind: NotifKindFollow,
358
-
For: followed,
359
-
Who: follower,
360
-
Record: recid,
361
-
}).Error
362
-
}
363
-
364
-
func (nm *DBNotifMan) AddRepost(ctx context.Context, op models.Uid, repost uint, reposter models.Uid) error {
365
-
return nm.db.Create(&NotifRecord{
366
-
Kind: NotifKindRepost,
367
-
For: op,
368
-
Record: repost,
369
-
Who: reposter,
370
-
}).Error
371
-
}
···
-47
notifs/null.go
-47
notifs/null.go
···
1
-
package notifs
2
-
3
-
import (
4
-
"context"
5
-
"fmt"
6
-
"time"
7
-
8
-
appbskytypes "github.com/bluesky-social/indigo/api/bsky"
9
-
"github.com/bluesky-social/indigo/models"
10
-
)
11
-
12
-
type NullNotifs struct {
13
-
}
14
-
15
-
var _ NotificationManager = (*NullNotifs)(nil)
16
-
17
-
func (nn *NullNotifs) GetNotifications(ctx context.Context, user models.Uid) ([]*appbskytypes.NotificationListNotifications_Notification, error) {
18
-
return nil, fmt.Errorf("no notifications engine loaded")
19
-
}
20
-
21
-
func (nn *NullNotifs) GetCount(ctx context.Context, user models.Uid) (int64, error) {
22
-
return 0, fmt.Errorf("no notifications engine loaded")
23
-
}
24
-
25
-
func (nn *NullNotifs) UpdateSeen(ctx context.Context, usr models.Uid, seen time.Time) error {
26
-
return nil
27
-
}
28
-
29
-
func (nn *NullNotifs) AddReplyTo(ctx context.Context, user models.Uid, replyid uint, replyto *models.FeedPost) error {
30
-
return nil
31
-
}
32
-
33
-
func (nn *NullNotifs) AddMention(ctx context.Context, user models.Uid, postid uint, mentioned models.Uid) error {
34
-
return nil
35
-
}
36
-
37
-
func (nn *NullNotifs) AddUpVote(ctx context.Context, voter models.Uid, postid uint, voteid uint, postauthor models.Uid) error {
38
-
return nil
39
-
}
40
-
41
-
func (nn *NullNotifs) AddFollow(ctx context.Context, follower, followed models.Uid, recid uint) error {
42
-
return nil
43
-
}
44
-
45
-
func (nn *NullNotifs) AddRepost(ctx context.Context, op models.Uid, repost uint, reposter models.Uid) error {
46
-
return nil
47
-
}
···
+1
-5
pds/server.go
+1
-5
pds/server.go
···
20
"github.com/bluesky-social/indigo/indexer"
21
lexutil "github.com/bluesky-social/indigo/lex/util"
22
"github.com/bluesky-social/indigo/models"
23
-
"github.com/bluesky-social/indigo/notifs"
24
pdsdata "github.com/bluesky-social/indigo/pds/data"
25
"github.com/bluesky-social/indigo/plc"
26
"github.com/bluesky-social/indigo/repomgr"
···
42
cs carstore.CarStore
43
repoman *repomgr.RepoManager
44
feedgen *FeedGenerator
45
-
notifman notifs.NotificationManager
46
indexer *indexer.Indexer
47
events *events.EventManager
48
signingKey *did.PrivKey
···
74
kmgr := indexer.NewKeyManager(didr, serkey)
75
76
repoman := repomgr.NewRepoManager(cs, kmgr)
77
-
notifman := notifs.NewNotificationManager(db, repoman.GetRecord)
78
79
rf := indexer.NewRepoFetcher(db, repoman, 10)
80
81
-
ix, err := indexer.NewIndexer(db, notifman, evtman, didr, rf, false, true, true)
82
if err != nil {
83
return nil, err
84
}
···
87
signingKey: serkey,
88
db: db,
89
cs: cs,
90
-
notifman: notifman,
91
indexer: ix,
92
plc: didr,
93
events: evtman,
···
20
"github.com/bluesky-social/indigo/indexer"
21
lexutil "github.com/bluesky-social/indigo/lex/util"
22
"github.com/bluesky-social/indigo/models"
23
pdsdata "github.com/bluesky-social/indigo/pds/data"
24
"github.com/bluesky-social/indigo/plc"
25
"github.com/bluesky-social/indigo/repomgr"
···
41
cs carstore.CarStore
42
repoman *repomgr.RepoManager
43
feedgen *FeedGenerator
44
indexer *indexer.Indexer
45
events *events.EventManager
46
signingKey *did.PrivKey
···
72
kmgr := indexer.NewKeyManager(didr, serkey)
73
74
repoman := repomgr.NewRepoManager(cs, kmgr)
75
76
rf := indexer.NewRepoFetcher(db, repoman, 10)
77
78
+
ix, err := indexer.NewIndexer(db, evtman, didr, rf, false, true, true)
79
if err != nil {
80
return nil, err
81
}
···
84
signingKey: serkey,
85
db: db,
86
cs: cs,
87
indexer: ix,
88
plc: didr,
89
events: evtman,
+1
-16
testing/utils.go
+1
-16
testing/utils.go
···
29
"github.com/bluesky-social/indigo/indexer"
30
lexutil "github.com/bluesky-social/indigo/lex/util"
31
"github.com/bluesky-social/indigo/models"
32
-
"github.com/bluesky-social/indigo/notifs"
33
"github.com/bluesky-social/indigo/pds"
34
"github.com/bluesky-social/indigo/plc"
35
"github.com/bluesky-social/indigo/repo"
···
469
return resp.Feed
470
}
471
472
-
func (u *TestUser) GetNotifs(t *testing.T) []*bsky.NotificationListNotifications_Notification {
473
-
t.Helper()
474
-
475
-
ctx := context.TODO()
476
-
resp, err := bsky.NotificationListNotifications(ctx, u.client, "", 100, false, nil, "")
477
-
if err != nil {
478
-
t.Fatal(err)
479
-
}
480
-
481
-
return resp.Notifications
482
-
}
483
-
484
func (u *TestUser) ChangeHandle(t *testing.T, nhandle string) {
485
t.Helper()
486
···
572
573
repoman := repomgr.NewRepoManager(cs, kmgr)
574
575
-
notifman := notifs.NewNotificationManager(maindb, repoman.GetRecord)
576
-
577
opts := events.DefaultDiskPersistOptions()
578
opts.EventsPerFile = 10
579
diskpersist, err := events.NewDiskPersistence(filepath.Join(dir, "dp-primary"), filepath.Join(dir, "dp-archive"), maindb, opts)
···
581
evtman := events.NewEventManager(diskpersist)
582
rf := indexer.NewRepoFetcher(maindb, repoman, 10)
583
584
-
ix, err := indexer.NewIndexer(maindb, notifman, evtman, didr, rf, true, true, true)
585
if err != nil {
586
return nil, err
587
}
···
29
"github.com/bluesky-social/indigo/indexer"
30
lexutil "github.com/bluesky-social/indigo/lex/util"
31
"github.com/bluesky-social/indigo/models"
32
"github.com/bluesky-social/indigo/pds"
33
"github.com/bluesky-social/indigo/plc"
34
"github.com/bluesky-social/indigo/repo"
···
468
return resp.Feed
469
}
470
471
func (u *TestUser) ChangeHandle(t *testing.T, nhandle string) {
472
t.Helper()
473
···
559
560
repoman := repomgr.NewRepoManager(cs, kmgr)
561
562
opts := events.DefaultDiskPersistOptions()
563
opts.EventsPerFile = 10
564
diskpersist, err := events.NewDiskPersistence(filepath.Join(dir, "dp-primary"), filepath.Join(dir, "dp-archive"), maindb, opts)
···
566
evtman := events.NewEventManager(diskpersist)
567
rf := indexer.NewRepoFetcher(maindb, repoman, 10)
568
569
+
ix, err := indexer.NewIndexer(maindb, evtman, didr, rf, true, true, true)
570
if err != nil {
571
return nil, err
572
}