Merge branch '19092-upload-crunchstat_summary-to-pypi'
[arvados-dev.git] / lib / redmine / redmine.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 // Somewhat inspired by https://github.com/mattn/go-redmine (MIT licensed)
6
7 package redmine
8
9 import (
10         "encoding/json"
11         "errors"
12         "fmt"
13         "net/http"
14         "strings"
15 )
16
17 type Client struct {
18         endpoint string
19         apikey   string
20         *http.Client
21 }
22
23 type errorsResult struct {
24         Errors []string `json:"errors"`
25 }
26
27 type IDName struct {
28         ID   int    `json:"id"`
29         Name string `json:"name"`
30 }
31
32 type ID struct {
33         ID int `json:"id"`
34 }
35
36 func NewClient(endpoint, apikey string) *Client {
37         return &Client{endpoint, apikey, http.DefaultClient}
38 }
39
40 func (c *Client) Get(url string) (*http.Response, error) {
41         req, err := http.NewRequest("GET", c.endpoint+url, nil)
42         if err != nil {
43                 return nil, err
44         }
45         req.Header.Add("X-Redmine-API-Key", c.apikey)
46         res, err := c.Do(req)
47         if err != nil {
48                 return nil, err
49         }
50         return res, err
51 }
52
53 func (c *Client) Post(url string, payload string) (*http.Response, error) {
54         req, err := http.NewRequest("POST", c.endpoint+url, strings.NewReader(payload))
55         if err != nil {
56                 return nil, err
57         }
58         req.Header.Set("Content-Type", "application/json")
59         req.Header.Add("X-Redmine-API-Key", c.apikey)
60         res, err := c.Do(req)
61         if err != nil {
62                 return nil, err
63         }
64         return res, err
65 }
66
67 func (c *Client) Put(url string, payload string) (*http.Response, error) {
68         req, err := http.NewRequest("PUT", c.endpoint+url, strings.NewReader(payload))
69         if err != nil {
70                 return nil, err
71         }
72         req.Header.Set("Content-Type", "application/json")
73         req.Header.Add("X-Redmine-API-Key", c.apikey)
74         res, err := c.Do(req)
75         if err != nil {
76                 return nil, err
77         }
78         return res, err
79 }
80
81 func responseHelper(res *http.Response, r interface{}, okCode int) error {
82         var err error
83         decoder := json.NewDecoder(res.Body)
84         if res.StatusCode != okCode {
85                 var result errorsResult
86                 err = decoder.Decode(&result)
87                 if err == nil {
88                         err = errors.New(strings.Join(result.Errors, "\n"))
89                 } else if err.Error() == "EOF" {
90                         // The body is empty, just return the status code as an error. This is
91                         // an error because res.StatusCode != okCode.
92                         err = fmt.Errorf("[error] %s", res.Status)
93                 }
94         } else if r != nil {
95                 // When r is nil, the API call is not expected to return a result (empty res.Body)
96                 err = decoder.Decode(&r)
97         }
98         //fmt.Printf("***\nRAW RESPONSE: %+v\n***\n", r)
99         return err
100 }