diff --git a/cmd/files.go b/cmd/files.go index 24a2759..f711cae 100644 --- a/cmd/files.go +++ b/cmd/files.go @@ -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) { - m[directory] = append(m[directory], path) - } else if filter == "" { + if filters.IsEmpty() { m[directory] = append(m[directory], path) + } 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()) diff --git a/cmd/version.go b/cmd/version.go index 4caf63f..4326a71 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -10,7 +10,7 @@ import ( "github.com/spf13/cobra" ) -var Version = "0.13.4" +var Version = "0.14.0" func init() { rootCmd.AddCommand(versionCmd) diff --git a/cmd/web.go b/cmd/web.go index 3bbb324..1fa1f71 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -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 += `
` - htmlBody += fmt.Sprintf(` @@ -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