Add time
operation
Just spits out the duration on a line by itself
This commit is contained in:
parent
52eb4f95c0
commit
ba0e465723
20
app_state.go
20
app_state.go
@ -86,6 +86,9 @@ func (a *AppState) doVersionCheck() {
|
|||||||
a.config.SetInt("version", confVer)
|
a.config.SetInt("version", confVer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data Migrations
|
||||||
|
// 0 -> 1: Initialize Config
|
||||||
|
// 1 -> 2: No migration Needed
|
||||||
func (a *AppState) migrate(from, to int) int {
|
func (a *AppState) migrate(from, to int) int {
|
||||||
if from == to {
|
if from == to {
|
||||||
return to
|
return to
|
||||||
@ -107,6 +110,17 @@ func (a *AppState) initialize() {
|
|||||||
}
|
}
|
||||||
a.ValidOperations = make(map[string][]string)
|
a.ValidOperations = make(map[string][]string)
|
||||||
a.OpFuncs = make(map[string]func([]string) int)
|
a.OpFuncs = make(map[string]func([]string) int)
|
||||||
|
a.addOperation("time",
|
||||||
|
[]string{
|
||||||
|
"time [contexts] [projects] - Only output the total time value",
|
||||||
|
" --a - Include done.txt file",
|
||||||
|
" [start] - List entries after this date",
|
||||||
|
" [end] - List entries before this date",
|
||||||
|
" [@contexts] - Filter entries with the given contexts",
|
||||||
|
" [+projects] - Filter entries with the given projects",
|
||||||
|
},
|
||||||
|
a.opShowTime,
|
||||||
|
)
|
||||||
a.addOperation("ls",
|
a.addOperation("ls",
|
||||||
[]string{
|
[]string{
|
||||||
"ls [--a] [start] [end] [contexts] [projects] - List Timers",
|
"ls [--a] [start] [end] [contexts] [projects] - List Timers",
|
||||||
@ -217,6 +231,12 @@ func (a *AppState) initialize() {
|
|||||||
},
|
},
|
||||||
a.opPrintUsage,
|
a.opPrintUsage,
|
||||||
)
|
)
|
||||||
|
a.addOperation("editor",
|
||||||
|
[]string{
|
||||||
|
"editor - Open the timer file in $EDITOR",
|
||||||
|
},
|
||||||
|
a.opEditor,
|
||||||
|
)
|
||||||
a.directory = a.config.Get("directory")
|
a.directory = a.config.Get("directory")
|
||||||
a.fileTimer = a.config.Get("timerfile")
|
a.fileTimer = a.config.Get("timerfile")
|
||||||
a.fileDone = a.config.Get("donefile")
|
a.fileDone = a.config.Get("donefile")
|
||||||
|
2
main.go
2
main.go
@ -4,7 +4,7 @@ import "os"
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
AppName = "gime"
|
AppName = "gime"
|
||||||
AppVersion = 1
|
AppVersion = 2
|
||||||
|
|
||||||
DefRoundTo = "1m0s"
|
DefRoundTo = "1m0s"
|
||||||
)
|
)
|
||||||
|
116
timer_ops.go
116
timer_ops.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -9,6 +10,24 @@ import (
|
|||||||
timertxt "github.com/br0xen/go-timertxt"
|
timertxt "github.com/br0xen/go-timertxt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (a *AppState) opEditor(args []string) int {
|
||||||
|
editor := os.Getenv("EDITOR")
|
||||||
|
if editor == "" {
|
||||||
|
fmt.Println("No $EDITOR set")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fmt.Println(editor, a.directory+a.fileTimer)
|
||||||
|
return 0
|
||||||
|
/*
|
||||||
|
err := exec.Command(editor, a.directory+a.fileTimer).Run()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error opening editor: " + err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
func (a *AppState) opStatus(args []string) int {
|
func (a *AppState) opStatus(args []string) int {
|
||||||
if len(*a.TimerList.GetActiveTimers()) == 0 {
|
if len(*a.TimerList.GetActiveTimers()) == 0 {
|
||||||
fmt.Println("No timers running")
|
fmt.Println("No timers running")
|
||||||
@ -28,6 +47,103 @@ func (a *AppState) opStatus(args []string) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just output the time given the filters
|
||||||
|
*/
|
||||||
|
func (a *AppState) opShowTime(args []string) int {
|
||||||
|
var includeArchive bool
|
||||||
|
var err error
|
||||||
|
start := time.Time{}
|
||||||
|
end := time.Now()
|
||||||
|
var contextFilters []string
|
||||||
|
var projectFilters []string
|
||||||
|
|
||||||
|
var allFilters []func(timertxt.Timer) bool
|
||||||
|
|
||||||
|
if len(args) > 0 {
|
||||||
|
contextFilters, args = getContextsFromSlice(args)
|
||||||
|
projectFilters, args = getProjectsFromSlice(args)
|
||||||
|
}
|
||||||
|
if len(args) > 0 {
|
||||||
|
if args[0] == "--a" {
|
||||||
|
includeArchive = true
|
||||||
|
args = args[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(args) > 0 {
|
||||||
|
if start, err = parseFuzzyTime(args[0]); err != nil {
|
||||||
|
y, m, d := time.Now().Date()
|
||||||
|
start = time.Date(y, m, d, 0, 0, 0, 0, time.Now().Location())
|
||||||
|
} else {
|
||||||
|
args = args[1:]
|
||||||
|
}
|
||||||
|
if len(args) > 0 {
|
||||||
|
if end, err = parseFuzzyTime(args[0]); err != nil {
|
||||||
|
y, m, d := time.Now().Date()
|
||||||
|
end = time.Date(y, m, d, 23, 59, 59, 0, time.Now().Location())
|
||||||
|
} else {
|
||||||
|
args = args[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if includeArchive {
|
||||||
|
if err = a.LoadDoneList(); err != nil {
|
||||||
|
fmt.Println("Error loading done.txt entries")
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list := a.TimerList.GetTimersInRange(start, end)
|
||||||
|
if includeArchive {
|
||||||
|
*list = append(*list, (*a.DoneList.GetTimersInRange(start, end))...)
|
||||||
|
}
|
||||||
|
if len(contextFilters) > 0 {
|
||||||
|
allFilters = append(allFilters, func(t timertxt.Timer) bool {
|
||||||
|
for _, v := range contextFilters {
|
||||||
|
v = strings.TrimPrefix(v, "@")
|
||||||
|
if !t.HasContext(v) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(projectFilters) > 0 {
|
||||||
|
allFilters = append(allFilters, func(t timertxt.Timer) bool {
|
||||||
|
for _, v := range projectFilters {
|
||||||
|
v = strings.TrimPrefix(v, "+")
|
||||||
|
if !t.HasProject(v) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
doFilters := func(t timertxt.Timer) bool {
|
||||||
|
for _, v := range allFilters {
|
||||||
|
if !v(t) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we made it all the way down here, it matches
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
list = list.Filter(doFilters)
|
||||||
|
|
||||||
|
var total time.Duration
|
||||||
|
for _, v := range *list {
|
||||||
|
dur := v.FinishDate.Sub(v.StartDate)
|
||||||
|
if v.FinishDate.IsZero() {
|
||||||
|
dur = time.Now().Sub(v.StartDate)
|
||||||
|
}
|
||||||
|
total += dur
|
||||||
|
}
|
||||||
|
total = total.Round(GetRoundToDuration())
|
||||||
|
fmt.Printf("%.2f\n", DurationToDecimal(total))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List timers for a given time span
|
* List timers for a given time span
|
||||||
* By default, only list Today
|
* By default, only list Today
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// +build !windows
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
48
ui_loop_windows.go
Normal file
48
ui_loop_windows.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// +build windows
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
termbox "github.com/nsf/termbox-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func uiLoop() int {
|
||||||
|
err := termbox.Init()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
termbox.SetOutputMode(termbox.Output256)
|
||||||
|
app.BuildScreens()
|
||||||
|
displayScreen := app.screens[ScreenMain]
|
||||||
|
bundle := Bundle{}
|
||||||
|
bundle.setValue(MainBundleListKey, MainBundleListRecent)
|
||||||
|
displayScreen.initialize(bundle)
|
||||||
|
app.layoutAndDrawScreen(displayScreen)
|
||||||
|
eventChan := make(chan termbox.Event)
|
||||||
|
go readUserInput(eventChan)
|
||||||
|
go checkForUpdate(eventChan)
|
||||||
|
for {
|
||||||
|
event := <-eventChan
|
||||||
|
if event.Type == termbox.EventKey {
|
||||||
|
if event.Key == termbox.KeyCtrlC {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
newScreenIndex := displayScreen.handleKeyEvent(event)
|
||||||
|
if newScreenIndex < len(app.screens) {
|
||||||
|
displayScreen = app.screens[newScreenIndex]
|
||||||
|
app.layoutAndDrawScreen(displayScreen)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if event.Type == termbox.EventResize {
|
||||||
|
displayScreen.initialize(nil)
|
||||||
|
app.layoutAndDrawScreen(displayScreen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
termbox.Close()
|
||||||
|
// Any wrap up should be done here...
|
||||||
|
return 0
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user