appview: ingest issue comment records

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.sh>

anirudh.fi 1db01d86 6b9d5c80

verified
Changed files
+120 -6
appview
+40 -6
appview/db/issues.go
··· 3 3 import ( 4 4 "database/sql" 5 5 "fmt" 6 + mathrand "math/rand/v2" 6 7 "strings" 7 8 "time" 8 9 ··· 109 110 } 110 111 111 112 comment := Comment{ 112 - OwnerDid: ownerDid, 113 - RepoAt: repoAt, 114 - Rkey: rkey, 115 - Body: record.Body, 116 - Issue: issueId, 117 - Created: &created, 113 + OwnerDid: ownerDid, 114 + RepoAt: repoAt, 115 + Rkey: rkey, 116 + Body: record.Body, 117 + Issue: issueId, 118 + CommentId: mathrand.IntN(1000000), 119 + Created: &created, 118 120 } 119 121 120 122 return comment, nil ··· 621 623 deleted = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') 622 624 where repo_at = ? and issue_id = ? and comment_id = ? 623 625 `, repoAt, issueId, commentId) 626 + return err 627 + } 628 + 629 + func UpdateCommentByRkey(e Execer, ownerDid, rkey, newBody string) error { 630 + _, err := e.Exec( 631 + ` 632 + update comments 633 + set body = ?, 634 + edited = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') 635 + where owner_did = ? and rkey = ? 636 + `, newBody, ownerDid, rkey) 637 + return err 638 + } 639 + 640 + func DeleteCommentByRkey(e Execer, ownerDid, rkey string) error { 641 + _, err := e.Exec( 642 + ` 643 + update comments 644 + set body = "", 645 + deleted = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') 646 + where owner_did = ? and rkey = ? 647 + `, ownerDid, rkey) 648 + return err 649 + } 650 + 651 + func UpdateIssueByRkey(e Execer, ownerDid, rkey, title, body string) error { 652 + _, err := e.Exec(`update issues set title = ?, body = ? where owner_did = ? and rkey = ?`, title, body, ownerDid, rkey) 653 + return err 654 + } 655 + 656 + func DeleteIssueByRkey(e Execer, ownerDid, rkey string) error { 657 + _, err := e.Exec(`delete from issues where owner_did = ? and rkey = ?`, ownerDid, rkey) 624 658 return err 625 659 } 626 660
+79
appview/ingester.go
··· 74 74 err = i.ingestString(e) 75 75 case tangled.RepoIssueNSID: 76 76 err = i.ingestIssue(ctx, e) 77 + case tangled.RepoIssueCommentNSID: 78 + err = i.ingestIssueComment(e) 77 79 } 78 80 l = i.Logger.With("nsid", e.Commit.Collection) 79 81 } ··· 862 864 863 865 return fmt.Errorf("unknown operation: %s", e.Commit.Operation) 864 866 } 867 + 868 + func (i *Ingester) ingestIssueComment(e *models.Event) error { 869 + did := e.Did 870 + rkey := e.Commit.RKey 871 + 872 + var err error 873 + 874 + l := i.Logger.With("handler", "ingestIssueComment", "nsid", e.Commit.Collection, "did", did, "rkey", rkey) 875 + l.Info("ingesting record") 876 + 877 + ddb, ok := i.Db.Execer.(*db.DB) 878 + if !ok { 879 + return fmt.Errorf("failed to index issue comment record, invalid db cast") 880 + } 881 + 882 + switch e.Commit.Operation { 883 + case models.CommitOperationCreate: 884 + raw := json.RawMessage(e.Commit.Record) 885 + record := tangled.RepoIssueComment{} 886 + err = json.Unmarshal(raw, &record) 887 + if err != nil { 888 + l.Error("invalid record", "err", err) 889 + return err 890 + } 891 + 892 + comment, err := db.IssueCommentFromRecord(ddb, did, rkey, record) 893 + if err != nil { 894 + l.Error("failed to parse comment from record", "err", err) 895 + return err 896 + } 897 + 898 + sanitizer := markup.NewSanitizer() 899 + if sb := strings.TrimSpace(sanitizer.SanitizeDefault(comment.Body)); sb == "" { 900 + return fmt.Errorf("body is empty after HTML sanitization") 901 + } 902 + 903 + err = db.NewIssueComment(ddb, &comment) 904 + if err != nil { 905 + l.Error("failed to create issue comment", "err", err) 906 + return err 907 + } 908 + 909 + return nil 910 + 911 + case models.CommitOperationUpdate: 912 + raw := json.RawMessage(e.Commit.Record) 913 + record := tangled.RepoIssueComment{} 914 + err = json.Unmarshal(raw, &record) 915 + if err != nil { 916 + l.Error("invalid record", "err", err) 917 + return err 918 + } 919 + 920 + sanitizer := markup.NewSanitizer() 921 + if sb := strings.TrimSpace(sanitizer.SanitizeDefault(record.Body)); sb == "" { 922 + return fmt.Errorf("body is empty after HTML sanitization") 923 + } 924 + 925 + err = db.UpdateCommentByRkey(ddb, did, rkey, record.Body) 926 + if err != nil { 927 + l.Error("failed to update issue comment", "err", err) 928 + return err 929 + } 930 + 931 + return nil 932 + 933 + case models.CommitOperationDelete: 934 + if err := db.DeleteCommentByRkey(ddb, did, rkey); err != nil { 935 + l.Error("failed to delete", "err", err) 936 + return fmt.Errorf("failed to delete issue comment record: %w", err) 937 + } 938 + 939 + return nil 940 + } 941 + 942 + return fmt.Errorf("unknown operation: %s", e.Commit.Operation) 943 + }
+1
appview/state/state.go
··· 100 100 tangled.SpindleNSID, 101 101 tangled.StringNSID, 102 102 tangled.RepoIssueNSID, 103 + tangled.RepoIssueCommentNSID, 103 104 }, 104 105 nil, 105 106 slog.Default(),