slideshow-api/internal/scanner.go

88 lines
2.3 KiB
Go

package internal
import (
"errors"
"io/fs"
"math/rand"
"path/filepath"
"strconv"
"strings"
"time"
"git.velvettear.de/velvettear/loggo"
"git.velvettear.de/velvettear/slideshow-api/internal/config"
)
// map of images
var images map[string]string
// temporary map of images
var tmpImages map[string]string
// Scan the specified directory
func Scan() {
timestamp := time.Now()
directory := config.Directory
loggo.Info("scanning directory for images and subdirectories...", "interval: "+strconv.FormatFloat(config.ScanInterval.Seconds(), 'f', 0, 64)+" seconds", "directory: "+directory)
tmpImages = make(map[string]string)
filepath.WalkDir(directory, checkDirectory)
images = tmpImages
tmpImages = nil
loggo.InfoTimed("found "+strconv.Itoa(len(images))+" image(s)", timestamp.UnixMilli())
go scheduleRescan()
}
// get a random image
func GetRandomImage() (string, error) {
if len(images) == 0 {
return "", errors.New("no images have been found in directory '" + config.Directory + "'")
}
random := rand.Intn(len(images))
index := 0
for key := range images {
if index == random {
return key, nil
}
index++
}
return "", errors.New("could not find a random image with index '" + strconv.Itoa(random) + "'")
}
// get the path of an image by name
func GetImagePath(name string) (string, error) {
var path string
if len(name) == 0 {
return path, errors.New("no image name provided")
}
image := images[name]
if len(image) == 0 {
return path, errors.New("could not find image '" + name + "' in internal map")
}
return image, nil
}
// sleep the specified interval and then trigger a rescan of the specified directory
func scheduleRescan() {
loggo.Debug("sleeping for " + strconv.FormatInt(config.ScanInterval.Milliseconds(), 10) + "ms before next scan...")
time.Sleep(config.ScanInterval)
Scan()
}
// add image files to the map of images
func checkDirectory(path string, dir fs.DirEntry, err error) error {
if err != nil {
return err
}
if dir.IsDir() || !isImage(path) {
return nil
}
tmpImages[filepath.Base(path)] = path
loggo.Debug("added image to temporary map 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")
}