+10
-11
automod/engine.go
+10
-11
automod/engine.go
···
5
5
"fmt"
6
6
"log/slog"
7
7
"strings"
8
-
"sync"
9
8
10
9
appbsky "github.com/bluesky-social/indigo/api/bsky"
11
10
"github.com/bluesky-social/indigo/atproto/identity"
12
11
"github.com/bluesky-social/indigo/atproto/syntax"
13
-
"github.com/bluesky-social/indigo/xrpc"
14
12
)
15
13
16
14
// runtime for executing rules, managing state, and recording moderation actions.
17
15
//
18
16
// TODO: careful when initializing: several fields should not be null or zero, even though they are pointer type.
19
17
type Engine struct {
20
-
Logger *slog.Logger
18
+
Logger *slog.Logger
21
19
Directory identity.Directory
22
20
// current rule sets. will eventually be possible to swap these out at runtime
23
-
RulesMap sync.Map
21
+
// TODO: RulesMap sync.Map
24
22
// used to persist moderation actions in mod service (optional)
25
-
AdminClient *xrpc.Client
26
-
CountStore CountStore
23
+
// TODO: AdminClient *xrpc.Client
24
+
Counters CountStore
25
+
Sets SetStore
27
26
}
28
27
29
28
func (e *Engine) ProcessIdentityEvent(ctx context.Context, t string, did syntax.DID) error {
···
92
91
93
92
func (e *Engine) NewPostEvent(ident *identity.Identity, path string, post *appbsky.FeedPost) PostEvent {
94
93
return PostEvent{
95
-
RecordEvent {
94
+
RecordEvent{
96
95
Event{
97
96
Engine: e,
98
97
Account: AccountMeta{Identity: ident},
···
119
118
}
120
119
121
120
func (e *Engine) GetCount(key, period string) (int, error) {
122
-
return e.CountStore.GetCount(context.TODO(), key, period)
121
+
return e.Counters.GetCount(context.TODO(), key, period)
123
122
}
124
123
125
-
func (e *Engine) InSet(setName, val string) (bool, error) {
126
-
// XXX: implement
127
-
return false, nil
124
+
// checks if `val` is an element of set `name`
125
+
func (e *Engine) InSet(name, val string) (bool, error) {
126
+
return e.Sets.InSet(context.TODO(), name, val)
128
127
}
+30
automod/setstore.go
+30
automod/setstore.go
···
1
+
package automod
2
+
3
+
import (
4
+
"context"
5
+
"fmt"
6
+
)
7
+
8
+
type SetStore interface {
9
+
InSet(ctx context.Context, name, val string) (bool, error)
10
+
}
11
+
12
+
// TODO: this implementation isn't race-safe (yet)!
13
+
type MemSetStore struct {
14
+
Sets map[string]map[string]bool
15
+
}
16
+
17
+
func NewMemSetStore() MemSetStore {
18
+
return MemSetStore{
19
+
Sets: make(map[string]map[string]bool),
20
+
}
21
+
}
22
+
23
+
func (s MemSetStore) InSet(ctx context.Context, name, val string) (bool, error) {
24
+
set, ok := s.Sets[name]
25
+
if !ok {
26
+
return false, fmt.Errorf("not a known set: %s", name)
27
+
}
28
+
_, ok = set[val]
29
+
return ok, nil
30
+
}
+3
-3
cmd/hepa/otel.go
+3
-3
cmd/hepa/otel.go
+3
-2
cmd/hepa/server.go
+3
-2
cmd/hepa/server.go
···
38
38
}
39
39
40
40
engine := automod.Engine{
41
-
Logger: logger,
41
+
Logger: logger,
42
42
Directory: dir,
43
-
CountStore: automod.NewMemCountStore(),
43
+
Counters: automod.NewMemCountStore(),
44
+
Sets: automod.NewMemSetStore(),
44
45
// TODO: RulesMap (loaded/config from somewhere)
45
46
// TODO: AdminClient (XRPC with mod access)
46
47
}