Replaced option to filter for a single stream with include and exclude options, each accepting multiple comma-delimited values

This commit is contained in:
Seednode 2022-10-19 19:27:11 -05:00
parent 4d6c6f9bf1
commit 5d9a815bf2
3 changed files with 84 additions and 36 deletions

View File

@ -36,18 +36,36 @@ var (
ErrNoImagesFound = fmt.Errorf("no supported image formats found") ErrNoImagesFound = fmt.Errorf("no supported image formats found")
) )
func appendPaths(m map[string][]string, path, filter string) (map[string][]string, error) { func appendPaths(m map[string][]string, path string, filters *Filters) (map[string][]string, error) {
absolutePath, err := filepath.Abs(path) absolutePath, err := filepath.Abs(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
directory, _ := filepath.Split(absolutePath) directory, filename := filepath.Split(absolutePath)
if filter != "" && strings.Contains(path, filter) { if filters.IsEmpty() {
m[directory] = append(m[directory], path) m[directory] = append(m[directory], path)
} else if filter == "" { } else {
for i := 0; i < len(filters.Excludes); i++ {
if strings.Contains(
strings.ToLower(filename),
strings.ToLower(filters.Excludes[i]),
) {
return m, nil
}
}
for i := 0; i < len(filters.Includes); i++ {
if strings.Contains(
strings.ToLower(filename),
strings.ToLower(filters.Includes[i]),
) {
m[directory] = append(m[directory], path) m[directory] = append(m[directory], path)
break
}
}
} }
return m, nil return m, nil
@ -203,7 +221,7 @@ func isImage(path string) (bool, error) {
return filetype.IsImage(head), nil return filetype.IsImage(head), nil
} }
func getFiles(m map[string][]string, path, filter string) (map[string][]string, error) { func getFiles(m map[string][]string, path string, filters *Filters) (map[string][]string, error) {
err := filepath.WalkDir(path, func(p string, info os.DirEntry, err error) error { err := filepath.WalkDir(path, func(p string, info os.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
@ -212,13 +230,13 @@ func getFiles(m map[string][]string, path, filter string) (map[string][]string,
switch { switch {
case !Recursive && info.IsDir() && p != path: case !Recursive && info.IsDir() && p != path:
return filepath.SkipDir return filepath.SkipDir
case filter != "" && !info.IsDir(): case !filters.IsEmpty() && !info.IsDir():
m, err = appendPaths(m, p, filter) m, err = appendPaths(m, p, filters)
if err != nil { if err != nil {
return err return err
} }
case !info.IsDir(): case !info.IsDir():
m, err = appendPaths(m, p, "") m, err = appendPaths(m, p, filters)
if err != nil { if err != nil {
return err return err
} }
@ -233,12 +251,12 @@ func getFiles(m map[string][]string, path, filter string) (map[string][]string,
return m, nil return m, nil
} }
func getFileList(paths []string, filter string) (map[string][]string, error) { func getFileList(paths []string, filters *Filters) (map[string][]string, error) {
fileMap := map[string][]string{} fileMap := map[string][]string{}
var err error var err error
for i := 0; i < len(paths); i++ { for i := 0; i < len(paths); i++ {
fileMap, err = getFiles(fileMap, paths[i], filter) fileMap, err = getFiles(fileMap, paths[i], filters)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -259,14 +277,13 @@ func prepareDirectory(directory []string) []string {
last = cleanFilename(last) last = cleanFilename(last)
if first == last { if first == last {
d := append([]string{}, directory[0]) return append([]string{}, directory[0])
return d
} else { } else {
return directory return directory
} }
} }
func prepareDirectories(m map[string][]string, sorting string) []string { func prepareDirectories(m map[string][]string, sort string) []string {
directories := []string{} directories := []string{}
keys := make([]string, len(m)) keys := make([]string, len(m))
@ -277,7 +294,7 @@ func prepareDirectories(m map[string][]string, sorting string) []string {
i++ i++
} }
if sorting == "asc" || sorting == "desc" { if sort == "asc" || sort == "desc" {
for i := 0; i < len(keys); i++ { for i := 0; i < len(keys); i++ {
directories = append(directories, prepareDirectory(m[keys[i]])...) directories = append(directories, prepareDirectory(m[keys[i]])...)
} }
@ -290,13 +307,13 @@ func prepareDirectories(m map[string][]string, sorting string) []string {
return directories return directories
} }
func pickFile(args []string, filter, sorting string) (string, error) { func pickFile(args []string, filters *Filters, sort string) (string, error) {
fileMap, err := getFileList(args, filter) fileMap, err := getFileList(args, filters)
if err != nil { if err != nil {
return "", err return "", err
} }
fileList := prepareDirectories(fileMap, sorting) fileList := prepareDirectories(fileMap, sort)
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())

View File

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

View File

@ -16,6 +16,27 @@ import (
"time" "time"
) )
type Filters struct {
Includes []string
Excludes []string
}
func (f *Filters) IsEmpty() bool {
if len(f.Includes) == 0 && len(f.Excludes) == 0 {
return true
}
return false
}
func (f *Filters) GetIncludes() string {
return strings.Join(f.Includes, ",")
}
func (f *Filters) GetExcludes() string {
return strings.Join(f.Excludes, ",")
}
type appHandler func(http.ResponseWriter, *http.Request) error type appHandler func(http.ResponseWriter, *http.Request) error
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@ -61,7 +82,7 @@ func serveHtml(w http.ResponseWriter, r *http.Request, filePath string) error {
htmlBody += `</title> htmlBody += `</title>
</head> </head>
<body>` <body>`
htmlBody += fmt.Sprintf(`<a href="/?f=%v&s=%v"><img src="`, r.URL.Query().Get("f"), r.URL.Query().Get("s")) 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"))
htmlBody += PREFIX + filePath htmlBody += PREFIX + filePath
htmlBody += `"></img></a> htmlBody += `"></img></a>
</body> </body>
@ -134,6 +155,14 @@ 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 := stripQueryParam(refererToUri(r.Referer()))
@ -141,11 +170,13 @@ func serveHtmlHandler(paths []string) appHandler {
return err return err
} }
filter := r.URL.Query().Get("f") filters := Filters{}
sorting := r.URL.Query().Get("s") filters.Includes = parseQueryParams(r.URL.Query().Get("include"))
filters.Excludes = parseQueryParams(r.URL.Query().Get("exclude"))
sort := r.URL.Query().Get("sort")
switch { switch {
case r.URL.Path == "/" && sorting == "asc" && refererUri != "": case r.URL.Path == "/" && sort == "asc" && refererUri != "":
query, err := url.QueryUnescape(refererUri) query, err := url.QueryUnescape(refererUri)
if err != nil { if err != nil {
return err return err
@ -162,7 +193,7 @@ func serveHtmlHandler(paths []string) appHandler {
} }
if filePath == "" { if filePath == "" {
filePath, err = pickFile(paths, filter, sorting) filePath, err = pickFile(paths, &filters, sort)
switch { switch {
case err != nil && err == ErrNoImagesFound: case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r) http.NotFound(w, r)
@ -183,10 +214,10 @@ func serveHtmlHandler(paths []string) appHandler {
} }
} }
newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, sorting) newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
http.Redirect(w, r, newUrl, http.StatusSeeOther) http.Redirect(w, r, newUrl, http.StatusSeeOther)
case r.URL.Path == "/" && sorting == "asc" && refererUri == "": case r.URL.Path == "/" && sort == "asc" && refererUri == "":
filePath, err := pickFile(paths, filter, sorting) filePath, err := pickFile(paths, &filters, sort)
if err != nil && err == ErrNoImagesFound { if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r) http.NotFound(w, r)
@ -205,9 +236,9 @@ func serveHtmlHandler(paths []string) appHandler {
return err return err
} }
newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, sorting) newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
http.Redirect(w, r, newUrl, http.StatusSeeOther) http.Redirect(w, r, newUrl, http.StatusSeeOther)
case r.URL.Path == "/" && sorting == "desc" && refererUri != "": case r.URL.Path == "/" && sort == "desc" && refererUri != "":
query, err := url.QueryUnescape(refererUri) query, err := url.QueryUnescape(refererUri)
if err != nil { if err != nil {
return err return err
@ -224,7 +255,7 @@ func serveHtmlHandler(paths []string) appHandler {
} }
if filePath == "" { if filePath == "" {
filePath, err = pickFile(paths, filter, sorting) filePath, err = pickFile(paths, &filters, sort)
switch { switch {
case err != nil && err == ErrNoImagesFound: case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r) http.NotFound(w, r)
@ -245,10 +276,10 @@ func serveHtmlHandler(paths []string) appHandler {
} }
} }
newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, sorting) newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
http.Redirect(w, r, newUrl, http.StatusSeeOther) http.Redirect(w, r, newUrl, http.StatusSeeOther)
case r.URL.Path == "/" && sorting == "desc" && refererUri == "": case r.URL.Path == "/" && sort == "desc" && refererUri == "":
filePath, err := pickFile(paths, filter, sorting) filePath, err := pickFile(paths, &filters, sort)
if err != nil && err == ErrNoImagesFound { if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r) http.NotFound(w, r)
@ -267,10 +298,10 @@ func serveHtmlHandler(paths []string) appHandler {
return err return err
} }
newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, sorting) newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
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, filter, sorting) filePath, err := pickFile(paths, &filters, sort)
if err != nil && err == ErrNoImagesFound { if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r) http.NotFound(w, r)
@ -279,7 +310,7 @@ func serveHtmlHandler(paths []string) appHandler {
return err return err
} }
newUrl := fmt.Sprintf("%v%v?f=%v&s=%v", r.URL.Host, filePath, filter, sorting) newUrl := fmt.Sprintf("%v%v?include=%v&exclude=%v&sort=%v", r.URL.Host, filePath, filters.GetIncludes(), filters.GetExcludes(), sort)
http.Redirect(w, r, newUrl, http.StatusSeeOther) http.Redirect(w, r, newUrl, http.StatusSeeOther)
default: default:
filePath := r.URL.Path filePath := r.URL.Path