A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
72
fork

Configure Feed

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

fix up lexicons and remvoe unused endpoints

+2 -150
-66
lexicons/io/atcr/hold/setStats.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "io.atcr.hold.setStats", 4 - "defs": { 5 - "main": { 6 - "type": "procedure", 7 - "description": "Set absolute stats values for a repository. Used for migration/admin purposes to set specific pull/push counts.", 8 - "input": { 9 - "encoding": "application/json", 10 - "schema": { 11 - "type": "object", 12 - "required": ["ownerDid", "repository"], 13 - "properties": { 14 - "ownerDid": { 15 - "type": "string", 16 - "format": "did", 17 - "description": "DID of the repository owner" 18 - }, 19 - "repository": { 20 - "type": "string", 21 - "maxLength": 256, 22 - "description": "Repository name" 23 - }, 24 - "pullCount": { 25 - "type": "integer", 26 - "minimum": 0, 27 - "description": "Absolute pull count to set" 28 - }, 29 - "pushCount": { 30 - "type": "integer", 31 - "minimum": 0, 32 - "description": "Absolute push count to set" 33 - }, 34 - "lastPull": { 35 - "type": "string", 36 - "format": "datetime", 37 - "description": "RFC3339 timestamp of last pull" 38 - }, 39 - "lastPush": { 40 - "type": "string", 41 - "format": "datetime", 42 - "description": "RFC3339 timestamp of last push" 43 - } 44 - } 45 - } 46 - }, 47 - "output": { 48 - "encoding": "application/json", 49 - "schema": { 50 - "type": "object", 51 - "required": ["success"], 52 - "properties": { 53 - "success": { 54 - "type": "boolean", 55 - "description": "Whether the stats were successfully updated" 56 - } 57 - } 58 - } 59 - }, 60 - "errors": [ 61 - { "name": "InvalidOwner" }, 62 - { "name": "InvalidRepository" } 63 - ] 64 - } 65 - } 66 - }
-33
lexicons/io/atcr/hold/uploadPart.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "io.atcr.hold.uploadPart", 4 - "defs": { 5 - "main": { 6 - "type": "procedure", 7 - "description": "Direct buffered part upload. Alternative to using presigned URLs from getPartUploadUrl. Requires X-Upload-Id and X-Part-Number headers.", 8 - "input": { 9 - "encoding": "*/*", 10 - "description": "Raw binary part data" 11 - }, 12 - "output": { 13 - "encoding": "application/json", 14 - "schema": { 15 - "type": "object", 16 - "required": ["etag"], 17 - "properties": { 18 - "etag": { 19 - "type": "string", 20 - "maxLength": 256, 21 - "description": "ETag of the uploaded part, required for completeUpload" 22 - } 23 - } 24 - } 25 - }, 26 - "errors": [ 27 - { "name": "InvalidUploadId" }, 28 - { "name": "InvalidPartNumber" }, 29 - { "name": "UploadFailed" } 30 - ] 31 - } 32 - } 33 - }
+2 -2
lexicons/io/atcr/sailor/profile.json
··· 12 12 "properties": { 13 13 "defaultHold": { 14 14 "type": "string", 15 - "format": "uri", 16 - "description": "Default hold endpoint for blob storage. If null, user has opted out of defaults." 15 + "format": "did", 16 + "description": "Default hold DID for blob storage. If null, user has opted out of defaults." 17 17 }, 18 18 "autoRemoveUntagged": { 19 19 "type": "boolean",
-6
pkg/atproto/endpoints.go
··· 46 46 // Response: {"success": true, "layersCreated": 5, "postCreated": true, "postUri": "at://..."} 47 47 HoldNotifyManifest = "/xrpc/io.atcr.hold.notifyManifest" 48 48 49 - // HoldSetStats sets absolute stats values for a repository (used by migration). 50 - // Method: POST 51 - // Request: {"ownerDid": "...", "repository": "...", "pullCount": 10, "pushCount": 5, "lastPull": "...", "lastPush": "..."} 52 - // Response: {"success": true} 53 - HoldSetStats = "/xrpc/io.atcr.hold.setStats" 54 - 55 49 // HoldGetQuota returns storage quota information for a user. 56 50 // Method: GET 57 51 // Query: userDid={did}
-43
pkg/hold/pds/stats.go
··· 93 93 return recordCID, statsRecord, nil 94 94 } 95 95 96 - // SetStats directly sets the stats for a repository (used for migration) 97 - // Creates or updates the stats record with the specified counts 98 - func (p *HoldPDS) SetStats(ctx context.Context, ownerDID, repository string, pullCount, pushCount int64, lastPull, lastPush string) error { 99 - rkey := atproto.StatsRecordKey(ownerDID, repository) 100 - now := time.Now().Format(time.RFC3339) 101 - 102 - // Try to get existing record 103 - _, existing, err := p.GetStats(ctx, ownerDID, repository) 104 - if err != nil { 105 - // Record doesn't exist - create new one 106 - record := &atproto.StatsRecord{ 107 - Type: atproto.StatsCollection, 108 - OwnerDID: ownerDID, 109 - Repository: repository, 110 - PullCount: pullCount, 111 - PushCount: pushCount, 112 - LastPull: lastPull, 113 - LastPush: lastPush, 114 - UpdatedAt: now, 115 - } 116 - 117 - _, _, err := p.repomgr.PutRecord(ctx, p.uid, atproto.StatsCollection, rkey, record) 118 - if err != nil { 119 - return fmt.Errorf("failed to create stats record: %w", err) 120 - } 121 - return nil 122 - } 123 - 124 - // Record exists - update it 125 - existing.PullCount = pullCount 126 - existing.PushCount = pushCount 127 - existing.LastPull = lastPull 128 - existing.LastPush = lastPush 129 - existing.UpdatedAt = now 130 - 131 - _, err = p.repomgr.UpdateRecord(ctx, p.uid, atproto.StatsCollection, rkey, existing) 132 - if err != nil { 133 - return fmt.Errorf("failed to update stats record: %w", err) 134 - } 135 - 136 - return nil 137 - } 138 - 139 96 // ListStats returns all stats records in the hold's PDS 140 97 // This is used by AppView to aggregate stats from all holds 141 98 func (p *HoldPDS) ListStats(ctx context.Context) ([]*atproto.StatsRecord, error) {