add helpers to client, begin isolating project/label resolution logic
This commit is contained in:
parent
a5d586ae59
commit
d23a0c9ae7
|
@ -2,9 +2,9 @@
|
|||
|
||||
CLI for [Todoist's](https://todoist.com) [v8 API](https://developer.todoist.com/rest/v8/) written in Go.
|
||||
|
||||
[![docker size](https://img.shields.io/microbadger/image-size/ssube/togo.svg)](https://hub.docker.com/r/ssube/togo/)
|
||||
[![pipeline status](https://git.apextoaster.com/ssube/togo/badges/master/pipeline.svg)](https://git.apextoaster.com/ssube/togo/commits/master)
|
||||
[![docker size](https://images.microbadger.com/badges/image/ssube/togo:master.svg)](https://microbadger.com/images/ssube/togo:master)
|
||||
[![license](https://img.shields.io/github/license/ssube/togo.svg)](MIT license)
|
||||
[![license](https://img.shields.io/github/license/ssube/togo.svg)](https://github.com/ssube/togo/blob/master/LICENSE.md)
|
||||
|
||||
Binaries are available from [the Github releases page](https://github.com/ssube/togo/releases) and container images
|
||||
from [the Docker hub](https://hub.docker.com/r/ssube/togo/).
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -99,8 +100,25 @@ func New(config *config.Config) *Client {
|
|||
return client
|
||||
}
|
||||
|
||||
// GetEndpoint formats a partial path as an API endpoint
|
||||
func (c *Client) GetEndpoint(parts ...string) string {
|
||||
func (c *Client) Get(parts ...string) (body []byte, status int, err error) {
|
||||
resp, err := c.Request().Get(c.Resolve(parts...))
|
||||
if err != nil {
|
||||
log.Printf("error getting labels: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
status = resp.StatusCode()
|
||||
if status != 200 {
|
||||
log.Printf("unexpected response status: %d", status)
|
||||
return nil, status, errors.New("unexpected response status")
|
||||
}
|
||||
|
||||
body = resp.Body()
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve a partial path as an API endpoint
|
||||
func (c *Client) Resolve(parts ...string) string {
|
||||
path := []string{
|
||||
c.config.Root,
|
||||
}
|
||||
|
|
|
@ -56,18 +56,13 @@ func (c *Client) FindLabel(name string) (Label, error) {
|
|||
|
||||
// GetLabels from API
|
||||
func (c *Client) GetLabels() ([]Label, error) {
|
||||
resp, err := c.Request().Get(c.GetEndpoint("labels"))
|
||||
body, _, err := c.Get("labels")
|
||||
if err != nil {
|
||||
log.Printf("error getting labels: %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode() != 200 {
|
||||
log.Printf("unexpected response status: %d", resp.StatusCode())
|
||||
return nil, errors.New("unexpected response status")
|
||||
}
|
||||
|
||||
labels, err := ParseLabels(resp.Body())
|
||||
labels, err := ParseLabels(body)
|
||||
if err != nil {
|
||||
log.Printf("error parsing labels: %s", err.Error())
|
||||
return nil, err
|
||||
|
|
|
@ -58,18 +58,13 @@ func (c *Client) FindProject(name string) (Project, error) {
|
|||
|
||||
// GetProjects from API
|
||||
func (c *Client) GetProjects() ([]Project, error) {
|
||||
resp, err := c.Request().Get(c.GetEndpoint("projects"))
|
||||
body, _, err := c.Get("projects")
|
||||
if err != nil {
|
||||
log.Printf("error getting projects: %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode() != 200 {
|
||||
log.Printf("unexpected response status: %d", resp.StatusCode())
|
||||
return nil, errors.New("unexpected response status")
|
||||
}
|
||||
|
||||
projects, err := ParseProjects(resp.Body())
|
||||
projects, err := ParseProjects(body)
|
||||
if err != nil {
|
||||
log.Printf("error parsing projects: %s", err.Error())
|
||||
return nil, err
|
||||
|
|
|
@ -46,8 +46,22 @@ func ParseTasks(data []byte) ([]Task, error) {
|
|||
return out, err
|
||||
}
|
||||
|
||||
func (c *Client) BuildFilter(required []string, optional []string) string {
|
||||
filter := make([]string, 0)
|
||||
|
||||
if len(required) > 0 {
|
||||
filter = append(filter, "("+strings.Join(required, " & ")+")")
|
||||
}
|
||||
|
||||
if len(optional) > 0 {
|
||||
filter = append(filter, "("+strings.Join(optional, " | ")+")")
|
||||
}
|
||||
|
||||
return strings.Join(filter, " & ")
|
||||
}
|
||||
|
||||
// GetTasks lists incomplete and recurring tasks
|
||||
func (c *Client) GetTasks(project string, required []string, optionals []string) ([]Task, error) {
|
||||
func (c *Client) GetTasks(project string, required []string, optional []string) ([]Task, error) {
|
||||
r := c.Request()
|
||||
|
||||
if project != "" {
|
||||
|
@ -55,19 +69,9 @@ func (c *Client) GetTasks(project string, required []string, optionals []string)
|
|||
}
|
||||
|
||||
// build the filters
|
||||
filter := make([]string, 0)
|
||||
r = r.SetQueryParam("filter", c.BuildFilter(required, optional))
|
||||
|
||||
if len(required) > 0 {
|
||||
filter = append(filter, "("+strings.Join(required, " & ")+")")
|
||||
}
|
||||
|
||||
if len(optionals) > 0 {
|
||||
filter = append(filter, "("+strings.Join(optionals, " | ")+")")
|
||||
}
|
||||
|
||||
r = r.SetQueryParam("filter", strings.Join(filter, " & "))
|
||||
|
||||
resp, err := r.Get(c.GetEndpoint("tasks"))
|
||||
resp, err := r.Get(c.Resolve("tasks"))
|
||||
if err != nil {
|
||||
log.Printf("error listing tasks: %s", err.Error())
|
||||
return nil, err
|
||||
|
@ -101,7 +105,7 @@ func (c *Client) AddTask(task Task) ([]Task, error) {
|
|||
resp, err := c.Request().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetBody(post).
|
||||
Post(c.GetEndpoint("tasks"))
|
||||
Post(c.Resolve("tasks"))
|
||||
if err != nil {
|
||||
log.Printf("error adding task: %s", err.Error())
|
||||
return nil, err
|
||||
|
@ -132,7 +136,7 @@ func (c *Client) CloseTask(task Task) error {
|
|||
|
||||
log.Printf("closing %d", task.ID)
|
||||
|
||||
path := c.GetEndpoint("tasks", strconv.Itoa(task.ID), "close")
|
||||
path := c.Resolve("tasks", strconv.Itoa(task.ID), "close")
|
||||
resp, err := c.Request().Post(path)
|
||||
if err != nil {
|
||||
log.Fatalf("error adding task: %s", err.Error())
|
||||
|
|
71
cmd/add.go
71
cmd/add.go
|
@ -10,6 +10,44 @@ import (
|
|||
"github.com/ssube/togo/client"
|
||||
)
|
||||
|
||||
func resolveLabels(labels []string) []int {
|
||||
labelIDs := make([]int, len(labels))
|
||||
|
||||
if len(labels) == 0 {
|
||||
return labelIDs
|
||||
}
|
||||
|
||||
for i, l := range labels {
|
||||
id, err := strconv.Atoi(l)
|
||||
if err == nil {
|
||||
labelIDs[i] = id
|
||||
continue
|
||||
}
|
||||
|
||||
label, err := rootClient.FindLabel(l)
|
||||
if err != nil {
|
||||
log.Fatalf("error getting labels: %s", err.Error())
|
||||
}
|
||||
|
||||
labelIDs[i] = label.ID
|
||||
}
|
||||
|
||||
return labelIDs
|
||||
}
|
||||
|
||||
func resolveProject(ref string) int {
|
||||
if ref == "" {
|
||||
return 0
|
||||
}
|
||||
|
||||
project, err := rootClient.FindProject(ref)
|
||||
if err != nil {
|
||||
log.Fatalf("error getting projects: %s", err.Error())
|
||||
}
|
||||
|
||||
return project.ID
|
||||
}
|
||||
|
||||
func init() {
|
||||
columns := []string{
|
||||
"ID",
|
||||
|
@ -27,37 +65,8 @@ func init() {
|
|||
Run: func(cmd *cobra.Command, args []string) {
|
||||
task := client.Task{
|
||||
Content: strings.Join(args, " "),
|
||||
}
|
||||
|
||||
// resolve labels
|
||||
if len(labels) > 0 {
|
||||
labelIDs := make([]int, len(labels))
|
||||
for i, l := range labels {
|
||||
id, err := strconv.Atoi(l)
|
||||
if err == nil {
|
||||
labelIDs[i] = id
|
||||
continue
|
||||
}
|
||||
|
||||
label, err := rootClient.FindLabel(l)
|
||||
if err != nil {
|
||||
log.Fatalf("error getting labels: %s", err.Error())
|
||||
}
|
||||
|
||||
labelIDs[i] = label.ID
|
||||
}
|
||||
|
||||
task.Labels = labelIDs
|
||||
}
|
||||
|
||||
// resolve project
|
||||
if project != "" {
|
||||
project, err := rootClient.FindProject(project)
|
||||
if err != nil {
|
||||
log.Fatalf("error getting projects: %s", err.Error())
|
||||
}
|
||||
|
||||
task.Project = project.ID
|
||||
Labels: resolveLabels(labels),
|
||||
Project: resolveProject(project),
|
||||
}
|
||||
|
||||
// add task
|
||||
|
|
Loading…
Reference in New Issue