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")
)
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)
if err != nil {
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)
} 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)
break
}
}
}
return m, nil
@ -203,7 +221,7 @@ func isImage(path string) (bool, error) {
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 {
if err != nil {
return err
@ -212,13 +230,13 @@ func getFiles(m map[string][]string, path, filter string) (map[string][]string,
switch {
case !Recursive && info.IsDir() && p != path:
return filepath.SkipDir
case filter != "" && !info.IsDir():
m, err = appendPaths(m, p, filter)
case !filters.IsEmpty() && !info.IsDir():
m, err = appendPaths(m, p, filters)
if err != nil {
return err
}
case !info.IsDir():
m, err = appendPaths(m, p, "")
m, err = appendPaths(m, p, filters)
if err != nil {
return err
}
@ -233,12 +251,12 @@ func getFiles(m map[string][]string, path, filter string) (map[string][]string,
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{}
var err error
for i := 0; i < len(paths); i++ {
fileMap, err = getFiles(fileMap, paths[i], filter)
fileMap, err = getFiles(fileMap, paths[i], filters)
if err != nil {
return nil, err
}
@ -259,14 +277,13 @@ func prepareDirectory(directory []string) []string {
last = cleanFilename(last)
if first == last {
d := append([]string{}, directory[0])
return d
return append([]string{}, directory[0])
} else {
return directory
}
}
func prepareDirectories(m map[string][]string, sorting string) []string {
func prepareDirectories(m map[string][]string, sort string) []string {
directories := []string{}
keys := make([]string, len(m))
@ -277,7 +294,7 @@ func prepareDirectories(m map[string][]string, sorting string) []string {
i++
}
if sorting == "asc" || sorting == "desc" {
if sort == "asc" || sort == "desc" {
for i := 0; i < len(keys); i++ {
directories = append(directories, prepareDirectory(m[keys[i]])...)
}
@ -290,13 +307,13 @@ func prepareDirectories(m map[string][]string, sorting string) []string {
return directories
}
func pickFile(args []string, filter, sorting string) (string, error) {
fileMap, err := getFileList(args, filter)
func pickFile(args []string, filters *Filters, sort string) (string, error) {
fileMap, err := getFileList(args, filters)
if err != nil {
return "", err
}
fileList := prepareDirectories(fileMap, sorting)
fileList := prepareDirectories(fileMap, sort)
rand.Seed(time.Now().UnixNano())

View File

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

View File

@ -16,6 +16,27 @@ import (
"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
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>
</head>
<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 += `"></img></a>
</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 {
return func(w http.ResponseWriter, r *http.Request) error {
refererUri, err := stripQueryParam(refererToUri(r.Referer()))
@ -141,11 +170,13 @@ func serveHtmlHandler(paths []string) appHandler {
return err
}
filter := r.URL.Query().Get("f")
sorting := r.URL.Query().Get("s")
filters := Filters{}
filters.Includes = parseQueryParams(r.URL.Query().Get("include"))
filters.Excludes = parseQueryParams(r.URL.Query().Get("exclude"))
sort := r.URL.Query().Get("sort")
switch {
case r.URL.Path == "/" && sorting == "asc" && refererUri != "":
case r.URL.Path == "/" && sort == "asc" && refererUri != "":
query, err := url.QueryUnescape(refererUri)
if err != nil {
return err
@ -162,7 +193,7 @@ func serveHtmlHandler(paths []string) appHandler {
}
if filePath == "" {
filePath, err = pickFile(paths, filter, sorting)
filePath, err = pickFile(paths, &filters, sort)
switch {
case err != nil && err == ErrNoImagesFound:
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)
case r.URL.Path == "/" && sorting == "asc" && refererUri == "":
filePath, err := pickFile(paths, filter, sorting)
case r.URL.Path == "/" && sort == "asc" && refererUri == "":
filePath, err := pickFile(paths, &filters, sort)
if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r)
@ -205,9 +236,9 @@ func serveHtmlHandler(paths []string) appHandler {
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)
case r.URL.Path == "/" && sorting == "desc" && refererUri != "":
case r.URL.Path == "/" && sort == "desc" && refererUri != "":
query, err := url.QueryUnescape(refererUri)
if err != nil {
return err
@ -224,7 +255,7 @@ func serveHtmlHandler(paths []string) appHandler {
}
if filePath == "" {
filePath, err = pickFile(paths, filter, sorting)
filePath, err = pickFile(paths, &filters, sort)
switch {
case err != nil && err == ErrNoImagesFound:
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)
case r.URL.Path == "/" && sorting == "desc" && refererUri == "":
filePath, err := pickFile(paths, filter, sorting)
case r.URL.Path == "/" && sort == "desc" && refererUri == "":
filePath, err := pickFile(paths, &filters, sort)
if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r)
@ -267,10 +298,10 @@ func serveHtmlHandler(paths []string) appHandler {
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)
case r.URL.Path == "/":
filePath, err := pickFile(paths, filter, sorting)
filePath, err := pickFile(paths, &filters, sort)
if err != nil && err == ErrNoImagesFound {
http.NotFound(w, r)
@ -279,7 +310,7 @@ func serveHtmlHandler(paths []string) appHandler {
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)
default:
filePath := r.URL.Path