Monorepo for Tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview: migrate legacy comment pds records

Signed-off-by: Seongmin Lee <git@boltless.me>

+130
+14
appview/db/db.go
··· 1527 1527 return err 1528 1528 }) 1529 1529 1530 + orm.RunMigration(conn, logger, "migrate-legacy-comments", func(tx *sql.Tx) error { 1531 + _, err := tx.Exec(` 1532 + insert into pds_migration (name, did, collection, rkey) 1533 + select 1534 + 'use-feed-comment', 1535 + did, 1536 + collection, 1537 + rkey 1538 + from comments 1539 + where collection <> 'sh.tangled.feed.comment'; 1540 + `) 1541 + return err 1542 + }) 1543 + 1530 1544 return &DB{ 1531 1545 db, 1532 1546 logger,
+114
appview/migration/migrate_use_feed_comment.go
··· 1 + package migration 2 + 3 + import ( 4 + "context" 5 + "fmt" 6 + 7 + "github.com/bluesky-social/indigo/api/agnostic" 8 + comatproto "github.com/bluesky-social/indigo/api/atproto" 9 + "github.com/bluesky-social/indigo/atproto/atclient" 10 + "github.com/bluesky-social/indigo/atproto/syntax" 11 + "github.com/bluesky-social/indigo/lex/util" 12 + "github.com/bluesky-social/indigo/xrpc" 13 + "tangled.org/core/api/tangled" 14 + "tangled.org/core/appview/db" 15 + "tangled.org/core/orm" 16 + ) 17 + 18 + 19 + func (s *Migration) migrateUseFeedComment(ctx context.Context, client *atclient.APIClient, did syntax.DID, record syntax.ATURI) error { 20 + l := s.logger.With("aturi", record) 21 + l.Debug("migrating record") 22 + 23 + switch record.Collection() { 24 + case tangled.RepoIssueCommentNSID: 25 + case tangled.RepoPullCommentNSID: 26 + default: 27 + return fmt.Errorf("unexpected collection: '%s'", record.Collection()) 28 + } 29 + 30 + comment, err := db.GetComment(s.db, orm.FilterEq("at_uri", record)) 31 + if err != nil { 32 + return fmt.Errorf("db: %w", err) 33 + } 34 + 35 + comment.Collection = tangled.FeedCommentNSID 36 + 37 + // only update from DB if comment is deleted 38 + if comment.Deleted != nil { 39 + l.Info("skipping pds migration for deleted record") 40 + 41 + return nil 42 + } 43 + 44 + // fill missing reference CIDs 45 + if comment.Subject.Cid == "" { 46 + cid, err := s.getRecordCid(ctx, syntax.ATURI(comment.Subject.Uri)) 47 + if err != nil { 48 + return fmt.Errorf("pds: getRecordCid for subject.uri: %w", err) 49 + } 50 + comment.Subject.Cid = cid.String() 51 + } 52 + if comment.ReplyTo != nil && comment.ReplyTo.Cid == "" { 53 + uri, err := syntax.ParseATURI(comment.ReplyTo.Uri) 54 + if err != nil { 55 + return fmt.Errorf("invalid replyTo.uri: %w", err) 56 + } 57 + 58 + // assume parent comment is already migrated to `sh.tangled.feed.comment`. 59 + // fail if it isn't ready 60 + uri = syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", uri.Authority(), tangled.FeedCommentNSID, uri.RecordKey())) 61 + 62 + cid, err := s.getRecordCid(ctx, uri) 63 + if err != nil { 64 + return fmt.Errorf("pds: getRecordCid for replyTo.uri: %w", err) 65 + } 66 + comment.ReplyTo.Uri = uri.String() 67 + comment.ReplyTo.Cid = cid.String() 68 + } 69 + 70 + // use same rkey for new record 71 + rkey := record.RecordKey().String() 72 + 73 + if _, err := comatproto.RepoApplyWrites(ctx, client, &comatproto.RepoApplyWrites_Input{ 74 + Repo: did.String(), 75 + Writes: []*comatproto.RepoApplyWrites_Input_Writes_Elem{ 76 + {RepoApplyWrites_Delete: &comatproto.RepoApplyWrites_Delete{ 77 + Collection: record.Collection().String(), 78 + Rkey: rkey, 79 + }}, 80 + {RepoApplyWrites_Create: &comatproto.RepoApplyWrites_Create{ 81 + Collection: tangled.FeedCommentNSID, 82 + Rkey: &rkey, 83 + Value: &util.LexiconTypeDecoder{Val: comment.AsRecord()}, 84 + }}, 85 + }, 86 + }); err != nil { 87 + return fmt.Errorf("pds: applyWrites: %w", err) 88 + } 89 + 90 + return nil 91 + } 92 + 93 + func (s *Migration) getRecordCid(ctx context.Context, uri syntax.ATURI) (syntax.CID, error) { 94 + ident, err := s.dir.Lookup(ctx, uri.Authority()) 95 + if err != nil { 96 + return "", err 97 + } 98 + 99 + xrpcc := xrpc.Client{Host: ident.PDSEndpoint()} 100 + out, err := agnostic.RepoGetRecord(ctx, &xrpcc, "", uri.Collection().String(), ident.DID.String(), uri.RecordKey().String()) 101 + if err != nil { 102 + return "", err 103 + } 104 + if out.Cid == nil { 105 + return "", fmt.Errorf("record CID is empty") 106 + } 107 + 108 + cid, err := syntax.ParseCID(*out.Cid) 109 + if err != nil { 110 + return "", err 111 + } 112 + 113 + return cid, nil 114 + }
+2
appview/migration/migration.go
··· 71 71 switch migration.Name { 72 72 case "add-repo-did": 73 73 err = s.migrateAddRepoDid(ctx, client, migration.Did, migration.RecordAtUri()) 74 + case "use-feed-comment": 75 + err = s.migrateUseFeedComment(ctx, client, migration.Did, migration.RecordAtUri()) 74 76 default: 75 77 return fmt.Errorf("unexpected migration name %s", migration.Name) 76 78 }