sampler-fork/trigger/trigger.go

112 lines
2.0 KiB
Go

package trigger
import (
"fmt"
"github.com/sqshq/sampler/asset"
"github.com/sqshq/sampler/config"
"os"
"os/exec"
)
const (
TrueIndicator = "1"
BellCharacter = "\a"
)
type Trigger struct {
title string
condition string
actions Actions
data map[string]Data
}
type Actions struct {
terminalBell bool
sound bool
visual bool
script *string
}
type Data struct {
previousValue interface{}
currentValue interface{}
}
func NewTriggers(configs []config.TriggerConfig) []Trigger {
triggers := make([]Trigger, len(configs))
for _, c := range configs {
triggers = append(triggers, NewTrigger(c))
}
return triggers
}
func NewTrigger(config config.TriggerConfig) Trigger {
return Trigger{
title: config.Title,
condition: config.Condition,
data: make(map[string]Data),
actions: Actions{
terminalBell: *config.Actions.TerminalBell,
sound: *config.Actions.Sound,
visual: *config.Actions.Visual,
script: config.Actions.Script,
},
}
}
func (t Trigger) Execute(label string, value interface{}) {
if data, ok := t.data[label]; ok {
data.previousValue = data.currentValue
data.currentValue = value
} else {
t.data[label] = Data{previousValue: nil, currentValue: value}
}
t.evaluate(label, t.data[label])
}
func (t Trigger) evaluate(label string, data Data) {
output, err := runScript(t.condition, label, data)
if err != nil {
//println(err) // TODO visual notification
}
if string(output) != TrueIndicator {
return
}
if t.actions.terminalBell {
fmt.Print(BellCharacter)
}
if t.actions.sound {
_ = asset.Beep()
}
if t.actions.visual {
// TODO visual notification
}
if t.actions.script != nil {
_, _ = runScript(*t.actions.script, label, data)
}
}
func runScript(script, label string, data Data) ([]byte, error) {
cmd := exec.Command("sh", "-c", script)
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env,
fmt.Sprintf("prev=%v", data.previousValue),
fmt.Sprintf("cur=%v", data.currentValue),
fmt.Sprintf("label=%v", label))
return cmd.Output()
}