/* Copyright © 2022 NAME HERE */ package cmd import ( "fmt" "strings" "time" "git.bullercodeworks.com/brian/gime/cli" "git.bullercodeworks.com/brian/gime/util" "git.bullercodeworks.com/brian/go-timertxt" "github.com/spf13/cobra" ) // listCmd represents the list command var listCmd = &cobra.Command{ Use: "list", Aliases: []string{"ls", "lsa", "lsd"}, Short: "List Timers", RunE: opListTimers, } func init() { 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 listCmd.Flags().BoolP("all", "a", false, "Include done.txt timers") listCmd.Flags().BoolP("done", "d", false, "Only done.txt timers") } func opListTimers(cmd *cobra.Command, args []string) error { var err error var includeArchive bool var onlyArchive bool //onlyArchive := cmd.CalledAs() == "lsd" || listCmd.Flags().Lookup if onlyArchive, err = cmd.Flags().GetBool("done"); err != nil { return err } else if includeArchive, err = cmd.Flags().GetBool("all"); err != nil { return err } if cmd.CalledAs() == "lsd" { onlyArchive = true } else if cmd.CalledAs() == "lsa" { includeArchive = true } p := cli.Program{} err = p.Initialize() if err != nil { return err } if !onlyArchive { if err := p.LoadTimerList(); err != nil { return err } } if includeArchive || onlyArchive { if err := p.LoadDoneList(); err != nil { 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() if !onlyArchive { list = p.TimerList.GetTimersInRange(start, end) if includeArchive { *list = append(*list, (*p.DoneList.GetTimersInRange(start, end))...) } } else { list = p.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) if v.FinishDate.IsZero() { dur = time.Now().Sub(v.StartDate) } dayTotals[v.StartDate.Format("2006/01/02")] += dur } var oldDayStr, dayStr string for _, v := range *list { oldDayStr = dayStr dayStr = v.StartDate.Format("2006/01/02") if dayStr != oldDayStr { // TODO: wrkDur := dayTotals[dayStr].Round(util.GetRoundToDuration()) fmtStr := dayStr + " ( %.2f )\n" fmt.Printf(fmtStr, util.DurationToDecimal(wrkDur)) } fmt.Println(" " + util.TimerToFriendlyString(v)) } return nil }