-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstorage.go
More file actions
139 lines (115 loc) · 3.16 KB
/
Copy pathstorage.go
File metadata and controls
139 lines (115 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"context"
"database/sql"
"fmt"
"log"
"github.com/bits-and-blooms/bloom/v3"
"github.com/fiatjaf/relayer/v2/storage/postgresql"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip19"
"github.com/stemstr/blastr"
)
func newStorage(cfg Config) *storage {
store := &storage{
PostgresBackend: &postgresql.PostgresBackend{
DatabaseURL: cfg.DatabaseURL,
QueryLimit: 1000,
QueryAuthorsLimit: 1000,
QueryIDsLimit: 1000,
QueryKindsLimit: 10,
QueryTagsLimit: 20,
},
cfg: cfg,
}
if cfg.BlastrNsec != "" {
store.blastr, _ = blastr.New(cfg.BlastrNsec)
}
return store
}
type storage struct {
*postgresql.PostgresBackend
cfg Config
blastr blastrIface
seenEvents *bloom.BloomFilter
}
type blastrIface interface {
Send(context.Context, nostr.Event) error
}
func (s *storage) Init() error {
// First call the shadowed relayer Init
if err := s.PostgresBackend.Init(); err != nil {
return err
}
// Now do our own init
if s.cfg.BloomFilterSize > 0 && s.cfg.BloomFilterFP > 0 {
log.Printf("bloom filter size: %v fp: %v\n", s.cfg.BloomFilterSize, s.cfg.BloomFilterFP)
s.seenEvents = bloom.NewWithEstimates(s.cfg.BloomFilterSize, s.cfg.BloomFilterFP)
} else {
log.Printf("defaulting bloom filter size: 1,000,000 fp: 0.01\n")
s.seenEvents = bloom.NewWithEstimates(1_000_000, 0.01)
}
if err := s.initSeenEvents(); err != nil {
return fmt.Errorf("initSeenEvents: %w", err)
}
return nil
}
func (s *storage) BeforeSave(ctx context.Context, event *nostr.Event) {
}
func (s *storage) AfterSave(event *nostr.Event) {
// Update the Bloom Filter
s.seenEvents.Add([]byte(event.ID))
switch event.Kind {
case 1808:
shareEvent := generateShareEvent(event)
if shareEvent != nil && s.blastr != nil {
s.blastr.Send(context.Background(), *shareEvent)
}
}
}
func (s *storage) initSeenEvents() error {
ids, err := s.getAllEventIDs()
if err != nil {
return err
}
for _, id := range ids {
s.seenEvents.Add([]byte(id))
}
log.Printf("seenFilter count: %d\n", s.seenEvents.ApproximatedSize())
return nil
}
func (s *storage) getAllEventIDs() ([]string, error) {
var ids []string
err := s.DB.Select(&ids, "SELECT id FROM event")
if err != nil && err != sql.ErrNoRows {
return nil, fmt.Errorf("failed to select events: %w", err)
}
return ids, nil
}
const (
stemstrNpub = "npub1stemstrls4f5plqeqkeq43gtjhtycuqd9w25v5r5z5ygaq2n2sjsd6mul5"
stemstrHexpub = "82f3b82c7f855340fc1905b20ac50b95d64c700d2b9546507415088e81535425"
)
func generateShareEvent(event *nostr.Event) *nostr.Event {
npub, err := nip19.EncodePublicKey(event.PubKey)
if err != nil {
log.Printf("failed to encoded share event npub: %v", err)
return nil
}
content := fmt.Sprintf(
"🎉 Let's gooo! nostr:%s just shared a track on nostr:%s 🙌.\n\nCheck it out at https://stemstr.app/thread/%s/\n\n#stemstr #music #tunestr",
npub, stemstrNpub, event.ID,
)
shareEvent := nostr.Event{
Kind: nostr.KindTextNote,
Tags: nostr.Tags{
{"p", event.PubKey}, // Tag author
{"p", stemstrHexpub}, // Tag stemstr
{"t", "stemstr"},
{"t", "music"},
{"t", "tunestr"},
},
Content: content,
}
return &shareEvent
}