diff --git a/asanaclient/workspaceclient.go b/asanaclient/workspaceclient.go index 4262b21..74f9c67 100644 --- a/asanaclient/workspaceclient.go +++ b/asanaclient/workspaceclient.go @@ -20,6 +20,7 @@ type WorkspaceClient struct { type SearchQuery struct { SectionsAny []*Section Completed *bool + Due *bool DueOn *civil.Date DueBefore *civil.Date DueAfter *civil.Date @@ -215,6 +216,14 @@ func (wc *WorkspaceClient) Search(q *SearchQuery) ([]*Task, error) { values.Add("completed", fmt.Sprintf("%t", *q.Completed)) } + if q.Due != nil { + if *q.Due { + values.Add("due_on.after", "1970-01-01") + } else { + values.Add("due_on", "null") + } + } + if q.DueOn != nil { values.Add("due_on", q.DueOn.String()) } diff --git a/asanarules/rules.go b/asanarules/rules.go index f5a80a0..66e2bac 100644 --- a/asanarules/rules.go +++ b/asanarules/rules.go @@ -8,6 +8,7 @@ import "github.com/firestuff/asana-rules/asanaclient" type queryMutator func(*asanaclient.WorkspaceClient, *asanaclient.SearchQuery) error type taskActor func(*asanaclient.WorkspaceClient, *asanaclient.Task) error +type taskFilter func(*asanaclient.WorkspaceClient, *asanaclient.Task) (bool, error) type workspaceClientGetter func(*asanaclient.Client) (*asanaclient.WorkspaceClient, error) type periodic struct { @@ -16,6 +17,7 @@ type periodic struct { workspaceClientGetter workspaceClientGetter queryMutators []queryMutator + taskFilters []taskFilter taskActors []taskActor } @@ -155,6 +157,15 @@ func (p *periodic) OnlyComplete() *periodic { return p } +func (p *periodic) WithoutDue() *periodic { + // We can't mutate the query because due_on=null is buggy in the Asana API + p.taskFilters = append(p.taskFilters, func(wc *asanaclient.WorkspaceClient, t *asanaclient.Task) (bool, error) { + return t.ParsedDueOn == nil, nil + }) + + return p +} + // Task actors func (p *periodic) MoveToMyTasksSection(name string) *periodic { p.taskActors = append(p.taskActors, func(wc *asanaclient.WorkspaceClient, t *asanaclient.Task) error { @@ -235,7 +246,28 @@ func (p *periodic) exec(c *asanaclient.Client) error { return err } + filteredTasks := []*asanaclient.Task{} for _, task := range tasks { + included := true + + for _, filter := range p.taskFilters { + include, err := filter(wc, task) + if err != nil { + return err + } + + if !include { + included = false + break + } + } + + if included { + filteredTasks = append(filteredTasks, task) + } + } + + for _, task := range filteredTasks { for _, act := range p.taskActors { err = act(wc, task) if err != nil { diff --git a/main.go b/main.go index e4a81c7..f7a47a2 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,7 @@ import . "github.com/firestuff/asana-rules/asanarules" func main() { EverySeconds(30). InWorkspace("flamingcow.io"). - InMyTasksSections("Recently Assigned", "Upcoming", "Later"). + InMyTasksSections("Recently Assigned", "Upcoming", "Later", "Someday"). OnlyIncomplete(). DueInDays(0). PrintTasks(). @@ -13,7 +13,7 @@ func main() { EverySeconds(30). InWorkspace("flamingcow.io"). - InMyTasksSections("Recently Assigned", "Today", "Later"). + InMyTasksSections("Recently Assigned", "Today", "Meetings", "Maybe Today", "Tonight", "Later", "Someday"). OnlyIncomplete(). DueInAtLeastDays(1). DueInAtMostDays(7). @@ -22,11 +22,27 @@ func main() { EverySeconds(30). InWorkspace("flamingcow.io"). - InMyTasksSections("Recently Assigned", "Today", "Upcoming"). + InMyTasksSections("Recently Assigned", "Today", "Meetings", "Maybe Today", "Tonight", "Upcoming", "Someday"). OnlyIncomplete(). DueInAtLeastDays(8). PrintTasks(). MoveToMyTasksSection("Later") + EverySeconds(30). + InWorkspace("flamingcow.io"). + InMyTasksSections("Recently Assigned", "Today", "Meetings", "Maybe Today", "Tonight", "Upcoming", "Someday"). + OnlyIncomplete(). + DueInAtLeastDays(8). + PrintTasks(). + MoveToMyTasksSection("Later") + + EverySeconds(30). + InWorkspace("flamingcow.io"). + InMyTasksSections("Recently Assigned", "Today", "Meetings", "Maybe Today", "Tonight", "Upcoming", "Later"). + OnlyIncomplete(). + WithoutDue(). + PrintTasks(). + MoveToMyTasksSection("Someday") + Loop() }