add due date to tasks, columns
This commit is contained in:
parent
d23a0c9ae7
commit
1393b0a334
4
Makefile
4
Makefile
|
@ -13,6 +13,10 @@ go-deps:
|
|||
go-test:
|
||||
go test ${BUILD_OPTS} -cover ./...
|
||||
|
||||
git-push:
|
||||
git push github
|
||||
git push gitlab
|
||||
|
||||
docker-build:
|
||||
docker build -T ${IMAGE_NAME} .
|
||||
|
||||
|
|
|
@ -203,6 +203,7 @@ Features:
|
|||
- [x] add task labels
|
||||
- [x] config defaults
|
||||
- [x] columns & sort on root
|
||||
- [x] add due date column
|
||||
- [ ] list project names
|
||||
- [ ] list label names
|
||||
- [ ] test coverage
|
||||
|
@ -214,4 +215,4 @@ Features:
|
|||
|
||||
togo was written by [ssube](https://github.com/ssube) and is not created by, affiliated with, or supported by Doist.
|
||||
|
||||
Source, documentation, and everything else in this repository is distributed under the included MIT license.
|
||||
Source, documentation, and everything else in this repository is distributed under the included MIT license.
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/ssube/togo/config"
|
||||
"gopkg.in/resty.v1"
|
||||
|
@ -39,8 +40,27 @@ func CreateTable(f *os.File, cols []string) *tabwriter.Writer {
|
|||
return w
|
||||
}
|
||||
|
||||
func FormatDate(d DueDate, dateFmt string) (string, error) {
|
||||
// if no timezone is provided, this is a simple date (day)
|
||||
if d.Timezone == "" {
|
||||
return d.Date, nil
|
||||
}
|
||||
|
||||
zone, err := time.LoadLocation(d.Timezone)
|
||||
if err != nil {
|
||||
return d.DateTime, err
|
||||
}
|
||||
|
||||
local, err := time.ParseInLocation(time.RFC3339, d.DateTime, zone)
|
||||
if err != nil {
|
||||
return d.DateTime, err
|
||||
}
|
||||
|
||||
return local.Format(dateFmt), nil
|
||||
}
|
||||
|
||||
// GetFields from a column list using reflection
|
||||
func GetFields(val interface{}, cols []string) []string {
|
||||
func GetFields(val interface{}, cols []string, dateFmt string) []string {
|
||||
out := make([]string, len(cols))
|
||||
rv := reflect.ValueOf(val).Elem()
|
||||
|
||||
|
@ -59,6 +79,18 @@ func GetFields(val interface{}, cols []string) []string {
|
|||
out[i] = strconv.FormatInt(field.Int(), 10)
|
||||
case reflect.String:
|
||||
out[i] = field.String()
|
||||
case reflect.Struct:
|
||||
val := field.Interface()
|
||||
switch val.(type) {
|
||||
case DueDate:
|
||||
fmt, err := FormatDate(val.(DueDate), dateFmt)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to format date: %s", err.Error)
|
||||
}
|
||||
out[i] = fmt
|
||||
default:
|
||||
log.Printf("unknown struct for column %s: %v", c, val)
|
||||
}
|
||||
case reflect.Slice:
|
||||
fallthrough
|
||||
default:
|
||||
|
|
|
@ -26,12 +26,12 @@ func ParseLabels(data []byte) ([]Label, error) {
|
|||
}
|
||||
|
||||
// PrintLabels after sorting, with column headers
|
||||
func PrintLabels(f *os.File, labels []Label, cols []string, sortCol string) {
|
||||
func PrintLabels(f *os.File, labels []Label, cols []string, sortCol string, dateFmt string) {
|
||||
w := CreateTable(f, cols)
|
||||
SortByField(labels, sortCol)
|
||||
|
||||
for _, l := range labels {
|
||||
fields := GetFields(&l, cols)
|
||||
fields := GetFields(&l, cols, dateFmt)
|
||||
fmt.Fprintln(w, Tabulate(fields)...)
|
||||
}
|
||||
|
||||
|
|
|
@ -27,13 +27,13 @@ func ParseProjects(data []byte) ([]Project, error) {
|
|||
}
|
||||
|
||||
// PrintProjects after sorting, with column headers
|
||||
func PrintProjects(f *os.File, projects []Project, cols []string, sortCol string) {
|
||||
func PrintProjects(f *os.File, projects []Project, cols []string, sortCol string, dateFmt string) {
|
||||
w := CreateTable(f, cols)
|
||||
SortByField(projects, sortCol)
|
||||
|
||||
// prepare a slice for cols and tabs
|
||||
for _, p := range projects {
|
||||
fields := GetFields(&p, cols)
|
||||
fields := GetFields(&p, cols, dateFmt)
|
||||
fmt.Fprintln(w, Tabulate(fields)...)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,25 +13,32 @@ import (
|
|||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type DueDate struct {
|
||||
Date string `json:"date" yaml:"date"`
|
||||
DateTime string `json:"datetime" yaml:"datetime"`
|
||||
Timezone string `json:"timezone" yaml:"timezone"`
|
||||
}
|
||||
|
||||
// Task model
|
||||
// https://developer.todoist.com/rest/v8/#tasks
|
||||
type Task struct {
|
||||
Content string `json:"content" yaml:"content"`
|
||||
ID int `json:"id" yaml:"id,omitempty"`
|
||||
Labels []int `json:"label_ids" yaml:"label_ids"`
|
||||
Order int `json:"order" yaml:"order,omitempty"`
|
||||
Priority int `json:"priority" yaml:"priority,omitempty"`
|
||||
Project int `json:"project_id" yaml:"project_id"`
|
||||
Content string `json:"content" yaml:"content"`
|
||||
Due DueDate `json:"due" yaml:"due"`
|
||||
ID int `json:"id" yaml:"id,omitempty"`
|
||||
Labels []int `json:"label_ids" yaml:"label_ids"`
|
||||
Order int `json:"order" yaml:"order,omitempty"`
|
||||
Priority int `json:"priority" yaml:"priority,omitempty"`
|
||||
Project int `json:"project_id" yaml:"project_id"`
|
||||
}
|
||||
|
||||
// PrintTasks in a table
|
||||
func PrintTasks(f *os.File, tasks []Task, cols []string, sortCol string) {
|
||||
func PrintTasks(f *os.File, tasks []Task, cols []string, sortCol string, dateFmt string) {
|
||||
w := CreateTable(f, cols)
|
||||
SortByField(tasks, sortCol)
|
||||
|
||||
// prepare a slice for cols and tabs
|
||||
for _, t := range tasks {
|
||||
fields := GetFields(&t, cols)
|
||||
fields := GetFields(&t, cols, dateFmt)
|
||||
fmt.Fprintln(w, Tabulate(fields)...)
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ func init() {
|
|||
"ID",
|
||||
"Content",
|
||||
}
|
||||
date := rootConfig.Default.Date
|
||||
done := false
|
||||
labels := rootConfig.Default.Tasks.Labels
|
||||
project := rootConfig.Default.Tasks.Project
|
||||
|
@ -76,8 +77,9 @@ func init() {
|
|||
}
|
||||
|
||||
columns := rootClient.Columns(columns, rootColumns, rootClient.Config().Default.Projects.Columns)
|
||||
date := rootClient.Sort(date, rootDate, rootClient.Config().Default.Date)
|
||||
sort := rootClient.Sort(sort, rootSort, rootClient.Config().Default.Projects.Sort)
|
||||
client.PrintTasks(os.Stdout, tasks, columns, sort)
|
||||
client.PrintTasks(os.Stdout, tasks, columns, sort, date)
|
||||
if done {
|
||||
// this should be a single item
|
||||
for _, t := range tasks {
|
||||
|
|
|
@ -3,6 +3,7 @@ package cmd
|
|||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/ssube/togo/client"
|
||||
|
@ -13,6 +14,7 @@ func init() {
|
|||
"ID",
|
||||
"Name",
|
||||
}
|
||||
date := time.RFC3339
|
||||
sort := "Name"
|
||||
|
||||
labelsCmd := &cobra.Command{
|
||||
|
@ -25,8 +27,9 @@ func init() {
|
|||
}
|
||||
|
||||
columns := rootClient.Columns(columns, rootColumns, rootClient.Config().Default.Labels.Columns)
|
||||
date := rootClient.Sort(date, rootDate, rootClient.Config().Default.Date)
|
||||
sort := rootClient.Sort(sort, rootSort, rootClient.Config().Default.Labels.Sort)
|
||||
client.PrintLabels(os.Stdout, labels, columns, sort)
|
||||
client.PrintLabels(os.Stdout, labels, columns, sort, date)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/ssube/togo/client"
|
||||
|
@ -14,6 +15,7 @@ func init() {
|
|||
"ID",
|
||||
"Content",
|
||||
}
|
||||
date := time.RFC3339
|
||||
labels := rootConfig.Default.Tasks.Labels
|
||||
project := rootConfig.Default.Tasks.Project
|
||||
sort := "ID"
|
||||
|
@ -38,8 +40,9 @@ func init() {
|
|||
}
|
||||
|
||||
columns := rootClient.Columns(columns, rootColumns, rootClient.Config().Default.Tasks.Columns)
|
||||
date := rootClient.Sort(date, rootDate, rootClient.Config().Default.Date)
|
||||
sort := rootClient.Sort(sort, rootSort, rootClient.Config().Default.Tasks.Sort)
|
||||
client.PrintTasks(os.Stdout, tasks, columns, sort)
|
||||
client.PrintTasks(os.Stdout, tasks, columns, sort, date)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package cmd
|
|||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/ssube/togo/client"
|
||||
|
@ -13,6 +14,7 @@ func init() {
|
|||
"ID",
|
||||
"Name",
|
||||
}
|
||||
date := time.RFC3339
|
||||
sort := "Name"
|
||||
|
||||
projectsCmd := &cobra.Command{
|
||||
|
@ -25,8 +27,9 @@ func init() {
|
|||
}
|
||||
|
||||
columns := rootClient.Columns(columns, rootColumns, rootClient.Config().Default.Projects.Columns)
|
||||
date := rootClient.Sort(date, rootDate, rootClient.Config().Default.Date)
|
||||
sort := rootClient.Sort(sort, rootSort, rootClient.Config().Default.Projects.Sort)
|
||||
client.PrintProjects(os.Stdout, projects, columns, sort)
|
||||
client.PrintProjects(os.Stdout, projects, columns, sort, date)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ var rootConfig = &config.Config{}
|
|||
|
||||
// persistent flags
|
||||
var rootColumns = []string{}
|
||||
var rootDate = ""
|
||||
var rootSort = ""
|
||||
|
||||
// flags
|
||||
|
@ -46,6 +47,7 @@ func Execute(client *client.Client) {
|
|||
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().StringSliceVarP(&rootColumns, "columns", "c", []string{}, "display columns")
|
||||
rootCmd.PersistentFlags().StringVarP(&rootDate, "date", "d", "", "date format")
|
||||
rootCmd.PersistentFlags().StringVarP(&rootSort, "sort", "s", "", "sort column")
|
||||
|
||||
// root-only flags
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
type Config struct {
|
||||
Default struct {
|
||||
Date string
|
||||
Labels struct {
|
||||
Columns []string
|
||||
Sort string
|
||||
|
|
Loading…
Reference in New Issue