Several improvements
Fix 'switch' issue Archive by tag Much faster archiving
This commit is contained in:
		
							
								
								
									
										2
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							| @@ -5,7 +5,7 @@ | |||||||
| 	"Deps": [ | 	"Deps": [ | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "git.bullercodeworks.com/brian/gime-lib", | 			"ImportPath": "git.bullercodeworks.com/brian/gime-lib", | ||||||
| 			"Rev": "579fc6c62aa8f5452e02d3fe3334e2d035b0b712" | 			"Rev": "2a2aea8641e8b327544452f900ea4f5fcc43fc7e" | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "github.com/BurntSushi/toml", | 			"ImportPath": "github.com/BurntSushi/toml", | ||||||
|   | |||||||
							
								
								
									
										30
									
								
								helpers.go
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								helpers.go
									
									
									
									
									
								
							| @@ -145,6 +145,20 @@ func findIdOfTimer(tmr *gime.TimeEntry) (int, error) { | |||||||
| 	return -1, errors.New("Unable to find timer") | 	return -1, errors.New("Unable to find timer") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // pullTagsFromArgs takes a list of arguments, removes all tags from them | ||||||
|  | // then returns the tags and the remaining args | ||||||
|  | func pullTagsFromArgs(args []string) ([]string, []string) { | ||||||
|  | 	var tags, rem []string | ||||||
|  | 	for _, opt := range args { | ||||||
|  | 		if opt[0] == '+' { | ||||||
|  | 			tags = append(tags, opt[1:]) | ||||||
|  | 		} else { | ||||||
|  | 			rem = append(rem, opt) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return tags, rem | ||||||
|  | } | ||||||
|  |  | ||||||
| func parseFuzzyTime(t string) (time.Time, error) { | func parseFuzzyTime(t string) (time.Time, error) { | ||||||
| 	var ret time.Time | 	var ret time.Time | ||||||
| 	var err error | 	var err error | ||||||
| @@ -167,6 +181,22 @@ func parseFuzzyTime(t string) (time.Time, error) { | |||||||
| 	return time.Time{}, errors.New("Unable to parse time: " + t) | 	return time.Time{}, errors.New("Unable to parse time: " + t) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func friendlyFormatForTime(t time.Time) string { | ||||||
|  | 	nowTime := time.Now() | ||||||
|  | 	if t.Year() != nowTime.Year() || t.Month() != nowTime.Month() { | ||||||
|  | 		return "2006-01-02 15:04" | ||||||
|  | 	} else if t.Day() != nowTime.Day() { | ||||||
|  | 		return "01/02 15:04" | ||||||
|  | 	} | ||||||
|  | 	return "15:04" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // timeToFriendlyString returns an easier to read version of the time | ||||||
|  | // giving enough details that the user should be fine inferring the rest | ||||||
|  | func timeToFriendlyString(t time.Time) string { | ||||||
|  | 	return t.Format(friendlyFormatForTime(t)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func sinceToString(tm time.Time) string { | func sinceToString(tm time.Time) string { | ||||||
| 	return diffToString(tm, time.Now()) | 	return diffToString(tm, time.Now()) | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								main.go
									
									
									
									
									
								
							| @@ -244,10 +244,11 @@ func initialize() { | |||||||
| 	validOperations["list"] = []string{ | 	validOperations["list"] = []string{ | ||||||
| 		"list [duration] [+tags] - List time entries", | 		"list [duration] [+tags] - List time entries", | ||||||
| 		"                          valid values of [duration] include:", | 		"                          valid values of [duration] include:", | ||||||
| 		"                            day   - List all entries for the current day", | 		"                            :day   - List all entries for the current day", | ||||||
| 		"                            week  - List all entries for the current week", | 		"                            :week  - List all entries for the current week", | ||||||
| 		"                            month - List all entries for the current month", | 		"                            :month - List all entries for the current month", | ||||||
| 		"                            year  - List all entries for the current year", | 		"                            :year  - List all entries for the current year", | ||||||
|  | 		"                            Or other date values, we'll try to parse it.", | ||||||
| 		"                          To list entries by tag, preceed the tags with a +", | 		"                          To list entries by tag, preceed the tags with a +", | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,6 +9,39 @@ import ( | |||||||
| 	"git.bullercodeworks.com/brian/gime-lib" | 	"git.bullercodeworks.com/brian/gime-lib" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // cmdStartTimer takes a list of arguments and returns the return code | ||||||
|  | // to be passed along to os.Exit | ||||||
|  | func cmdStartTimer(args []string) int { | ||||||
|  | 	var err error | ||||||
|  | 	var entry *gime.TimeEntry | ||||||
|  | 	// By default we start the timer now | ||||||
|  | 	tm := time.Now() | ||||||
|  | 	tags, rem := pullTagsFromArgs(args) | ||||||
|  |  | ||||||
|  | 	if len(rem) > 0 { | ||||||
|  | 		// Check if the first argument looks like a date/time | ||||||
|  | 		tm, err = parseFuzzyTime(rem[0]) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tc := new(gime.TagCollection) | ||||||
|  | 	for i := range tags { | ||||||
|  | 		tc.Push(tags[i]) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if entry, err = gime.CreateTimeEntry(tm, time.Time{}, tc); err != nil { | ||||||
|  | 		fmt.Println(err) | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err = gdb.SaveTimeEntry(entry); err != nil { | ||||||
|  | 		fmt.Println(err) | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	fmt.Println("  " + TimerToString(entry)) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
| func cmdContinueTimer(args []string) int { | func cmdContinueTimer(args []string) int { | ||||||
| 	// Get the last running timer and start a new one with the same tags | 	// Get the last running timer and start a new one with the same tags | ||||||
| 	te, err := getMostRecentTimeEntry() | 	te, err := getMostRecentTimeEntry() | ||||||
| @@ -19,7 +52,7 @@ func cmdContinueTimer(args []string) int { | |||||||
| 	tagColl := te.GetTags() | 	tagColl := te.GetTags() | ||||||
| 	var tags []string | 	var tags []string | ||||||
| 	for i := 0; i < tagColl.Length(); i++ { | 	for i := 0; i < tagColl.Length(); i++ { | ||||||
| 		tags = append(tags, tagColl.Get(i)) | 		tags = append(tags, "+"+tagColl.Get(i)) | ||||||
| 	} | 	} | ||||||
| 	args = append(args, tags...) | 	args = append(args, tags...) | ||||||
| 	return cmdStartTimer(args) | 	return cmdStartTimer(args) | ||||||
| @@ -28,73 +61,40 @@ func cmdContinueTimer(args []string) int { | |||||||
| // switchTimer performs a stop on any currently running timers | // switchTimer performs a stop on any currently running timers | ||||||
| // and starts a new timer with the given arguments | // and starts a new timer with the given arguments | ||||||
| func cmdSwitchTimer(args []string) int { | func cmdSwitchTimer(args []string) int { | ||||||
| 	loadActiveTimeEntries() | 	var foundId bool | ||||||
| 	tm := time.Now() | 	for i := range args { | ||||||
| 	if timeEntries.Length() > 0 { | 		// see if we have a timer id in the args | ||||||
| 		fmt.Println("Stopped Timers:") | 		if args[i][0] == '@' { | ||||||
| 	} | 			foundId = true | ||||||
| 	for i := 0; i < timeEntries.Length(); i++ { |  | ||||||
| 		tmr := timeEntries.Get(i) |  | ||||||
| 		tmr.SetEnd(tm) |  | ||||||
| 		if err := gdb.UpdateTimeEntry(tmr); err != nil { |  | ||||||
| 			fmt.Println(err.Error()) |  | ||||||
| 			return 1 |  | ||||||
| 		} | 		} | ||||||
| 		fmt.Println("  " + TimerToString(tmr)) | 	} | ||||||
|  | 	stopArgs := make([]string, len(args)) | ||||||
|  | 	copy(stopArgs, args) | ||||||
|  | 	if !foundId { | ||||||
|  | 		// We didn't find one, so make sure we stop _all_ timers | ||||||
|  | 		stopArgs = append(stopArgs, "@all") | ||||||
|  | 	} | ||||||
|  | 	fmt.Println(stopArgs) | ||||||
|  | 	fmt.Println(args) | ||||||
|  | 	return 0 | ||||||
|  | 	if cmdStopTimer(args) != 0 { | ||||||
|  | 		// Error while stopping timers | ||||||
|  | 		return 1 | ||||||
| 	} | 	} | ||||||
| 	fmt.Println("Started Timer:") | 	fmt.Println("Started Timer:") | ||||||
| 	return cmdStartTimer(args) | 	return cmdStartTimer(args) | ||||||
| } | } | ||||||
|  |  | ||||||
| // cmdStartTimer takes a list of arguments and returns the return code |  | ||||||
| // to be passed along to os.Exit |  | ||||||
| func cmdStartTimer(args []string) int { |  | ||||||
| 	var err error |  | ||||||
| 	var tm time.Time |  | ||||||
| 	tagStart := 0 |  | ||||||
| 	if len(args) > 0 { |  | ||||||
| 		// Check if the first argument looks like a date/time |  | ||||||
| 		tm, err = parseFuzzyTime(args[0]) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if len(args) == 0 || err != nil { |  | ||||||
| 		// Just start it now |  | ||||||
| 		tm = time.Now() |  | ||||||
| 	} else { |  | ||||||
| 		tagStart = 1 |  | ||||||
| 	} |  | ||||||
| 	var entry *gime.TimeEntry |  | ||||||
|  |  | ||||||
| 	var timerArgs []string |  | ||||||
| 	if tagStart < len(args) { |  | ||||||
| 		timerArgs = args[tagStart:] |  | ||||||
| 	} |  | ||||||
| 	tc := new(gime.TagCollection) |  | ||||||
| 	for i := range timerArgs { |  | ||||||
| 		tc.Push(timerArgs[i]) |  | ||||||
| 	} |  | ||||||
| 	if entry, err = gime.CreateTimeEntry(tm, time.Time{}, tc); err != nil { |  | ||||||
| 		fmt.Println(err) |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
| 	if err = gdb.SaveTimeEntry(entry); err != nil { |  | ||||||
| 		fmt.Println(err) |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
| 	fmt.Println("  " + TimerToString(entry)) |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // cmdStopTimer takes parameters that describe which times to stop | // cmdStopTimer takes parameters that describe which times to stop | ||||||
| func cmdStopTimer(args []string) int { | func cmdStopTimer(args []string) int { | ||||||
| 	// args[0] should either be a timer id (starting with '@') or 'all' | 	// args[0] should be a timer id (starting with '@') | ||||||
| 	var err error | 	var err error | ||||||
| 	tm := time.Now() | 	tm := time.Now() | ||||||
| 	actTimers := gdb.LoadTimeEntryCollection(gime.TypeCurrent) | 	actTimers := gdb.LoadTimeEntryCollection(gime.TypeCurrent) | ||||||
| 	var tmr *gime.TimeEntry | 	var tmr *gime.TimeEntry | ||||||
| 	stopId := "@0" // By default, stop the first timer | 	stopId := "@0" // By default, stop the first timer | ||||||
| 	for i := range args { | 	for i := range args { | ||||||
| 		if args[i] == "all" || args[i][0] == '@' { | 		if args[i][0] == '@' { | ||||||
| 			stopId = args[i] | 			stopId = args[i] | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| @@ -105,7 +105,7 @@ func cmdStopTimer(args []string) int { | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if stopId != "all" { | 	if stopId != "@all" { | ||||||
| 		// Find the timer that we're stopping | 		// Find the timer that we're stopping | ||||||
| 		timerId, err := strconv.Atoi(stopId[1:]) | 		timerId, err := strconv.Atoi(stopId[1:]) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -128,7 +128,7 @@ func cmdStopTimer(args []string) int { | |||||||
| 		fmt.Println("Stopped:", InferTimerDetailString(tmr)) | 		fmt.Println("Stopped:", InferTimerDetailString(tmr)) | ||||||
| 		return 0 | 		return 0 | ||||||
| 	} | 	} | ||||||
| 	if stopId == "all" { | 	if stopId == "@all" { | ||||||
| 		var ret int | 		var ret int | ||||||
| 		for i := 0; i < actTimers.Length(); i++ { | 		for i := 0; i < actTimers.Length(); i++ { | ||||||
| 			ret += stopTimer(actTimers.Get(i), tm) | 			ret += stopTimer(actTimers.Get(i), tm) | ||||||
| @@ -161,7 +161,7 @@ func cmdDeleteTimer(args []string) int { | |||||||
| 		fmt.Println(err.Error()) | 		fmt.Println(err.Error()) | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
| 	if gdb.RemoveTimeEntry(tmr.GetUUID()) != nil { | 	if gdb.RemoveTimeEntry(tmr) != nil { | ||||||
| 		fmt.Println("Error removing entry " + gime.TypeToString(tp) + "." + tmr.GetUUID()) | 		fmt.Println("Error removing entry " + gime.TypeToString(tp) + "." + tmr.GetUUID()) | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
| @@ -179,12 +179,35 @@ func cmdPrintList(args []string) int { | |||||||
| 		var tmpBeg, tmpEnd time.Time | 		var tmpBeg, tmpEnd time.Time | ||||||
| 		// Check for command modifiers | 		// Check for command modifiers | ||||||
| 		if strings.HasPrefix(opt, ":") { | 		if strings.HasPrefix(opt, ":") { | ||||||
| 			if opt == ":ids" { | 			switch opt { | ||||||
|  | 			case ":ids": | ||||||
| 				showIds = true | 				showIds = true | ||||||
|  | 			// Special durations | ||||||
|  | 			case ":day": | ||||||
|  | 				beg, _ = parseFuzzyTime("00:00") | ||||||
|  | 				end, _ = parseFuzzyTime("23:59") | ||||||
|  | 			case ":week": | ||||||
|  | 				currDoW := time.Now().Weekday() | ||||||
|  | 				beg = time.Now().AddDate(0, 0, int(currDoW)*-1) | ||||||
|  | 				beg = time.Date(beg.Year(), beg.Month(), beg.Day(), 0, 0, 0, 0, beg.Location()) | ||||||
|  | 			case ":month": | ||||||
|  | 				currDoM := time.Now().Day() | ||||||
|  | 				beg = time.Now().AddDate(0, 0, int(currDoM)*-1) | ||||||
|  | 				beg = time.Date(beg.Year(), beg.Month(), beg.Day(), 0, 0, 0, 0, beg.Location()) | ||||||
|  | 			case ":year": | ||||||
|  | 				yr := strconv.Itoa(time.Now().Year()) | ||||||
|  | 				beg, _ = parseFuzzyTime(yr + "0101T00:00") | ||||||
|  | 				end, _ = parseFuzzyTime(yr + "1231T23:59") | ||||||
| 			} | 			} | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		// Find tags | ||||||
|  | 		if strings.HasPrefix(opt, "+") { | ||||||
|  | 			searchTags = append(searchTags, opt[1:]) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		// Do our best to figure out what timers the user wants to list | 		// Do our best to figure out what timers the user wants to list | ||||||
| 		var err error | 		var err error | ||||||
| 		if strings.Contains(opt, "-") { | 		if strings.Contains(opt, "-") { | ||||||
| @@ -194,9 +217,6 @@ func cmdPrintList(args []string) int { | |||||||
| 				// This should be the starting date | 				// This should be the starting date | ||||||
| 				tmpBeg, err = parseFuzzyTime(pts[0]) | 				tmpBeg, err = parseFuzzyTime(pts[0]) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					// We couldn't parse it as a time, |  | ||||||
| 					// Probably this is just a tag |  | ||||||
| 					searchTags = append(searchTags, opt) |  | ||||||
| 					continue | 					continue | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @@ -204,13 +224,9 @@ func cmdPrintList(args []string) int { | |||||||
| 				// This should be the ending date | 				// This should be the ending date | ||||||
| 				tmpEnd, err = parseFuzzyTime(pts[1]) | 				tmpEnd, err = parseFuzzyTime(pts[1]) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					searchTags = append(searchTags, opt) |  | ||||||
| 					continue | 					continue | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} else { |  | ||||||
| 			// Tag filters |  | ||||||
| 			searchTags = append(searchTags, opt) |  | ||||||
| 		} | 		} | ||||||
| 		if !tmpBeg.IsZero() || !tmpEnd.IsZero() { | 		if !tmpBeg.IsZero() || !tmpEnd.IsZero() { | ||||||
| 			beg, end = tmpBeg, tmpEnd | 			beg, end = tmpBeg, tmpEnd | ||||||
| @@ -248,10 +264,19 @@ func cmdPrintList(args []string) int { | |||||||
|  |  | ||||||
| 	dayStr := "" | 	dayStr := "" | ||||||
| 	timers := filterTimerCollection(timeEntries, compoundFilter) | 	timers := filterTimerCollection(timeEntries, compoundFilter) | ||||||
| 	_ = dayStr |  | ||||||
| 	var str string | 	var str string | ||||||
| 	var currId int | 	var currId int | ||||||
| 	var err error | 	var err error | ||||||
|  | 	if timers.Length() == 0 { | ||||||
|  | 		begFmt := friendlyFormatForTime(beg) | ||||||
|  | 		endFmt := friendlyFormatForTime(end) | ||||||
|  | 		useFmt := endFmt | ||||||
|  | 		if len(begFmt) > len(endFmt) { | ||||||
|  | 			useFmt = begFmt | ||||||
|  | 		} | ||||||
|  | 		fmt.Println("No timers found in period " + beg.Format(useFmt) + " - " + end.Format(useFmt)) | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
| 	for i := 0; i < timers.Length(); i++ { | 	for i := 0; i < timers.Length(); i++ { | ||||||
| 		wrk := timers.Get(i) | 		wrk := timers.Get(i) | ||||||
| 		oldDayStr := dayStr | 		oldDayStr := dayStr | ||||||
| @@ -283,19 +308,49 @@ func cmdDoArchive(args []string) int { | |||||||
| 		fmt.Println("Nothing to do") | 		fmt.Println("Nothing to do") | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
| 	bef, err := parseFuzzyTime(args[0]) |  | ||||||
| 	if err != nil { | 	var tags []string | ||||||
| 		fmt.Println("Error parsing time") | 	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 | 		return 1 | ||||||
| 	} | 	} | ||||||
| 	ret := 0 | 	ret := 0 | ||||||
| 	fmt.Print("Archive all timers before ", bef) |  | ||||||
| 	loadActiveAndRecentTimeEntries() | 	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++ { | 	for i := 0; i < timeEntries.Length(); i++ { | ||||||
| 		tst := timeEntries.Get(i) | 		tst := timeEntries.Get(i) | ||||||
| 		if tst.GetEnd().Before(bef) { | 		archIt := false | ||||||
|  | 		if !bef.IsZero() { | ||||||
|  | 			archIt = tst.GetEnd().Before(bef) | ||||||
|  | 		} else { | ||||||
|  | 			archIt = true | ||||||
|  | 		} | ||||||
|  | 		if archIt { | ||||||
| 			fmt.Print(".") | 			fmt.Print(".") | ||||||
| 			if err = gdb.ArchiveTimeEntry(tst.GetUUID()); err != nil { | 			if err = gdb.ArchiveTimeEntry(tst); err != nil { | ||||||
| 				fmt.Print("Error archiving entry (", tst.GetUUID(), ")", err.Error()) | 				fmt.Print("Error archiving entry (", tst.GetUUID(), ")", err.Error()) | ||||||
| 				ret = 1 | 				ret = 1 | ||||||
| 			} | 			} | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								vendor/git.bullercodeworks.com/brian/gime-lib/model.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/git.bullercodeworks.com/brian/gime-lib/model.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -25,6 +25,7 @@ const ( | |||||||
| 	TypeNoArchive = 3 // 011 | 	TypeNoArchive = 3 // 011 | ||||||
| 	TypeArchive   = 4 // 100 | 	TypeArchive   = 4 // 100 | ||||||
| 	TypeAll       = 7 // 111 | 	TypeAll       = 7 // 111 | ||||||
|  | 	TypeError     = 8 //1000 | ||||||
|  |  | ||||||
| 	ArchiveDays = time.Hour * 24 * 90 // Archive anything older than 90 days | 	ArchiveDays = time.Hour * 24 * 90 // Archive anything older than 90 days | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										81
									
								
								vendor/git.bullercodeworks.com/brian/gime-lib/model_timeentry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/git.bullercodeworks.com/brian/gime-lib/model_timeentry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -13,21 +13,25 @@ import ( | |||||||
| func (gdb *GimeDB) GetLatestTimeEntry() (*TimeEntry, error) { | func (gdb *GimeDB) GetLatestTimeEntry() (*TimeEntry, error) { | ||||||
| 	var ret *TimeEntry | 	var ret *TimeEntry | ||||||
| 	var err error | 	var err error | ||||||
| 	tc := gdb.LoadTimeEntryCollection(TypeRecent) |  | ||||||
| 	for i := 0; i < tc.Length(); i++ { | 	var useDb *boltease.DB | ||||||
| 		te := tc.Get(i) | 	if useDb, err = gdb.openDBType(TypeRecent); err != nil { | ||||||
| 		if ret == nil { | 		return ret, err | ||||||
| 			ret = te |  | ||||||
| 		} else { |  | ||||||
| 			if te.GetEnd().After(ret.GetEnd()) { |  | ||||||
| 				ret = te |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	if ret == nil { | 	defer gdb.closeDBType(TypeRecent) | ||||||
| 		err = errors.New("Could not find latest time entry") |  | ||||||
|  | 	var sttimes []string | ||||||
|  | 	if sttimes, err = useDb.GetBucketList([]string{TypeToString(TypeRecent)}); err != nil { | ||||||
|  | 		return ret, err | ||||||
| 	} | 	} | ||||||
| 	return ret, err | 	sort.Slice(sttimes, func(i, j int) bool { | ||||||
|  | 		return sttimes[j] < sttimes[i] | ||||||
|  | 	}) | ||||||
|  | 	// The first entry should be the most recent | ||||||
|  | 	if len(sttimes) > 0 { | ||||||
|  | 		return gdb.dbGetTimeEntry(TypeRecent, sttimes[0]) | ||||||
|  | 	} | ||||||
|  | 	return nil, errors.New("No recent time entries found") | ||||||
| } | } | ||||||
|  |  | ||||||
| // findTimeEntryAndTypeByUUID searches all entries | // findTimeEntryAndTypeByUUID searches all entries | ||||||
| @@ -87,13 +91,20 @@ func (gdb *GimeDB) SaveTimeEntryType(tp int, te *TimeEntry) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (gdb *GimeDB) ArchiveTimeEntry(te *TimeEntry) error { | ||||||
|  | 	if err := gdb.RemoveTimeEntryFromCategory(te, TypeRecent); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return gdb.SaveTimeEntryType(TypeArchive, te) | ||||||
|  | } | ||||||
|  |  | ||||||
| // ArchiveTimeEntry takes a time from TypeRecent and moves it to TypeArchive | // ArchiveTimeEntry takes a time from TypeRecent and moves it to TypeArchive | ||||||
| func (gdb *GimeDB) ArchiveTimeEntry(uuid string) error { | func (gdb *GimeDB) ArchiveTimeEntryByUUID(uuid string) error { | ||||||
| 	archTime, tp, err := gdb.findTimeEntryAndTypeByUUID(uuid) | 	archTime, tp, err := gdb.findTimeEntryAndTypeByUUID(uuid) | ||||||
| 	if tp != TypeRecent { | 	if tp != TypeRecent { | ||||||
| 		return errors.New("Couldn't find timer to archive in the 'Recent' bucket") | 		return errors.New("Couldn't find timer to archive in the 'Recent' bucket") | ||||||
| 	} | 	} | ||||||
| 	if err = gdb.RemoveTimeEntry(archTime.uuid); err != nil { | 	if err = gdb.RemoveTimeEntry(archTime); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return gdb.SaveTimeEntryType(TypeArchive, archTime) | 	return gdb.SaveTimeEntryType(TypeArchive, archTime) | ||||||
| @@ -106,14 +117,36 @@ func (gdb *GimeDB) UpdateTimeEntry(te *TimeEntry) error { | |||||||
| 	if te.uuid == "" { | 	if te.uuid == "" { | ||||||
| 		return errors.New("Given time entry has no uuid") | 		return errors.New("Given time entry has no uuid") | ||||||
| 	} | 	} | ||||||
| 	if err = gdb.RemoveTimeEntry(te.uuid); err != nil { | 	if err = gdb.RemoveTimeEntry(te); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return gdb.SaveTimeEntry(te) | 	return gdb.SaveTimeEntry(te) | ||||||
| } | } | ||||||
|  |  | ||||||
| // RemoveTimeEntry removes a time entry with the given uuid from the database | // RemoveTimeEntry removes a time entry with the given uuid from the database | ||||||
| func (gdb *GimeDB) RemoveTimeEntry(uuid string) error { | func (gdb *GimeDB) RemoveTimeEntry(te *TimeEntry) error { | ||||||
|  | 	for _, v := range gdb.AllTypes { | ||||||
|  | 		if gdb.RemoveTimeEntryFromCategory(te, v) == nil { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return errors.New("Couldn't find Time Entry to Remove") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (gdb *GimeDB) RemoveTimeEntryFromCategory(te *TimeEntry, tp int) error { | ||||||
|  | 	if !gdb.dbTimeEntryIsInCategory(te, tp) { | ||||||
|  | 		return errors.New("Couldn't find timer to remove in the given bucket") | ||||||
|  | 	} | ||||||
|  | 	var err error | ||||||
|  | 	var useDb *boltease.DB | ||||||
|  | 	if useDb, err = gdb.openDBType(tp); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer gdb.closeDBType(tp) | ||||||
|  | 	return useDb.DeleteBucket([]string{TypeToString(tp)}, te.start.Format(time.RFC3339)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (gdb *GimeDB) RemoveTimeEntryByUUID(uuid string) error { | ||||||
| 	fndEntry, tp, err := gdb.findTimeEntryAndTypeByUUID(uuid) | 	fndEntry, tp, err := gdb.findTimeEntryAndTypeByUUID(uuid) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return errors.New("Unable to find time entry with uuid " + uuid) | 		return errors.New("Unable to find time entry with uuid " + uuid) | ||||||
| @@ -193,6 +226,20 @@ func (gdb *GimeDB) dbGetAllTimeEntries(tp int) []TimeEntry { | |||||||
| 	return ret | 	return ret | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (gdb *GimeDB) dbFindTimeEntryCategory(te *TimeEntry) int { | ||||||
|  | 	for _, v := range gdb.AllTypes { | ||||||
|  | 		if gdb.dbTimeEntryIsInCategory(te, v) { | ||||||
|  | 			return v | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return TypeError | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (gdb *GimeDB) dbTimeEntryIsInCategory(te *TimeEntry, tp int) bool { | ||||||
|  | 	_, err := gdb.dbGetTimeEntry(tp, te.start.Format(time.RFC3339)) | ||||||
|  | 	return err == nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // dbGetTimeEntry pulls a time entry of type tp with the given start time | // dbGetTimeEntry pulls a time entry of type tp with the given start time | ||||||
| // from the db and returns it. | // from the db and returns it. | ||||||
| func (gdb *GimeDB) dbGetTimeEntry(tp int, sttm string) (*TimeEntry, error) { | func (gdb *GimeDB) dbGetTimeEntry(tp int, sttm string) (*TimeEntry, error) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user