Monorepo for Tangled
tangled.org
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 AvatarUrl string `json:"avatarUrl"`
54 Title string `json:"title"`
55 IssueNumber int `json:"issueNumber"`
56 Status string `json:"status"`
57 Labels []LabelData `json:"labels"`
58 CommentCount int `json:"commentCount"`
59 ReactionCount int `json:"reactionCount"`
60 CreatedAt string `json:"createdAt"`
61}
62
63type PullRequestCardPayload struct {
64 Type string `json:"type"`
65 RepoName string `json:"repoName"`
66 OwnerHandle string `json:"ownerHandle"`
67 AvatarUrl string `json:"avatarUrl"`
68 Title string `json:"title"`
69 PullRequestNumber int `json:"pullRequestNumber"`
70 Status string `json:"status"`
71 FilesChanged int `json:"filesChanged"`
72 Additions int `json:"additions"`
73 Deletions int `json:"deletions"`
74 Rounds int `json:"rounds"`
75 CommentCount int `json:"commentCount"`
76 ReactionCount int `json:"reactionCount"`
77 CreatedAt string `json:"createdAt"`
78}
79
80func (c *Client) doRequest(ctx context.Context, path string, payload any) ([]byte, error) {
81 body, err := json.Marshal(payload)
82 if err != nil {
83 return nil, fmt.Errorf("marshal payload: %w", err)
84 }
85
86 url := fmt.Sprintf("%s/%s", c.host, path)
87 req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(body))
88 if err != nil {
89 return nil, fmt.Errorf("create request: %w", err)
90 }
91 req.Header.Set("Content-Type", "application/json")
92
93 resp, err := c.client.Do(req)
94 if err != nil {
95 return nil, fmt.Errorf("do request: %w", err)
96 }
97 defer resp.Body.Close()
98
99 if resp.StatusCode != http.StatusOK {
100 respBody, _ := io.ReadAll(resp.Body)
101 return nil, fmt.Errorf("unexpected status: %d, body: %s", resp.StatusCode, string(respBody))
102 }
103
104 return io.ReadAll(resp.Body)
105}
106
107func (c *Client) RenderRepositoryCard(ctx context.Context, payload RepositoryCardPayload) ([]byte, error) {
108 return c.doRequest(ctx, "repository", payload)
109}
110
111func (c *Client) RenderIssueCard(ctx context.Context, payload IssueCardPayload) ([]byte, error) {
112 return c.doRequest(ctx, "issue", payload)
113}
114
115func (c *Client) RenderPullRequestCard(ctx context.Context, payload PullRequestCardPayload) ([]byte, error) {
116 return c.doRequest(ctx, "pullRequest", payload)
117}