diff --git a/cmd/gime/main.go b/cmd/gime/main.go index e5c5688..bc3fb20 100644 --- a/cmd/gime/main.go +++ b/cmd/gime/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + "sort" "strings" "time" @@ -60,8 +61,30 @@ func getMostRecentTimeEntry() (*gime.TimeEntry, error) { } func cmdDoArchive(args []string) int { - fmt.Println("Not implemented yet.") - return 1 + 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 { @@ -216,6 +239,33 @@ func cmdPrintList(args []string) int { return 0 } +func cmdListTags(args []string) int { + loadActiveAndRecentTimeEntries() + var allTags []string + for i := 0; i < timeEntries.Length(); i++ { + tc := timeEntries.Get(i).GetTags() + for j := 0; j < tc.Length(); j++ { + tg := tc.Get(j) + var found bool + for tst := range allTags { + if allTags[tst] == tg { + found = true + break + } + } + if !found { + allTags = append(allTags, tg) + } + } + } + + sort.Sort(sort.StringSlice(allTags)) + for i := range allTags { + fmt.Println(allTags[i]) + } + return 0 +} + func cmdPrintStatus(args []string) int { loadActiveTimeEntries() curr := time.Now() @@ -350,7 +400,7 @@ func initialize() { opFuncs["archive"] = cmdDoArchive validOperations["archive"] = []string{ - "archive - Archive all entries older than the archive date", + "archive [date] - Archive all entries older than the given date", } opFuncs["fuzzyparse"] = cmdDoFuzzyParse @@ -359,6 +409,12 @@ func initialize() { " the RFC3339 result. (Basically for testing)", } + opFuncs["tags"] = cmdListTags + validOperations["tags"] = []string{ + "tags - List all tags that have been used in non-archived", + " time entries", + } + // Load the Config cfg, err = userConfig.NewConfig(AppName) if err != nil { @@ -384,6 +440,7 @@ func initialize() { } fuzzyFormats = []string{ + "1504", "15:04", // Kitchen, 24hr time.Kitchen, time.RFC3339, @@ -404,6 +461,10 @@ func initialize() { "20060102 15:04:05", "20060102 1504", "20060102 150405", + "20060102T15:04", + "20060102T15:04:05", + "20060102T1504", + "20060102T150405", } } diff --git a/model_timeentry.go b/model_timeentry.go index e521e2e..a1b12af 100644 --- a/model_timeentry.go +++ b/model_timeentry.go @@ -48,19 +48,17 @@ func (gdb *GimeDB) FindTimeEntryByUUID(uuid string) (*TimeEntry, int, error) { // SaveTimeEntry creates a time entry in the database // If TimeEntry.end is zero, then it puts it in TypeCurrent func (gdb *GimeDB) SaveTimeEntry(te *TimeEntry) error { - var err error - var useDb *boltease.DB tp := TypeRecent if te.end.IsZero() { // Currently running tp = TypeCurrent - } else { - // We have an end time. Does this entry go in 'recent' or 'archive' - // We shove times that happened 90 days ago (~1/4 year) into 'archive' - if time.Since(te.end) > (time.Hour * 24 * 90) { - tp = TypeArchive - } } + return gdb.SaveTimeEntryType(tp, te) +} + +func (gdb *GimeDB) SaveTimeEntryType(tp int, te *TimeEntry) error { + var err error + var useDb *boltease.DB useDb, err = gdb.openDBType(tp) if err != nil { return err @@ -81,6 +79,18 @@ func (gdb *GimeDB) SaveTimeEntry(te *TimeEntry) error { return nil } +// ArchiveTimeEntry takes a time from TypeRecent and moves it to TypeArchive +func (gdb *GimeDB) ArchiveTimeEntry(uuid string) error { + archTime, tp, err := gdb.FindTimeEntryByUUID(uuid) + if tp != TypeRecent { + return errors.New("Couldn't find timer to archive in the 'Recent' bucket") + } + if err = gdb.RemoveTimeEntry(archTime.uuid); err != nil { + return err + } + return gdb.SaveTimeEntryType(TypeArchive, archTime) +} + // UpdateTimeEntry updates the time entry in the database // It first finds the current entry in the database by the uuid func (gdb *GimeDB) UpdateTimeEntry(te *TimeEntry) error {