A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
0
fork

Configure Feed

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

clean up some lexicon usage

+18 -24
+3
pkg/atproto/lexicon.go
··· 41 41 // TangledProfileCollection is the collection name for tangled profiles 42 42 // Stored in hold's embedded PDS (singleton record at rkey "self") 43 43 TangledProfileCollection = "sh.tangled.actor.profile" 44 + 45 + // BskyPostCollection is the collection name for Bluesky posts 46 + BskyPostCollection = "app.bsky.feed.post" 44 47 45 48 // SailorProfileCollection is the collection name for user profiles 46 49 SailorProfileCollection = "io.atcr.sailor.profile"
+4 -3
pkg/hold/pds/manifest_post.go
··· 9 9 "strings" 10 10 "time" 11 11 12 + "atcr.io/pkg/atproto" 12 13 bsky "github.com/bluesky-social/indigo/api/bsky" 13 14 "github.com/distribution/distribution/v3/registry/storage/driver" 14 15 ) ··· 70 71 71 72 // Create post struct with facets and embed 72 73 post := &bsky.FeedPost{ 73 - LexiconTypeID: "app.bsky.feed.post", 74 + LexiconTypeID: atproto.BskyPostCollection, 74 75 Text: text, 75 76 Facets: facets, 76 77 Embed: embed, ··· 82 83 rkey, recordCID, err := p.repomgr.CreateRecord( 83 84 ctx, 84 85 p.uid, 85 - "app.bsky.feed.post", 86 + atproto.BskyPostCollection, 86 87 post, 87 88 ) 88 89 ··· 91 92 } 92 93 93 94 // Build ATProto URI for the post 94 - postURI := fmt.Sprintf("at://%s/app.bsky.feed.post/%s", p.did, rkey) 95 + postURI := fmt.Sprintf("at://%s/%s/%s", p.did, atproto.BskyPostCollection, rkey) 95 96 96 97 slog.Info("Created manifest post", 97 98 "uri", postURI,
+3 -2
pkg/hold/pds/manifest_post_test.go
··· 4 4 "strings" 5 5 "testing" 6 6 7 + "atcr.io/pkg/atproto" 7 8 bsky "github.com/bluesky-social/indigo/api/bsky" 8 9 ) 9 10 ··· 196 197 197 198 // Verify the complete post structure 198 199 post := &bsky.FeedPost{ 199 - LexiconTypeID: "app.bsky.feed.post", 200 + LexiconTypeID: atproto.BskyPostCollection, 200 201 Text: text, 201 202 Facets: facets, 202 203 Langs: []string{"en"}, ··· 250 251 251 252 // Verify the complete post structure 252 253 post := &bsky.FeedPost{ 253 - LexiconTypeID: "app.bsky.feed.post", 254 + LexiconTypeID: atproto.BskyPostCollection, 254 255 Text: text, 255 256 Facets: facets, 256 257 Langs: []string{"en"},
+4 -8
pkg/hold/pds/status.go
··· 6 6 "log/slog" 7 7 "time" 8 8 9 + "atcr.io/pkg/atproto" 9 10 bsky "github.com/bluesky-social/indigo/api/bsky" 10 - ) 11 - 12 - const ( 13 - // StatusPostCollection is the collection name for Bluesky posts 14 - StatusPostCollection = "app.bsky.feed.post" 15 11 ) 16 12 17 13 // SetStatus creates a new status post on Bluesky ··· 40 36 // Create post struct 41 37 now := time.Now() 42 38 post := &bsky.FeedPost{ 43 - LexiconTypeID: "app.bsky.feed.post", 39 + LexiconTypeID: atproto.BskyPostCollection, 44 40 Text: text, 45 41 CreatedAt: now.Format(time.RFC3339), 46 42 } 47 43 48 44 // Use repomgr.CreateRecord to create the post with auto-generated TID 49 45 // CreateRecord automatically generates a unique TID using the repo's clock 50 - rkey, recordCID, err := p.repomgr.CreateRecord(ctx, p.uid, StatusPostCollection, post) 46 + rkey, recordCID, err := p.repomgr.CreateRecord(ctx, p.uid, atproto.BskyPostCollection, post) 51 47 if err != nil { 52 48 return fmt.Errorf("failed to create status post: %w", err) 53 49 } 54 50 55 51 slog.Info("Created status post", 56 - "collection", StatusPostCollection, 52 + "collection", atproto.BskyPostCollection, 57 53 "rkey", rkey, 58 54 "cid", recordCID.String(), 59 55 "text", text)
+3 -10
pkg/hold/pds/status_test.go
··· 61 61 listPosts := func() ([]map[string]any, error) { 62 62 req := makeXRPCGetRequest(atproto.RepoListRecords, map[string]string{ 63 63 "repo": did, 64 - "collection": StatusPostCollection, 64 + "collection": atproto.BskyPostCollection, 65 65 "limit": "100", 66 66 "reverse": "true", // Most recent first 67 67 }) ··· 134 134 } 135 135 // URI format: at://did:web:test.example.com/app.bsky.feed.post/3m3c4... 136 136 // We just check that it contains the collection 137 - if !contains(uri, StatusPostCollection) { 138 - t.Errorf("Expected URI to contain collection %s, got %s", StatusPostCollection, uri) 137 + if !contains(uri, atproto.BskyPostCollection) { 138 + t.Errorf("Expected URI to contain collection %s, got %s", atproto.BskyPostCollection, uri) 139 139 } 140 140 }) 141 141 ··· 224 224 t.Errorf("Expected text '🔴 Current status: offline', got '%s'", text) 225 225 } 226 226 }) 227 - } 228 - 229 - func TestStatusPostCollection(t *testing.T) { 230 - // Verify constant 231 - if StatusPostCollection != "app.bsky.feed.post" { 232 - t.Errorf("Expected StatusPostCollection 'app.bsky.feed.post', got '%s'", StatusPostCollection) 233 - } 234 227 } 235 228 236 229 // Helper function to check if a string contains a substring
+1 -1
pkg/hold/pds/xrpc.go
··· 366 366 repoHandle, err := repo.OpenRepo(ctx, session, head) 367 367 if err == nil { 368 368 postCount := 0 369 - _ = repoHandle.ForEach(ctx, "app.bsky.feed.post", func(k string, v cid.Cid) error { 369 + _ = repoHandle.ForEach(ctx, atproto.BskyPostCollection, func(k string, v cid.Cid) error { 370 370 postCount++ 371 371 return nil 372 372 })