diff --git a/README.md b/README.md index 941e7aa..e56ea76 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,8 @@ If a positive-value `refresh=` query parameter is provided, the p This can be used to generate a sort of slideshow of files. +Minimum accepted value is 500ms, as anything lower seems to cause inconsistent behavior. This might be changed in a future release. + Supported units are `ns`, `us`/`µs`, `ms`, `s`, `m`, and `h`. ## Caching @@ -95,19 +97,20 @@ Usage: roulette [path]... [flags] Flags: - -b, --bind string address to bind to (default "0.0.0.0") - -c, --cache generate directory cache at startup - --cache-file string path to optional persistent cache file - -d, --debug expose debug endpoint - -f, --filter enable filtering - -h, --help help for roulette - --maximum-files uint32 skip directories with file counts over this value (default 4294967295) - --minimum-files uint32 skip directories with file counts under this value - -p, --port uint16 port to listen on (default 8080) - -r, --recursive recurse into subdirectories - -s, --sort enable sorting - --stats expose stats endpoint - --stats-file string path to optional persistent stats file - -v, --verbose log accessed files to stdout - -V, --version display version and exit -``` + -b, --bind string address to bind to (default "0.0.0.0") + -c, --cache generate directory cache at startup + --cache-file string path to optional persistent cache file + -d, --debug expose debug endpoint + -f, --filter enable filtering + -h, --help help for roulette + --maximum-files uint32 skip directories with file counts over this value (default 4294967295) + --minimum-files uint32 skip directories with file counts under this value + -p, --port uint16 port to listen on (default 8080) + -r, --recursive recurse into subdirectories + --refresh-interval string force refresh interval equal to this duration (minimum 500ms) + -s, --sort enable sorting + --stats expose stats endpoint + --stats-file string path to optional persistent stats file + -v, --verbose log accessed files to stdout + -V, --version display version and exit +``` \ No newline at end of file diff --git a/cmd/root.go b/cmd/root.go index 84d4a21..38963ba 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -5,13 +5,19 @@ Copyright © 2023 Seednode package cmd import ( + "errors" "log" + "time" "github.com/spf13/cobra" ) +var ( + ErrIncorrectRefreshInterval = errors.New("refresh interval must be a duration string >= 500ms") +) + const ( - Version string = "0.57.1" + Version string = "0.57.2" ) var ( @@ -24,6 +30,7 @@ var ( minimumFileCount uint32 port uint16 recursive bool + refreshInterval string sorting bool statistics bool statisticsFile string @@ -38,6 +45,13 @@ var ( if debug { cmd.MarkFlagRequired("cache") } + + if refreshInterval != "" { + interval, err := time.ParseDuration(refreshInterval) + if err != nil || interval < 500*time.Millisecond { + log.Fatal(ErrIncorrectRefreshInterval) + } + } }, RunE: func(cmd *cobra.Command, args []string) error { err := ServePage(args) @@ -67,6 +81,7 @@ func init() { rootCmd.Flags().Uint32Var(&minimumFileCount, "minimum-files", 0, "skip directories with file counts under this value") rootCmd.Flags().Uint16VarP(&port, "port", "p", 8080, "port to listen on") rootCmd.Flags().BoolVarP(&recursive, "recursive", "r", false, "recurse into subdirectories") + rootCmd.Flags().StringVar(&refreshInterval, "refresh-interval", "", "force refresh interval equal to this duration (minimum 500ms)") rootCmd.Flags().BoolVarP(&sorting, "sort", "s", false, "enable sorting") rootCmd.Flags().BoolVar(&statistics, "stats", false, "expose stats endpoint") rootCmd.Flags().StringVar(&statisticsFile, "stats-file", "", "path to optional persistent stats file") diff --git a/cmd/web.go b/cmd/web.go index 2f8049c..1fff029 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -408,18 +408,24 @@ func serverErrorHandler() func(http.ResponseWriter, *http.Request, interface{}) } func RefreshInterval(r *http.Request, Regexes *Regexes) (int64, string) { - refreshInterval := r.URL.Query().Get("refresh") + var interval string - if !Regexes.units.MatchString(refreshInterval) { - return 0, "0ms" + if refreshInterval == "" { + interval = r.URL.Query().Get("refresh") + } else { + interval = refreshInterval } - duration, err := time.ParseDuration(refreshInterval) - if err != nil { - return 0, "0ms" - } + duration, err := time.ParseDuration(interval) - return duration.Milliseconds(), refreshInterval + switch { + case err != nil || duration == 0: + return 0, "0ms" + case duration < 500*time.Millisecond: + return 500, "500ms" + default: + return duration.Milliseconds(), interval + } } func SortOrder(r *http.Request) string {