diff --git a/sort.go b/sort.go index 61966c9..b8a86a1 100644 --- a/sort.go +++ b/sort.go @@ -8,7 +8,8 @@ import ( // Flags for defining sort element and order. const ( - SORT_START_DATE_ASC = iota + SORT_UNFINISHED_START = iota + SORT_START_DATE_ASC SORT_START_DATE_DESC SORT_FINISH_DATE_ASC SORT_FINISH_DATE_DESC @@ -18,6 +19,8 @@ const ( // See constants SORT_* for fields and sort order. func (timerlist *TimerList) Sort(sortFlag int) error { switch sortFlag { + case SORT_UNFINISHED_START: + timerlist.sortByUnfinishedThenStart() case SORT_START_DATE_ASC, SORT_START_DATE_DESC: timerlist.sortByStartDate(sortFlag) case SORT_FINISH_DATE_ASC, SORT_FINISH_DATE_DESC: @@ -81,3 +84,15 @@ func (timerlist *TimerList) sortByFinishDate(order int) *TimerList { }) return timerlist } + +func (timerlist *TimerList) sortByUnfinishedThenStart() *TimerList { + timerlist.sortBy(func(t1, t2 *Timer) bool { + if t1.FinishDate.IsZero() && !t2.FinishDate.IsZero() { + return true + } else if t2.FinishDate.IsZero() && !t1.FinishDate.IsZero() { + return false + } + return sortByDate(false, t1.StartDate, t2.StartDate) + }) + return timerlist +} diff --git a/timer.go b/timer.go index 74c2bbb..c7c059b 100644 --- a/timer.go +++ b/timer.go @@ -43,7 +43,7 @@ func (timer Timer) String() string { var text string if timer.Finished { text += "x " - if timer.HasFinishDate() { + if !timer.FinishDate.IsZero() { text += fmt.Sprintf("%s ", timer.FinishDate.Format(DateLayout)) } } @@ -76,10 +76,10 @@ func (timer Timer) String() string { } // NewTimer creates a new empty Timer with default values. (StartDate is set to Now()) -func NewTimer() Timer { +func NewTimer() *Timer { timer := Timer{} timer.StartDate = time.Now() - return timer + return &timer } // ParseTimer parses the input text string into a Timer struct @@ -104,13 +104,15 @@ func ParseTimer(text string) (*Timer, error) { originalParts = originalParts[1:] var notes []string for _, v := range originalParts { - if strings.HasPrefix("@", v) { + if strings.HasPrefix(v, "@") { + v = strings.TrimPrefix(v, "@") // Contexts timer.Contexts = append(timer.Contexts, v) - } else if strings.HasPrefix("+", v) { + } else if strings.HasPrefix(v, "+") { // Projects + v = strings.TrimPrefix(v, "+") timer.Projects = append(timer.Projects, v) - } else if strings.Contains(":", v) { + } else if strings.Contains(v, ":") { // Additional tags tagPts := strings.Split(v, ":") if tagPts[0] != "" && tagPts[1] != "" { @@ -122,7 +124,7 @@ func ParseTimer(text string) (*Timer, error) { } timer.Notes = strings.Join(notes, " ") - return timer, nil + return &timer, nil } // Timer returns a complete timer string in timer.txt format. @@ -133,7 +135,7 @@ func (timer *Timer) Timer() string { // Finish sets Timer.Finished to true if the timer hasn't already been finished. // Also sets Timer.FinishDate to time.Now() -func (timer *Timer) Finish() bool { +func (timer *Timer) Finish() { if !timer.Finished { timer.Finished = true timer.FinishDate = time.Now() @@ -148,3 +150,26 @@ func (timer *Timer) Reopen() { timer.FinishDate = time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC) // time.IsZero() value } } + +func (timer *Timer) Duration() time.Duration { + end := time.Now() + if !timer.FinishDate.IsZero() { + end = timer.FinishDate + } + return end.Sub(timer.StartDate) +} + +func (timer *Timer) ActiveToday() bool { + return timer.ActiveOnDay(time.Now()) +} + +func (timer *Timer) ActiveOnDay(t time.Time) bool { + f := "2006/01/02" + tStr := t.Format(f) + // If StartDate or FinishDate is _on_ t, true + if timer.StartDate.Format(f) == tStr || timer.FinishDate.Format(f) == tStr { + return true + } + // Otherwise, if StartDate is before t and FinishDate is after t + return timer.StartDate.Before(t) && timer.FinishDate.After(t) +} diff --git a/timerlist.go b/timerlist.go index fd5117e..0bde275 100644 --- a/timerlist.go +++ b/timerlist.go @@ -2,6 +2,7 @@ package timertxt import ( "bufio" + "errors" "fmt" "io/ioutil" "os" @@ -13,15 +14,32 @@ import ( type TimerList []Timer // NewTimerList creates a new empty TimerList. -func NewTimerList() TimerList { - timerlist := TimerList{} - return timerlist +func NewTimerList() *TimerList { + return &TimerList{} +} + +func (timerlist *TimerList) GetTimersInRange(start, end time.Time) *TimerList { + t := *NewTimerList() + for _, v := range *timerlist { + if v.FinishDate.Before(end) && + } + return &t +} + +func (timerlist *TimerList) GetActiveTimers() *TimerList { + t := *NewTimerList() + for _, v := range *timerlist { + if v.FinishDate.IsZero() { + t = append(t, v) + } + } + return &t } // String returns a complete list of timers in timer.txt format. -func (timerlist TimerList) String() string { +func (timerlist *TimerList) String() string { var ret string - for _, timer := range timerlist { + for _, timer := range *timerlist { ret += fmt.Sprintf("%s\n", timer.String()) } return ret @@ -47,7 +65,7 @@ func (timerlist *TimerList) GetTimer(id int) (*Timer, error) { return &([]Timer(*timerlist))[i], nil } } - return nil, errors.new("timer not found") + return nil, errors.New("timer not found") } // RemoveTimerById removes any Timer with given Timer 'id' from the TimerList. @@ -63,7 +81,7 @@ func (timerlist *TimerList) RemoveTimerById(id int) error { } } if !found { - return errors.new("timer not found") + return errors.New("timer not found") } *timerlist = newList return nil @@ -126,6 +144,14 @@ func (timerlist *TimerList) LoadFromFile(file *os.File) error { return nil } +// WriteToFile writes a TimerList to *os.File +func (timerlist *TimerList) WriteToFile(file *os.File) error { + writer := bufio.NewWriter(file) + _, err := writer.WriteString(timerlist.String()) + writer.Flush() + return err +} + // WriteToFile writes a TimerList to *os.File. func (timerlist *TimerList) LoadFromFilename(filename string) error { file, err := os.Open(filename)