Use github go-timertxt library

Also more feature add
This commit is contained in:
Brian Buller 2019-02-26 09:41:00 -06:00
parent 69e1c959f6
commit 655c4f199e
6 changed files with 220 additions and 40 deletions

View File

@ -5,7 +5,7 @@ import (
"os"
"strings"
timertxt "git.bullercodeworks.com/brian/go-timertxt"
timertxt "github.com/br0xen/go-timertxt"
"github.com/br0xen/user-config"
)
@ -109,64 +109,89 @@ func (a *AppState) initialize() {
a.OpFuncs = make(map[string]func([]string) int)
a.addOperation("ls",
[]string{
"ls - List Timers",
"ls [--a] [start] [end] [contexts] [projects] - List Timers",
" --a - Include done.txt file",
" [start] - List entries after this date",
" [end] - List entries before this date",
" [@contexts] - List entries with the given contexts",
" [+projects] - List entries with the given projects",
},
a.opListTimers,
)
a.addOperation("lsa",
[]string{
"lsa - The same as 'ls -a'",
"lsa [start] [end] [contexts] [projects] - Shortcut for 'ls --a'",
},
func(args []string) int {
return a.opListTimers(append([]string{"-a"}, args...))
return a.opListTimers(append([]string{"--a"}, args...))
},
)
a.addOperation("start",
[]string{
"start [time] [@contexts...] [+projects...] [tag:value...]",
" - Start a timer with the given details",
" If the first argument looks like a time,",
" the timer will be started then (past or future)",
" - Start a timer with the given details",
" If the first argument looks like a time,",
" the timer will be started then (past or future)",
},
a.opStartTimer,
)
a.addOperation("stop",
[]string{
"stop [time] - Stops the current timer",
" If the first argument looks like a time,",
" the timer will be stopped then (past or future)",
"stop [time] - Stops the current timer",
" If the first argument looks like a time,",
" the timer will be stopped then (past or future)",
},
a.opStopTimer,
)
a.addOperation("switch",
[]string{
"switch [time] [@contexts...] [+projects...] [tag:value...] - Stops all active timers and starts a new one",
" with the given arguments",
},
a.opSwitchTimer,
)
a.addOperation("archive",
[]string{
"archive [id] - Archive the timer with the given id",
},
a.opArchiveTimer,
)
a.addOperation("status",
[]string{
"status - Prints the status of all active timers",
"status - Prints the status of all active timers",
},
a.opStatus,
)
a.addOperation("mod",
[]string{
"mod <id> [start=<start>] [end=<end>] [projects=<project,...>] [contexts=<context,...>]",
" - Prints the status of all active timers",
},
a.opModifyTimer,
)
a.addOperation("fuzzyparse",
[]string{
"fuzzyparse [date string] - Parses the passed string and print the RFC3339 result (for testing)",
"fuzzyparse [date string] - Parses the passed string and print the RFC3339 result (for testing)",
},
a.opFuzzyParse,
)
a.addOperation("--reinit",
[]string{"--reinit - Reset all Configuration Settings"},
[]string{"--reinit - Reset all Configuration Settings"},
func(args []string) int {
a.initializeConfig()
return 0
},
)
a.addOperation("-h",
[]string{"-h - Print this message"},
[]string{"-h - Print this message"},
a.opPrintUsage,
)
a.addOperation("help",
[]string{"help - Print this message"},
[]string{"help - Print this message"},
a.opPrintUsage,
)
a.addOperation("--h",
[]string{"--h - Print this message"},
[]string{"--h - Print this message"},
a.opPrintUsage,
)
a.directory = a.config.Get("directory")

View File

@ -6,7 +6,7 @@ import (
"strings"
"time"
timertxt "git.bullercodeworks.com/brian/go-timertxt"
timertxt "github.com/br0xen/go-timertxt"
)
func GetRoundToDuration() time.Duration {
@ -118,7 +118,14 @@ func timerToFriendlyString(t *timertxt.Timer) string {
for _, v := range t.Projects {
projects += "+" + v + " "
}
return fmt.Sprintf("% 2d. %s - %s [ %s] [ %s] %s", t.Id, start, end, contexts, projects, t.Notes)
var dur time.Duration
if t.FinishDate.IsZero() {
dur = time.Now().Sub(t.StartDate)
} else {
dur = t.FinishDate.Sub(t.StartDate)
}
dur = dur.Round(GetRoundToDuration())
return fmt.Sprintf("% 2d. %s - %s [ %s] [ %s] %s ( %.2f )", t.Id, start, end, contexts, projects, t.Notes, DurationToDecimal(dur))
}
func friendlyFormatForTime(t time.Time) string {

View File

@ -4,7 +4,7 @@ import (
"strings"
"time"
timertxt "git.bullercodeworks.com/brian/go-timertxt"
timertxt "github.com/br0xen/go-timertxt"
)
func (a *AppState) SetTimerFinished(id int, end time.Time) error {

View File

@ -1,6 +1,9 @@
package main
import (
"errors"
"time"
termbox "github.com/nsf/termbox-go"
)
@ -46,15 +49,19 @@ func readUserInput(e chan termbox.Event) {
}
}
func refreshList(e chan termbox.Event) {
/*
for {
time.Sleep(5 * time.Minute)
app.LoadTasklist()
app.LoadDoneList()
e <- termbox.Event{Type: termbox.EventNone}
func checkForUpdate(e chan termbox.Event) {
for {
time.Sleep(time.Minute)
// Check if the on-disk tasklist has changed
//app.LoadTasklist()
//app.LoadDoneList()
if false {
e <- termbox.Event{
Type: termbox.EventError,
Err: errors.New("List changed elsewhere"),
}
}
*/
}
}
/*

View File

@ -5,7 +5,7 @@ import (
"strings"
"time"
timertxt "git.bullercodeworks.com/brian/go-timertxt"
timertxt "github.com/br0xen/go-timertxt"
"github.com/br0xen/termbox-util"
termbox "github.com/nsf/termbox-go"
)

View File

@ -6,7 +6,7 @@ import (
"strings"
"time"
timertxt "git.bullercodeworks.com/brian/go-timertxt"
timertxt "github.com/br0xen/go-timertxt"
)
func (a *AppState) opStatus(args []string) int {
@ -33,21 +33,33 @@ func (a *AppState) opStatus(args []string) int {
* By default, only list Today
*/
func (a *AppState) opListTimers(args []string) int {
var start, end time.Time
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" {
start = time.Time{}
end = time.Now()
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 {
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:]
}
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())
@ -56,8 +68,51 @@ func (a *AppState) opListTimers(args []string) int {
}
}
}
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)
dayTotals := make(map[string]time.Duration)
for _, v := range *list {
dur := v.FinishDate.Sub(v.StartDate)
@ -149,7 +204,27 @@ func (a *AppState) opStopTimer(args []string) int {
}
func (a *AppState) opSwitchTimer(args []string) int {
return 0
var timerIds []int
var err error
end := time.Now()
// Stop all running timers and start a new one with the given args
for _, v := range *a.TimerList.GetActiveTimers() {
timerIds = append(timerIds, v.Id)
}
fmt.Print("Stopping ", timerIds, "\n")
for _, v := range timerIds {
var stopped *timertxt.Timer
if stopped, err = a.TimerList.GetTimer(v); err != nil {
fmt.Println(err.Error())
continue
}
if err = a.SetTimerFinished(v, end); err != nil {
fmt.Println(err.Error())
continue
}
fmt.Println("Stopped Timer:", timerToFriendlyString(stopped))
}
return a.opStartTimer(args)
}
func (a *AppState) opArchiveTimer(args []string) int {
@ -186,7 +261,73 @@ func (a *AppState) opArchiveTimer(args []string) int {
return 0
}
func (a *AppState) opState(args []string) int {
func (a *AppState) opModifyTimer(args []string) int {
var timer *timertxt.Timer
var contexts, projects []string
id, err := strconv.Atoi(args[0])
if err != nil {
// We didn't have a timer id, so try to modify the first active timer
if len(*a.TimerList.GetActiveTimers()) > 0 {
timer = &(*a.TimerList.GetActiveTimers())[0]
} else {
// And we don't have any active timers
fmt.Println("No active timers, 'id' must be provided.")
return 1
}
} else {
args = args[1:]
if timer, err = a.TimerList.GetTimer(id); err != nil {
fmt.Printf("Error getting timer %d\n", id)
return 1
}
}
var start, end time.Time
for _, v := range args {
pts := strings.Split(v, "=")
switch pts[0] {
case "beginning", "start":
if start, err = parseFuzzyTime(pts[1]); err != nil {
fmt.Println("Error parsing start time.")
return 1
}
case "stop", "finish", "end":
if end, err = parseFuzzyTime(pts[1]); err != nil {
fmt.Println("Error parsing end time.")
return 1
}
case "project", "projects":
projects = strings.Split(pts[1], ",")
case "context", "contexts":
contexts = strings.Split(pts[1], ",")
}
}
if len(contexts) > 0 {
for k := range contexts {
contexts[k] = strings.TrimPrefix(contexts[k], "@")
}
timer.Contexts = contexts
}
if len(projects) > 0 {
for k := range projects {
projects[k] = strings.TrimPrefix(projects[k], "+")
}
timer.Projects = projects
}
if !start.IsZero() {
timer.StartDate = start
}
if !end.IsZero() {
timer.FinishDate = end
timer.Finished = true
}
fmt.Println("Modified Timer:")
fmt.Println(timerToFriendlyString(timer))
if err := a.WriteList(); err != nil {
fmt.Println(err.Error())
return 1
}
return 0
}