Added flags to enable/disable filtering and sorting
This commit is contained in:
parent
7819cf3090
commit
6508f2d170
|
@ -14,7 +14,7 @@ Builds available [here](https://cdn.seedno.de/builds/roulette).
|
||||||
|
|
||||||
## Filtering
|
## Filtering
|
||||||
|
|
||||||
You can provide a comma-delimited string of patterns to match via the `include=` query parameter.
|
You can provide a comma-delimited string of patterns to match via the `include=` query parameter, assuming the `-f|--filter` flag is enabled.
|
||||||
|
|
||||||
Only filenames matching one or more of the patterns will be served.
|
Only filenames matching one or more of the patterns will be served.
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ Both filtering parameters ignore the file extension and full path; they only com
|
||||||
|
|
||||||
## Sorting
|
## Sorting
|
||||||
|
|
||||||
You can specify a sorting pattern via the `sort=` query parameter.
|
You can specify a sorting pattern via the `sort=` query parameter, assuming the `-s|--sort` flag is enabled.
|
||||||
|
|
||||||
A value of `asc` means files will be served in ascending order (lowest-numbered to highest).
|
A value of `asc` means files will be served in ascending order (lowest-numbered to highest).
|
||||||
|
|
||||||
|
@ -58,9 +58,11 @@ Available Commands:
|
||||||
version Print version
|
version Print version
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
|
-f, --filter enable filtering via query parameters
|
||||||
-h, --help help for roulette
|
-h, --help help for roulette
|
||||||
-p, --port uint16 port to listen on (default 8080)
|
-p, --port uint16 port to listen on (default 8080)
|
||||||
-r, --recursive recurse into subdirectories
|
-r, --recursive recurse into subdirectories
|
||||||
|
-s, --sort enable sorting via query parameters
|
||||||
-v, --verbose log accessed files to stdout
|
-v, --verbose log accessed files to stdout
|
||||||
|
|
||||||
Use "roulette [command] --help" for more information about a command.
|
Use "roulette [command] --help" for more information about a command.
|
||||||
|
|
|
@ -11,8 +11,10 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Filter bool
|
||||||
var Port uint16
|
var Port uint16
|
||||||
var Recursive bool
|
var Recursive bool
|
||||||
|
var Sort bool
|
||||||
var Verbose bool
|
var Verbose bool
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
|
@ -36,8 +38,10 @@ func Execute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
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().Uint16VarP(&Port, "port", "p", 8080, "port to listen on")
|
||||||
rootCmd.Flags().BoolVarP(&Recursive, "recursive", "r", false, "recurse into subdirectories")
|
rootCmd.Flags().BoolVarP(&Recursive, "recursive", "r", false, "recurse into subdirectories")
|
||||||
|
rootCmd.Flags().BoolVarP(&Sort, "sort", "s", false, "enable sorting via query parameters")
|
||||||
rootCmd.Flags().BoolVarP(&Verbose, "verbose", "v", false, "log accessed files to stdout")
|
rootCmd.Flags().BoolVarP(&Verbose, "verbose", "v", false, "log accessed files to stdout")
|
||||||
rootCmd.Flags().SetInterspersed(true)
|
rootCmd.Flags().SetInterspersed(true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version = "0.14.2"
|
var Version = "0.15.0"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(versionCmd)
|
rootCmd.AddCommand(versionCmd)
|
||||||
|
|
115
cmd/web.go
115
cmd/web.go
|
@ -48,7 +48,35 @@ func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
const LOGDATE string = "2006-01-02T15:04:05.000-07:00"
|
const LOGDATE string = "2006-01-02T15:04:05.000-07:00"
|
||||||
const PREFIX string = "/src"
|
const PREFIX string = "/src"
|
||||||
|
|
||||||
func stripQueryParam(inUrl string) (string, error) {
|
func splitQueryParams(query string) []string {
|
||||||
|
if query == "" {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Split(query, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateQueryParams(filters *Filters, sort string) string {
|
||||||
|
switch {
|
||||||
|
case Filter && !Sort:
|
||||||
|
return fmt.Sprintf("?include=%v&exclude=%v",
|
||||||
|
filters.GetIncludes(),
|
||||||
|
filters.GetExcludes(),
|
||||||
|
)
|
||||||
|
case !Filter && Sort:
|
||||||
|
return fmt.Sprintf("?sort=%v", sort)
|
||||||
|
case Filter && Sort:
|
||||||
|
return fmt.Sprintf("?include=%v&exclude=%v&sort=%v",
|
||||||
|
filters.GetIncludes(),
|
||||||
|
filters.GetExcludes(),
|
||||||
|
sort,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func stripQueryParams(inUrl string) (string, error) {
|
||||||
url, err := url.Parse(inUrl)
|
url, err := url.Parse(inUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -82,7 +110,24 @@ func serveHtml(w http.ResponseWriter, r *http.Request, filePath string) error {
|
||||||
htmlBody += `</title>
|
htmlBody += `</title>
|
||||||
</head>
|
</head>
|
||||||
<body>`
|
<body>`
|
||||||
htmlBody += fmt.Sprintf(`<a href="/?include=%v&exclude=%v&sort=%v"><img src="`, r.URL.Query().Get("include"), r.URL.Query().Get("exclude"), r.URL.Query().Get("sort"))
|
switch {
|
||||||
|
case Filter && Sort:
|
||||||
|
htmlBody += fmt.Sprintf(`<a href="/?include=%v&exclude=%v&sort=%v"><img src="`,
|
||||||
|
r.URL.Query().Get("include"),
|
||||||
|
r.URL.Query().Get("exclude"), r.URL.Query().Get("sort"),
|
||||||
|
)
|
||||||
|
case Filter && !Sort:
|
||||||
|
htmlBody += fmt.Sprintf(`<a href="/?include=%v&exclude=%v"><img src="`,
|
||||||
|
r.URL.Query().Get("include"),
|
||||||
|
r.URL.Query().Get("exclude"),
|
||||||
|
)
|
||||||
|
case !Filter && Sort:
|
||||||
|
htmlBody += fmt.Sprintf(`<a href="/?sort=%v"><img src="`,
|
||||||
|
r.URL.Query().Get("sort"),
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
htmlBody += `<a href="/"><img src="`
|
||||||
|
}
|
||||||
htmlBody += PREFIX + filePath
|
htmlBody += PREFIX + filePath
|
||||||
htmlBody += `"></img></a>
|
htmlBody += `"></img></a>
|
||||||
</body>
|
</body>
|
||||||
|
@ -97,7 +142,7 @@ func serveHtml(w http.ResponseWriter, r *http.Request, filePath string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveStaticFile(w http.ResponseWriter, r *http.Request, paths []string) error {
|
func serveStaticFile(w http.ResponseWriter, r *http.Request, paths []string) error {
|
||||||
strippedUrl, err := stripQueryParam(r.URL.Path)
|
strippedUrl, err := stripQueryParams(r.URL.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -155,29 +200,21 @@ func serveStaticFileHandler(paths []string) appHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseQueryParams(query string) []string {
|
|
||||||
if query == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Split(query, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
func serveHtmlHandler(paths []string) appHandler {
|
func serveHtmlHandler(paths []string) appHandler {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
refererUri, err := stripQueryParam(refererToUri(r.Referer()))
|
refererUri, err := stripQueryParams(refererToUri(r.Referer()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
filters := Filters{}
|
filters := Filters{}
|
||||||
filters.Includes = parseQueryParams(r.URL.Query().Get("include"))
|
filters.Includes = splitQueryParams(r.URL.Query().Get("include"))
|
||||||
filters.Excludes = parseQueryParams(r.URL.Query().Get("exclude"))
|
filters.Excludes = splitQueryParams(r.URL.Query().Get("exclude"))
|
||||||
|
|
||||||
sort := r.URL.Query().Get("sort")
|
sortOrder := r.URL.Query().Get("sort")
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case r.URL.Path == "/" && sort == "asc" && refererUri != "":
|
case r.URL.Path == "/" && sortOrder == "asc" && refererUri != "":
|
||||||
query, err := url.QueryUnescape(refererUri)
|
query, err := url.QueryUnescape(refererUri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -194,7 +231,7 @@ func serveHtmlHandler(paths []string) appHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if filePath == "" {
|
if filePath == "" {
|
||||||
filePath, err = pickFile(paths, &filters, sort)
|
filePath, err = pickFile(paths, &filters, sortOrder)
|
||||||
switch {
|
switch {
|
||||||
case err != nil && err == ErrNoImagesFound:
|
case err != nil && err == ErrNoImagesFound:
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
@ -215,10 +252,14 @@ func serveHtmlHandler(paths []string) appHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
|
newUrl := fmt.Sprintf("%v%v%v",
|
||||||
|
r.URL.Host,
|
||||||
|
filePath,
|
||||||
|
generateQueryParams(&filters, sortOrder),
|
||||||
|
)
|
||||||
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
||||||
case r.URL.Path == "/" && sort == "asc" && refererUri == "":
|
case r.URL.Path == "/" && sortOrder == "asc" && refererUri == "":
|
||||||
filePath, err := pickFile(paths, &filters, sort)
|
filePath, err := pickFile(paths, &filters, sortOrder)
|
||||||
if err != nil && err == ErrNoImagesFound {
|
if err != nil && err == ErrNoImagesFound {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
|
||||||
|
@ -237,9 +278,13 @@ func serveHtmlHandler(paths []string) appHandler {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
|
newUrl := fmt.Sprintf("%v%v%v",
|
||||||
|
r.URL.Host,
|
||||||
|
filePath,
|
||||||
|
generateQueryParams(&filters, sortOrder),
|
||||||
|
)
|
||||||
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
||||||
case r.URL.Path == "/" && sort == "desc" && refererUri != "":
|
case r.URL.Path == "/" && sortOrder == "desc" && refererUri != "":
|
||||||
query, err := url.QueryUnescape(refererUri)
|
query, err := url.QueryUnescape(refererUri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -256,7 +301,7 @@ func serveHtmlHandler(paths []string) appHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if filePath == "" {
|
if filePath == "" {
|
||||||
filePath, err = pickFile(paths, &filters, sort)
|
filePath, err = pickFile(paths, &filters, sortOrder)
|
||||||
switch {
|
switch {
|
||||||
case err != nil && err == ErrNoImagesFound:
|
case err != nil && err == ErrNoImagesFound:
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
@ -277,10 +322,14 @@ func serveHtmlHandler(paths []string) appHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
|
newUrl := fmt.Sprintf("%v%v%v",
|
||||||
|
r.URL.Host,
|
||||||
|
filePath,
|
||||||
|
generateQueryParams(&filters, sortOrder),
|
||||||
|
)
|
||||||
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
||||||
case r.URL.Path == "/" && sort == "desc" && refererUri == "":
|
case r.URL.Path == "/" && sortOrder == "desc" && refererUri == "":
|
||||||
filePath, err := pickFile(paths, &filters, sort)
|
filePath, err := pickFile(paths, &filters, sortOrder)
|
||||||
if err != nil && err == ErrNoImagesFound {
|
if err != nil && err == ErrNoImagesFound {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
|
||||||
|
@ -299,10 +348,14 @@ func serveHtmlHandler(paths []string) appHandler {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
|
newUrl := fmt.Sprintf("%v%v%v",
|
||||||
|
r.URL.Host,
|
||||||
|
filePath,
|
||||||
|
generateQueryParams(&filters, sortOrder),
|
||||||
|
)
|
||||||
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
||||||
case r.URL.Path == "/":
|
case r.URL.Path == "/":
|
||||||
filePath, err := pickFile(paths, &filters, sort)
|
filePath, err := pickFile(paths, &filters, sortOrder)
|
||||||
if err != nil && err == ErrNoImagesFound {
|
if err != nil && err == ErrNoImagesFound {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
|
||||||
|
@ -311,7 +364,11 @@ func serveHtmlHandler(paths []string) appHandler {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
|
newUrl := fmt.Sprintf("%v%v%v",
|
||||||
|
r.URL.Host,
|
||||||
|
filePath,
|
||||||
|
generateQueryParams(&filters, sortOrder),
|
||||||
|
)
|
||||||
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
http.Redirect(w, r, newUrl, http.StatusSeeOther)
|
||||||
default:
|
default:
|
||||||
filePath := r.URL.Path
|
filePath := r.URL.Path
|
||||||
|
|
Loading…
Reference in New Issue