gime-lib/cmd/gime/helpers.go

252 lines
5.6 KiB
Go
Raw Normal View History

2017-08-01 20:39:24 +00:00
package main
import (
"errors"
2018-01-11 16:52:44 +00:00
"fmt"
2017-08-01 20:39:24 +00:00
"strconv"
2018-01-11 16:52:44 +00:00
"time"
2017-08-01 20:39:24 +00:00
"git.bullercodeworks.com/brian/gime"
)
2018-01-11 16:52:44 +00:00
// filterTimerCollection takes a collection and a function that it runs every entry through
// If the function returns true for the entry, it adds it to a new collection to be returned
func filterTimerCollection(c *gime.TimeEntryCollection, fn func(t *gime.TimeEntry) bool) *gime.TimeEntryCollection {
ret := new(gime.TimeEntryCollection)
for i := 0; i < c.Length(); i++ {
if fn(c.Get(i)) {
ret.Push(c.Get(i))
}
}
return ret
}
func TimerCollectionToString(c *gime.TimeEntryCollection) string {
var ret string
for i := 0; i < c.Length(); i++ {
ret += TimerToString(c.Get(i))
if i < c.Length()-1 {
ret += "\n"
}
}
return ret
}
2017-08-02 19:14:53 +00:00
// TimerToString takes a TimeEntry and gives a nicely formatted string
2017-08-01 20:39:24 +00:00
func TimerToString(t *gime.TimeEntry) string {
var ret string
2017-08-02 19:14:53 +00:00
var end string
2017-08-01 20:39:24 +00:00
if t.StartsToday() {
ret = t.GetStart().Format("15:04 - ")
2017-08-02 19:14:53 +00:00
end = "**:**"
2017-08-01 20:39:24 +00:00
} else {
ret = t.GetStart().Format("2006/01/02 15:04:05 - ")
2017-08-02 19:14:53 +00:00
end = "**:**:**"
2017-08-01 20:39:24 +00:00
}
if !t.GetEnd().IsZero() {
if t.EndsToday() {
2017-08-02 19:14:53 +00:00
end = t.GetEnd().Format("15:04")
2017-08-01 20:39:24 +00:00
} else {
2017-08-02 19:14:53 +00:00
end = t.GetEnd().Format("2006/01/02 15:04:05")
2017-08-01 20:39:24 +00:00
}
}
2017-08-02 19:14:53 +00:00
ret += end
2017-08-01 20:39:24 +00:00
tags := t.GetTags()
if tags.Length() > 0 {
ret += " [ "
for i := 0; i < tags.Length(); i++ {
ret += tags.Get(i) + " "
}
ret += "]"
}
return ret
}
2018-01-11 16:52:44 +00:00
func InferTimerDetailString(t *gime.TimeEntry) string {
diffEnd := time.Now()
if !t.GetEnd().IsZero() {
diffEnd = t.GetEnd()
}
if int(diffEnd.Sub(t.GetStart())) >= (int(time.Hour) * diffEnd.Hour()) {
return TimerDetailToLongString(t)
}
return TimerDetailToString(t)
}
func TimerDetailToString(t *gime.TimeEntry) string {
ret := t.GetStart().Format("15:04")
if t.GetEnd().IsZero() {
ret += " (" + padLeft(sinceToString(t.GetStart()), len("00h 00m 00s")) + ") "
} else {
ret += " (" + padLeft(diffToString(t.GetStart(), t.GetEnd()), len("00h 00m 00s")) + ") "
}
if t.GetTags().Length() > 0 {
ret += " [ "
for j := 0; j < t.GetTags().Length(); j++ {
ret += t.GetTags().Get(j)
if j < t.GetTags().Length()-1 {
ret += ", "
}
}
ret += " ] "
}
return ret
}
// ...ToLongString includes year/month/day
func TimerDetailToLongString(t *gime.TimeEntry) string {
ret := t.GetStart().Format(time.Stamp)
if t.GetEnd().IsZero() {
ret += " (" + padLeft(sinceToString(t.GetStart()), len("0000y 00m 00d 00h 00m 00s")) + ") "
} else {
ret += " (" + padLeft(diffToString(t.GetStart(), t.GetEnd()), len("0000y 00m 00d 00h 00m 00s")) + ") "
}
if t.GetTags().Length() > 0 {
ret += " [ "
for j := 0; j < t.GetTags().Length(); j++ {
ret += t.GetTags().Get(j)
if j < t.GetTags().Length()-1 {
ret += ", "
}
}
ret += " ] "
}
return ret
}
2017-08-01 20:39:24 +00:00
// findTimerById takes a timer id and returns the TimeEntry and the type string
// of the entry corresponding to that id
// It searches TypeCurrent -> TypeRecent -> TypeArchive
2018-01-11 16:52:44 +00:00
func findTimerById(tmrId int) (*gime.TimeEntry, int, error) {
2017-08-01 20:39:24 +00:00
// Find the timer for this tmrId
var prevNum, numLoaded int
for i := range gdb.AllTypes {
timeCollection := gdb.LoadTimeEntryCollection(gdb.AllTypes[i])
numLoaded += timeCollection.Length()
if numLoaded > tmrId {
// This is the set that it's in, the index we need is tmrId - prevNum
return timeCollection.Get(tmrId - prevNum), gdb.AllTypes[i], nil
}
prevNum = numLoaded
}
2018-01-11 16:52:44 +00:00
return nil, gime.TypeAll, errors.New("Unable to find timer with id: " + strconv.Itoa(tmrId))
}
func parseFuzzyTime(t string) (time.Time, error) {
var ret time.Time
var err error
for i := range fuzzyFormats {
ret, err = time.Parse(fuzzyFormats[i], t)
if err == nil {
// Make sure it's in the local timezone
tz := time.Now().Format("Z07:00")
t = ret.Format("2006-01-02T15:04:05") + tz
if ret, err = time.Parse(time.RFC3339, t); err != nil {
return ret, err
}
// Check for zero on year/mo/day
if ret.Year() == 0 && ret.Month() == time.January && ret.Day() == 1 {
ret = ret.AddDate(time.Now().Year(), int(time.Now().Month())-1, time.Now().Day()-1)
}
return ret, nil
}
}
return time.Time{}, errors.New("Unable to parse time: " + t)
}
func sinceToString(tm time.Time) string {
return diffToString(tm, time.Now())
}
func diffToString(tm1, tm2 time.Time) string {
ret := ""
yr, mo, dy, hr, mn, sc := diff(tm1, tm2)
higher := false
if yr > 0 {
ret += fmt.Sprintf("%4dy ", yr)
higher = true
}
if mo > 0 || higher {
ret += fmt.Sprintf("%2dm ", mo)
higher = true
}
if dy > 0 || higher {
ret += fmt.Sprintf("%2dd ", dy)
higher = true
}
if hr > 0 || higher {
ret += fmt.Sprintf("%2dh ", hr)
higher = true
}
if mn > 0 || higher {
ret += fmt.Sprintf("%2dm ", mn)
higher = true
}
if sc > 0 || higher {
ret += fmt.Sprintf("%2ds", sc)
}
return ret
}
func padRight(st string, l int) string {
for len(st) < l {
st = st + " "
}
return st
}
func padLeft(st string, l int) string {
for len(st) < l {
st = " " + st
}
return st
}
func diff(a, b time.Time) (year, month, day, hour, min, sec int) {
if a.Location() != b.Location() {
b = b.In(a.Location())
}
if a.After(b) {
a, b = b, a
}
y1, M1, d1 := a.Date()
y2, M2, d2 := b.Date()
h1, m1, s1 := a.Clock()
h2, m2, s2 := b.Clock()
year = int(y2 - y1)
month = int(M2 - M1)
day = int(d2 - d1)
hour = int(h2 - h1)
min = int(m2 - m1)
sec = int(s2 - s1)
// Normalize negative values
if sec < 0 {
sec += 60
min--
}
if min < 0 {
min += 60
hour--
}
if hour < 0 {
hour += 24
day--
}
if day < 0 {
// days in month:
t := time.Date(y1, M1, 32, 0, 0, 0, 0, time.UTC)
day += 32 - t.Day()
month--
}
if month < 0 {
month += 12
year--
}
return
2017-08-01 20:39:24 +00:00
}