diff --git a/asana/client.go b/asana/client.go index 186e304..be4c57a 100644 --- a/asana/client.go +++ b/asana/client.go @@ -1,44 +1,143 @@ package asana +import "encoding/json" +import "io/ioutil" import "fmt" import "net/http" +import "net/url" import "os" -type withHeader struct { - Header http.Header - rt http.RoundTripper +import "github.com/firestuff/asana-rules/headers" + +type Client struct { + client *http.Client } -func WithHeader(rt http.RoundTripper) withHeader { - if rt == nil { - rt = http.DefaultTransport - } +type Project struct { + GID string `json:"gid"` + Name string `json:"name"` +} - return withHeader{ - Header: make(http.Header), - rt: rt, +type Task struct { + GID string `json:"gid"` + Name string `json:"name"` +} + +type User struct { + GID string `json:"gid"` + Name string `json:"name"` + Email string `json:"email"` +} + +type Workspace struct { + GID string `json:"gid"` + Name string `json:"name"` +} + +type projectsResponse struct { + Data []*Project `json:"data"` +} + +type userResponse struct { + Data *User `json:"data"` +} + +type workspacesResponse struct { + Data []*Workspace `json:"data"` +} + +func NewClient(token string) *Client { + c := &Client{ + client: &http.Client{}, } + + hdrs := headers.NewHeaders(c.client) + hdrs.Add("Accept", "application/json") + hdrs.Add("Authorization", fmt.Sprintf("Bearer %s", token)) + + return c } -func (h withHeader) RoundTrip(req *http.Request) (*http.Response, error) { - for k, v := range h.Header { - req.Header[k] = v - } - - return h.rt.RoundTrip(req) +func NewClientFromEnv() *Client { + return NewClient(os.Getenv("ASANA_TOKEN")) } -func Fetch() { - c := &http.Client{} - - rt := WithHeader(c.Transport) - rt.Header.Set("Authorization", fmt.Sprintf("Bearer %s", os.Getenv("ASANA_TOKEN"))) - c.Transport = rt - - resp, err := c.Get("https://app.asana.com/api/1.0/users/me") +func (c *Client) Me() (*User, error) { + resp := &userResponse{} + err := c.get("users/me", nil, resp) if err != nil { - panic(err) + return nil, err + } + return resp.Data, nil +} + +func (c *Client) Projects(workspaceGID string) ([]*Project, error) { + resp := &projectsResponse{} + path := fmt.Sprintf("workspaces/%s/projects", workspaceGID) + err := c.get(path, nil, resp) + if err != nil { + return nil, err + } + return resp.Data, nil +} + +func (c *Client) Workspaces() ([]*Workspace, error) { + resp := &workspacesResponse{} + err := c.get("workspaces", nil, resp) + if err != nil { + return nil, err + } + return resp.Data, nil +} + +// Returns one workspace if there is only one +func (c *Client) Workspace() (*Workspace, error) { + workspaces, err := c.Workspaces() + if err != nil { + return nil, err } - fmt.Printf("%#v\n", resp) + if len(workspaces) != 1 { + return nil, fmt.Errorf("%d workspaces found", len(workspaces)) + } + + return workspaces[0], nil +} + +const baseURL = "https://app.asana.com/api/1.0/" + +func (c *Client) get(path string, values *url.Values, out interface{}) error { + if values == nil { + values = &url.Values{} + } + values.Add("limit", "100") + + url := fmt.Sprintf("%s%s?%s", baseURL, path, values.Encode()) + fmt.Printf("%s\n", url) + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return err + } + + resp, err := c.client.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != 200 { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + return fmt.Errorf("%s: %s", resp.Status, string(body)) + } + + dec := json.NewDecoder(resp.Body) + err = dec.Decode(out) + if err != nil { + return err + } + + return nil } diff --git a/headers/headers.go b/headers/headers.go new file mode 100644 index 0000000..8967a5c --- /dev/null +++ b/headers/headers.go @@ -0,0 +1,37 @@ +package headers + +import "net/http" + +type Headers struct { + header http.Header + rt http.RoundTripper +} + +func NewHeaders(c *http.Client) Headers { + if c.Transport == nil { + c.Transport = http.DefaultTransport + } + + ret := Headers{ + header: http.Header{}, + rt: c.Transport, + } + + c.Transport = ret + + return ret +} + +func (h *Headers) Add(key, value string) { + h.header.Add(key, value) +} + +func (h Headers) RoundTrip(req *http.Request) (*http.Response, error) { + for key, vals := range h.header { + for _, val := range vals { + req.Header.Add(key, val) + } + } + + return h.rt.RoundTrip(req) +} diff --git a/main.go b/main.go index 61a41ad..b614462 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,30 @@ package main +import "fmt" + import "github.com/firestuff/asana-rules/asana" func main() { - asana.Fetch() + a := asana.NewClientFromEnv() + + /* + me, err := a.Me() + if err != nil { + panic(err) + } + */ + + wrk, err := a.Workspace() + if err != nil { + panic(err) + } + + prjs, err := a.Projects(wrk.GID) + if err != nil { + panic(err) + } + + for _, prj := range prjs { + fmt.Printf("%#v\n", prj) + } }