Skip to content

Commit

Permalink
Finish date filter
Browse files Browse the repository at this point in the history
  • Loading branch information
Grant Ammons committed Aug 27, 2020
1 parent b64d21f commit f8c76c8
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 62 deletions.
13 changes: 1 addition & 12 deletions ultralist/create_todo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,14 @@ import "time"

// CreateTodo will create a TodoItem from a Filter
func CreateTodo(filter *Filter) (*Todo, error) {
dueDateString := ""

if filter.LastDue() != "" {
dateParser := &DateParser{}
dueDate, err := dateParser.ParseDate(filter.LastDue(), time.Now())
if err != nil {
return nil, err
}
dueDateString = dueDate.Format("2006-01-02")
}

todoItem := &Todo{
Subject: filter.Subject,
Archived: filter.Archived,
IsPriority: filter.IsPriority,
Completed: filter.Completed,
Projects: filter.Projects,
Contexts: filter.Contexts,
Due: dueDateString,
Due: filter.Due,
Status: filter.LastStatus(),
}
if todoItem.Completed {
Expand Down
2 changes: 2 additions & 0 deletions ultralist/date_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ func (dp *DateParser) ParseDate(dateString string, pivotDay time.Time) (date tim
switch dateString {
case "none":
return time.Time{}, nil
case "yesterday", "yes":
return bod(pivotDay).AddDate(0, 0, -1), nil
case "today", "tod":
return bod(pivotDay), nil
case "tomorrow", "tom":
Expand Down
14 changes: 1 addition & 13 deletions ultralist/edit_todo.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
package ultralist

import "time"

// EditTodo edits a todo based upon a filter
func EditTodo(todo *Todo, filter *Filter) error {
if filter.HasDue {
dateParser := &DateParser{}
dueDate, err := dateParser.ParseDate(filter.LastDue(), time.Now())
if err != nil {
return err
}

if dueDate.IsZero() {
todo.Due = ""
} else {
todo.Due = dueDate.Format("2006-01-02")
}
todo.Due = filter.Due
}

if filter.HasCompleted {
Expand Down
34 changes: 16 additions & 18 deletions ultralist/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,32 @@ type Filter struct {
IsPriority bool
Completed bool

HasCompleted bool
HasCompletedAt bool
HasArchived bool
HasIsPriority bool
HasDue bool
HasStatus bool
HasProjectFilter bool
HasContextFilter bool
Due string
DueBefore string
DueAfter string

Contexts []string
Due []string
Projects []string
Status []string

ExcludeContexts []string
ExcludeDue []string
ExcludeProjects []string
ExcludeStatus []string

CompletedAt []string

HasCompleted bool
HasCompletedAt bool
HasArchived bool
HasIsPriority bool

HasDueBefore bool
HasDue bool
HasDueAfter bool

HasStatus bool
HasProjectFilter bool
HasContextFilter bool
}

// LastStatus returns the last status from the filter
Expand All @@ -36,11 +42,3 @@ func (f *Filter) LastStatus() string {
}
return f.Status[len(f.Status)-1]
}

// LastDue returns the last due from the filter
func (f *Filter) LastDue() string {
if len(f.Due) == 0 {
return ""
}
return f.Due[len(f.Due)-1]
}
64 changes: 55 additions & 9 deletions ultralist/input_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ultralist
import (
"regexp"
"strings"
"time"
)

// InputParser parses text to extract a Filter struct
Expand Down Expand Up @@ -37,16 +38,20 @@ project:one,-two

// Parse parses raw input and returns a Filter object
func (p *InputParser) Parse(input string) (*Filter, error) {

filter := &Filter{
HasStatus: false,
HasCompleted: false,
HasCompletedAt: false,
HasIsPriority: false,
HasProjectFilter: false,
HasContextFilter: false,
HasDueBefore: false,
HasDue: false,
HasDueAfter: false,
}

dateParser := &DateParser{}

var subjectMatches []string

cr, _ := regexp.Compile(`\@[\p{L}\d_-]+`)
Expand Down Expand Up @@ -78,10 +83,51 @@ func (p *InputParser) Parse(input string) (*Filter, error) {
match = true
}

r4, _ := regexp.Compile(`due:.*$`)
if r4.MatchString(word) {
rDueBefore, _ := regexp.Compile(`duebefore:.*$`)
if rDueBefore.MatchString(word) {
filter.HasDueBefore = true
dueDate, err := dateParser.ParseDate(rDueBefore.FindString(word)[10:], time.Now())
if err != nil {
return filter, err
}

if dueDate.IsZero() {
filter.DueBefore = ""
} else {
filter.DueBefore = dueDate.Format("2006-01-02")
}
match = true
}

rDue, _ := regexp.Compile(`due:.*$`)
if rDue.MatchString(word) {
filter.HasDue = true
filter.Due, filter.ExcludeDue = p.parseString(r4.FindString(word)[4:])
dueDate, err := dateParser.ParseDate(rDue.FindString(word)[4:], time.Now())
if err != nil {
return filter, err
}

if dueDate.IsZero() {
filter.Due = ""
} else {
filter.Due = dueDate.Format("2006-01-02")
}
match = true
}

rDueAfter, _ := regexp.Compile(`dueafter:.*$`)
if rDueAfter.MatchString(word) {
filter.HasDueAfter = true
dueDate, err := dateParser.ParseDate(rDueAfter.FindString(word)[9:], time.Now())
if err != nil {
return filter, err
}

if dueDate.IsZero() {
filter.DueAfter = ""
} else {
filter.DueAfter = dueDate.Format("2006-01-02")
}
match = true
}

Expand Down Expand Up @@ -122,16 +168,16 @@ func (p *InputParser) Parse(input string) (*Filter, error) {
}

func (p *InputParser) parseString(input string) ([]string, []string) {
var positive []string
var negative []string
var include []string
var exclude []string
for _, str := range strings.Split(input, ",") {
if strings.HasPrefix(str, "-") {
negative = append(negative, str[1:])
exclude = append(exclude, str[1:])
} else {
positive = append(positive, str)
include = append(include, str)
}
}
return positive, negative
return include, exclude
}

func (p *InputParser) parseBool(input string) bool {
Expand Down
8 changes: 5 additions & 3 deletions ultralist/input_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ultralist
import (
"fmt"
"testing"
"time"

"github.com/stretchr/testify/assert"
)
Expand All @@ -18,8 +19,8 @@ func TestInputParser(t *testing.T) {
assert.Equal("now", filter.Status[0])
assert.Equal("next", filter.Status[1])

assert.Equal(1, len(filter.Due))
assert.Equal("tom", filter.Due[0])
tomorrow := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
assert.Equal(tomorrow, filter.Due)
assert.Equal("do this thing", filter.Subject)
}

Expand All @@ -30,7 +31,8 @@ func TestSubject(t *testing.T) {
filter, _ := parser.Parse("due:tom here is the subject")

assert.Equal("here is the subject", filter.Subject)
assert.Equal("tom", filter.Due[0])
tomorrow := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
assert.Equal(tomorrow, filter.Due)
}

func TestProjectsInSubject(t *testing.T) {
Expand Down
40 changes: 40 additions & 0 deletions ultralist/todo_filter.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package ultralist

import (
"time"
)

// TodoFilter filters todos based on patterns.
type TodoFilter struct {
Filter *Filter
Expand Down Expand Up @@ -54,6 +58,42 @@ func (f *TodoFilter) ApplyFilter() []*Todo {
continue
}

// has exact due date
if f.Filter.HasDue {
if todo.Due == f.Filter.Due {
filtered = append(filtered, todo)
}
continue
}

if f.Filter.HasDueBefore {
if todo.Due == "" {
continue
}

todoTime, _ := time.Parse("2006-01-02", todo.Due)
dueBeforeTime, _ := time.Parse("2006-01-02", f.Filter.DueBefore)

if todoTime.Before(dueBeforeTime) {
filtered = append(filtered, todo)
}
continue
}

if f.Filter.HasDueAfter {
if todo.Due == "" {
continue
}

todoTime, _ := time.Parse("2006-01-02", todo.Due)
dueAfterTime, _ := time.Parse("2006-01-02", f.Filter.DueAfter)

if todoTime.After(dueAfterTime) {
filtered = append(filtered, todo)
}
continue
}

filtered = append(filtered, todo)
}

Expand Down
Loading

0 comments on commit f8c76c8

Please sign in to comment.