diff --git a/push/push.go b/push/push.go new file mode 100644 index 0000000000..9cfb507157 --- /dev/null +++ b/push/push.go @@ -0,0 +1,80 @@ +package push + +import ( + "context" + "encoding/json" + "strings" + + "github.com/evcc-io/evcc/api" + "github.com/evcc-io/evcc/provider" + "github.com/evcc-io/evcc/util" +) + +func init() { + registry.AddCtx(api.Custom, NewConfigurableFromConfig) +} + +// NewConfigurableFromConfig creates Messenger from config +func NewConfigurableFromConfig(ctx context.Context, other map[string]interface{}) (Messenger, error) { + var cc struct { + Send provider.Config + Encoding string + } + + if err := util.DecodeOther(other, &cc); err != nil { + return nil, err + } + + send, err := provider.NewStringSetterFromConfig(ctx, "send", cc.Send) + if err != nil { + return nil, err + } + + return NewConfigurable(send, cc.Encoding) +} + +// NewConfigurable creates a new Messenger +func NewConfigurable(send func(string) error, encoding string) (*Push, error) { + m := &Push{ + log: util.NewLogger("push"), + send: send, + encoding: strings.ToLower(encoding), + } + return m, nil +} + +// Push is a configurable Messenger implementation +type Push struct { + log *util.Logger + send func(string) error + encoding string +} + +// Send implements the Messenger interface +func (m *Push) Send(title, msg string) { + var res string + + switch m.encoding { + case "json": + b, _ := json.Marshal(struct { + Title string `json:"title"` + Msg string `json:"msg"` + }{ + Title: title, + Msg: msg, + }) + res = string(b) + case "csv": + res = title + "," + msg + case "tsv": + res = title + "\t" + msg + case "title": + res = title + default: + res = msg + } + + if err := m.send(res); err != nil { + m.log.ERROR.Printf("send: %v", err) + } +} diff --git a/push/script.go b/push/script.go deleted file mode 100644 index 367aafe507..0000000000 --- a/push/script.go +++ /dev/null @@ -1,85 +0,0 @@ -package push - -import ( - "context" - "errors" - "os/exec" - "strings" - "time" - - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" - "github.com/kballard/go-shellquote" -) - -func init() { - registry.Add("script", NewScriptFromConfig) -} - -// Script implements shell script-based message service and setters -type Script struct { - log *util.Logger - script string - timeout time.Duration -} - -// NewScriptFromConfig creates a Script messenger. Script execution is aborted after given timeout. -func NewScriptFromConfig(other map[string]interface{}) (Messenger, error) { - cc := struct { - CmdLine string - Timeout time.Duration - }{ - Timeout: request.Timeout, - } - - if err := util.DecodeOther(other, &cc); err != nil { - return nil, err - } - - s := &Script{ - log: util.NewLogger("script"), - script: cc.CmdLine, - timeout: cc.Timeout, - } - - return s, nil -} - -// Send calls the script -func (m *Script) Send(title, msg string) { - _, err := m.exec(m.script, title, msg) - if err != nil { - m.log.ERROR.Printf("exec: %v", err) - } -} - -func (m *Script) exec(script, title, msg string) (string, error) { - args, err := shellquote.Split(script) - if err != nil { - return "", err - } - - ctx, cancel := context.WithTimeout(context.Background(), m.timeout) - defer cancel() - - args = append(args, title, msg) - cmd := exec.CommandContext(ctx, args[0], args[1:]...) - b, err := cmd.Output() - - s := strings.TrimSpace(string(b)) - - if err != nil { - // use STDOUT if available - var ee *exec.ExitError - if errors.As(err, &ee) { - s = strings.TrimSpace(string(ee.Stderr)) - } - - m.log.ERROR.Printf("%s: %s", strings.Join(args, " "), s) - return "", err - } - - m.log.DEBUG.Printf("%s: %s", strings.Join(args, " "), s) - - return s, nil -}