diff options
Diffstat (limited to 'general/records.go')
| -rw-r--r-- | general/records.go | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/general/records.go b/general/records.go new file mode 100644 index 0000000..12825bd --- /dev/null +++ b/general/records.go @@ -0,0 +1,148 @@ +package general + +import ( + "encoding/json" + "fmt" + "io" + "llostre/auth" + "log/slog" + "net/http" +) + +type RawRecord struct { + URI string `json:"uri"` + Value json.RawMessage `json:"value"` +} + +func FetchRawRecordCollection(logger *slog.Logger, did, collection, baseURL string, session *auth.OAuthState) ([]RawRecord, error) { + url := fmt.Sprintf("%s/xrpc/com.atproto.repo.listRecords?repo=%s&collection=%s", baseURL, did, collection) + + logger.Debug("fetching raw record collection", "did", did, "endpoint", baseURL, "collection", collection) + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + + // only add auth if provided + if session != nil { + dpopProof, err := session.KeyPair.GenerateDPoPProof("GET", url, "") + if err != nil { + return nil, err + } + req.Header.Set("Authorization", "Bearer "+session.AccessToken) + req.Header.Set("DPoP", dpopProof) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + body, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("server returned %d: %s", resp.StatusCode, string(body)) + } + + var result struct { + Records []RawRecord `json:"records"` + } + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + return nil, err + } + + return result.Records, nil +} + +func FetchRawRecordCollectionWithCursor(logger *slog.Logger, did, collection, baseURL string, session *auth.OAuthState, cursor string, limit int) ([]RawRecord, string, error) { + url := fmt.Sprintf("%s/xrpc/com.atproto.repo.listRecords?repo=%s&collection=%s", baseURL, did, collection) + if cursor != "" { + url += "&cursor=" + cursor + } + if limit > 0 { + url += fmt.Sprintf("&limit=%d", limit) + } + + logger.Debug("fetching raw record collection", "did", did, "endpoint", baseURL, "collection", collection, "cursor", cursor) + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, "", err + } + + if session != nil { + dpopProof, err := session.KeyPair.GenerateDPoPProof("GET", url, "") + if err != nil { + return nil, "", err + } + req.Header.Set("Authorization", "Bearer "+session.AccessToken) + req.Header.Set("DPoP", dpopProof) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, "", err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + body, _ := io.ReadAll(resp.Body) + return nil, "", fmt.Errorf("server returned %d: %s", resp.StatusCode, string(body)) + } + + var result struct { + Records []RawRecord `json:"records"` + Cursor string `json:"cursor"` + } + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + return nil, "", err + } + + return result.Records, result.Cursor, nil +} + +func FetchRawRecordByURI(logger *slog.Logger, uri, baseURL string, session *auth.OAuthState) (*RawRecord, error) { + repo, collection, rkey, err := ParseURI(uri) + if err != nil { + return nil, err + } + + url := fmt.Sprintf("%s/xrpc/com.atproto.repo.getRecord?repo=%s&collection=%s&rkey=%s", + baseURL, repo, collection, rkey) + + logger.Debug("fetching raw record by URI", "uri", uri, "endpoint", baseURL) + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + + // only add auth if provided + if session != nil { + dpopProof, err := session.KeyPair.GenerateDPoPProof("GET", url, "") + if err != nil { + return nil, err + } + req.Header.Set("Authorization", "Bearer "+session.AccessToken) + req.Header.Set("DPoP", dpopProof) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + body, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("endpoint returned %d: %s", resp.StatusCode, string(body)) + } + + var result RawRecord + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + return nil, err + } + + return &result, nil +} |
