forked from sachaos/todoist
-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter_eval.go
124 lines (114 loc) · 2.64 KB
/
filter_eval.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"regexp"
"strconv"
"time"
"github.com/sachaos/todoist/lib"
)
var priorityRegex = regexp.MustCompile("^p([1-4])$")
func Eval(e Expression, item todoist.AbstractItem, projects todoist.Projects, labels todoist.Labels) (result bool, err error) {
result = false
switch e.(type) {
case BoolInfixOpExpr:
e := e.(BoolInfixOpExpr)
lr, err := Eval(e.left, item, projects, labels)
rr, err := Eval(e.right, item, projects, labels)
if err != nil {
return false, nil
}
switch e.operator {
case '&':
return lr && rr, nil
case '|':
return lr || rr, nil
}
case ProjectExpr:
e := e.(ProjectExpr)
return EvalProject(e, item.GetProjectID(), projects), err
case LabelExpr:
e := e.(LabelExpr)
return EvalLabel(e, item.GetLabelNames(), labels), err
case StringExpr:
switch item.(type) {
case *todoist.Item:
item := item.(*todoist.Item)
e := e.(StringExpr)
return EvalAsPriority(e, item), err
default:
return false, nil
}
case DateExpr:
e := e.(DateExpr)
return EvalDate(e, item.DateTime()), err
case NotOpExpr:
e := e.(NotOpExpr)
r, err := Eval(e.expr, item, projects, labels)
if err != nil {
return false, nil
}
return !r, nil
default:
return true, err
}
return
}
func EvalDate(e DateExpr, itemDate time.Time) (result bool) {
if (itemDate == time.Time{}) {
return e.operation == NO_DUE_DATE
}
allDay := e.allDay
dueDate := e.datetime
switch e.operation {
case DUE_ON:
var startDate, endDate time.Time
if allDay {
startDate = dueDate
endDate = dueDate.AddDate(0, 0, 1)
if itemDate.Equal(startDate) || (itemDate.After(startDate) && itemDate.Before(endDate)) {
return true
}
}
return false
case DUE_BEFORE:
return itemDate.Before(dueDate)
case DUE_AFTER:
endDateTime := dueDate
if allDay {
endDateTime = dueDate.AddDate(0, 0, 1).Add(-time.Duration(time.Microsecond))
}
return itemDate.After(endDateTime)
default:
return false
}
}
func EvalAsPriority(e StringExpr, item *todoist.Item) (result bool) {
matched := priorityRegex.FindStringSubmatch(e.literal)
if len(matched) == 0 {
return false
} else {
p, _ := strconv.Atoi(matched[1])
if p == priorityMapping[item.Priority] {
return true
}
}
return false
}
func EvalProject(e ProjectExpr, projectID string, projects todoist.Projects) bool {
for _, id := range projects.GetIDsByName(e.name, e.isAll) {
if id == projectID {
return true
}
}
return false
}
func EvalLabel(e LabelExpr, labelNames []string, labels todoist.Labels) bool {
if e.name == "" {
return len(labelNames) == 0
}
for _, name := range labelNames {
if name == e.name {
return true
}
}
return false
}