This repository was archived by the owner on Apr 2, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtask.go
151 lines (137 loc) · 4.1 KB
/
task.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package todo
import (
"errors"
"fmt"
"math"
"strings"
"time"
"unicode/utf8"
)
const CONTENT_LENGTH int = 58
const DAY_HOURS = time.Hour * 24
const RECORD_TIME_FORMAT = "2006/01/02 MST 15:04:05"
const EXPLICIT_TIME_FORMAT = "2006/01/02 MST"
const RELATIVE_TIME_FORMAT = "Monday MST"
type Task struct {
// The "body" content of the task.
BodyContent string
// The first day when this task will appear. Not the actual due date.
DueDate time.Time
// When to repeat this task when it is deleted.
// If it is null this task does not repeat.
//
// Can either be a time.Duration (as an int) or a more flexible date
// representation (e.g. Monday or a list of days with , separating).
Repeat *string
// How many days until this task is actually due.
OverdueDays int
fileName string
// The minimal index needed to specify this task
index string
// The full index
fullIndex string
// optional category
category *string
}
func (task Task) GetFullIndex() string {
return task.fullIndex
}
func (task Task) Category() string {
if task.category != nil {
return *task.category
}
return ""
}
func (task Task) String() string {
categoryName := ""
if task.category != nil {
categoryName = "(" + *task.category + ")"
}
daysLeft := " "
dueDate := time.Now().AddDate(0, 0, -task.OverdueDays)
if task.DueBefore(dueDate) {
passedDueDate := task.DueDate.AddDate(0, 0, task.OverdueDays)
/*passedDueDate = passedDueDate.Truncate(DAY_HOURS)*/
overdueDays := int(math.Floor(time.Now().Sub(passedDueDate).Hours() / 24))
if task.DueBefore(time.Now().Truncate(DAY_HOURS)) && overdueDays > /*=*/ 0 {
if overdueDays == 1 || overdueDays == 0 {
daysLeft = fmt.Sprintf(" (%d day overdue)", 1)
} else {
daysLeft = fmt.Sprintf(" (%d days overdue)", overdueDays)
}
} else {
daysLeft = " (due today)"
}
} else if task.OverdueDays > 0 {
finalDueDate := task.DueDate.AddDate(0, 0, task.OverdueDays)
days := int(math.Ceil(finalDueDate.Sub(time.Now()).Hours() / 24))
if days == 0 {
daysLeft = " (due today)"
} else if days == 1 {
daysLeft = fmt.Sprintf(" (%d day left)", days)
} else {
daysLeft = fmt.Sprintf(" (%d days left)", days)
}
}
trimmed_content := strings.TrimSuffix(task.BodyContent, "\n")
preamble := task.index + ":"
return HardWrapString(trimmed_content,
60,
preamble,
10,
fmt.Sprintf("%-15s%s", categoryName, daysLeft),
" ")
}
/// Creates a new task, without saving it.
func NewTask(text string, dueDate time.Time, repeat *string, overdueDays int) (Task, error) {
if !utf8.ValidString(text) {
panic(fmt.Sprintf("Invalid UTF-8 string: %v", text))
}
text = strings.TrimSuffix(text, "\n")
if text == "" {
msg := "Cannot make a task with an empty string"
LogError(msg)
return Task{}, errors.New(msg)
}
var task Task
task.BodyContent = text
task.DueDate = dueDate
task.Repeat = repeat
task.OverdueDays = overdueDays
return task, nil
}
// Format just the task body
func (task *Task) FormatTask() string {
passedDueDate := task.DueDate.AddDate(0, 0, task.OverdueDays)
overdueDays := int(math.Floor(time.Now().Sub(passedDueDate).Hours() / 24))
if overdueDays > 0 {
//if task.DueBefore(time.Now().AddDate(0, 0, -task.OverdueDays)) {
return RED + task.String() + RESET
} else if task.DueAfter(time.Now().AddDate(0, 0, 6)) {
return GREY + task.String() + RESET
}
return RESET + task.String()
}
/// Determines if a task is due exactly on this day. Not before, not after.
func (task *Task) DueOn(date time.Time) bool {
return !(task.DueDate.Before(date) || task.DueBefore(date))
}
// Determines if a task is due today (or any days before today)
//
// NOTE This is NOT a special case of Task.DueOn.
func (task *Task) DueToday() bool {
return is_same_day(task.DueDate, time.Now()) ||
task.DueDate.Before(time.Now())
}
/// Determines if a task is due before today.
func (task *Task) DueBefore(date time.Time) bool {
return task.DueDate.Before(date.Truncate(DAY_HOURS))
}
func (task *Task) DueAfter(after time.Time) bool {
return task.DueDate.After(after)
}
func is_same_day(a time.Time, b time.Time) bool {
return a.Day() == b.Day() &&
a.Month() == b.Month() &&
a.Year() == b.Year()
}