forked from
tangled.org/core
Monorepo for Tangled
1package ogre
2
3import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "fmt"
8 "io"
9 "net/http"
10 "time"
11)
12
13type Client struct {
14 host string
15 client *http.Client
16}
17
18func NewClient(host string) *Client {
19 return &Client{
20 host: host,
21 client: &http.Client{
22 Timeout: 10 * time.Second,
23 },
24 }
25}
26
27type LabelData struct {
28 Name string `json:"name"`
29 Color string `json:"color"`
30}
31
32type LanguageData struct {
33 Color string `json:"color"`
34 Percentage float32 `json:"percentage"`
35}
36
37type RepositoryCardPayload struct {
38 Type string `json:"type"`
39 RepoName string `json:"repoName"`
40 OwnerHandle string `json:"ownerHandle"`
41 Stars int `json:"stars"`
42 Pulls int `json:"pulls"`
43 Issues int `json:"issues"`
44 CreatedAt string `json:"createdAt"`
45 AvatarUrl string `json:"avatarUrl"`
46 Languages []LanguageData `json:"languages"`
47}
48
49type IssueCardPayload struct {
50 Type string `json:"type"`
51 RepoName string `json:"repoName"`
52 OwnerHandle string `json:"ownerHandle"`
53 AuthorHandle string `json:"authorHandle"`
54 AvatarUrl string `json:"avatarUrl"`
55 AuthorAvatarUrl string `json:"authorAvatarUrl"`
56 Title string `json:"title"`
57 IssueNumber int `json:"issueNumber"`
58 Status string `json:"status"`
59 Labels []LabelData `json:"labels"`
60 CommentCount int `json:"commentCount"`
61 ReactionCount int `json:"reactionCount"`
62 CreatedAt string `json:"createdAt"`
63}
64
65type PullRequestCardPayload struct {
66 Type string `json:"type"`
67 RepoName string `json:"repoName"`
68 OwnerHandle string `json:"ownerHandle"`
69 AuthorHandle string `json:"authorHandle"`
70 AvatarUrl string `json:"avatarUrl"`
71 AuthorAvatarUrl string `json:"authorAvatarUrl"`
72 Title string `json:"title"`
73 PullRequestNumber int `json:"pullRequestNumber"`
74 Status string `json:"status"`
75 FilesChanged int `json:"filesChanged"`
76 Additions int `json:"additions"`
77 Deletions int `json:"deletions"`
78 Rounds int `json:"rounds"`
79 CommentCount int `json:"commentCount"`
80 ReactionCount int `json:"reactionCount"`
81 CreatedAt string `json:"createdAt"`
82}
83
84func (c *Client) doRequest(ctx context.Context, path string, payload any) ([]byte, error) {
85 body, err := json.Marshal(payload)
86 if err != nil {
87 return nil, fmt.Errorf("marshal payload: %w", err)
88 }
89
90 url := fmt.Sprintf("%s/%s", c.host, path)
91 req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(body))
92 if err != nil {
93 return nil, fmt.Errorf("create request: %w", err)
94 }
95 req.Header.Set("Content-Type", "application/json")
96
97 resp, err := c.client.Do(req)
98 if err != nil {
99 return nil, fmt.Errorf("do request: %w", err)
100 }
101 defer resp.Body.Close()
102
103 if resp.StatusCode != http.StatusOK {
104 respBody, _ := io.ReadAll(resp.Body)
105 return nil, fmt.Errorf("unexpected status: %d, body: %s", resp.StatusCode, string(respBody))
106 }
107
108 return io.ReadAll(resp.Body)
109}
110
111func (c *Client) RenderRepositoryCard(ctx context.Context, payload RepositoryCardPayload) ([]byte, error) {
112 return c.doRequest(ctx, "repository", payload)
113}
114
115func (c *Client) RenderIssueCard(ctx context.Context, payload IssueCardPayload) ([]byte, error) {
116 return c.doRequest(ctx, "issue", payload)
117}
118
119func (c *Client) RenderPullRequestCard(ctx context.Context, payload PullRequestCardPayload) ([]byte, error) {
120 return c.doRequest(ctx, "pullRequest", payload)
121}