Added flag to cache directory scan at startup

This commit is contained in:
Seednode 2022-10-28 17:19:04 -05:00
parent 44972fde78
commit f21c01e085
5 changed files with 78 additions and 37 deletions

View File

@ -60,6 +60,7 @@ Available Commands:
version Print version
Flags:
-c, --cache only scan directories once, at startup
-f, --filter enable filtering via query parameters
-h, --help help for roulette
-p, --port uint16 port to listen on (default 8080)

View File

@ -105,12 +105,26 @@ func preparePath(path string) string {
return path
}
func appendPath(directory, path string, files *Files, stats *Stats) {
func appendPath(directory, path string, files *Files, stats *Stats) error {
// If caching, check for valid images here, to speed up future pickFile() calls
if Cache {
image, err := isImage(path)
if err != nil {
return err
}
if !image {
return nil
}
}
files.Mutex.Lock()
files.List[directory] = append(files.List[directory], path)
files.Mutex.Unlock()
stats.IncrementFilesMatched()
return nil
}
func appendPaths(path string, files *Files, filters *Filters, stats *Stats) error {
@ -142,7 +156,10 @@ func appendPaths(path string, files *Files, filters *Filters, stats *Stats) erro
filename,
filters.Includes[i],
) {
appendPath(directory, path, files, stats)
err := appendPath(directory, path, files, stats)
if err != nil {
return err
}
return nil
}
@ -153,7 +170,10 @@ func appendPaths(path string, files *Files, filters *Filters, stats *Stats) erro
return nil
}
appendPath(directory, path, files, stats)
err = appendPath(directory, path, files, stats)
if err != nil {
return err
}
return nil
}
@ -418,45 +438,61 @@ func prepareDirectories(files *Files, sort string) []string {
return directories
}
func pickFile(args []string, filters *Filters, sort string) (string, error) {
files := Files{}
files.List = make(map[string][]string)
func pickFile(args []string, filters *Filters, sort string, fileCache *[]string) (string, error) {
var fileList []string
stats := Stats{}
if Cache && len(*fileCache) != 0 {
fileList = *fileCache
} else {
files := Files{}
files.List = make(map[string][]string)
concurrency := Concurrency{}
concurrency.DirectoryScans = make(chan int, maxDirectoryScans)
concurrency.FileScans = make(chan int, maxFileScans)
stats := Stats{}
startTime := time.Now()
getFileList(args, &files, filters, &stats, &concurrency)
runTime := time.Since(startTime)
concurrency := Concurrency{}
concurrency.DirectoryScans = make(chan int, maxDirectoryScans)
concurrency.FileScans = make(chan int, maxFileScans)
if Verbose {
fmt.Printf("%v | Scanned %v/%v files across %v directories in %v\n",
time.Now().Format(LOGDATE),
stats.GetFilesMatched(),
stats.GetFilesTotal(),
stats.GetDirectoriesMatched(),
runTime,
)
startTime := time.Now()
getFileList(args, &files, filters, &stats, &concurrency)
runTime := time.Since(startTime)
if Verbose {
fmt.Printf("%v | Scanned %v/%v files across %v directories in %v\n",
time.Now().Format(LOGDATE),
stats.GetFilesMatched(),
stats.GetFilesTotal(),
stats.GetDirectoriesMatched(),
runTime,
)
}
fileList = prepareDirectories(&files, sort)
if Cache {
*fileCache = append(*fileCache, fileList...)
}
}
fileList := prepareDirectories(&files, sort)
rand.Seed(time.Now().UnixNano())
rand.Shuffle(len(fileList), func(i, j int) { fileList[i], fileList[j] = fileList[j], fileList[i] })
for i := 0; i < len(fileList); i++ {
filePath := fileList[i]
isImage, err := isImage(filePath)
if err != nil {
return "", err
// If not caching, check for valid images just before serving, to speed up scanning
if !Cache {
isImage, err := isImage(filePath)
if err != nil {
return "", err
}
if isImage {
return filePath, nil
}
}
if isImage {
return filePath, nil
}
return filePath, nil
}
return "", ErrNoImagesFound

View File

@ -24,6 +24,7 @@ type Concurrency struct {
FileScans chan int
}
var Cache bool
var Filter bool
var Port uint16
var Recursive bool
@ -51,6 +52,7 @@ func Execute() {
}
func init() {
rootCmd.Flags().BoolVarP(&Cache, "cache", "c", false, "only scan directories once, at startup")
rootCmd.Flags().BoolVarP(&Filter, "filter", "f", false, "enable filtering via query parameters")
rootCmd.Flags().Uint16VarP(&Port, "port", "p", 8080, "port to listen on")
rootCmd.Flags().BoolVarP(&Recursive, "recursive", "r", false, "recurse into subdirectories")

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra"
)
var Version = "0.18.4"
var Version = "0.19.0"
func init() {
rootCmd.AddCommand(versionCmd)

View File

@ -241,7 +241,7 @@ func serveStaticFileHandler(paths []string) appHandler {
}
}
func serveHtmlHandler(paths []string, re regexp.Regexp) appHandler {
func serveHtmlHandler(paths []string, re regexp.Regexp, fileCache *[]string) appHandler {
return func(w http.ResponseWriter, r *http.Request) error {
refererUri, err := stripQueryParams(refererToUri(r.Referer()))
if err != nil {
@ -279,7 +279,7 @@ func serveHtmlHandler(paths []string, re regexp.Regexp) appHandler {
}
if filePath == "" {
filePath, err = pickFile(paths, &filters, sortOrder)
filePath, err = pickFile(paths, &filters, sortOrder, fileCache)
switch {
case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r)
@ -307,7 +307,7 @@ func serveHtmlHandler(paths []string, re regexp.Regexp) appHandler {
)
http.Redirect(w, r, newUrl, RedirectStatusCode)
case r.URL.Path == "/" && sortOrder == "asc" && refererUri == "":
filePath, err := pickFile(paths, &filters, sortOrder)
filePath, err := pickFile(paths, &filters, sortOrder, fileCache)
if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r)
@ -349,7 +349,7 @@ func serveHtmlHandler(paths []string, re regexp.Regexp) appHandler {
}
if filePath == "" {
filePath, err = pickFile(paths, &filters, sortOrder)
filePath, err = pickFile(paths, &filters, sortOrder, fileCache)
switch {
case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r)
@ -377,7 +377,7 @@ func serveHtmlHandler(paths []string, re regexp.Regexp) appHandler {
)
http.Redirect(w, r, newUrl, RedirectStatusCode)
case r.URL.Path == "/" && sortOrder == "desc" && refererUri == "":
filePath, err := pickFile(paths, &filters, sortOrder)
filePath, err := pickFile(paths, &filters, sortOrder, fileCache)
if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r)
@ -404,7 +404,7 @@ func serveHtmlHandler(paths []string, re regexp.Regexp) appHandler {
fmt.Printf("New URL is %v\n", newUrl)
http.Redirect(w, r, newUrl, RedirectStatusCode)
case r.URL.Path == "/":
filePath, err := pickFile(paths, &filters, sortOrder)
filePath, err := pickFile(paths, &filters, sortOrder, fileCache)
if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r)
@ -469,7 +469,9 @@ func ServePage(args []string) error {
re := regexp.MustCompile(`(.+)([0-9]{3})(\..+)`)
http.Handle("/", serveHtmlHandler(paths, *re))
fileCache := []string{}
http.Handle("/", serveHtmlHandler(paths, *re, &fileCache))
http.Handle(PREFIX+"/", http.StripPrefix(PREFIX, serveStaticFileHandler(paths)))
http.HandleFunc("/favicon.ico", doNothing)