diff --git a/helpers.go b/helpers.go index 347f77d..5b7f814 100644 --- a/helpers.go +++ b/helpers.go @@ -132,6 +132,19 @@ func findTimerById(tmrId int) (*gime.TimeEntry, int, error) { return nil, gime.TypeAll, errors.New("Unable to find timer with id: " + strconv.Itoa(tmrId)) } +func findIdOfTimer(tmr *gime.TimeEntry) (int, error) { + var prevNum int + for i := range gdb.AllTypes { + timeCollection := gdb.LoadTimeEntryCollection(gdb.AllTypes[i]) + if idx := timeCollection.Index(tmr); idx > -1 { + // It's in this collection + return (prevNum + idx), nil + } + prevNum += timeCollection.Length() + } + return -1, errors.New("Unable to find timer") +} + func parseFuzzyTime(t string) (time.Time, error) { var ret time.Time var err error diff --git a/main.go b/main.go index 52e1349..d5c1ab0 100644 --- a/main.go +++ b/main.go @@ -60,33 +60,6 @@ func getMostRecentTimeEntry() (*gime.TimeEntry, error) { return gdb.GetLatestTimeEntry() } -func cmdDoArchive(args []string) int { - if len(args) == 0 { - fmt.Println("Nothing to do") - return 1 - } - bef, err := parseFuzzyTime(args[0]) - if err != nil { - fmt.Println("Error parsing time") - return 1 - } - ret := 0 - fmt.Print("Archive all timers before ", bef) - loadActiveAndRecentTimeEntries() - for i := 0; i < timeEntries.Length(); i++ { - tst := timeEntries.Get(i) - if tst.GetEnd().Before(bef) { - fmt.Print(".") - if err = gdb.ArchiveTimeEntry(tst.GetUUID()); err != nil { - fmt.Print("Error archiving entry (", tst.GetUUID(), ")", err.Error()) - ret = 1 - } - } - } - fmt.Println("Done") - return ret -} - func cmdDoConfig(args []string) int { if len(args) == 0 { fmt.Println("Invalid configuration options passed") @@ -132,11 +105,6 @@ func cmdDoConfig(args []string) int { return 0 } -func cmdPrintDetail(args []string) int { - fmt.Println("Not implemented yet.") - return 1 -} - func cmdPrintHelp(args []string) int { if len(args) == 0 { fmt.Println("gime - A simple timekeeping application\n") @@ -160,87 +128,6 @@ func cmdPrintHelp(args []string) int { return 0 } -func cmdPrintList(args []string) int { - loadActiveAndRecentTimeEntries() - - useDefaultFilter := true - - var beg, end time.Time - searchTags := []string{} - - for _, opt := range args { - var tmpBeg, tmpEnd time.Time - - // Do our best to figure out what timers the user wants to list - var err error - if strings.Contains(opt, "@ids") { - // Print timer ids - } else if strings.Contains(opt, "-") { - useDefaultFilter = false - pts := strings.Split(opt, "-") - if len(pts[0]) > 0 { - // This should be the starting date - tmpBeg, err = parseFuzzyTime(pts[0]) - if err != nil { - // We couldn't parse it as a time, - // Probably this is just a tag - searchTags = append(searchTags, opt) - continue - } - } - if len(pts[1]) > 0 { - // This should be the ending date - tmpEnd, err = parseFuzzyTime(pts[1]) - if err != nil { - searchTags = append(searchTags, opt) - continue - } - } - } else { - // Tag filters - searchTags = append(searchTags, opt) - } - if !tmpBeg.IsZero() || !tmpEnd.IsZero() { - beg, end = tmpBeg, tmpEnd - } - } - if end.IsZero() { - end = time.Now() - } - - // By default, list all entries ending today or still running - defaultFilter := func(t *gime.TimeEntry) bool { - return t.EndsToday() || t.IsRunning() - } - - timeSpanFilter := func(t *gime.TimeEntry) bool { - return t.GetStart().After(beg) && t.GetEnd().Before(end) - } - tagFilter := func(t *gime.TimeEntry) bool { - for i := range searchTags { - if !t.HasTag(searchTags[i]) { - return false - } - } - return true - } - - compoundFilter := func(t *gime.TimeEntry) bool { - // If we didn't get any other filter specifications, just use the default - if useDefaultFilter { - return defaultFilter(t) - } - // Otherwise we want to filter timespan and tags - return timeSpanFilter(t) && tagFilter(t) - } - - fmt.Println(time.Now().Format("2006/01/02")) - str := TimerCollectionToString(filterTimerCollection(timeEntries, compoundFilter)) - str = " " + strings.Replace(str, "\n", "\n ", -1) - fmt.Println(str) - return 0 -} - func cmdListTags(args []string) int { loadActiveAndRecentTimeEntries() var allTags []string diff --git a/timer_operations.go b/timer_operations.go index bef4b5f..dc9976e 100644 --- a/timer_operations.go +++ b/timer_operations.go @@ -3,6 +3,7 @@ package main import ( "fmt" "strconv" + "strings" "time" "git.bullercodeworks.com/brian/gime-lib" @@ -167,3 +168,139 @@ func cmdDeleteTimer(args []string) int { fmt.Println("Deleted Time Entry: " + TimerToString(tmr)) return 0 } + +func cmdPrintList(args []string) int { + loadActiveAndRecentTimeEntries() + useDefaultFilter := true + var showIds bool + var beg, end time.Time + searchTags := []string{} + for _, opt := range args { + var tmpBeg, tmpEnd time.Time + // Check for command modifiers + if strings.HasPrefix(opt, ":") { + if opt == ":ids" { + showIds = true + } + continue + } + + // Do our best to figure out what timers the user wants to list + var err error + if strings.Contains(opt, "-") { + useDefaultFilter = false + pts := strings.Split(opt, "-") + if len(pts[0]) > 0 { + // This should be the starting date + tmpBeg, err = parseFuzzyTime(pts[0]) + if err != nil { + // We couldn't parse it as a time, + // Probably this is just a tag + searchTags = append(searchTags, opt) + continue + } + } + if len(pts[1]) > 0 { + // This should be the ending date + tmpEnd, err = parseFuzzyTime(pts[1]) + if err != nil { + searchTags = append(searchTags, opt) + continue + } + } + } else { + // Tag filters + searchTags = append(searchTags, opt) + } + if !tmpBeg.IsZero() || !tmpEnd.IsZero() { + beg, end = tmpBeg, tmpEnd + } + } + if end.IsZero() { + end = time.Now() + } + + // By default, list all entries ending today or still running + defaultFilter := func(t *gime.TimeEntry) bool { + return t.EndsToday() || t.IsRunning() + } + + timeSpanFilter := func(t *gime.TimeEntry) bool { + return t.GetStart().After(beg) && t.GetEnd().Before(end) + } + tagFilter := func(t *gime.TimeEntry) bool { + for i := range searchTags { + if !t.HasTag(searchTags[i]) { + return false + } + } + return true + } + + compoundFilter := func(t *gime.TimeEntry) bool { + // If we didn't get any other filter specifications, just use the default + if useDefaultFilter { + return defaultFilter(t) + } + // Otherwise we want to filter timespan and tags + return timeSpanFilter(t) && tagFilter(t) + } + + dayStr := "" + timers := filterTimerCollection(timeEntries, compoundFilter) + _ = dayStr + var str string + var currId int + var err error + for i := 0; i < timers.Length(); i++ { + wrk := timers.Get(i) + oldDayStr := dayStr + dayStr = wrk.GetStart().Format("2006/01/02") + if dayStr != oldDayStr { + str += fmt.Sprintln(dayStr) + } + id := "" + if showIds { + if currId, err = findIdOfTimer(wrk); err == nil { + id = fmt.Sprintf("%3s", fmt.Sprintf("@%d", currId)) + } else { + id = "@!" + } + } + str += fmt.Sprintf(" %s %s\n", id, TimerToString(timers.Get(i))) + } + fmt.Println(str) + return 0 +} + +func cmdPrintDetail(args []string) int { + fmt.Println("Not implemented yet.") + return 1 +} + +func cmdDoArchive(args []string) int { + if len(args) == 0 { + fmt.Println("Nothing to do") + return 1 + } + bef, err := parseFuzzyTime(args[0]) + if err != nil { + fmt.Println("Error parsing time") + return 1 + } + ret := 0 + fmt.Print("Archive all timers before ", bef) + loadActiveAndRecentTimeEntries() + for i := 0; i < timeEntries.Length(); i++ { + tst := timeEntries.Get(i) + if tst.GetEnd().Before(bef) { + fmt.Print(".") + if err = gdb.ArchiveTimeEntry(tst.GetUUID()); err != nil { + fmt.Print("Error archiving entry (", tst.GetUUID(), ")", err.Error()) + ret = 1 + } + } + } + fmt.Println("Done") + return ret +}