summaryrefslogtreecommitdiffstats
path: root/internal/client
diff options
context:
space:
mode:
Diffstat (limited to 'internal/client')
-rw-r--r--internal/client/reddit.go20
-rw-r--r--internal/client/x.go108
2 files changed, 118 insertions, 10 deletions
diff --git a/internal/client/reddit.go b/internal/client/reddit.go
index da95782..907e094 100644
--- a/internal/client/reddit.go
+++ b/internal/client/reddit.go
@@ -7,14 +7,14 @@ import (
"git.db.org.ai/dborg/internal/models"
)
-func (c *Client) GetSubredditPosts(params *models.RedditSubredditParams) (*models.RedditResponse, error) {
+func (c *Client) GetSubredditPosts(params *models.RedditSubredditParams) (*models.SubredditResponse, error) {
path := fmt.Sprintf("/reddit/r/%s", params.Subreddit)
data, err := c.Get(path, nil)
if err != nil {
return nil, err
}
- var response models.RedditResponse
+ var response models.SubredditResponse
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
@@ -22,14 +22,14 @@ func (c *Client) GetSubredditPosts(params *models.RedditSubredditParams) (*model
return &response, nil
}
-func (c *Client) GetSubredditComments(params *models.RedditSubredditParams) (*models.RedditResponse, error) {
+func (c *Client) GetSubredditComments(params *models.RedditSubredditParams) (*models.SubredditResponse, error) {
path := fmt.Sprintf("/reddit/r/%s/comments", params.Subreddit)
data, err := c.Get(path, nil)
if err != nil {
return nil, err
}
- var response models.RedditResponse
+ var response models.SubredditResponse
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
@@ -37,14 +37,14 @@ func (c *Client) GetSubredditComments(params *models.RedditSubredditParams) (*mo
return &response, nil
}
-func (c *Client) GetUserPosts(params *models.RedditUserParams) (*models.RedditResponse, error) {
+func (c *Client) GetUserPosts(params *models.RedditUserParams) (*models.UserResponse, error) {
path := fmt.Sprintf("/reddit/user/%s/posts", params.Username)
data, err := c.Get(path, nil)
if err != nil {
return nil, err
}
- var response models.RedditResponse
+ var response models.UserResponse
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
@@ -52,14 +52,14 @@ func (c *Client) GetUserPosts(params *models.RedditUserParams) (*models.RedditRe
return &response, nil
}
-func (c *Client) GetUserComments(params *models.RedditUserParams) (*models.RedditResponse, error) {
+func (c *Client) GetUserComments(params *models.RedditUserParams) (*models.UserResponse, error) {
path := fmt.Sprintf("/reddit/user/%s/comments", params.Username)
data, err := c.Get(path, nil)
if err != nil {
return nil, err
}
- var response models.RedditResponse
+ var response models.UserResponse
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
@@ -67,14 +67,14 @@ func (c *Client) GetUserComments(params *models.RedditUserParams) (*models.Reddi
return &response, nil
}
-func (c *Client) GetUserAbout(params *models.RedditUserParams) (*models.RedditResponse, error) {
+func (c *Client) GetUserAbout(params *models.RedditUserParams) (*models.UserResponse, error) {
path := fmt.Sprintf("/reddit/user/%s/about", params.Username)
data, err := c.Get(path, nil)
if err != nil {
return nil, err
}
- var response models.RedditResponse
+ var response models.UserResponse
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
diff --git a/internal/client/x.go b/internal/client/x.go
index bd16692..b6ddba8 100644
--- a/internal/client/x.go
+++ b/internal/client/x.go
@@ -99,3 +99,111 @@ func (c *Client) FetchTweetsStream(username string, callback func(result json.Ra
return nil
}
+
+func (c *Client) FetchRepliesStream(tweetID string, limit int, callback func(result json.RawMessage) error) error {
+ path := fmt.Sprintf("/x/replies/%s", url.PathEscape(tweetID))
+
+ params := url.Values{}
+ if limit > 0 {
+ params.Set("limit", fmt.Sprintf("%d", limit))
+ }
+
+ fullURL := c.config.BaseURL + path
+ if len(params) > 0 {
+ fullURL += "?" + params.Encode()
+ }
+
+ req, err := http.NewRequest(http.MethodGet, fullURL, nil)
+ if err != nil {
+ return fmt.Errorf("failed to create request: %w", err)
+ }
+
+ req.Header.Set("User-Agent", c.config.UserAgent)
+ req.Header.Set("Accept", "application/x-ndjson, application/json")
+ req.Header.Set("X-API-Key", c.config.APIKey)
+
+ resp, err := c.httpClient.Do(req)
+ if err != nil {
+ return fmt.Errorf("failed to execute request: %w", err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ body, _ := io.ReadAll(resp.Body)
+ return fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(body))
+ }
+
+ scanner := bufio.NewScanner(resp.Body)
+ for scanner.Scan() {
+ line := scanner.Bytes()
+ if len(line) == 0 {
+ continue
+ }
+
+ if err := callback(json.RawMessage(line)); err != nil {
+ return err
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ if !strings.Contains(err.Error(), "context deadline exceeded") && !strings.Contains(err.Error(), "timeout") {
+ return fmt.Errorf("stream reading error: %w", err)
+ }
+ }
+
+ return nil
+}
+
+func (c *Client) SearchTweetsStream(query string, limit int, callback func(result json.RawMessage) error) error {
+ path := fmt.Sprintf("/x/search/%s", url.PathEscape(query))
+
+ params := url.Values{}
+ if limit > 0 {
+ params.Set("limit", fmt.Sprintf("%d", limit))
+ }
+
+ fullURL := c.config.BaseURL + path
+ if len(params) > 0 {
+ fullURL += "?" + params.Encode()
+ }
+
+ req, err := http.NewRequest(http.MethodGet, fullURL, nil)
+ if err != nil {
+ return fmt.Errorf("failed to create request: %w", err)
+ }
+
+ req.Header.Set("User-Agent", c.config.UserAgent)
+ req.Header.Set("Accept", "application/x-ndjson, application/json")
+ req.Header.Set("X-API-Key", c.config.APIKey)
+
+ resp, err := c.httpClient.Do(req)
+ if err != nil {
+ return fmt.Errorf("failed to execute request: %w", err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ body, _ := io.ReadAll(resp.Body)
+ return fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(body))
+ }
+
+ scanner := bufio.NewScanner(resp.Body)
+ for scanner.Scan() {
+ line := scanner.Bytes()
+ if len(line) == 0 {
+ continue
+ }
+
+ if err := callback(json.RawMessage(line)); err != nil {
+ return err
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ if !strings.Contains(err.Error(), "context deadline exceeded") && !strings.Contains(err.Error(), "timeout") {
+ return fmt.Errorf("stream reading error: %w", err)
+ }
+ }
+
+ return nil
+}