package main import ( "fmt" "strconv" "strings" "time" "git.bullercodeworks.com/brian/gime-lib" ) func cmdModifyTimer(args []string) int { var err error // If no timer id is specified, edit the most recent one modId := "@0" var tags, remTags, rem []string tags, rem = pullTagsFromArgs(args) remTags, rem = pullRemoveTagsFromArgs(rem) var start, end time.Time for i := range rem { if rem[i][0] == '@' { modId = rem[i] } if strings.HasPrefix(rem[i], "start:") { stStr := strings.TrimPrefix(rem[i], "start:") start, err = parseFuzzyTime(stStr) if err != nil { fmt.Println("Unable to parse start time: " + stStr) return 1 } } if strings.HasPrefix(rem[i], "end:") { endStr := strings.TrimPrefix(rem[i], "end:") end, err = parseFuzzyTime(endStr) if err != nil { fmt.Println("Unable to parse end time: " + endStr) return 1 } } } timerId, err := strconv.Atoi(modId[1:]) if err != nil { fmt.Println("error parsing timer id:", err.Error()) return 1 } tmr, _, err := findTimerById(timerId) if err != nil { fmt.Println(err.Error()) return 1 } for i := range tags { tmr.AddTag(tags[i]) } for i := range remTags { tmr.RemoveTag(remTags[i]) } if !start.IsZero() { // TODO: Fix keying by start time fmt.Println("Not supported") return 1 //tmr.SetStart(start) } if tmr.GetEnd().IsZero() { // At this point, timers must be stopped to modify the end date fmt.Println("Timer has not been stopped. Cowardly refusing to modify stop time.") return 1 } if !end.IsZero() { tmr.SetEnd(end) } if err = gdb.SaveTimeEntry(tmr); err != nil { fmt.Println("Error saving modified timer:", err.Error()) return 1 } fmt.Println("Modified Timer:") fmt.Println(" ", TimerToString(tmr)) return 0 } // cmdStopTimer takes parameters that describe which times to stop func cmdStopTimer(args []string) int { // args[0] should be a timer id (starting with '@') var err error tm := time.Now() actTimers := gdb.LoadTimeEntryCollection(gime.TypeCurrent) var tmr *gime.TimeEntry stopId := "@0" // By default, stop the first timer for i := range args { if args[i][0] == '@' { stopId = args[i] continue } tmpTm, err := parseFuzzyTime(args[i]) if err == nil { // We found a time tm = tmpTm continue } } if stopId != "@all" { // Find the timer that we're stopping timerId, err := strconv.Atoi(stopId[1:]) if err != nil { fmt.Println("Error parsing timer id:", err.Error()) return 1 } tmr = actTimers.Get(timerId) if timerId >= actTimers.Length() || timerId < 0 || tmr == nil { fmt.Println("Error finding timer with id:", timerId) return 1 } } stopTimer := func(tmr *gime.TimeEntry, at time.Time) int { tmr.SetEnd(at) if err = gdb.UpdateTimeEntry(tmr); err != nil { fmt.Println(err.Error()) return 1 } fmt.Println("Stopped:", InferTimerDetailString(tmr)) return 0 } if stopId == "@all" { var ret int for i := 0; i < actTimers.Length(); i++ { ret += stopTimer(actTimers.Get(i), tm) } if ret > 0 { return 1 // One or more stop operations failed } return 0 } // Just stop the one timer return stopTimer(tmr, tm) } // cmdDeleteTimer takes parameters that describe the timers to be deleted. func cmdDeleteTimer(args []string) int { var err error if len(args) < 1 || args[0][0] != '@' { fmt.Println("Couldn't determine which timer(s) to delete") return 1 } // We've got a timer id to delete timerId, err := strconv.Atoi(args[0][1:]) if err != nil { fmt.Println("Error parsing timer id: " + err.Error()) return 1 } tmr, tp, err := findTimerById(timerId) if err != nil { fmt.Println(err.Error()) return 1 } if gdb.RemoveTimeEntry(tmr) != nil { fmt.Println("Error removing entry " + gime.TypeToString(tp) + "." + tmr.GetUUID()) return 1 } fmt.Println("Deleted Time Entry: " + TimerToString(tmr)) return 0 } func cmdDoArchive(args []string) int { if len(args) == 0 { fmt.Println("Nothing to do") return 1 } var tags []string tags, args = pullTagsFromArgs(args) var bef time.Time var err error if len(args) > 0 { bef, err = parseFuzzyTime(args[0]) } if bef.IsZero() && len(tags) == 0 { fmt.Println("Couldn't figure out what to archive") return 1 } ret := 0 loadActiveAndRecentTimeEntries() tagFilter := func(t *gime.TimeEntry) bool { for i := range tags { if !t.HasTag(tags[i]) { return false } } return true } if len(tags) > 0 { timeEntries = filterTimerCollection(timeEntries, tagFilter) } fmt.Print("Archive all timers ") if !bef.IsZero() { fmt.Print("before ", bef, " ") } if len(tags) > 0 { fmt.Print("with tags ", tags) } for i := 0; i < timeEntries.Length(); i++ { tst := timeEntries.Get(i) archIt := false if !bef.IsZero() { archIt = tst.GetEnd().Before(bef) } else { archIt = true } if archIt { fmt.Print(".") if err = gdb.ArchiveTimeEntry(tst); err != nil { fmt.Print("Error archiving entry (", tst.GetUUID(), ")", err.Error()) ret = 1 } } } fmt.Println("Done") return ret }