+70
-6
appview/ingester.go
+70
-6
appview/ingester.go
···
5
5
"encoding/json"
6
6
"fmt"
7
7
"log/slog"
8
+
"strings"
8
9
"time"
9
10
10
11
"github.com/bluesky-social/indigo/atproto/syntax"
···
14
15
"tangled.sh/tangled.sh/core/api/tangled"
15
16
"tangled.sh/tangled.sh/core/appview/config"
16
17
"tangled.sh/tangled.sh/core/appview/db"
18
+
"tangled.sh/tangled.sh/core/appview/pages/markup"
17
19
"tangled.sh/tangled.sh/core/appview/spindleverify"
18
20
"tangled.sh/tangled.sh/core/idresolver"
19
21
"tangled.sh/tangled.sh/core/rbac"
···
61
63
case tangled.ActorProfileNSID:
62
64
err = i.ingestProfile(e)
63
65
case tangled.SpindleMemberNSID:
64
-
err = i.ingestSpindleMember(e)
66
+
err = i.ingestSpindleMember(ctx, e)
65
67
case tangled.SpindleNSID:
66
-
err = i.ingestSpindle(e)
68
+
err = i.ingestSpindle(ctx, e)
67
69
case tangled.StringNSID:
68
70
err = i.ingestString(e)
71
+
case tangled.RepoIssueNSID:
72
+
err = i.ingestIssue(ctx, e)
69
73
}
70
74
l = i.Logger.With("nsid", e.Commit.Collection)
71
75
}
···
336
340
return nil
337
341
}
338
342
339
-
func (i *Ingester) ingestSpindleMember(e *models.Event) error {
343
+
func (i *Ingester) ingestSpindleMember(ctx context.Context, e *models.Event) error {
340
344
did := e.Did
341
345
var err error
342
346
···
359
363
return fmt.Errorf("failed to enforce permissions: %w", err)
360
364
}
361
365
362
-
memberId, err := i.IdResolver.ResolveIdent(context.Background(), record.Subject)
366
+
memberId, err := i.IdResolver.ResolveIdent(ctx, record.Subject)
363
367
if err != nil {
364
368
return err
365
369
}
···
442
446
return nil
443
447
}
444
448
445
-
func (i *Ingester) ingestSpindle(e *models.Event) error {
449
+
func (i *Ingester) ingestSpindle(ctx context.Context, e *models.Event) error {
446
450
did := e.Did
447
451
var err error
448
452
···
475
479
return err
476
480
}
477
481
478
-
err = spindleverify.RunVerification(context.Background(), instance, did, i.Config.Core.Dev)
482
+
err = spindleverify.RunVerification(ctx, instance, did, i.Config.Core.Dev)
479
483
if err != nil {
480
484
l.Error("failed to add spindle to db", "err", err, "instance", instance)
481
485
return err
···
609
613
610
614
return nil
611
615
}
616
+
617
+
func (i *Ingester) ingestIssue(ctx context.Context, e *models.Event) error {
618
+
did := e.Did
619
+
rkey := e.Commit.RKey
620
+
621
+
var err error
622
+
623
+
l := i.Logger.With("handler", "ingestIssue", "nsid", e.Commit.Collection, "did", did, "rkey", rkey)
624
+
l.Info("ingesting record")
625
+
626
+
ddb, ok := i.Db.Execer.(*db.DB)
627
+
if !ok {
628
+
return fmt.Errorf("failed to index issue record, invalid db cast")
629
+
}
630
+
631
+
switch e.Commit.Operation {
632
+
case models.CommitOperationCreate:
633
+
raw := json.RawMessage(e.Commit.Record)
634
+
record := tangled.RepoIssue{}
635
+
err = json.Unmarshal(raw, &record)
636
+
if err != nil {
637
+
l.Error("invalid record", "err", err)
638
+
return err
639
+
}
640
+
641
+
issue := db.IssueFromRecord(did, rkey, record)
642
+
643
+
sanitizer := markup.NewSanitizer()
644
+
if st := strings.TrimSpace(sanitizer.SanitizeDescription(issue.Title)); st == "" {
645
+
return fmt.Errorf("title is empty after HTML sanitization")
646
+
}
647
+
if sb := strings.TrimSpace(sanitizer.SanitizeDefault(issue.Body)); sb == "" {
648
+
return fmt.Errorf("body is empty after HTML sanitization")
649
+
}
650
+
651
+
tx, err := ddb.BeginTx(ctx, nil)
652
+
if err != nil {
653
+
l.Error("failed to begin transaction", "err", err)
654
+
return err
655
+
}
656
+
657
+
err = db.NewIssue(tx, &issue)
658
+
if err != nil {
659
+
l.Error("failed to create issue", "err", err)
660
+
return err
661
+
}
662
+
663
+
return nil
664
+
665
+
case models.CommitOperationUpdate:
666
+
// TODO: implement updates
667
+
return nil
668
+
669
+
case models.CommitOperationDelete:
670
+
// TODO: implement issue deletion
671
+
return nil
672
+
}
673
+
674
+
return fmt.Errorf("unknown operation: %s", e.Commit.Operation)
675
+
}