An atproto PDS written in Go
1package server 2 3import ( 4 "github.com/haileyok/cocoon/internal/helpers" 5 "github.com/haileyok/cocoon/models" 6 "github.com/ipfs/go-cid" 7 "github.com/labstack/echo/v4" 8) 9 10type ComAtprotoSyncListBlobsResponse struct { 11 Cursor *string `json:"cursor,omitempty"` 12 Cids []string `json:"cids"` 13} 14 15func (s *Server) handleSyncListBlobs(e echo.Context) error { 16 did := e.QueryParam("did") 17 if did == "" { 18 return helpers.InputError(e, nil) 19 } 20 21 // TODO: add tid param 22 cursor := e.QueryParam("cursor") 23 limit, err := getLimitFromContext(e, 50) 24 if err != nil { 25 return helpers.InputError(e, nil) 26 } 27 28 cursorquery := "" 29 30 params := []any{did} 31 if cursor != "" { 32 params = append(params, cursor) 33 cursorquery = "AND created_at < ?" 34 } 35 params = append(params, limit) 36 37 var blobs []models.Blob 38 if err := s.db.Raw("SELECT * FROM blobs WHERE did = ? "+cursorquery+" ORDER BY created_at DESC LIMIT ?", nil, params...).Scan(&blobs).Error; err != nil { 39 s.logger.Error("error getting records", "error", err) 40 return helpers.ServerError(e, nil) 41 } 42 43 var cstrs []string 44 for _, b := range blobs { 45 c, err := cid.Cast(b.Cid) 46 if err != nil { 47 s.logger.Error("error casting cid", "error", err) 48 return helpers.ServerError(e, nil) 49 } 50 cstrs = append(cstrs, c.String()) 51 } 52 53 var newcursor *string 54 if len(blobs) == 50 { 55 newcursor = &blobs[len(blobs)-1].CreatedAt 56 } 57 58 return e.JSON(200, ComAtprotoSyncListBlobsResponse{ 59 Cursor: newcursor, 60 Cids: cstrs, 61 }) 62}