removed 'watcher' in favor of 'scanner'

This commit is contained in:
Daniel Sommer 2023-11-23 16:57:43 +01:00
parent 3cf0e9f857
commit fd4347ca75
7 changed files with 81 additions and 94 deletions

2
.vscode/launch.json vendored
View file

@ -10,6 +10,7 @@
"env":{ "env":{
"SLIDESHOW_INTERVAL": "10", "SLIDESHOW_INTERVAL": "10",
"SLIDESHOW_DIRECTORY": "/home/velvettear/images", "SLIDESHOW_DIRECTORY": "/home/velvettear/images",
"SLIDESHOW_SCANINTERVAL": "10",
"SLIDESHOW_RESOLUTION": "600x1024", "SLIDESHOW_RESOLUTION": "600x1024",
"SLIDESHOW_LOGLEVEL": "debug", "SLIDESHOW_LOGLEVEL": "debug",
"SLIDESHOW_PALETTE": "/tmp/.slideshow.palette", "SLIDESHOW_PALETTE": "/tmp/.slideshow.palette",
@ -27,6 +28,7 @@
"env":{ "env":{
"SLIDESHOW_INTERVAL": "10", "SLIDESHOW_INTERVAL": "10",
"SLIDESHOW_DIRECTORY": "/home/velvettear/images", "SLIDESHOW_DIRECTORY": "/home/velvettear/images",
"SLIDESHOW_SCANINTERVAL": "10",
"SLIDESHOW_LOGLEVEL": "debug", "SLIDESHOW_LOGLEVEL": "debug",
"SLIDESHOW_PALETTE": "/tmp/.slideshow.palette", "SLIDESHOW_PALETTE": "/tmp/.slideshow.palette",
"SLIDESHOW_PALETTE_ALGORITHM": "wsm", "SLIDESHOW_PALETTE_ALGORITHM": "wsm",

View file

@ -15,6 +15,7 @@ configuration is entirely done via environment variables.
| --------------------------- | ----------------- | -----------------------------------------------------------| | --------------------------- | ----------------- | -----------------------------------------------------------|
| SLIDESHOW_INTERVAL | 60 | the interval of the slideshow in seconds | | 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_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 | | path to a file where the color palette will be stored |
| SLIDESHOW_PALETTE_ALGORITHM | "wsm" | the algorithm used to generate the color palette | | SLIDESHOW_PALETTE_ALGORITHM | "wsm" | the algorithm used to generate the color palette |

View file

@ -11,6 +11,7 @@ import (
var Interval time.Duration var Interval time.Duration
var Directory string var Directory string
var ScanInterval time.Duration
var Resolution string var Resolution string
var PaletteFile string var PaletteFile string
var PaletteAlgorithm int var PaletteAlgorithm int
@ -39,6 +40,11 @@ func Initialize() {
if !stats.IsDir() { if !stats.IsDir() {
loggo.Fatal("configured directory '" + Directory + "' is not a valid directory") 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") Resolution = os.Getenv("SLIDESHOW_RESOLUTION")
if len(Resolution) > 0 { if len(Resolution) > 0 {
width, height, found := strings.Cut(Resolution, "x") width, height, found := strings.Cut(Resolution, "x")

View file

@ -11,7 +11,7 @@ import (
"git.velvettear.de/velvettear/loggo" "git.velvettear.de/velvettear/loggo"
"git.velvettear.de/velvettear/slideshow/internal/config" "git.velvettear.de/velvettear/slideshow/internal/config"
"git.velvettear.de/velvettear/slideshow/internal/watcher" "git.velvettear.de/velvettear/slideshow/scanner"
) )
// remember last shown image // remember last shown image
@ -28,7 +28,7 @@ func Start() {
var palette []color.Color var palette []color.Color
var data []byte var data []byte
for { for {
image = watcher.GetRandomImage() image = scanner.GetRandomImage()
if image != previousImage { if image != previousImage {
break break
} }
@ -47,7 +47,7 @@ func Start() {
palette, _ = getColorPalette(image) palette, _ = getColorPalette(image)
} }
if sleepTime > 0 { 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) time.Sleep(sleepTime)
} }
go exportPalette(palette) go exportPalette(palette)

View file

@ -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")
}

View file

@ -7,7 +7,7 @@ import (
"git.velvettear.de/velvettear/loggo" "git.velvettear.de/velvettear/loggo"
"git.velvettear.de/velvettear/slideshow/internal/config" "git.velvettear.de/velvettear/slideshow/internal/config"
"git.velvettear.de/velvettear/slideshow/internal/slideshow" "git.velvettear.de/velvettear/slideshow/internal/slideshow"
"git.velvettear.de/velvettear/slideshow/internal/watcher" "git.velvettear.de/velvettear/slideshow/scanner"
) )
func main() { func main() {
@ -16,7 +16,7 @@ func main() {
var waitgroup sync.WaitGroup var waitgroup sync.WaitGroup
waitgroup.Add(1) waitgroup.Add(1)
config.Initialize() config.Initialize()
watcher.Initialize(config.Directory) scanner.Initialize()
slideshow.Start() slideshow.Start()
waitgroup.Wait() waitgroup.Wait()
loggo.InfoTimed("slideshow is shutting down now!", timestamp) loggo.InfoTimed("slideshow is shutting down now!", timestamp)

66
scanner/scanner.go Normal file
View file

@ -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")
}