Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion asana.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Package asana provides a client for the Asana API
package asana // import "bitbucket.org/mikehouston/asana-go"
package asana

import (
"bytes"
Expand Down
21 changes: 14 additions & 7 deletions attachments.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ package asana

import (
"fmt"
"github.com/pkg/errors"
"io"
"time"

"github.com/pkg/errors"
)

// Attachment represents any file attached to a task in Asana,
// whether it’s an uploaded file or one associated via a third-party service
// such as Dropbox or Google Drive.
type Attachment struct {
client *Client

// Read-only. Globally unique ID of the object
ID string `json:"gid,omitempty"`

Expand Down Expand Up @@ -45,13 +48,16 @@ type Attachment struct {
}

// Attachments lists all attachments attached to a task
func (t *Task) Attachments(client *Client, opts ...*Options) ([]*Attachment, *NextPage, error) {
client.trace("Listing attachments for %q", t.Name)
func (t *Task) Attachments(opts ...*Options) ([]*Attachment, *NextPage, error) {
t.client.trace("Listing attachments for %q", t.Name)

var result []*Attachment

// Make the request
nextPage, err := client.get(fmt.Sprintf("/tasks/%s/attachments", t.ID), nil, &result, opts...)
nextPage, err := t.client.get(fmt.Sprintf("/tasks/%s/attachments", t.ID), nil, &result, opts...)
for _, r := range result {
r.client = t.client
}
return result, nextPage, err
}

Expand All @@ -61,13 +67,14 @@ type NewAttachment struct {
ContentType string
}

func (t *Task) CreateAttachment(client *Client, request *NewAttachment) (*Attachment, error) {
client.trace("Uploading attachment for %q", t.Name)
func (t *Task) CreateAttachment(request *NewAttachment) (*Attachment, error) {
t.client.trace("Uploading attachment for %q", t.Name)

result := &Attachment{}
err := client.postMultipart(fmt.Sprintf("/tasks/%s/attachments", t.ID), result, "file", request.Reader, request.FileName, request.ContentType)
err := t.client.postMultipart(fmt.Sprintf("/tasks/%s/attachments", t.ID), result, "file", request.Reader, request.FileName, request.ContentType)
if err != nil {
return nil, errors.Wrap(err, "Upload attachment")
}
result.client = t.client
return result, nil
}
12 changes: 6 additions & 6 deletions cmd/asana/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ func ListWorkspaces(c *asana.Client) error {
return nil
}

func ListProjects(client *asana.Client, w *asana.Workspace) error {
func ListProjects(w *asana.Workspace) error {
// List projects
projects, err := w.AllProjects(client, &asana.Options{
projects, err := w.AllProjects(&asana.Options{
Fields: []string{"name", "section_migration_status", "layout"},
})
if err != nil {
Expand All @@ -39,9 +39,9 @@ func ListProjects(client *asana.Client, w *asana.Workspace) error {
return nil
}

func ListTasks(client *asana.Client, p *asana.Project) error {
func ListTasks(p *asana.Project) error {
// List projects
tasks, nextPage, err := p.Tasks(client, asana.Fields(asana.Task{}))
tasks, nextPage, err := p.Tasks(asana.Fields(asana.Task{}))
if err != nil {
return err
}
Expand All @@ -53,9 +53,9 @@ func ListTasks(client *asana.Client, p *asana.Project) error {
return nil
}

func ListSections(client *asana.Client, p *asana.Project) error {
func ListSections(p *asana.Project) error {
// List sections
sections, nextPage, err := p.Sections(client)
sections, nextPage, err := p.Sections()
if err != nil {
return err
}
Expand Down
26 changes: 13 additions & 13 deletions cmd/asana/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"fmt"
"github.com/jessevdk/go-flags"
"log"
"mime"
"net/http"
Expand All @@ -11,6 +10,7 @@ import (
"path/filepath"

"bitbucket.org/mikehouston/asana-go"
"github.com/jessevdk/go-flags"
)

var options struct {
Expand Down Expand Up @@ -70,7 +70,7 @@ func main() {

for _, w := range options.Workspace {
workspace := &asana.Workspace{ID: w}
check(ListProjects(client, workspace))
check(ListProjects(workspace))
}
return
}
Expand All @@ -83,12 +83,12 @@ func main() {
Name: options.AddSection,
}

_, err := project.CreateSection(client, request)
_, err := project.CreateSection(request)
check(err)
return
}

fmtProject(client, project)
fmtProject(project)
}
return
}
Expand All @@ -99,22 +99,22 @@ func main() {

fmt.Printf("Task %s: %q\n", task.ID, task.Name)
if options.Attach != "" {
addAttachment(task, client)
addAttachment(task)
return
}

fmtTask(task, client)
fmtTask(task)
}
}

func fmtProject(client *asana.Client, project *asana.Project) {
func fmtProject(project *asana.Project) {
fmt.Println("\nSections:")
check(ListSections(client, project))
check(ListSections(project))
fmt.Println("\nTasks:")
check(ListTasks(client, project))
check(ListTasks(project))
}

func fmtTask(task *asana.Task, client *asana.Client) {
func fmtTask(task *asana.Task) {
fmt.Printf(" Completed: %v\n", task.Completed)
if task.Completed != nil && !*task.Completed {
fmt.Printf(" Due: %s\n", task.DueAt)
Expand All @@ -123,19 +123,19 @@ func fmtTask(task *asana.Task, client *asana.Client) {
fmt.Printf(" Notes: %q\n", task.Notes)
}
// Get subtasks
subtasks, nextPage, err := task.Subtasks(client)
subtasks, nextPage, err := task.Subtasks()
check(err)
_ = nextPage
for _, subtask := range subtasks {
fmt.Printf(" Subtask %s: %q\n", subtask.ID, subtask.Name)
}
}

func addAttachment(task *asana.Task, client *asana.Client) {
func addAttachment(task *asana.Task) {
f, err := os.Open(options.Attach)
check(err)
defer f.Close()
a, err := task.CreateAttachment(client, &asana.NewAttachment{
a, err := task.CreateAttachment(&asana.NewAttachment{
Reader: f,
FileName: f.Name(),
ContentType: mime.TypeByExtension(filepath.Ext(f.Name())),
Expand Down
34 changes: 20 additions & 14 deletions customfields.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ type CustomFieldBase struct {
// Users in Asana can lock custom fields, which will make them read-only when accessed by other users.
// Attempting to edit a locked custom field will return HTTP error code 403 Forbidden.
type CustomField struct {
client *Client
// Read-only. Globally unique ID of the object
ID string `json:"gid,omitempty"`

Expand Down Expand Up @@ -128,8 +129,8 @@ type AddCustomFieldSettingRequest struct {
InsertAfter string `json:"insert_after,omitempty"`
}

func (p *Project) AddCustomFieldSetting(client *Client, request *AddCustomFieldSettingRequest) (*CustomFieldSetting, error) {
client.trace("Attach custom field %q to project %q", request.CustomField, p.ID)
func (p *Project) AddCustomFieldSetting(request *AddCustomFieldSettingRequest) (*CustomFieldSetting, error) {
p.client.trace("Attach custom field %q to project %q", request.CustomField, p.ID)

// Custom request encoding
m := map[string]interface{}{}
Expand All @@ -149,19 +150,20 @@ func (p *Project) AddCustomFieldSetting(client *Client, request *AddCustomFieldS
}

result := &CustomFieldSetting{}
err := client.post(fmt.Sprintf("/projects/%s/addCustomFieldSetting", p.ID), m, result)
err := p.client.post(fmt.Sprintf("/projects/%s/addCustomFieldSetting", p.ID), m, result)
result.CustomField.client = p.client
return result, err
}

func (p *Project) RemoveCustomFieldSetting(client *Client, customFieldID string) error {
client.trace("Remove custom field %q from project %q", customFieldID, p.ID)
func (p *Project) RemoveCustomFieldSetting(customFieldID string) error {
p.client.trace("Remove custom field %q from project %q", customFieldID, p.ID)

// Custom request encoding
m := map[string]interface{}{
"custom_field": customFieldID,
}

err := client.post(fmt.Sprintf("/projects/%s/removeCustomFieldSetting", p.ID), m, &json.RawMessage{})
err := p.client.post(fmt.Sprintf("/projects/%s/removeCustomFieldSetting", p.ID), m, &json.RawMessage{})
return err
}

Expand All @@ -181,6 +183,7 @@ func (c *Client) CreateCustomField(request *CreateCustomFieldRequest) (*CustomFi

result := &CustomField{}
err := c.post("/custom_fields", request, result)
result.client = c
return result, err
}

Expand Down Expand Up @@ -208,25 +211,28 @@ type CustomFieldValue struct {
}

// Fetch loads the full details for this CustomField
func (f *CustomField) Fetch(client *Client, options ...*Options) error {
client.trace("Loading details for custom field %q", f.ID)
func (f *CustomField) Fetch(options ...*Options) error {
f.client.trace("Loading details for custom field %q", f.ID)

_, err := client.get(fmt.Sprintf("/custom_fields/%s", f.ID), nil, f, options...)
_, err := f.client.get(fmt.Sprintf("/custom_fields/%s", f.ID), nil, f, options...)
return err
}

// CustomFields returns the compact records for all custom fields in the workspace
func (w *Workspace) CustomFields(client *Client, options ...*Options) ([]*CustomField, *NextPage, error) {
client.trace("Listing custom fields in workspace %s...\n", w.ID)
func (w *Workspace) CustomFields(options ...*Options) ([]*CustomField, *NextPage, error) {
w.client.trace("Listing custom fields in workspace %s...\n", w.ID)
var result []*CustomField

// Make the request
nextPage, err := client.get(fmt.Sprintf("/workspaces/%s/custom_fields", w.ID), nil, &result, options...)
nextPage, err := w.client.get(fmt.Sprintf("/workspaces/%s/custom_fields", w.ID), nil, &result, options...)
for _, r := range result {
r.client = w.client
}
return result, nextPage, err
}

// AllCustomFields repeatedly pages through all available custom fields in a workspace
func (w *Workspace) AllCustomFields(client *Client, options ...*Options) ([]*CustomField, error) {
func (w *Workspace) AllCustomFields(options ...*Options) ([]*CustomField, error) {
var allCustomFields []*CustomField
nextPage := &NextPage{}

Expand All @@ -240,7 +246,7 @@ func (w *Workspace) AllCustomFields(client *Client, options ...*Options) ([]*Cus
}

allOptions := append([]*Options{page}, options...)
customFields, nextPage, err = w.CustomFields(client, allOptions...)
customFields, nextPage, err = w.CustomFields(allOptions...)
if err != nil {
return nil, err
}
Expand Down
12 changes: 7 additions & 5 deletions portfolios.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package asana

import "fmt"

type Portfolio struct {
client *Client
// Read-only. Globally unique ID of the object
ID string `json:"gid,omitempty"`
}

// Projects returns a list of projects in this workspace
func (w *Workspace) Portfolios(client *Client, options ...*Options) ([]*Portfolio, *NextPage, error) {
client.trace("Listing portfolios in %q", w.Name)
func (w *Workspace) Portfolios(options ...*Options) ([]*Portfolio, *NextPage, error) {
w.client.trace("Listing portfolios in %q", w.Name)

var result []*Portfolio

Expand All @@ -19,6 +18,9 @@ func (w *Workspace) Portfolios(client *Client, options ...*Options) ([]*Portfoli
}

// Make the request
nextPage, err := client.get(fmt.Sprintf("/portfolios"), nil, &result, append(options, o)...)
nextPage, err := w.client.get("/portfolios", nil, &result, append(options, o)...)
for _, r := range result {
r.client = w.client
}
return result, nextPage, err
}
Loading