diff --git a/README.md b/README.md index cb8e7f7..92878f3 100644 --- a/README.md +++ b/README.md @@ -142,4 +142,4 @@ return totalCount - [streamdeck-sdk-go](https://github.com/tystuyfzand/streamdeck-sdk-go) - StreamDeck SDK for Go - [streamdeck-easypi](https://github.com/BarRaider/streamdeck-easypi) - EasyPI for StreamDeck - [gopher-lua](https://github.com/yuin/gopher-lua) - Lua VM in Go -- [gjson](https://github.com/tidwall/gjson) - JSON parser for Go \ No newline at end of file +- [gjson](https://github.com/tidwall/gjson) - JSON parser for Go diff --git a/main.go b/main.go index dd96a08..3fb7438 100644 --- a/main.go +++ b/main.go @@ -68,12 +68,13 @@ func main() { return } - if err = manager.StartAsync(event.Context); err != nil { + if err = manager.StartAsync(event.Context, true); err != nil { lg.Err(err).Send() return } }) sdk.AddHandler(func(event *sdk.WillDisappearEvent) { + defer recoverPanic() if event.Payload == nil { return } @@ -84,13 +85,19 @@ func main() { }) sdk.AddHandler(func(event *sdk.ReceiveSettingsEvent) { + defer recoverPanic() if err := manager.SetInstanceConfig(event.Context, event.Settings); err != nil { lg.Err(err).Send() return } + if err := manager.StartAsync(event.Context, false); err != nil { + lg.Err(err).Send() + return + } }) sdk.AddHandler(func(event *sdk.KeyDownEvent) { + defer recoverPanic() if err := manager.KeyPressed(event.Context); err != nil { lg.Err(err).Send() return diff --git a/pkg/common/config.go b/pkg/common/config.go index fe3baef..451ff78 100644 --- a/pkg/common/config.go +++ b/pkg/common/config.go @@ -11,6 +11,7 @@ type Config struct { TitlePrefix string `json:"titlePrefix"` BodyScript string `json:"bodyScript"` ShowSuccessNotification bool `json:"showSuccessNotification"` + InsecureSkipVerify bool `json:"insecureSkipVerify"` MethodType string `json:"methodType"` Body string `json:"body"` } diff --git a/pkg/executor/executor.go b/pkg/executor/executor.go index 49a8ba1..e2f770f 100644 --- a/pkg/executor/executor.go +++ b/pkg/executor/executor.go @@ -2,6 +2,7 @@ package executor import ( "context" + "crypto/tls" "strings" "github.com/cockroachdb/errors" @@ -28,7 +29,11 @@ func (e *Executor) Execute( ctx context.Context, executeReq ExecuteRequest, ) (*ExecuteResponse, error) { - httpReq := req.C().NewRequest() + client := req.C() + if executeReq.Config.InsecureSkipVerify { + client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) + } + httpReq := client.NewRequest() httpReq = httpReq.SetContext(ctx) httpReq.Method = executeReq.Config.MethodType diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go index 6fc7e09..7309ee0 100644 --- a/pkg/instance/instance.go +++ b/pkg/instance/instance.go @@ -77,7 +77,7 @@ func (i *DefaultInstance) ShowOk() { i.sdk.ShowOk(i.ctxID) } -func (i *DefaultInstance) StartAsync() { +func (i *DefaultInstance) StartAsync(immediate bool) { i.mut.Lock() defer i.mut.Unlock() @@ -87,18 +87,18 @@ func (i *DefaultInstance) StartAsync() { i.ctx = ctx i.ctxCancel = cancel - go i.run() + go i.run(immediate) } -func (i *DefaultInstance) run() { - ctx := i.ctx - - for ctx.Err() == nil { - interval := 30 - if i.cfg.IntervalSeconds > 0 { - interval = i.cfg.IntervalSeconds +func (i *DefaultInstance) run(immediate bool) { + defer func() { + if rec := recover(); rec != nil { + log.Error().Msgf("panic in run: %v", rec) } + }() + ctx := i.ctx + if immediate { newLogger := log.With(). Str("id", uuid.NewString()). Str("ctxID", i.ctxID). @@ -109,14 +109,43 @@ func (i *DefaultInstance) run() { i.ExecuteSingleRequest(innerCtx) innerCancel() + } - time.Sleep(time.Duration(interval) * time.Second) + if i.cfg == nil || i.cfg.IntervalSeconds <= 0 { + return + } + + ticker := time.NewTicker(time.Duration(i.cfg.IntervalSeconds) * time.Second) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + newLogger := log.With(). + Str("id", uuid.NewString()). + Str("ctxID", i.ctxID). + Logger() + + innerCtx, innerCancel := context.WithCancel(ctx) + innerCtx = newLogger.WithContext(innerCtx) + + i.ExecuteSingleRequest(innerCtx) + innerCancel() + } } } func (i *DefaultInstance) ExecuteSingleRequest( ctx context.Context, ) { + if i.cfg == nil { + zerolog.Ctx(ctx).Error().Msg("config is nil, cannot execute request") + i.ShowAlert() + return + } + resp, err := i.executor.Execute(ctx, executor.ExecuteRequest{ Config: *i.cfg, }) @@ -221,9 +250,32 @@ func (i *DefaultInstance) stopWithoutLock() { } func (i *DefaultInstance) KeyPressed() error { + i.mut.Lock() + defer i.mut.Unlock() + + if i.cfg == nil { + i.ShowAlert() + return errors.New("instance config is nil") + } + targetUrl := i.cfg.BrowserUrl if targetUrl == "" { - targetUrl = i.cfg.ApiUrl + ctx := i.ctx + if ctx == nil { + ctx = context.Background() + } + + newLogger := log.With(). + Str("id", uuid.NewString()). + Str("ctxID", i.ctxID). + Logger() + + innerCtx, innerCancel := context.WithCancel(ctx) + defer innerCancel() + innerCtx = newLogger.WithContext(innerCtx) + + i.ExecuteSingleRequest(innerCtx) + return nil } targetUrl, err := utils.ExecuteTemplate(targetUrl, i.cfg.TemplateParameters) diff --git a/pkg/instance/interfaces.go b/pkg/instance/interfaces.go index dcbcd6d..d8a9fac 100644 --- a/pkg/instance/interfaces.go +++ b/pkg/instance/interfaces.go @@ -30,7 +30,7 @@ type Factory interface { type Instance interface { SetConfig(payload *fastjson.Value) error - StartAsync() + StartAsync(immediate bool) Stop() KeyPressed() error } diff --git a/pkg/instance/manager.go b/pkg/instance/manager.go index afe1175..5b94c91 100644 --- a/pkg/instance/manager.go +++ b/pkg/instance/manager.go @@ -36,7 +36,7 @@ func (m *Manager) InitInstance(ctxId string) (Instance, error) { return instance, nil } -func (m *Manager) StartAsync(ctxId string) error { +func (m *Manager) StartAsync(ctxId string, immediate bool) error { m.mut.Lock() defer m.mut.Unlock() instance, ok := m.instances[ctxId] @@ -45,7 +45,7 @@ func (m *Manager) StartAsync(ctxId string) error { return errors.New("instance not found") } - instance.StartAsync() + instance.StartAsync(immediate) return nil } diff --git a/pkg/instance/manager_test.go b/pkg/instance/manager_test.go index 03e203d..b438ce6 100644 --- a/pkg/instance/manager_test.go +++ b/pkg/instance/manager_test.go @@ -20,14 +20,14 @@ func TestNewManager(t *testing.T) { mockInstance := NewMockInstance(gomock.NewController(t)) factory.EXPECT().Create(ctxID).Return(mockInstance) - mockInstance.EXPECT().StartAsync() + mockInstance.EXPECT().StartAsync(gomock.Any()) mockInstance.EXPECT().Stop() mockInstance.EXPECT().KeyPressed() _, err := mgr.InitInstance(ctxID) assert.Nil(t, err) - assert.NoError(t, mgr.StartAsync(ctxID)) + assert.NoError(t, mgr.StartAsync(ctxID, true)) assert.NoError(t, mgr.KeyPressed(ctxID)) js := &fastjson.Value{} @@ -43,7 +43,7 @@ func TestNotExist(t *testing.T) { ctxID := "1231231" - assert.ErrorContains(t, mgr.StartAsync(ctxID), "instance not found") + assert.ErrorContains(t, mgr.StartAsync(ctxID, true), "instance not found") assert.ErrorContains(t, mgr.KeyPressed(ctxID), "instance not found") assert.ErrorContains(t, mgr.SetInstanceConfig(ctxID, nil), "instance not found") assert.NoError(t, mgr.Stop(ctxID)) diff --git a/resources/pi/pi.html b/resources/pi/pi.html index 16698bd..2014fb7 100644 --- a/resources/pi/pi.html +++ b/resources/pi/pi.html @@ -56,7 +56,7 @@
Interval (Sec)
- +
Indicator
@@ -66,8 +66,14 @@
-
- +
+
+
Invalid certs
+
+
+ + +