168 lines
4.0 KiB
Go
168 lines
4.0 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
gime "git.bullercodeworks.com/brian/gime-lib"
|
||
|
)
|
||
|
|
||
|
func cmdPrintList(args []string) int {
|
||
|
useDefaultFilter := true
|
||
|
var showIds bool
|
||
|
var beg, end time.Time
|
||
|
tags, rem := pullTagsFromArgs(args)
|
||
|
loadType := gime.TypeNoArchive
|
||
|
for _, opt := range rem {
|
||
|
var tmpBeg, tmpEnd time.Time
|
||
|
// Check for command modifiers
|
||
|
if strings.HasPrefix(opt, ":") {
|
||
|
switch opt {
|
||
|
case ":ids":
|
||
|
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
|
||
|
}
|
||
|
|
||
|
// 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 {
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
if len(pts[1]) > 0 {
|
||
|
// This should be the ending date
|
||
|
tmpEnd, err = parseFuzzyTime(pts[1])
|
||
|
if err != nil {
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if !tmpBeg.IsZero() || !tmpEnd.IsZero() {
|
||
|
beg, end = tmpBeg, tmpEnd
|
||
|
}
|
||
|
|
||
|
// Was 'archive' requested?
|
||
|
if strings.HasPrefix(opt, "arch") {
|
||
|
loadType = gime.TypeArchive
|
||
|
useDefaultFilter = false
|
||
|
}
|
||
|
}
|
||
|
if end.IsZero() {
|
||
|
end = time.Now()
|
||
|
}
|
||
|
|
||
|
timeEntries = gdb.LoadTimeEntryCollection(loadType)
|
||
|
|
||
|
// 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 tags {
|
||
|
if !t.HasTag(tags[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)
|
||
|
var str string
|
||
|
var currId int
|
||
|
var err error
|
||
|
if timers.Length() == 0 {
|
||
|
if useDefaultFilter {
|
||
|
fmt.Println("No timers found for today")
|
||
|
} else {
|
||
|
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
|
||
|
}
|
||
|
|
||
|
// Get day totals
|
||
|
dayTotals := make(map[string]time.Duration)
|
||
|
for i := 0; i < timers.Length(); i++ {
|
||
|
wrk := timers.Get(i)
|
||
|
dur := wrk.GetEnd().Sub(wrk.GetStart())
|
||
|
if wrk.GetEnd().IsZero() {
|
||
|
dur = time.Now().Sub(wrk.GetStart())
|
||
|
}
|
||
|
dayTotals[wrk.GetStart().Format("2006/01/02")] += dur
|
||
|
}
|
||
|
for i := 0; i < timers.Length(); i++ {
|
||
|
wrk := timers.Get(i)
|
||
|
oldDayStr := dayStr
|
||
|
dayStr = wrk.GetStart().Format("2006/01/02")
|
||
|
if dayStr != oldDayStr {
|
||
|
wrkDur := dayTotals[dayStr].Round(GetRoundToDuration())
|
||
|
fmtStr := dayStr + " ( %.2f )\n"
|
||
|
str += fmt.Sprintf(fmtStr, DurationToDecimal(wrkDur))
|
||
|
}
|
||
|
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 cmdDoExport(args []string) int {
|
||
|
return 0
|
||
|
}
|