appview: ingest issue comment records #525

merged
opened by anirudh.fi targeting master from push-wnotmtoqlnvl
Changed files
+81 -6
appview
+19 -6
appview/db/issues.go
··· 3 3 import ( 4 4 "database/sql" 5 5 "fmt" 6 + mathrand "math/rand/v2" 6 7 "time" 7 8 8 9 "github.com/bluesky-social/indigo/atproto/syntax" ··· 108 109 } 109 110 110 111 comment := Comment{ 111 - OwnerDid: ownerDid, 112 - RepoAt: repoAt, 113 - Rkey: rkey, 114 - Body: record.Body, 115 - Issue: issueId, 116 - Created: &created, 112 + OwnerDid: ownerDid, 113 + RepoAt: repoAt, 114 + Rkey: rkey, 115 + Body: record.Body, 116 + Issue: issueId, 117 + CommentId: mathrand.IntN(1000000), 118 + Created: &created, 117 119 } 118 120 119 121 return comment, nil ··· 543 545 return err 544 546 } 545 547 548 + func DeleteCommentByRkey(e Execer, ownerDid, rkey string) error { 549 + _, err := e.Exec( 550 + ` 551 + update comments 552 + set body = "", 553 + deleted = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') 554 + where owner_did = ? and rkey = ? 555 + `, ownerDid, rkey) 556 + return err 557 + } 558 + 546 559 func CloseIssue(e Execer, repoAt syntax.ATURI, issueId int) error { 547 560 _, err := e.Exec(`update issues set open = 0 where repo_at = ? and issue_id = ?`, repoAt, issueId) 548 561 return err
+61
appview/ingester.go
··· 70 70 err = i.ingestString(e) 71 71 case tangled.RepoIssueNSID: 72 72 err = i.ingestIssue(ctx, e) 73 + case tangled.RepoIssueCommentNSID: 74 + err = i.ingestIssueComment(e) 73 75 } 74 76 l = i.Logger.With("nsid", e.Commit.Collection) 75 77 } ··· 673 675 674 676 return fmt.Errorf("unknown operation: %s", e.Commit.Operation) 675 677 } 678 + 679 + func (i *Ingester) ingestIssueComment(e *models.Event) error { 680 + did := e.Did 681 + rkey := e.Commit.RKey 682 + 683 + var err error 684 + 685 + l := i.Logger.With("handler", "ingestIssueComment", "nsid", e.Commit.Collection, "did", did, "rkey", rkey) 686 + l.Info("ingesting record") 687 + 688 + ddb, ok := i.Db.Execer.(*db.DB) 689 + if !ok { 690 + return fmt.Errorf("failed to index issue comment record, invalid db cast") 691 + } 692 + 693 + switch e.Commit.Operation { 694 + case models.CommitOperationCreate: 695 + raw := json.RawMessage(e.Commit.Record) 696 + record := tangled.RepoIssueComment{} 697 + err = json.Unmarshal(raw, &record) 698 + if err != nil { 699 + l.Error("invalid record", "err", err) 700 + return err 701 + } 702 + 703 + comment, err := db.IssueCommentFromRecord(ddb, did, rkey, record) 704 + if err != nil { 705 + l.Error("failed to parse comment from record", "err", err) 706 + return err 707 + } 708 + 709 + sanitizer := markup.NewSanitizer() 710 + if sb := strings.TrimSpace(sanitizer.SanitizeDefault(comment.Body)); sb == "" { 711 + return fmt.Errorf("body is empty after HTML sanitization") 712 + } 713 + 714 + err = db.NewIssueComment(ddb, &comment) 715 + if err != nil { 716 + l.Error("failed to create issue comment", "err", err) 717 + return err 718 + } 719 + 720 + return nil 721 + 722 + case models.CommitOperationUpdate: 723 + // TODO: implement comment updates 724 + return nil 725 + 726 + case models.CommitOperationDelete: 727 + if err := db.DeleteCommentByRkey(ddb, did, rkey); err != nil { 728 + l.Error("failed to delete", "err", err) 729 + return fmt.Errorf("failed to delete issue comment record: %w", err) 730 + } 731 + 732 + return nil 733 + } 734 + 735 + return fmt.Errorf("unknown operation: %s", e.Commit.Operation) 736 + }
+1
appview/state/state.go
··· 95 95 tangled.SpindleNSID, 96 96 tangled.StringNSID, 97 97 tangled.RepoIssueNSID, 98 + tangled.RepoIssueCommentNSID, 98 99 }, 99 100 nil, 100 101 slog.Default(),