package cli import ( "fmt" "strings" "time" "git.bullercodeworks.com/brian/gime/util" timertxt "git.bullercodeworks.com/brian/go-timertxt" "github.com/spf13/viper" ) type Program struct { debug bool timerPath string TimerList *timertxt.TimerList donePath string DoneList *timertxt.TimerList } func (p *Program) Initialize() error { path := viper.GetString("directory") p.timerPath = fmt.Sprintf("%s%s", path, viper.GetString("timerfile")) p.donePath = fmt.Sprintf("%s%s", path, viper.GetString("donefile")) return nil } func (p *Program) GetTimerFilePath() string { return p.timerPath } func (p *Program) LoadTimerList() error { var err error var tl *timertxt.TimerList tl, err = timertxt.LoadFromFilename(p.timerPath) if err != nil { return err } tl.Sort(timertxt.SortUnfinishedStart) p.TimerList = tl return nil } func (p *Program) WriteLists() error { err := p.WriteTimerList() if dErr := p.WriteDoneList(); dErr != nil { if err == nil { return fmt.Errorf("Error writing Done list %w", dErr) } else { return fmt.Errorf("Error writing Both lists (Timer: %s; Done: %s) (%w)", err.Error(), dErr.Error(), err) } } return nil } func (p *Program) WriteTimerList() error { return p.TimerList.WriteToFilename(p.timerPath) } func (p *Program) GetDoneFilePath() string { return p.donePath } func (p *Program) LoadDoneList() error { var err error var tl *timertxt.TimerList tl, err = timertxt.LoadFromFilename(p.donePath) if err != nil { return err } p.DoneList = tl return nil } func (p *Program) WriteDoneList() error { return p.DoneList.WriteToFilename(p.donePath) } func (p *Program) ArchiveTimer(timer *timertxt.Timer) error { if err := p.TimerList.ArchiveTimerToFile(*timer, p.donePath); err != nil { return err } return p.WriteTimerList() } func (p *Program) GetFilteredTimerList(args []string) *timertxt.TimerList { var includeArchive bool var err error start := time.Time{} end := time.Now() var contextFilters []string var projectFilters []string var allFilters []func(timertxt.Timer) bool if len(args) > 0 { contextFilters, args = util.GetContextsFromSlice(args) projectFilters, args = util.GetProjectsFromSlice(args) } if len(args) > 0 { if args[0] == "--a" { includeArchive = true args = args[1:] } } if len(args) > 0 { if start, err = util.ParseFuzzyTime(args[0]); err != nil { y, m, d := time.Now().Date() start = time.Date(y, m, d, 0, 0, 0, 0, time.Now().Location()) } else { args = args[1:] } if len(args) > 0 { if end, err = util.ParseFuzzyTime(args[0]); err != nil { y, m, d := time.Now().Date() end = time.Date(y, m, d, 23, 59, 59, 0, time.Now().Location()) } else { args = args[1:] } } } list := p.TimerList.GetTimersInRange(start, end) if includeArchive { if err = p.LoadDoneList(); err != nil { fmt.Println("Error loading done.txt entries") fmt.Println(err.Error()) return nil } doneList := p.DoneList.GetTimersInRange(start, end) list.Combine(doneList) } if len(contextFilters) > 0 { allFilters = append(allFilters, func(t timertxt.Timer) bool { for _, v := range contextFilters { v = strings.TrimPrefix(v, "@") if !t.HasContext(v) { return false } } return true }) } if len(projectFilters) > 0 { allFilters = append(allFilters, func(t timertxt.Timer) bool { for _, v := range projectFilters { v = strings.TrimPrefix(v, "+") if !t.HasProject(v) { return false } } return true }) } doFilters := func(t *timertxt.Timer) bool { for _, v := range allFilters { if !v(*t) { return false } } // If we made it all the way down here, it matches return true } return list.Filter(doFilters) } func (p *Program) GetActiveOrMostRecent() (*timertxt.Timer, error) { work, wErr := p.TimerList.GetActiveOrMostRecent() if wErr == nil { return work, nil } return p.GetMostRecentTimer() } func (p *Program) GetMostRecentTimer() (*timertxt.Timer, error) { work, wErr := p.TimerList.GetMostRecentTimer() if wErr == nil && work.FinishDate.IsZero() { return work, nil } if err := p.LoadDoneList(); err != nil { return nil, err } done, dErr := p.DoneList.GetMostRecentTimer() if dErr != nil { return nil, dErr } if !done.FinishDate.IsZero() && work == nil || done.FinishDate.After(work.FinishDate) { return done, nil } return work, nil } func (p *Program) GetTimerString(timer *timertxt.Timer) string { return fmt.Sprintf("%d. %s", timer.Id, strings.TrimPrefix(timer.String(), "x ")) } func (p *Program) GetDoneTimerString(timer *timertxt.Timer) string { return fmt.Sprintf("--. %s", timer.String()) }