From fd4347ca75978b3ae6c1f9afdfa908ec3a8edcd4 Mon Sep 17 00:00:00 2001 From: velvettear Date: Thu, 23 Nov 2023 16:57:43 +0100 Subject: [PATCH] removed 'watcher' in favor of 'scanner' --- .vscode/launch.json | 2 + README.md | 3 +- internal/config/config.go | 6 +++ internal/slideshow/slideshow.go | 6 +-- internal/watcher/watcher.go | 88 --------------------------------- main.go | 4 +- scanner/scanner.go | 66 +++++++++++++++++++++++++ 7 files changed, 81 insertions(+), 94 deletions(-) delete mode 100644 internal/watcher/watcher.go create mode 100644 scanner/scanner.go diff --git a/.vscode/launch.json b/.vscode/launch.json index 01b3f23..934ef79 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,6 +10,7 @@ "env":{ "SLIDESHOW_INTERVAL": "10", "SLIDESHOW_DIRECTORY": "/home/velvettear/images", + "SLIDESHOW_SCANINTERVAL": "10", "SLIDESHOW_RESOLUTION": "600x1024", "SLIDESHOW_LOGLEVEL": "debug", "SLIDESHOW_PALETTE": "/tmp/.slideshow.palette", @@ -27,6 +28,7 @@ "env":{ "SLIDESHOW_INTERVAL": "10", "SLIDESHOW_DIRECTORY": "/home/velvettear/images", + "SLIDESHOW_SCANINTERVAL": "10", "SLIDESHOW_LOGLEVEL": "debug", "SLIDESHOW_PALETTE": "/tmp/.slideshow.palette", "SLIDESHOW_PALETTE_ALGORITHM": "wsm", diff --git a/README.md b/README.md index 46d5637..6f36882 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ configuration is entirely done via environment variables. | variable | default | description | | --------------------------- | ----------------- | -----------------------------------------------------------| | SLIDESHOW_INTERVAL | 60 | the interval of the slideshow in seconds | -| SLIDESHOW_DIRECTORY | "$HOME" | path to a directory containing images | +| SLIDESHOW_DIRECTORY | "$HOME" | path to a directory containing images | +| SLIDESHOW_SCANINTERVAL | 60 | the interval for directory scans in seconds | SLIDESHOW_RESOLUTION | | the resolution to which images are scaled (i.e. 1920x1080) | | SLIDESHOW_PALETTE | | path to a file where the color palette will be stored | | SLIDESHOW_PALETTE_ALGORITHM | "wsm" | the algorithm used to generate the color palette | diff --git a/internal/config/config.go b/internal/config/config.go index 2c85589..fa0097b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -11,6 +11,7 @@ import ( var Interval time.Duration var Directory string +var ScanInterval time.Duration var Resolution string var PaletteFile string var PaletteAlgorithm int @@ -39,6 +40,11 @@ func Initialize() { if !stats.IsDir() { loggo.Fatal("configured directory '" + Directory + "' is not a valid directory") } + tmpInt, _ = strconv.Atoi(os.Getenv("SLIDESHOW_SCANINTERVAL")) + if tmpInt <= 0 { + tmpInt = 60 + } + ScanInterval = time.Duration(tmpInt) * time.Second Resolution = os.Getenv("SLIDESHOW_RESOLUTION") if len(Resolution) > 0 { width, height, found := strings.Cut(Resolution, "x") diff --git a/internal/slideshow/slideshow.go b/internal/slideshow/slideshow.go index 971ce9a..873ce02 100644 --- a/internal/slideshow/slideshow.go +++ b/internal/slideshow/slideshow.go @@ -11,7 +11,7 @@ import ( "git.velvettear.de/velvettear/loggo" "git.velvettear.de/velvettear/slideshow/internal/config" - "git.velvettear.de/velvettear/slideshow/internal/watcher" + "git.velvettear.de/velvettear/slideshow/scanner" ) // remember last shown image @@ -28,7 +28,7 @@ func Start() { var palette []color.Color var data []byte for { - image = watcher.GetRandomImage() + image = scanner.GetRandomImage() if image != previousImage { break } @@ -47,7 +47,7 @@ func Start() { palette, _ = getColorPalette(image) } if sleepTime > 0 { - loggo.Debug("sleeping for " + strconv.FormatInt(sleepTime.Milliseconds(), 10) + "ms") + loggo.Debug("sleeping for " + strconv.FormatInt(sleepTime.Milliseconds(), 10) + "ms before next image will be displayed...") time.Sleep(sleepTime) } go exportPalette(palette) diff --git a/internal/watcher/watcher.go b/internal/watcher/watcher.go deleted file mode 100644 index cacad21..0000000 --- a/internal/watcher/watcher.go +++ /dev/null @@ -1,88 +0,0 @@ -package watcher - -import ( - "io/fs" - "math/rand" - "path/filepath" - "strconv" - "strings" - "time" - - "git.velvettear.de/velvettear/loggo" - "github.com/fsnotify/fsnotify" -) - -// the watcher -var watcher *fsnotify.Watcher - -// slice of images -var images []string - -// initialize the watcher -func Initialize(directory string) { - timestamp := time.Now().UnixMilli() - tmp, error := fsnotify.NewWatcher() - if error != nil { - loggo.FatalTimed("encountered an error initializing the watcher", timestamp, error.Error()) - } - watcher = tmp - loggo.Info("scanning directory for images and subdirectories...", directory) - filepath.WalkDir(directory, checkDirectory) - loggo.InfoTimed("found "+strconv.Itoa(len(images))+" images "+strconv.Itoa(len(watcher.WatchList()))+" directories to watch", timestamp) - go func() { - for { - event := <-watcher.Events - if !isImage(event.Name) { - continue - } - if event.Has(fsnotify.Create) { - images = append(images, event.Name) - loggo.Debug("added image to slice of images", event.Name) - } else if event.Has(fsnotify.Remove) { - for index, tmp := range images { - if tmp != event.Name { - continue - } - images = append(images[:index], images[index+1:]...) - loggo.Debug("removed image from slice of images", event.Name) - } - } - } - }() -} - -// stop the watcher -func Stop() { - error := watcher.Close() - if error != nil { - loggo.Fatal("encountered an error closing the watcher", error.Error()) - } -} - -// get a random image -func GetRandomImage() string { - return images[rand.Intn(len(images))] -} - -// add image files to the slice of images and subdirectoies to the watcher -func checkDirectory(path string, dir fs.DirEntry, err error) error { - if err != nil { - return err - } - if dir.IsDir() { - watcher.Add(path) - loggo.Debug("added directory to watcher", path) - return nil - } - if !isImage(path) { - return nil - } - images = append(images, path) - loggo.Debug("added image to slice of images", path) - return nil -} - -// check if a file is an image -func isImage(file string) bool { - return strings.HasSuffix(file, ".jpeg") || strings.HasSuffix(file, ".jpg") || strings.HasSuffix(file, ".png") -} diff --git a/main.go b/main.go index 9dd693c..67f3432 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,7 @@ import ( "git.velvettear.de/velvettear/loggo" "git.velvettear.de/velvettear/slideshow/internal/config" "git.velvettear.de/velvettear/slideshow/internal/slideshow" - "git.velvettear.de/velvettear/slideshow/internal/watcher" + "git.velvettear.de/velvettear/slideshow/scanner" ) func main() { @@ -16,7 +16,7 @@ func main() { var waitgroup sync.WaitGroup waitgroup.Add(1) config.Initialize() - watcher.Initialize(config.Directory) + scanner.Initialize() slideshow.Start() waitgroup.Wait() loggo.InfoTimed("slideshow is shutting down now!", timestamp) diff --git a/scanner/scanner.go b/scanner/scanner.go new file mode 100644 index 0000000..04fcf09 --- /dev/null +++ b/scanner/scanner.go @@ -0,0 +1,66 @@ +package scanner + +import ( + "io/fs" + "math/rand" + "path/filepath" + "strconv" + "strings" + "time" + + "git.velvettear.de/velvettear/loggo" + "git.velvettear.de/velvettear/slideshow/internal/config" +) + +// slice of images +var images []string + +// temporary slice of images +var tmpImages []string + +// scan the specified directories for images +func Initialize() { + directory := config.Directory + scan(directory) +} + +// get a random image +func GetRandomImage() string { + return images[rand.Intn(len(images))] +} + +// scan the specified directory +func scan(directory string) { + timestamp := time.Now().UnixMilli() + loggo.Info("scanning directory for images and subdirectories...", directory) + filepath.WalkDir(directory, checkDirectory) + images = tmpImages + tmpImages = nil + loggo.InfoTimed("found "+strconv.Itoa(len(images))+" image(s)", timestamp) + go scheduleRescan(directory) +} + +// sleep the specified interval and then trigger a rescan of the specified directory +func scheduleRescan(directory string) { + loggo.Debug("sleeping for " + strconv.FormatInt(config.Interval.Milliseconds(), 10) + "ms before next scan...") + time.Sleep(config.ScanInterval) + scan(directory) +} + +// add image files to the slice of images and subdirectoies to the watcher +func checkDirectory(path string, dir fs.DirEntry, err error) error { + if err != nil { + return err + } + if dir.IsDir() || !isImage(path) { + return nil + } + tmpImages = append(tmpImages, path) + loggo.Debug("added image to temporary slice of images", path) + return nil +} + +// check if a file is an image +func isImage(file string) bool { + return strings.HasSuffix(file, ".jpeg") || strings.HasSuffix(file, ".jpg") || strings.HasSuffix(file, ".png") +}