aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Ammons <gammons@gmail.com>2016-04-30 08:45:49 -0400
committerGrant Ammons <gammons@gmail.com>2016-04-30 08:45:49 -0400
commitef9427646b9464d1f8c376f75741e737117a1a83 (patch)
treeba3912135e071cd2c7b77e746126cc5eae67ccfb
parent695c60e3f58d831e4b05aa35114adff7e1c46d23 (diff)
Handle parsing dates, and printing them
-rw-r--r--todolist/formatter.go61
-rw-r--r--todolist/parser.go73
-rw-r--r--todolist/parser_test.go58
-rw-r--r--todolist/todo_item.go17
4 files changed, 166 insertions, 43 deletions
diff --git a/todolist/formatter.go b/todolist/formatter.go
index 77006e0..60517f1 100644
--- a/todolist/formatter.go
+++ b/todolist/formatter.go
@@ -7,6 +7,7 @@ import (
"strconv"
"strings"
"text/tabwriter"
+ "time"
"github.com/fatih/color"
)
@@ -24,23 +25,71 @@ func NewFormatter(todos *GroupedTodos) *Formatter {
}
func (f *Formatter) Print() {
- yellow := color.New(color.FgYellow).SprintFunc()
cyan := color.New(color.FgCyan).SprintFunc()
for key, todos := range f.GroupedTodos.Groups {
fmt.Fprintf(f.Writer, "\n \t%s\n", cyan(key))
-
for _, todo := range todos {
- fmt.Fprintf(f.Writer, " \t%s\t%s\t%s\t\n",
- yellow(strconv.Itoa(todo.Id)),
- f.formatCompleted(todo.Completed),
- f.formatSubject(todo.Subject))
+ f.printTodo(todo)
}
}
f.Writer.Flush()
}
+func (f *Formatter) printTodo(todo Todo) {
+ yellow := color.New(color.FgYellow).SprintFunc()
+ fmt.Fprintf(f.Writer, " \t%s\t%s\t%s\t%s\t\n",
+ yellow(strconv.Itoa(todo.Id)),
+ f.formatCompleted(todo.Completed),
+ f.formatDue(todo.Due),
+ f.formatSubject(todo.Subject))
+}
+
+func (f *Formatter) formatDue(due string) string {
+ if due == "" {
+ return ""
+ }
+ dueTime, err := time.Parse("2006-01-02", due)
+
+ if err != nil {
+ panic(err)
+ }
+
+ blue := color.New(color.FgBlue).SprintFunc()
+ red := color.New(color.FgRed).SprintFunc()
+
+ if isToday(dueTime) {
+ return blue("today")
+ } else if isTomorrow(dueTime) {
+ return blue("tomorrow")
+ } else if isPastDue(dueTime) {
+ return red(dueTime.Format("Mon Jan 2"))
+ } else {
+ return blue(dueTime.Format("Mon Jan 2"))
+ }
+}
+
+func isToday(t time.Time) bool {
+ nowYear, nowMonth, nowDay := time.Now().Date()
+ timeYear, timeMonth, timeDay := t.Date()
+ return nowYear == timeYear &&
+ nowMonth == timeMonth &&
+ nowDay == timeDay
+}
+
+func isTomorrow(t time.Time) bool {
+ nowYear, nowMonth, nowDay := time.Now().AddDate(0, 0, 1).Date()
+ timeYear, timeMonth, timeDay := t.Date()
+ return nowYear == timeYear &&
+ nowMonth == timeMonth &&
+ nowDay == timeDay
+}
+
+func isPastDue(t time.Time) bool {
+ return time.Now().After(t)
+}
+
func (f *Formatter) formatSubject(subject string) string {
red := color.New(color.FgRed).SprintFunc()
magenta := color.New(color.FgMagenta).SprintFunc()
diff --git a/todolist/parser.go b/todolist/parser.go
index 1e98d33..a857f16 100644
--- a/todolist/parser.go
+++ b/todolist/parser.go
@@ -17,7 +17,7 @@ func (p *Parser) ParseNewTodo(input string) *Todo {
todo.Projects = p.Projects(input)
todo.Contexts = p.Contexts(input)
if p.hasDue(input) {
- todo.FormattedDue = p.Due(input)
+ todo.Due = p.Due(input, time.Now())
}
return todo
}
@@ -49,31 +49,78 @@ func (p *Parser) hasDue(input string) bool {
return r.MatchString(input)
}
-func (p *Parser) Due(input string) time.Time {
+func (p *Parser) Due(input string, day time.Time) string {
r, _ := regexp.Compile(`due .*$`)
res := r.FindString(input)
res = res[4:len(res)]
switch {
case res == "today":
- return now.BeginningOfDay()
+ return now.BeginningOfDay().Format("2006-01-02")
case res == "tomorrow" || res == "tom":
- return now.BeginningOfDay().AddDate(0, 0, 1)
+ return now.BeginningOfDay().AddDate(0, 0, 1).Format("2006-01-02")
case res == "monday" || res == "mon":
- n := now.BeginningOfDay()
- return now.New(n).Monday().AddDate(0, 0, 7)
+ return p.monday(day)
case res == "tuesday" || res == "tue":
- n := now.BeginningOfDay()
- return now.New(n).Monday().AddDate(0, 0, 1)
+ return p.tuesday(day)
case res == "wednesday" || res == "wed":
- n := now.BeginningOfDay()
- return now.New(n).Monday().AddDate(0, 0, 2)
+ return p.wednesday(day)
+ case res == "thursday" || res == "thu":
+ return p.thursday(day)
+ case res == "friday" || res == "fri":
+ return p.friday(day)
+ case res == "saturday" || res == "sat":
+ return p.saturday(day)
+ case res == "sunday" || res == "sun":
+ return p.sunday(day)
case res == "next week":
n := now.BeginningOfDay()
- return now.New(n).Monday().AddDate(0, 0, 7)
+ return now.New(n).Monday().AddDate(0, 0, 7).Format("2006-01-02")
+ }
+ return time.Now().Format("2006-01-02")
+}
+
+func (p *Parser) monday(day time.Time) string {
+ mon := now.New(day).Monday()
+ return p.thisOrNextWeek(mon, day)
+}
+
+func (p *Parser) tuesday(day time.Time) string {
+ tue := now.New(day).Monday().AddDate(0, 0, 1)
+ return p.thisOrNextWeek(tue, day)
+}
+
+func (p *Parser) wednesday(day time.Time) string {
+ tue := now.New(day).Monday().AddDate(0, 0, 2)
+ return p.thisOrNextWeek(tue, day)
+}
+
+func (p *Parser) thursday(day time.Time) string {
+ tue := now.New(day).Monday().AddDate(0, 0, 3)
+ return p.thisOrNextWeek(tue, day)
+}
+
+func (p *Parser) friday(day time.Time) string {
+ tue := now.New(day).Monday().AddDate(0, 0, 4)
+ return p.thisOrNextWeek(tue, day)
+}
+
+func (p *Parser) saturday(day time.Time) string {
+ tue := now.New(day).Monday().AddDate(0, 0, 5)
+ return p.thisOrNextWeek(tue, day)
+}
+
+func (p *Parser) sunday(day time.Time) string {
+ tue := now.New(day).Monday().AddDate(0, 0, 6)
+ return p.thisOrNextWeek(tue, day)
+}
+
+func (p *Parser) thisOrNextWeek(day time.Time, pivotDay time.Time) string {
+ if day.Before(pivotDay) {
+ return day.AddDate(0, 0, 7).Format("2006-01-02")
+ } else {
+ return day.Format("2006-01-02")
}
- //return now.Parse(input)
- return time.Now()
}
func (p *Parser) matchWords(input string, r *regexp.Regexp) []string {
diff --git a/todolist/parser_test.go b/todolist/parser_test.go
index 1ab2826..9a2732c 100644
--- a/todolist/parser_test.go
+++ b/todolist/parser_test.go
@@ -6,11 +6,12 @@ import (
"time"
"github.com/jinzhu/now"
+ "github.com/stretchr/testify/assert"
)
func TestParseSubject(t *testing.T) {
parser := &Parser{}
- todo := parser.Parse("do this thing")
+ todo := parser.ParseNewTodo("do this thing")
if todo.Subject != "do this thing" {
t.Error("Expected todo.Subject to equal 'do this thing'")
}
@@ -18,7 +19,7 @@ func TestParseSubject(t *testing.T) {
func TestParseSubjectWithDue(t *testing.T) {
parser := &Parser{}
- todo := parser.Parse("do this thing due tomorrow")
+ todo := parser.ParseNewTodo("do this thing due tomorrow")
if todo.Subject != "do this thing" {
t.Error("Expected todo.Subject to equal 'do this thing', got ", todo.Subject)
}
@@ -26,7 +27,7 @@ func TestParseSubjectWithDue(t *testing.T) {
func TestParseProjects(t *testing.T) {
parser := &Parser{}
- todo := parser.Parse("do this thing +proj1 +proj2 due tomorrow")
+ todo := parser.ParseNewTodo("do this thing +proj1 +proj2 due tomorrow")
if len(todo.Projects) != 2 {
t.Error("Expected Projects length to be 2")
}
@@ -40,7 +41,7 @@ func TestParseProjects(t *testing.T) {
func TestParseContexts(t *testing.T) {
parser := &Parser{}
- todo := parser.Parse("do this thing with @bob and @mary due tomorrow")
+ todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow")
if len(todo.Contexts) != 2 {
t.Error("Expected Projects length to be 2")
}
@@ -54,20 +55,55 @@ func TestParseContexts(t *testing.T) {
func TestDueToday(t *testing.T) {
parser := &Parser{}
- todo := parser.Parse("do this thing with @bob and @mary due today")
- if todo.FormattedDue != now.BeginningOfDay() {
+ todo := parser.ParseNewTodo("do this thing with @bob and @mary due today")
+ if todo.Due != now.BeginningOfDay().Format("2006-01-02") {
fmt.Println("Date is different", todo.Due, time.Now())
}
}
func TestDueTomorrow(t *testing.T) {
parser := &Parser{}
- todo := parser.Parse("do this thing with @bob and @mary due tomorrow")
- if todo.FormattedDue != now.BeginningOfDay().AddDate(0, 0, 1) {
+ todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow")
+ if todo.Due != now.BeginningOfDay().AddDate(0, 0, 1).Format("2006-01-02") {
fmt.Println("Date is different", todo.Due, time.Now())
}
}
+func TestMondayOnSunday(t *testing.T) {
+ assert := assert.New(t)
+ parser := &Parser{}
+ now, _ := time.Parse("2006-01-02", "2016-04-24")
+ assert.Equal("2016-04-25", parser.monday(now))
+}
+
+func TestMondayOnMonday(t *testing.T) {
+ assert := assert.New(t)
+ parser := &Parser{}
+ now, _ := time.Parse("2006-01-02", "2016-04-25")
+ assert.Equal("2016-04-25", parser.monday(now))
+}
+
+func TestMondayOnTuesday(t *testing.T) {
+ assert := assert.New(t)
+ parser := &Parser{}
+ now, _ := time.Parse("2006-01-02", "2016-04-26")
+ assert.Equal("2016-05-02", parser.monday(now))
+}
+
+func TestTuesdayOnMonday(t *testing.T) {
+ assert := assert.New(t)
+ parser := &Parser{}
+ now, _ := time.Parse("2006-01-02", "2016-04-25")
+ assert.Equal("2016-04-26", parser.tuesday(now))
+}
+
+func TestTuesdayOnWednesday(t *testing.T) {
+ assert := assert.New(t)
+ parser := &Parser{}
+ now, _ := time.Parse("2006-01-02", "2016-04-27")
+ assert.Equal("2016-05-03", parser.tuesday(now))
+}
+
//func TestDueNextWeek(t *testing.T) {
// parser := &Parser{}
//
@@ -75,9 +111,3 @@ func TestDueTomorrow(t *testing.T) {
// todo := parser.Parse("do this thing with @bob and @mary due next week")
// fmt.Println(todo.Due)
//}
-
-func TestDueMonday(t *testing.T) {
- parser := &Parser{}
- todo := parser.Parse("do this thing with @bob and @mary due mon")
- fmt.Println(todo.Due)
-}
diff --git a/todolist/todo_item.go b/todolist/todo_item.go
index 0b6eeac..cc06615 100644
--- a/todolist/todo_item.go
+++ b/todolist/todo_item.go
@@ -1,16 +1,13 @@
package todolist
-import "time"
-
type Todo struct {
- Id int `json:"id"`
- Subject string `json:"subject"`
- Projects []string `json:"projects"`
- Contexts []string `json:"contexts"`
- Due string `json:"due"`
- FormattedDue time.Time `json:"-"`
- Completed bool `json:"completed"`
- Archived bool `json:"archived"`
+ Id int `json:"id"`
+ Subject string `json:"subject"`
+ Projects []string `json:"projects"`
+ Contexts []string `json:"contexts"`
+ Due string `json:"due"`
+ Completed bool `json:"completed"`
+ Archived bool `json:"archived"`
}
func NewTodo() *Todo {