From 7ef6d66564fba8dd5bd9af2ef83f31e8864616ee Mon Sep 17 00:00:00 2001 From: Ryan Cavicchioni Date: Thu, 26 Mar 2020 19:05:50 -0500 Subject: [PATCH] refactor command line code --- cmd/command.go | 23 +++++++- cmd/ls.go | 14 ++++- cmd/lume/main.go | 140 ++++++++++------------------------------------- cmd/toggle.go | 69 +++++++++++++++++++++++ 4 files changed, 134 insertions(+), 112 deletions(-) create mode 100644 cmd/toggle.go diff --git a/cmd/command.go b/cmd/command.go index 6afdf93..3864a5c 100644 --- a/cmd/command.go +++ b/cmd/command.go @@ -2,13 +2,14 @@ package lumecmd import ( "flag" + "fmt" "strconv" "git.kill0.net/chill9/go-lifx" ) type CmdArgs struct { - Flags *Flags + Flags Flags Client *lifx.Client Selector string } @@ -17,6 +18,13 @@ type Flags struct { *flag.FlagSet } +type Command struct { + Func func(CmdArgs) int + Flags *flag.FlagSet +} + +var commandRegistry = make(map[string]Command) + func (f Flags) String(name string) string { return f.FlagSet.Lookup(name).Value.String() } @@ -30,3 +38,16 @@ func (f Flags) Bool(name string) bool { val, _ := strconv.ParseBool(f.String(name)) return val } + +func RegisterCommand(name string, cmd Command) error { + if _, ok := commandRegistry[name]; ok { + return fmt.Errorf("%s command is already registered") + } + commandRegistry[name] = cmd + return nil +} + +func GetCommand(name string) (Command, bool) { + cmd, ok := commandRegistry[name] + return cmd, ok +} diff --git a/cmd/ls.go b/cmd/ls.go index 80f1f96..355ab4b 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -1,6 +1,7 @@ package lumecmd import ( + "flag" "fmt" "time" @@ -16,9 +17,20 @@ var ( powerWidth int = 0 ) +func init() { + fs := flag.NewFlagSet("toggle", flag.ExitOnError) + fs.String("selector", "all", "Set the selector") + + RegisterCommand("ls", Command{ + Func: LsCmd, + Flags: fs, + }) +} + func LsCmd(args CmdArgs) int { c := args.Client - lights, err := c.ListLights(args.Selector) + selector := args.Flags.String("selector") + lights, err := c.ListLights(selector) if err != nil { fmt.Println(err) return 1 diff --git a/cmd/lume/main.go b/cmd/lume/main.go index c45479d..7013cd5 100644 --- a/cmd/lume/main.go +++ b/cmd/lume/main.go @@ -4,135 +4,55 @@ import ( "flag" "fmt" "os" - "strconv" -) + "path" -import ( "git.kill0.net/chill9/go-lifx" lumecmd "git.kill0.net/chill9/go-lifx/cmd" + "github.com/BurntSushi/toml" ) +const lumercFile = ".lumerc" + +type Config struct { + AccessToken string +} + func main() { var ( - command string selector string - //r *lifx.Response - err error - color lifx.HSBKColor ) - accessToken := os.Getenv("LIFX_ACCESS_TOKEN") - if accessToken == "" { - fmt.Println("LIFX_ACCESS_TOKEN is undefined") + var config Config + homeDir, err := os.UserHomeDir() + _, err = toml.DecodeFile(path.Join(homeDir, lumercFile), &config) + if os.IsNotExist(err) { + config.AccessToken = os.Getenv("LIFX_ACCESS_TOKEN") + } + + if config.AccessToken == "" { + fmt.Println("access token is not set") os.Exit(1) } - flag.StringVar(&selector, "selector", "all", "LIFX selector") - - setStateCommand := flag.NewFlagSet("set-state", flag.ExitOnError) - setStateCommand.String("power", "", "Set the power state (on/off)") - setStateCommand.String("color", "", "Set the color (HSBK)") - setStateCommand.String("brightness", "", "Set the brightness") - setStateCommand.String("duration", "", "Set the duration") - setStateCommand.String("infrared", "", "Set the infrared brightness") - setStateCommand.Bool("fast", false, "Execute fast (no response)") - - setWhiteCommand := flag.NewFlagSet("set-white", flag.ExitOnError) - setWhiteCommand.String("name", "", "Set the kelvin by name") - setWhiteCommand.String("kelvin", "", "Set the kelvin by value") - setWhiteCommand.String("brightness", "", "Set the brightness") - setWhiteCommand.String("duration", "", "Set the duration") - setWhiteCommand.Bool("fast", false, "Execute fast (no response)") - flag.Parse() - command = flag.Arg(0) + command := flag.Arg(0) - c := lifx.NewClient(accessToken) + c := lifx.NewClient(config.AccessToken) cmdArgs := lumecmd.CmdArgs{ - Client: c, + Client: c, + Selector: selector, } - switch command { - case "toggle": - _, err = c.Toggle(selector, 1) - case "ls": - lumecmd.LsCmd(cmdArgs) - case "set-state": - setStateCommand.Parse(os.Args[4:]) - - fs := lumecmd.Flags{setStateCommand} - - power := fs.String("power") - color := fs.String("color") - brightness := fs.String("brightness") - duration := fs.String("duration") - infrared := fs.String("infrared") - fast := fs.String("fast") - - state := lifx.State{} - - if power != "" { - state.Power = power - } - if color != "" { - state.Color = lifx.NamedColor(color) - } - if brightness != "" { - state.Brightness, err = strconv.ParseFloat(brightness, 64) - } - if duration != "" { - state.Duration, err = strconv.ParseFloat(duration, 64) - } - if infrared != "" { - state.Infrared, err = strconv.ParseFloat(infrared, 64) - } - if fast != "" { - state.Fast, err = strconv.ParseBool(fast) - } - - _, err = c.SetState(selector, state) - case "set-white": - setWhiteCommand.Parse(os.Args[4:]) - - fs := lumecmd.Flags{setWhiteCommand} - - name := fs.String("name") - kelvin := fs.String("kelvin") - brightness := fs.String("brightness") - duration := fs.String("duration") - fast := fs.String("fast") - - state := lifx.State{} - - if name != "" { - color, err := lifx.NewWhiteString(name) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - state.Color = color - } - if kelvin != "" { - k, _ := strconv.ParseInt(kelvin, 10, 16) - color, err = lifx.NewWhite(int16(k)) - state.Color = color - } - if brightness != "" { - state.Brightness, err = strconv.ParseFloat(brightness, 64) - } - if duration != "" { - state.Duration, err = strconv.ParseFloat(duration, 64) - } - if fast != "" { - state.Fast, err = strconv.ParseBool(fast) - } - - _, err = c.SetState(selector, state) - if err != nil { - fmt.Println(err) - os.Exit(1) - } + cmd, ok := lumecmd.GetCommand(command) + if !ok { + fmt.Println("ERROR") + os.Exit(1) } + fs := cmd.Flags + fs.Parse(os.Args[2:]) + + cmdArgs.Flags = lumecmd.Flags{fs} + os.Exit(cmd.Func(cmdArgs)) } diff --git a/cmd/toggle.go b/cmd/toggle.go new file mode 100644 index 0000000..950fb19 --- /dev/null +++ b/cmd/toggle.go @@ -0,0 +1,69 @@ +package lumecmd + +import ( + "flag" + "fmt" + + "git.kill0.net/chill9/go-lifx" +) + +func init() { + fs := flag.NewFlagSet("toggle", flag.ExitOnError) + fs.Float64("duration", 1.0, "Set the duration") + fs.String("selector", "all", "Set the selector") + + RegisterCommand("toggle", Command{ + Func: ToggleCmd, + Flags: fs, + }) +} + +func ToggleCmd(args CmdArgs) int { + c := args.Client + duration := args.Flags.Float64("duration") + selector := args.Flags.String("selector") + r, err := c.Toggle(selector, duration) + if err != nil { + fmt.Println(err) + return 1 + } + PrintResults(r) + return 0 +} + +func PrintResults(resp *lifx.Response) { + var length, idWidth, labelWidth, statusWidth int + + for _, r := range resp.Results { + length = len(r.Id) + if idWidth < length { + idWidth = length + } + + length = len(r.Label) + if labelWidth < length { + labelWidth = length + } + + length = len(r.Status) + if statusWidth < length { + statusWidth = length + } + } + + for _, r := range resp.Results { + fmt.Printf("%*s %*s %*s\n", + idWidth, r.Id, + labelWidth, r.Label, + statusWidth, statusColor(r.Status)) + } +} + +func statusColor(s lifx.Status) string { + fs := "\033[1;31m%s\033[0m" + if s == "ok" { + fs = "\033[1;32m%s\033[0m" + } + + return fmt.Sprintf(fs, s) +}