diff --git a/asanaclient/client.go b/client/client.go similarity index 99% rename from asanaclient/client.go rename to client/client.go index 92c83bd..058e99f 100644 --- a/asanaclient/client.go +++ b/client/client.go @@ -1,4 +1,4 @@ -package asanaclient +package client import "bytes" import "encoding/json" diff --git a/asanaclient/workspaceclient.go b/client/workspaceclient.go similarity index 99% rename from asanaclient/workspaceclient.go rename to client/workspaceclient.go index 5afc2bd..47d29f6 100644 --- a/asanaclient/workspaceclient.go +++ b/client/workspaceclient.go @@ -1,4 +1,4 @@ -package asanaclient +package client import "fmt" import "net/url" diff --git a/go.mod b/go.mod index e6c72be..8d22126 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,9 @@ -module github.com/firestuff/asana-rules +module github.com/firestuff/automana go 1.13 require ( cloud.google.com/go v0.94.1 + github.com/firestuff/asana-rules v0.0.0-20210920001341-aa19b6923f09 golang.org/x/net v0.0.0-20210908191846-a5e095526f91 ) diff --git a/go.sum b/go.sum index e2ec8ca..8490030 100644 --- a/go.sum +++ b/go.sum @@ -66,6 +66,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/firestuff/asana-rules v0.0.0-20210920001341-aa19b6923f09 h1:rceBzwaFpPJzIpCNwZd/V9/g2ou1nMg1tiPc4ZYtc3k= +github.com/firestuff/asana-rules v0.0.0-20210920001341-aa19b6923f09/go.mod h1:Dk5K7WX+8STOek0oNw4Bw9qjsJj5YKf/8E8+cOsQCzo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -114,6 +116,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -384,6 +387,7 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= diff --git a/main.go b/main.go index 7c8ce8a..b89d211 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ package main -import . "github.com/firestuff/asana-rules/asanarules" +import . "github.com/firestuff/automana/rules" func main() { EverySeconds(30). @@ -21,6 +21,15 @@ func main() { PrintTasks(). MoveToMyTasksSection("Tonight") + EverySeconds(30). + InWorkspace("flamingcow.io"). + InMyTasksSections("Recently Assigned", "Today", "Maybe Today", "Tonight", "Upcoming", "Later", "Someday"). + OnlyIncomplete(). + DueInDays(0). + WithTagsAnyOf("section=Meetings"). + PrintTasks(). + MoveToMyTasksSection("Meetings") + EverySeconds(30). InWorkspace("flamingcow.io"). InMyTasksSections("Recently Assigned", "Today", "Meetings", "Maybe Today", "Tonight", "Later", "Someday"). @@ -48,7 +57,7 @@ func main() { EverySeconds(30). InWorkspace("flamingcow.io"). - InMyTasksSections("Today", "Meetings", "Maybe Today", "Tonight", "Upcoming", "Later"). + InMyTasksSections("Today", "Meetings", "Tonight", "Upcoming", "Later"). OnlyIncomplete(). WithoutDue(). PrintTasks(). diff --git a/asanarules/rules.go b/rules/rules.go similarity index 75% rename from asanarules/rules.go rename to rules/rules.go index f8f0f92..65a5412 100644 --- a/asanarules/rules.go +++ b/rules/rules.go @@ -1,4 +1,4 @@ -package asanarules +package rules import "bytes" import "fmt" @@ -7,14 +7,14 @@ import "strings" import "time" import "cloud.google.com/go/civil" -import "github.com/firestuff/asana-rules/asanaclient" +import "github.com/firestuff/automana/client" import "golang.org/x/net/html" import "golang.org/x/net/html/atom" -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 queryMutator func(*client.WorkspaceClient, *client.SearchQuery) error +type taskActor func(*client.WorkspaceClient, *client.Task) error +type taskFilter func(*client.WorkspaceClient, *client.Task) (bool, error) +type workspaceClientGetter func(*client.Client) (*client.WorkspaceClient, error) type periodic struct { period int @@ -40,10 +40,10 @@ func EverySeconds(seconds int) *periodic { } func Loop() { - client := asanaclient.NewClientFromEnv() + c := client.NewClientFromEnv() for _, periodic := range periodics { - periodic.start(client) + periodic.start(c) } for _, periodic := range periodics { @@ -56,7 +56,7 @@ func (p *periodic) InWorkspace(name string) *periodic { panic("Multiple calls to InWorkspace()") } - p.workspaceClientGetter = func(c *asanaclient.Client) (*asanaclient.WorkspaceClient, error) { + p.workspaceClientGetter = func(c *client.Client) (*client.WorkspaceClient, error) { return c.InWorkspace(name) } @@ -65,7 +65,7 @@ func (p *periodic) InWorkspace(name string) *periodic { // Query mutators func (p *periodic) InMyTasksSections(names ...string) *periodic { - p.queryMutators = append(p.queryMutators, func(wc *asanaclient.WorkspaceClient, q *asanaclient.SearchQuery) error { + p.queryMutators = append(p.queryMutators, func(wc *client.WorkspaceClient, q *client.SearchQuery) error { utl, err := wc.GetMyUserTaskList() if err != nil { return err @@ -92,7 +92,7 @@ func (p *periodic) InMyTasksSections(names ...string) *periodic { } func (p *periodic) DueInDays(days int) *periodic { - p.queryMutators = append(p.queryMutators, func(wc *asanaclient.WorkspaceClient, q *asanaclient.SearchQuery) error { + p.queryMutators = append(p.queryMutators, func(wc *client.WorkspaceClient, q *client.SearchQuery) error { if q.DueOn != nil { return fmt.Errorf("Multiple clauses set DueOn") } @@ -107,7 +107,7 @@ func (p *periodic) DueInDays(days int) *periodic { } func (p *periodic) DueInAtLeastDays(days int) *periodic { - p.queryMutators = append(p.queryMutators, func(wc *asanaclient.WorkspaceClient, q *asanaclient.SearchQuery) error { + p.queryMutators = append(p.queryMutators, func(wc *client.WorkspaceClient, q *client.SearchQuery) error { if q.DueAfter != nil { return fmt.Errorf("Multiple clauses set DueAfter") } @@ -122,7 +122,7 @@ func (p *periodic) DueInAtLeastDays(days int) *periodic { } func (p *periodic) DueInAtMostDays(days int) *periodic { - p.queryMutators = append(p.queryMutators, func(wc *asanaclient.WorkspaceClient, q *asanaclient.SearchQuery) error { + p.queryMutators = append(p.queryMutators, func(wc *client.WorkspaceClient, q *client.SearchQuery) error { if q.DueBefore != nil { return fmt.Errorf("Multiple clauses set DueBefore") } @@ -137,12 +137,12 @@ func (p *periodic) DueInAtMostDays(days int) *periodic { } func (p *periodic) OnlyIncomplete() *periodic { - p.queryMutators = append(p.queryMutators, func(wc *asanaclient.WorkspaceClient, q *asanaclient.SearchQuery) error { + p.queryMutators = append(p.queryMutators, func(wc *client.WorkspaceClient, q *client.SearchQuery) error { if q.Completed != nil { return fmt.Errorf("Multiple clauses set Completed") } - q.Completed = asanaclient.FALSE + q.Completed = client.FALSE return nil }) @@ -150,12 +150,12 @@ func (p *periodic) OnlyIncomplete() *periodic { } func (p *periodic) OnlyComplete() *periodic { - p.queryMutators = append(p.queryMutators, func(wc *asanaclient.WorkspaceClient, q *asanaclient.SearchQuery) error { + p.queryMutators = append(p.queryMutators, func(wc *client.WorkspaceClient, q *client.SearchQuery) error { if q.Completed != nil { return fmt.Errorf("Multiple clauses set Completed") } - q.Completed = asanaclient.TRUE + q.Completed = client.TRUE return nil }) @@ -163,7 +163,7 @@ func (p *periodic) OnlyComplete() *periodic { } func (p *periodic) WithTagsAnyOf(names ...string) *periodic { - p.queryMutators = append(p.queryMutators, func(wc *asanaclient.WorkspaceClient, q *asanaclient.SearchQuery) error { + p.queryMutators = append(p.queryMutators, func(wc *client.WorkspaceClient, q *client.SearchQuery) error { if len(q.TagsAny) > 0 { return fmt.Errorf("Multiple clauses set TagsAny") } @@ -189,7 +189,7 @@ func (p *periodic) WithTagsAnyOf(names ...string) *periodic { } func (p *periodic) WithoutTagsAnyOf(names ...string) *periodic { - p.queryMutators = append(p.queryMutators, func(wc *asanaclient.WorkspaceClient, q *asanaclient.SearchQuery) error { + p.queryMutators = append(p.queryMutators, func(wc *client.WorkspaceClient, q *client.SearchQuery) error { if len(q.TagsNot) > 0 { return fmt.Errorf("Multiple clauses set TagsNot") } @@ -216,7 +216,7 @@ func (p *periodic) WithoutTagsAnyOf(names ...string) *periodic { // Task filters func (p *periodic) WithUnlinkedURL() *periodic { - p.taskFilters = append(p.taskFilters, func(wc *asanaclient.WorkspaceClient, t *asanaclient.Task) (bool, error) { + p.taskFilters = append(p.taskFilters, func(wc *client.WorkspaceClient, t *client.Task) (bool, error) { return hasUnlinkedURL(t.ParsedHTMLNotes), nil }) @@ -225,7 +225,7 @@ func (p *periodic) WithUnlinkedURL() *periodic { 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) { + p.taskFilters = append(p.taskFilters, func(wc *client.WorkspaceClient, t *client.Task) (bool, error) { return t.ParsedDueOn == nil, nil }) @@ -234,7 +234,7 @@ func (p *periodic) WithoutDue() *periodic { // Task actors func (p *periodic) FixUnlinkedURL() *periodic { - p.taskActors = append(p.taskActors, func(wc *asanaclient.WorkspaceClient, t *asanaclient.Task) error { + p.taskActors = append(p.taskActors, func(wc *client.WorkspaceClient, t *client.Task) error { fixUnlinkedURL(t.ParsedHTMLNotes) buf := &bytes.Buffer{} @@ -246,7 +246,7 @@ func (p *periodic) FixUnlinkedURL() *periodic { notes := buf.String() - update := &asanaclient.Task{ + update := &client.Task{ GID: t.GID, HTMLNotes: strings.TrimSuffix(strings.TrimPrefix(notes, ""), ""), } @@ -258,7 +258,7 @@ func (p *periodic) FixUnlinkedURL() *periodic { } func (p *periodic) MoveToMyTasksSection(name string) *periodic { - p.taskActors = append(p.taskActors, func(wc *asanaclient.WorkspaceClient, t *asanaclient.Task) error { + p.taskActors = append(p.taskActors, func(wc *client.WorkspaceClient, t *client.Task) error { utl, err := wc.GetMyUserTaskList() if err != nil { return err @@ -276,7 +276,7 @@ func (p *periodic) MoveToMyTasksSection(name string) *periodic { } func (p *periodic) PrintTasks() *periodic { - p.taskActors = append(p.taskActors, func(wc *asanaclient.WorkspaceClient, t *asanaclient.Task) error { + p.taskActors = append(p.taskActors, func(wc *client.WorkspaceClient, t *client.Task) error { fmt.Printf("%s\n", t) return nil }) @@ -285,7 +285,7 @@ func (p *periodic) PrintTasks() *periodic { } // Infra -func (p *periodic) start(client *asanaclient.Client) { +func (p *periodic) start(client *client.Client) { err := p.validate() if err != nil { panic(err) @@ -302,7 +302,7 @@ func (p *periodic) wait() { <-p.done } -func (p *periodic) loop(client *asanaclient.Client) { +func (p *periodic) loop(client *client.Client) { for { time.Sleep(time.Duration(rand.Intn(p.period)) * time.Second) @@ -316,13 +316,13 @@ func (p *periodic) loop(client *asanaclient.Client) { close(p.done) } -func (p *periodic) exec(c *asanaclient.Client) error { +func (p *periodic) exec(c *client.Client) error { wc, err := p.workspaceClientGetter(c) if err != nil { return err } - q := &asanaclient.SearchQuery{} + q := &client.SearchQuery{} for _, mut := range p.queryMutators { err = mut(wc, q) @@ -336,7 +336,7 @@ func (p *periodic) exec(c *asanaclient.Client) error { return err } - filteredTasks := []*asanaclient.Task{} + filteredTasks := []*client.Task{} for _, task := range tasks { included := true