commit 603509210cb741ea32949a4d3b692e9c1855ba5c Author: kekskurse Date: Mon Mar 4 03:11:29 2024 +0100 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..011adc7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +config.go +.idea +trelloBot +trello-bot-pi \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ce12ee8 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +build-pi: + env GOOS=linux GOARCH=arm go build -o trello-bot-pi ./ \ No newline at end of file diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..89fcc96 --- /dev/null +++ b/Readme.md @@ -0,0 +1,20 @@ +# Trello Bot +Just some trello functions because i don't want to lean Automations.... + +# Functions + +## reset-daily-tasks +Add a Label with the text "Daily" and a colome with the Text "ToDo", it will move all card with the label to thiw collume if run, so best run its every day ... + +## remove-done-cards +Remove cards from the "Done" list which are older than 7 days + +## move-backlog-card-with-date +Move all cards in the Backlog where the due date is in the past to the "ToDo" list and remove the due date + +# Example Cron setup +``` +*/5 * * * * /home/pi/trello-bot-pi move-backlog-card-with-date +0 5 * * * /home/pi/trello-bot-pi reset-daily-tasks +0 5 * * * /home/pi/trello-bot-pi remove-done-cards +``` \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a6b7e42 --- /dev/null +++ b/go.mod @@ -0,0 +1,20 @@ +module trelloBot + +go 1.22.0 + +require ( + github.com/adlio/trello v1.10.0 + github.com/rs/zerolog v1.32.0 + github.com/urfave/cli/v2 v2.27.1 +) + +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..31999e2 --- /dev/null +++ b/go.sum @@ -0,0 +1,29 @@ +github.com/adlio/trello v1.10.0 h1:ia/rzoBwJJKr4IqnMlrU6n09CVqeyaahSkEVcV5/gPc= +github.com/adlio/trello v1.10.0/go.mod h1:I4Lti4jf2KxjTNgTqs5W3lLuE78QZZdYbbPnQQGwjOo= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/main.go b/main.go new file mode 100644 index 0000000..854149e --- /dev/null +++ b/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "github.com/adlio/trello" + _ "github.com/adlio/trello" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/urfave/cli/v2" + _ "github.com/urfave/cli/v2" + "os" +) + +func getTrelloClient() *trello.Client { + client := trello.NewClient(trelloAPIKey, trelloAPIToken) + return client +} + +func main() { + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) + + app := &cli.App{ + Commands: []*cli.Command{ + { + Name: "reset-daily-tasks", + Aliases: []string{"rd"}, + Usage: "Reset all Task with a label \"Daily\" back to the list \"ToDo\"", + Action: resetDailyTasks, + }, + { + Name: "remove-done-cards", + Aliases: []string{"rm"}, + Usage: "Reset all Cards in the list \"Done\"", + Action: removeDoneCArds, + }, + { + Name: "move-backlog-card-with-date", + //Aliases: []string{"rm"}, + Usage: "Move all cards from \"Backlog\" to \"ToDo\" where the End Date is in the past and remove the duedate", + Action: moveBacklogCardWithDate, + }, + }, + } + + if err := app.Run(os.Args); err != nil { + log.Fatal().Err(err).Msg("Error running app") + } +} diff --git a/move-backlog-card-with-date.go b/move-backlog-card-with-date.go new file mode 100644 index 0000000..6d5e249 --- /dev/null +++ b/move-backlog-card-with-date.go @@ -0,0 +1,81 @@ +package main + +import ( + "errors" + "fmt" + "github.com/adlio/trello" + "github.com/rs/zerolog/log" + "github.com/urfave/cli/v2" + "time" +) + +func moveBacklogCardWithDate(cCtx *cli.Context) error { + client := getTrelloClient() + board, err := client.GetBoard(trelloBordID, trello.Defaults()) + if err != nil { + return fmt.Errorf("cant get bord: %w", err) + } + + log.Debug().Interface("bord", board).Msg("get bord") + + lists, err := board.GetLists(trello.Defaults()) + if err != nil { + return fmt.Errorf("cant get losts for board: %w", err) + } + + log.Debug().Interface("lists", lists).Msg("got lists") + + var backlogList *trello.List + var todoList *trello.List + + for _, list := range lists { + if list.Name == "Backlog" { + backlogList = list + } + if list.Name == "ToDo" { + todoList = list + } + } + + if backlogList == nil { + return errors.New("cant find list with the text \"Backlog\"") + } + + if todoList == nil { + return errors.New("cant find list with the text \"ToDo\"") + } + + cards, err := backlogList.GetCards() + if err != nil { + return fmt.Errorf("cant get card for Backlog list list: %w", err) + } + + for _, card := range cards { + log.Debug().Str("name", card.Name).Msg("Found card") + if card.Due == nil { + continue + } + if card.Due.Before(time.Now()) { + err = card.MoveToList(todoList.ID) + if err != nil { + return fmt.Errorf("cant move card to todo list: %w", err) + } + err = card.MoveToTopOfList() + if err != nil { + return fmt.Errorf("cant move card to top of todo list: %w", err) + } + _, err = card.AddComment(fmt.Sprintf("Due Date %v in Backlog reached, moved to todo!", card.Due)) + if err != nil { + return fmt.Errorf("cant add comment to card: %w", err) + } + card.Due = nil + err = card.Update(trello.Arguments{"due": "null"}) + if err != nil { + return fmt.Errorf("cant update card to remove due date: %w", err) + } + } + + } + + return nil +} diff --git a/remove-done-cards.go b/remove-done-cards.go new file mode 100644 index 0000000..edc41eb --- /dev/null +++ b/remove-done-cards.go @@ -0,0 +1,62 @@ +package main + +import ( + "errors" + "fmt" + "github.com/adlio/trello" + "github.com/rs/zerolog/log" + "github.com/urfave/cli/v2" + "time" +) + +func removeDoneCArds(cCtx *cli.Context) error { + client := getTrelloClient() + board, err := client.GetBoard(trelloBordID, trello.Defaults()) + if err != nil { + return fmt.Errorf("cant get bord: %w", err) + } + + log.Debug().Interface("bord", board).Msg("get bord") + + lists, err := board.GetLists(trello.Defaults()) + if err != nil { + return fmt.Errorf("cant get losts for board: %w", err) + } + + log.Debug().Interface("lists", lists).Msg("got lists") + + var doneList *trello.List + + for _, list := range lists { + if list.Name == "Done" { + doneList = list + break + } + } + + if doneList == nil { + return errors.New("cant find list with the text \"Done\"") + } + + cards, err := doneList.GetCards() + if err != nil { + return fmt.Errorf("cant get card for Done list: %w", err) + } + + for _, card := range cards { + log.Debug().Str("name", card.Name).Time("date of last activity", *card.DateLastActivity).Msg("Found card") + if !card.DateLastActivity.Before(time.Now().Add(-7 * 24 * time.Hour)) { + log.Debug().Msg("card not old enough,. keep") + continue + } + log.Info().Msg("card old enough, need to be deletet") + + err := card.Delete() + if err != nil { + return fmt.Errorf("cant delete card frome done list: %w", err) + } + + } + + return nil +} diff --git a/reset-daily-tasks.go b/reset-daily-tasks.go new file mode 100644 index 0000000..61ed111 --- /dev/null +++ b/reset-daily-tasks.go @@ -0,0 +1,90 @@ +package main + +import ( + "errors" + "fmt" + "github.com/adlio/trello" + "github.com/rs/zerolog/log" + "github.com/urfave/cli/v2" +) + +func resetDailyTasks(cCtx *cli.Context) error { + client := getTrelloClient() + board, err := client.GetBoard(trelloBordID, trello.Defaults()) + if err != nil { + return fmt.Errorf("cant get bord: %w", err) + } + + log.Debug().Interface("bord", board).Msg("get bord") + + labels, err := board.GetLabels() + if err != nil { + return fmt.Errorf("cant get labels for bord: %w", err) + } + + log.Debug().Interface("labels", labels).Msg("got labels") + + var dailyLabel *trello.Label + + for _, l := range labels { + if l.Name == "Daily" { + dailyLabel = l + break + } + } + + if dailyLabel == nil { + return errors.New("cant find label with the name \"Daily\"") + } + + log.Debug().Interface("daily label", dailyLabel).Msg("got daily label") + + lists, err := board.GetLists(trello.Defaults()) + if err != nil { + return fmt.Errorf("cant get losts for board: %w", err) + } + + log.Debug().Interface("lists", lists).Msg("got lists") + + var todoList *trello.List + + for _, list := range lists { + if list.Name == "ToDo" { + todoList = list + break + } + } + + if todoList == nil { + return errors.New("cant find list with the text \"ToDo\"") + } + + cards, err := board.GetCards() + + if err != nil { + return fmt.Errorf("cant get cards for bord: %w", err) + } + + log.Debug().Int("number of cards", len(cards)).Msg("Get Cards") + + for _, card := range cards { + foundLabel := false + for _, label := range card.Labels { + if label.ID == dailyLabel.ID { + foundLabel = true + break + } + } + + if !foundLabel { + break + } + + err = card.MoveToList(todoList.ID, trello.Defaults()) + if err != nil { + return fmt.Errorf("cant move card to todo list: %w", err) + } + } + + return nil +}