this repo has no description
0
fork

Configure Feed

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

Implement pds ListRepos

Paul Frazee e9d9500f 87a11644

+76 -2
+76 -2
cmd/butterfly/remote/pds.go
··· 3 3 4 4 import ( 5 5 "context" 6 + "encoding/json" 6 7 "fmt" 8 + "io" 7 9 "net/http" 10 + "net/url" 11 + "strconv" 8 12 "time" 9 13 10 14 "github.com/bluesky-social/indigo/atproto/data" ··· 20 24 21 25 // ListRepos returns the DIDs hosted by the PDS 22 26 func (p *PdsRemote) ListRepos(ctx context.Context, params ListReposParams) (*ListReposResult, error) { 23 - // TODO 24 - return nil, fmt.Errorf("list repos: %w", ErrNotImplemented) 27 + // Build URL with query parameters 28 + u, err := url.Parse(fmt.Sprintf("%s/xrpc/com.atproto.sync.listRepos", p.Service)) 29 + if err != nil { 30 + return nil, fmt.Errorf("failed to parse PDS URL: %w", err) 31 + } 32 + 33 + q := u.Query() 34 + if params.Cursor != "" { 35 + q.Set("cursor", params.Cursor) 36 + } 37 + if params.Limit > 0 { 38 + q.Set("limit", strconv.Itoa(params.Limit)) 39 + } 40 + u.RawQuery = q.Encode() 41 + 42 + // Create request 43 + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) 44 + if err != nil { 45 + return nil, fmt.Errorf("failed to create request: %w", err) 46 + } 47 + 48 + req.Header.Set("Accept", "application/json") 49 + req.Header.Set("User-Agent", "butterfly/0.0.1") 50 + 51 + // Make request 52 + client := &http.Client{ 53 + Timeout: 30 * time.Second, 54 + } 55 + resp, err := client.Do(req) 56 + if err != nil { 57 + return nil, fmt.Errorf("failed to list repos: %w", err) 58 + } 59 + defer resp.Body.Close() 60 + 61 + if resp.StatusCode != http.StatusOK { 62 + body, _ := io.ReadAll(resp.Body) 63 + return nil, fmt.Errorf("failed to list repos: %s - %s", resp.Status, string(body)) 64 + } 65 + 66 + // Parse response 67 + var apiResp struct { 68 + Cursor *string `json:"cursor,omitempty"` 69 + Repos []struct { 70 + Did string `json:"did"` 71 + Head string `json:"head"` 72 + Rev string `json:"rev"` 73 + Active *bool `json:"active,omitempty"` 74 + Status *string `json:"status,omitempty"` 75 + } `json:"repos"` 76 + } 77 + 78 + if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil { 79 + return nil, fmt.Errorf("failed to decode response: %w", err) 80 + } 81 + 82 + // Extract DIDs from response 83 + dids := make([]string, 0, len(apiResp.Repos)) 84 + for _, repo := range apiResp.Repos { 85 + // Only include active repos by default 86 + if repo.Active == nil || *repo.Active { 87 + dids = append(dids, repo.Did) 88 + } 89 + } 90 + 91 + result := &ListReposResult{ 92 + Dids: dids, 93 + } 94 + if apiResp.Cursor != nil { 95 + result.Cursor = *apiResp.Cursor 96 + } 97 + 98 + return result, nil 25 99 } 26 100 27 101 // FetchRepo streams the contents of a repository from the PDS