diff --git a/README.md b/README.md index 4b1ceaf..0003099 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,14 @@ Browser history is preserved, so you can always go back to any previously displa Builds available [here](https://cdn.seedno.de/builds/roulette). +## [-s, --successive] + +This option is tailored specifically for my own use case. When loading a new image, it checks for a successively-numbered file in the same path. + +For example, if the file `/mnt/photos/MyVacation001.jpg` is being displayed, clicking on the image will search for a `/mnt/photos/MyVacation002.jpg`. + +If a matching file is not found, it will select a random file as usual. + ## Usage output ``` Usage: @@ -22,10 +30,11 @@ Available Commands: version Print version Flags: - -h, --help help for roulette - -p, --port int port to listen on (default 8080) - -r, --recursive recurse into subdirectories - -v, --verbose log accessed files to stdout + -h, --help help for roulette + -p, --port int port to listen on (default 8080) + -r, --recursive recurse into subdirectories + -s, --successive load the next sequential file, if possible + -v, --verbose log accessed files to stdout Use "roulette [command] --help" for more information about a command. ``` \ No newline at end of file diff --git a/cmd/files.go b/cmd/files.go index 348e335..2c27b97 100644 --- a/cmd/files.go +++ b/cmd/files.go @@ -6,14 +6,55 @@ package cmd import ( "errors" + "fmt" "math/rand" "os" "path/filepath" + "regexp" + "strconv" "time" "github.com/h2non/filetype" ) +func getNextFile(path string) (string, error) { + re := regexp.MustCompile("(.+)([0-9]{3})(\\..+)") + + split := re.FindAllStringSubmatch(path, -1) + + base := split[0][1] + number, err := strconv.Atoi(split[0][2]) + if err != nil { + return "", nil + } + extension := split[0][3] + + incremented := number + 1 + + fileName := fmt.Sprintf("%v%.3d%v", base, incremented, extension) + + nextFile, err := checkNextFile(fileName) + if err != nil { + return "", err + } + + if !nextFile { + return "", nil + } + + return fileName, nil +} + +func checkNextFile(path string) (bool, error) { + if _, err := os.Stat(path); err == nil { + return true, nil + } else if errors.Is(err, os.ErrNotExist) { + return false, nil + } else { + return false, err + } +} + func checkIfImage(path string) (bool, error) { file, err := os.Open(path) if err != nil { diff --git a/cmd/root.go b/cmd/root.go index 58181cd..24a6b5a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -12,6 +12,7 @@ import ( var Port int var Recursive bool +var Successive bool var Verbose bool var rootCmd = &cobra.Command{ @@ -33,6 +34,7 @@ func Execute() { func init() { rootCmd.Flags().IntVarP(&Port, "port", "p", 8080, "port to listen on") rootCmd.Flags().BoolVarP(&Recursive, "recursive", "r", false, "recurse into subdirectories") + rootCmd.Flags().BoolVarP(&Successive, "successive", "s", false, "load the next sequential file, if possible") rootCmd.Flags().BoolVarP(&Verbose, "verbose", "v", false, "log accessed files to stdout") rootCmd.Flags().SetInterspersed(true) } diff --git a/cmd/version.go b/cmd/version.go index 3739c23..5137955 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -10,7 +10,7 @@ import ( "github.com/spf13/cobra" ) -var Version = "0.6.3" +var Version = "0.7.0" func init() { rootCmd.AddCommand(versionCmd) diff --git a/cmd/web.go b/cmd/web.go index fb4c355..bfd2034 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -22,6 +22,16 @@ const LOGDATE string = "2006-01-02T15:04:05.000000000-07:00" const PREFIX string = "/src" +func refererToUri(referer string) string { + parts := strings.SplitAfterN(referer, "/", 4) + + if len(parts) < 4 { + return "" + } + + return "/" + parts[3] +} + func serveHtml(w http.ResponseWriter, r http.Request, filePath string) error { fileName := filepath.Base(filePath) @@ -123,9 +133,33 @@ func serveStaticFileHandler(paths []string) http.HandlerFunc { func serveHtmlHandler(paths []string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.RequestURI == "/" { - filePath, err := pickFile(paths) - if err != nil { - log.Fatal(err) + var filePath string + var err error + + if Successive { + refererUri := refererToUri(r.Referer()) + if refererUri != "" && Verbose { + fmt.Printf("Referer is %v\n", refererUri) + } + + if refererUri != "" { + f, err := url.QueryUnescape(refererUri) + if err != nil { + log.Fatal(err) + } + + filePath, err = getNextFile(f) + if err != nil { + log.Fatal(err) + } + } + } + + if filePath == "" { + filePath, err = pickFile(paths) + if err != nil { + log.Fatal(err) + } } newUrl := r.URL.Host + filePath