Dev a few more operations

* Archive
* Config
* Pull out filter generation (from list) for reuse
This commit is contained in:
Brian Buller 2022-01-20 08:51:39 -06:00
parent d597da3b64
commit 54c91f0d3c
6 changed files with 125 additions and 96 deletions

View File

@ -163,3 +163,11 @@ func (p *Program) GetMostRecentTimer() (*timertxt.Timer, error) {
} }
return work, nil return work, nil
} }
func (p *Program) GetTimerString(timer *timertxt.Timer) string {
return fmt.Sprintf("%d. %s", timer.Id, strings.TrimPrefix(timer.String(), "x "))
}
func (p *Program) GetDoneTimerString(timer *timertxt.Timer) string {
return fmt.Sprintf("--. %s", timer.String())
}

View File

@ -7,19 +7,15 @@ package cmd
import ( import (
"fmt" "fmt"
"git.bullercodeworks.com/brian/gime/cli"
"git.bullercodeworks.com/brian/gime/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// archiveCmd represents the archive command // archiveCmd represents the archive command
var archiveCmd = &cobra.Command{ var archiveCmd = &cobra.Command{
Use: "archive", Use: "archive",
Short: "A brief description of your command", Short: "Archive timers to the done file",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
RunE: opArchive, RunE: opArchive,
} }
@ -28,6 +24,26 @@ func init() {
} }
func opArchive(cmd *cobra.Command, args []string) error { func opArchive(cmd *cobra.Command, args []string) error {
fmt.Println("archive called") var err error
p := cli.Program{}
err = p.Initialize()
if err != nil {
return err
}
if err = p.LoadTimerList(); err != nil {
return err
}
filter := util.BuildFilterFromArgs(args)
list := p.TimerList.Filter(filter)
for _, v := range list.GetTimerSlice() {
if v.Finished {
if err := p.ArchiveTimer(v); err != nil {
return fmt.Errorf("Error archiving task %d: %w", v.Id, err)
}
fmt.Println(p.GetDoneTimerString(v))
}
}
return nil return nil
} }

View File

@ -6,20 +6,16 @@ package cmd
import ( import (
"fmt" "fmt"
"sort"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
// configCmd represents the config command // configCmd represents the config command
var configCmd = &cobra.Command{ var configCmd = &cobra.Command{
Use: "config", Use: "config",
Short: "A brief description of your command", Short: "Print all configuration values",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
RunE: opConfig, RunE: opConfig,
} }
@ -28,6 +24,14 @@ func init() {
} }
func opConfig(cmd *cobra.Command, args []string) error { func opConfig(cmd *cobra.Command, args []string) error {
fmt.Println("config called") var settings []string
for k, v := range viper.AllSettings() {
settings = append(settings, fmt.Sprintf("%s: %s", k, v))
}
sort.Strings(settings)
fmt.Println("Configuration File:", viper.ConfigFileUsed())
for _, v := range settings {
fmt.Println(v)
}
return nil return nil
} }

View File

@ -13,13 +13,7 @@ import (
// editorCmd represents the editor command // editorCmd represents the editor command
var editorCmd = &cobra.Command{ var editorCmd = &cobra.Command{
Use: "editor", Use: "editor",
Short: "A brief description of your command", Short: "Open either the timer.txt file or the done.txt file in the default editor ",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
RunE: opEditor, RunE: opEditor,
} }

View File

@ -6,7 +6,6 @@ package cmd
import ( import (
"fmt" "fmt"
"strings"
"time" "time"
"git.bullercodeworks.com/brian/gime/cli" "git.bullercodeworks.com/brian/gime/cli"
@ -26,12 +25,6 @@ var listCmd = &cobra.Command{
func init() { func init() {
rootCmd.AddCommand(listCmd) rootCmd.AddCommand(listCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// listCmd.PersistentFlags().String("foo", "", "A help for foo")
// Local Flags // Local Flags
listCmd.Flags().BoolP("all", "a", false, "Include done.txt timers") listCmd.Flags().BoolP("all", "a", false, "Include done.txt timers")
listCmd.Flags().BoolP("done", "d", false, "Only done.txt timers") listCmd.Flags().BoolP("done", "d", false, "Only done.txt timers")
@ -68,75 +61,19 @@ func opListTimers(cmd *cobra.Command, args []string) error {
return err return err
} }
} }
start := time.Time{}
end := time.Now()
var contextFilters []string
var projectFilters []string
var allFilters []func(timertxt.Timer) bool
if len(args) > 0 {
contextFilters, args = util.GetContextsFromSlice(args)
projectFilters, args = util.GetProjectsFromSlice(args)
}
if len(args) > 0 {
if start, err = util.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 = util.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:]
}
}
}
list := timertxt.NewTimerList() list := timertxt.NewTimerList()
if !onlyArchive { if !onlyArchive {
list = p.TimerList.GetTimersInRange(start, end) list = p.TimerList
if includeArchive { if includeArchive {
*list = append(*list, (*p.DoneList.GetTimersInRange(start, end))...) for _, tmr := range p.DoneList.GetTimerSlice() {
list.AddTimer(tmr)
}
} }
} else { } else {
list = p.DoneList.GetTimersInRange(start, end) list = p.DoneList
} }
if len(contextFilters) > 0 { filter := util.BuildFilterFromArgs(args)
allFilters = append(allFilters, func(t timertxt.Timer) bool { list = list.Filter(filter)
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) dayTotals := make(map[string]time.Duration)
for _, v := range *list { for _, v := range *list {

View File

@ -312,3 +312,73 @@ func BeginningOfMonth() time.Time {
now := time.Now() now := time.Now()
return time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location()) return time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
} }
func BuildFilterFromArgs(args []string) func(*timertxt.Timer) bool {
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 {
var err error
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:]
}
}
}
allFilters = append(allFilters, func(t timertxt.Timer) bool {
if t.StartDate.Before(end) && t.StartDate.After(start) {
return true
}
if t.FinishDate.Before(end) && t.FinishDate.After(start) {
return true
}
return false
})
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
}
return doFilters
}