removed 'watcher' in favor of 'scanner'
This commit is contained in:
parent
3cf0e9f857
commit
fd4347ca75
7 changed files with 81 additions and 94 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
@ -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",
|
||||||
|
|
|
@ -14,7 +14,8 @@ configuration is entirely done via environment variables.
|
||||||
| variable | default | description |
|
| variable | default | description |
|
||||||
| --------------------------- | ----------------- | -----------------------------------------------------------|
|
| --------------------------- | ----------------- | -----------------------------------------------------------|
|
||||||
| 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 |
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
|
||||||
}
|
|
4
main.go
4
main.go
|
@ -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
66
scanner/scanner.go
Normal 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")
|
||||||
|
}
|
Loading…
Reference in a new issue