ziggs/internal/cli/cli.go

244 lines
5.2 KiB
Go
Raw Normal View History

2022-09-26 15:25:21 +00:00
package cli
2022-03-07 14:57:42 +00:00
import (
2023-01-15 06:59:56 +00:00
"bufio"
2022-03-07 14:57:42 +00:00
"fmt"
"os"
2023-01-15 06:59:56 +00:00
"path/filepath"
2022-03-07 14:57:42 +00:00
"strings"
"time"
cli "git.tcp.direct/Mirrors/go-prompt"
tui "github.com/manifoldco/promptui"
"github.com/rs/zerolog"
2022-08-30 06:04:48 +00:00
"github.com/davecgh/go-spew/spew"
"github.com/google/shlex"
2022-07-29 10:44:08 +00:00
"git.tcp.direct/kayos/ziggs/internal/common"
"git.tcp.direct/kayos/ziggs/internal/config"
"git.tcp.direct/kayos/ziggs/internal/ziggy"
2022-03-07 14:57:42 +00:00
)
2022-09-06 00:29:02 +00:00
var (
log *zerolog.Logger
prompt *cli.Prompt
extraDebug = false
)
2022-03-07 14:57:42 +00:00
2023-01-15 12:23:44 +00:00
var noHist = map[string]bool{"clear": true, "exit": true, "quit": true}
2022-09-26 17:10:17 +00:00
// Interpret is where we will actuall define our Commands
2022-03-07 14:57:42 +00:00
func executor(cmd string) {
var status = 0
2023-01-15 06:59:56 +00:00
defer func() {
2023-01-15 12:23:44 +00:00
if r := recover(); r != nil {
log.Error().Msgf("PANIC: %s", r)
}
if _, ok := noHist[cmd]; !ok && status == 0 {
2023-01-15 12:23:44 +00:00
history = append(history, cmd)
go saveHist()
}
2023-01-15 06:59:56 +00:00
}()
args, err := shlex.Split(strings.TrimSpace(cmd))
if err != nil {
log.Error().Msgf("error parsing command: %s", err)
status = 1
return
}
2022-08-30 06:04:48 +00:00
if len(args) == 0 {
return
}
2022-03-07 14:57:42 +00:00
switch args[0] {
case "quit", "exit":
os.Exit(0)
case "use":
2022-09-06 00:29:02 +00:00
if len(ziggy.Lucifer.Bridges) < 2 {
return
}
2022-07-08 21:35:11 +00:00
if len(args) < 2 {
println("use: use <bridge>")
return
2022-03-07 14:57:42 +00:00
}
br, ok := ziggy.Lucifer.Bridges[args[1]]
if !ok {
log.Error().Msg("invalid bridge: " + args[1])
status = 1
return
2022-03-07 14:57:42 +00:00
}
sel.Bridge = args[1]
log.Info().Str("host", br.Host).Int("lights", len(br.HueLights)).Msg("switched to bridge: " + sel.Bridge)
2022-03-07 14:57:42 +00:00
case "debug":
levelsdebug := map[string]zerolog.Level{"info": zerolog.InfoLevel, "debug": zerolog.DebugLevel, "trace": zerolog.TraceLevel}
debuglevels := map[zerolog.Level]string{zerolog.InfoLevel: "info", zerolog.DebugLevel: "debug", zerolog.TraceLevel: "trace"}
if len(args) < 2 {
println("current debug level: " + debuglevels[log.GetLevel()])
2022-12-07 11:25:43 +00:00
return
2022-03-07 14:57:42 +00:00
}
if newlevel, ok := levelsdebug[args[1]]; ok {
zerolog.SetGlobalLevel(newlevel)
2022-09-06 00:29:02 +00:00
} else {
println("invalid argument: " + args[1])
2022-03-07 14:57:42 +00:00
}
case "help":
if len(args) < 2 {
2022-09-26 17:10:17 +00:00
getHelp("")
2022-03-07 14:57:42 +00:00
return
}
getHelp(args[len(args)-1])
case "clear":
print("\033[H\033[2J")
2022-09-06 00:29:02 +00:00
case "debugcli":
if extraDebug {
extraDebug = false
} else {
extraDebug = true
}
2022-08-30 06:04:48 +00:00
spew.Dump(suggestions)
2022-03-07 14:57:42 +00:00
default:
2022-08-30 06:04:48 +00:00
if len(args) == 0 {
return
}
2022-09-26 17:10:17 +00:00
bcmd, ok := Commands[args[0]]
2022-03-07 14:57:42 +00:00
if !ok {
2023-01-15 12:56:04 +00:00
log.Error().Msg("invalid command: " + args[0])
status = 1
2022-03-07 14:57:42 +00:00
return
}
2022-09-06 00:29:02 +00:00
br, ok := ziggy.Lucifer.Bridges[sel.Bridge]
if sel.Bridge == "" || !ok {
q := tui.Select{
2022-07-09 00:09:49 +00:00
Label: "Send to all known bridges?",
Items: []string{"yes", "no"},
Pointer: common.ZiggsPointer,
}
2022-09-06 00:29:02 +00:00
_, ch, _ := q.Run()
2022-07-09 00:09:49 +00:00
if ch != "yes" {
return
}
for _, br := range ziggy.Lucifer.Bridges {
2022-08-30 06:04:48 +00:00
go func(brj *ziggy.Bridge) {
2022-09-26 15:25:21 +00:00
err := bcmd.reactor(brj, args[1:])
2022-08-30 06:04:48 +00:00
if err != nil {
log.Error().Err(err).Msg("bridge command failed")
}
}(br)
2022-03-07 14:57:42 +00:00
}
return
}
err := bcmd.reactor(br, args[1:])
if err != nil {
log.Error().Err(err).Msg("error executing command")
status = 1
2022-03-07 14:57:42 +00:00
}
}
}
2022-07-09 00:09:49 +00:00
func cmdScan(br *ziggy.Bridge, args []string) error {
2022-03-07 14:57:42 +00:00
r, err := br.FindLights()
if err != nil {
return err
}
for resp := range r.Success {
2022-03-07 14:57:42 +00:00
log.Info().Msg(resp)
}
var count = 0
timer := time.NewTimer(5 * time.Second)
var newLights []string
loop:
for {
select {
case <-timer.C:
break loop
default:
newl, _ := br.GetNewLights()
if len(newl.Lights) <= count {
time.Sleep(250 * time.Millisecond)
print(".")
continue
}
count = len(newl.Lights)
timer.Reset(5 * time.Second)
newLights = append(newLights, newl.Lights...)
}
}
for _, nl := range newLights {
log.Info().Str("caller", nl).Msg("discovered light")
}
return nil
}
const bulb = ``
2023-01-15 06:59:56 +00:00
var (
history []string
histLoaded bool
)
func loadHist() {
var histMap = make(map[string]bool)
pth, _ := filepath.Split(config.Filename)
rb, _ := os.OpenFile(filepath.Join(pth, ".ziggs_history"), os.O_RDONLY, 0644)
xerox := bufio.NewScanner(rb)
for xerox.Scan() {
_, ok := histMap[strings.TrimSpace(xerox.Text())]
switch {
case strings.TrimSpace(xerox.Text()) == "":
continue
case ok:
continue
default:
histMap[strings.TrimSpace(xerox.Text())] = true
history = append(history, xerox.Text())
}
}
histLoaded = true
}
2022-07-31 08:23:26 +00:00
func getHist() []string {
2023-01-15 06:59:56 +00:00
if !histLoaded {
loadHist()
2023-01-15 06:59:56 +00:00
}
return history
}
func saveHist() {
pth, _ := filepath.Split(config.Filename)
_ = os.WriteFile(filepath.Join(pth, ".ziggs_history"), []byte(strings.Join(history, "\n")), 0644)
2022-07-31 08:23:26 +00:00
}
2022-03-07 14:57:42 +00:00
func StartCLI() {
log = config.GetLogger()
2022-09-06 00:29:02 +00:00
processBridges()
2022-10-12 12:50:02 +00:00
grpmap := ziggy.GetGroupMap()
2022-09-06 00:29:02 +00:00
processGroups(grpmap)
processLights()
prompt = cli.New(
2022-03-07 14:57:42 +00:00
executor,
completer,
// cli.OptionPrefixBackgroundColor(cli.Black),
cli.OptionPrefixTextColor(cli.Yellow),
2022-07-31 08:23:26 +00:00
cli.OptionHistory(getHist()),
2022-03-07 14:57:42 +00:00
cli.OptionSuggestionBGColor(cli.Black),
cli.OptionSuggestionTextColor(cli.White),
cli.OptionSelectedSuggestionBGColor(cli.Black),
cli.OptionSelectedSuggestionTextColor(cli.Green),
cli.OptionLivePrefix(
func() (prefix string, useLivePrefix bool) {
2022-09-06 00:29:02 +00:00
if len(ziggy.Lucifer.Bridges) == 1 {
2022-09-22 03:48:13 +00:00
for brid := range ziggy.Lucifer.Bridges {
2022-09-06 00:29:02 +00:00
sel.Bridge = brid
}
2022-03-07 14:57:42 +00:00
}
2022-09-06 00:29:02 +00:00
return fmt.Sprintf("ziggs[%s] %s ", sel.String(), bulb), true
2022-03-07 14:57:42 +00:00
}),
cli.OptionTitle("ziggs"),
2023-01-15 06:59:56 +00:00
// cli.OptionCompletionOnDown(),
2022-07-29 10:44:08 +00:00
)
2022-03-07 14:57:42 +00:00
2022-09-06 00:29:02 +00:00
prompt.Run()
2022-03-07 14:57:42 +00:00
}