s/asana-rules/automana/

This commit is contained in:
Ian Gulliver
2021-09-21 03:39:15 +00:00
parent aa19b6923f
commit 30dbdc4f98
6 changed files with 49 additions and 35 deletions

View File

@@ -1,4 +1,4 @@
package asanaclient
package client
import "bytes"
import "encoding/json"

View File

@@ -1,4 +1,4 @@
package asanaclient
package client
import "fmt"
import "net/url"

3
go.mod
View File

@@ -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
)

4
go.sum
View File

@@ -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=

13
main.go
View File

@@ -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().

View File

@@ -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, "<html><head></head>"), "</html>"),
}
@@ -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