package main import ( "context" "fmt" "git.aiterp.net/lucifer/new-server/app/client" "git.aiterp.net/lucifer/new-server/models" "log" "os" "strings" ) func handlerCmd( ctx context.Context, c client.Client, ) { cmd := parseCommand(os.Args[2:]) switch cmd.Name { case "list": handlers, err := c.GetHandlers(ctx) if err != nil { log.Fatalln(err) } WriteHandlerInfoTable(os.Stdout, handlers) case "add": model := models.EventHandler{} // Event name model.EventName = cmd.Params.Get(0).StringOr("") if len(model.EventName) == 0 { log.Fatalln("Event name needed!") } // Search fetchStr := cmd.Params.Get(1).String() if fetchStr == nil { log.Fatalln("Search filter needed!") } model.TargetKind, model.TargetValue = models.ParseFetchString(*fetchStr) model = applyCmdToHandler(model, cmd) newHandler, err := c.AddHandler(ctx, model) if err != nil { log.Fatalln(err) } WriteHandlerInfoTable(os.Stdout, []models.EventHandler{*newHandler}) case "edit": id := cmd.Params.Get(0).IntOr(0) if id == 0 { log.Fatalln("ID missing") } model, err := c.GetHandler(ctx, id) if err != nil { log.Fatalln(err.Error()) } eventStr := cmd.Params.Get("event").String() if eventStr != nil { model.EventName = *eventStr } fetchStr := cmd.Params.Get("search").String() if fetchStr != nil { model.TargetKind, model.TargetValue = models.ParseFetchString(*fetchStr) } modified := applyCmdToHandler(*model, cmd) returned, err := c.PutHandler(ctx, &modified) if err != nil { log.Fatalln(err.Error()) } WriteHandlerInfoTable(os.Stdout, []models.EventHandler{*returned}) case "delete": id := cmd.Params.Get(0).Int() if id == nil { log.Fatalln("ID missing") } handler, err := c.DeleteHandler(ctx, *id) if err != nil { log.Fatalln(err) } WriteHandlerInfoTable(os.Stdout, []models.EventHandler{*handler}) default: if cmd.Name != "help" { log.Println("Unknown command:", cmd.Name) } _, _ = fmt.Fprintln(os.Stderr, helpString[1:]) } } func applyCmdToHandler(model models.EventHandler, cmd Command) models.EventHandler { // Remove keys for _, elem := range cmd.Params.Strings(1) { if !strings.HasPrefix(elem, "-") { continue } keyToRemove := elem[1:] if strings.HasPrefix(keyToRemove, "conditions.") { condKeyToRemove := keyToRemove[11:] delete(model.Conditions, condKeyToRemove) } else if strings.HasPrefix(keyToRemove, "fire.payload.") && model.Actions.FireEvent != nil { firePayloadKeyToRemove := keyToRemove[13:] delete(model.Actions.FireEvent.Payload, firePayloadKeyToRemove) } else { switch keyToRemove { case "set-power": model.Actions.SetPower = nil case "set-color": model.Actions.SetColor = nil case "set-intensity": model.Actions.SetIntensity = nil case "add-intensity": model.Actions.AddIntensity = nil case "fire": fallthrough case "fire.name": model.Actions.FireEvent = nil case "from": model.From = models.Never case "to": model.To = models.Never case "set-scene": model.Actions.SetScene = nil case "push-scene": model.Actions.PushScene = nil } } } // From / To model.From = cmd.Params.Get("from").TimeOfDayOr(models.Never) model.To = cmd.Params.Get("to").TimeOfDayOr(models.Never) if model.From.IsNever() != model.To.IsNever() { log.Fatalln("from and to must be specified together!") } // One shot model.OneShot = cmd.Params.Get("one-shot").StringOr("false") == "true" // Priority model.Priority = cmd.Params.Get("priority").IntOr(100) // Conditions model.Conditions = cmd.Params.Subset("conditions").EventConditions() // Power, Color, Intensity, Temperature nds := cmd.Params.DeviceState("set-") model.Actions.SetPower = nds.Power model.Actions.SetColor = nds.Color model.Actions.SetIntensity = nds.Intensity // Add intensity model.Actions.AddIntensity = cmd.Params.Get("add-intensity").Float() // Fire fireParams := cmd.Params.Subset("fire") fireName := fireParams.Get("name").String() if fireName != nil { firePayloadParams := fireParams.Subset("payload") model.Actions.FireEvent = &models.Event{ Name: *fireName, Payload: make(map[string]string, len(firePayloadParams)), } for key, value := range firePayloadParams.StringMap() { model.Actions.FireEvent.Payload[key] = value } } // Scenes model.Actions.SetScene = cmd.Params.SceneAssignment("set-") model.Actions.PushScene = cmd.Params.SceneAssignment("push-") return model }