From 77bd37ca907aee2645db6c4b88d27fcc7b8829c1 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 26 Sep 2023 22:04:58 +0100 Subject: [PATCH 1/2] feature: onfileindir --- cmd/OliveTin/main.go | 2 + internal/config/config.go | 26 +++++----- internal/onfileindir/fileindir.go | 85 +++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 internal/onfileindir/fileindir.go diff --git a/cmd/OliveTin/main.go b/cmd/OliveTin/main.go index c6ca646..91cbf96 100644 --- a/cmd/OliveTin/main.go +++ b/cmd/OliveTin/main.go @@ -9,6 +9,7 @@ import ( grpcapi "github.com/OliveTin/OliveTin/internal/grpcapi" "github.com/OliveTin/OliveTin/internal/installationinfo" "github.com/OliveTin/OliveTin/internal/oncron" + "github.com/OliveTin/OliveTin/internal/onfileindir" "github.com/OliveTin/OliveTin/internal/onstartup" updatecheck "github.com/OliveTin/OliveTin/internal/updatecheck" "github.com/OliveTin/OliveTin/internal/websocket" @@ -115,6 +116,7 @@ func main() { go onstartup.Execute(cfg, executor) go oncron.Schedule(cfg, executor) + go onfileindir.WatchFilesInDirectory(cfg, executor) go updatecheck.StartUpdateChecker(version, commit, cfg, configDir) diff --git a/internal/config/config.go b/internal/config/config.go index fdb6e98..3f9348c 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -3,18 +3,20 @@ package config // Action represents the core functionality of OliveTin - commands that show up // as buttons in the UI. type Action struct { - ID string - Title string - Icon string - Shell string - CSS map[string]string `mapstructure:"omitempty"` - Timeout int - Acls []string - ExecOnStartup bool - ExecOnCron []string - MaxConcurrent int - Arguments []ActionArgument - PopupOnStart bool + ID string + Title string + Icon string + Shell string + CSS map[string]string `mapstructure:"omitempty"` + Timeout int + Acls []string + ExecOnStartup bool + ExecOnCron []string + ExecOnFileCreatedInDir []string + ExecOnFileChangedInDir []string + MaxConcurrent int + Arguments []ActionArgument + PopupOnStart bool } // ActionArgument objects appear on Actions. diff --git a/internal/onfileindir/fileindir.go b/internal/onfileindir/fileindir.go new file mode 100644 index 0000000..b3eb836 --- /dev/null +++ b/internal/onfileindir/fileindir.go @@ -0,0 +1,85 @@ +package onfileindir + +import ( + "github.com/OliveTin/OliveTin/internal/acl" + "github.com/OliveTin/OliveTin/internal/config" + "github.com/OliveTin/OliveTin/internal/executor" + "github.com/fsnotify/fsnotify" + log "github.com/sirupsen/logrus" +) + +func WatchFilesInDirectory(cfg *config.Config, ex *executor.Executor) { + for _, action := range cfg.Actions { + for _, dirname := range action.ExecOnFileChangedInDir { + watch(dirname, action, cfg, ex, fsnotify.Write) + } + + for _, dirname := range action.ExecOnFileCreatedInDir { + watch(dirname, action, cfg, ex, fsnotify.Create) + } + } +} + +func watch(directory string, action config.Action, cfg *config.Config, ex *executor.Executor, eventType fsnotify.Op) { + log.WithFields(log.Fields{ + "dir": directory, + "eventType": eventType, + }).Infof("Watching dir") + + watcher, err := fsnotify.NewWatcher() + + if err != nil { + log.Errorf("Could not watch for files being created: %v", err) + return + } + + defer watcher.Close() + + done := make(chan bool) + + go func() { + for { + processEvent(watcher, action, cfg, ex, eventType) + } + }() + + err = watcher.Add("/tmp") + + if err != nil { + log.Errorf("Could not create watcher: %v", err) + } + + <-done +} + +func processEvent(watcher *fsnotify.Watcher, action config.Action, cfg *config.Config, ex *executor.Executor, eventType fsnotify.Op) { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + + checkEvent(&event, action, cfg, ex, eventType) + case err := <-watcher.Errors: + log.Errorf("Error in fsnotify: %v", err) + return + } +} + +func checkEvent(event *fsnotify.Event, action config.Action, cfg *config.Config, ex *executor.Executor, eventType fsnotify.Op) { + if event.Has(eventType) { + req := &executor.ExecutionRequest{ + ActionName: action.Title, + Cfg: cfg, + Tags: []string{"fileindir"}, + Arguments: map[string]string{ + "filename": event.Name, + }, + AuthenticatedUser: &acl.AuthenticatedUser{ + Username: "fileindir", + }, + } + + ex.ExecRequest(req) + } +} From 75a9697586ccfad43d4a353094c906e5e45094e6 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 26 Sep 2023 22:09:42 +0100 Subject: [PATCH 2/2] fmt: ActionButton.js --- webui/js/ActionButton.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webui/js/ActionButton.js b/webui/js/ActionButton.js index 694218e..317e2ad 100644 --- a/webui/js/ActionButton.js +++ b/webui/js/ActionButton.js @@ -53,8 +53,8 @@ class ActionButton extends window.HTMLElement { } } - getUniqueId() { - if (window.isSecureContext) { + getUniqueId () { + if (window.isSecureContext) { return window.crypto.randomUUID() } else { return Date.now()