Reworked functions to be more concise (e.g. now getNewFile and getNextFile work with or without sortOrder)

This commit is contained in:
Seednode 2022-11-05 11:00:42 -05:00
parent 70a1eaf91d
commit b6f7d9c104
3 changed files with 98 additions and 224 deletions

View File

@ -30,7 +30,7 @@ import (
) )
var ( var (
ErrNoImagesFound = fmt.Errorf("no supported image formats found") ErrNoImagesFound = fmt.Errorf("no supported image formats found which match all criteria")
extensions = [6]string{".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"} extensions = [6]string{".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"}
) )
@ -107,6 +107,9 @@ func humanReadableSize(bytes int) string {
func getImageDimensions(path string) (string, error) { func getImageDimensions(path string) (string, error) {
file, err := os.Open(path) file, err := os.Open(path)
if err != nil {
return "", err
}
defer file.Close() defer file.Close()
myImage, _, err := image.DecodeConfig(file) myImage, _, err := image.DecodeConfig(file)
@ -200,60 +203,60 @@ func appendPaths(path string, files *Files, filters *Filters, stats *Stats) erro
return nil return nil
} }
func getFirstFile(p *Path) (string, error) { func getNewFile(paths []string, filters *Filters, sortOrder string, re regexp.Regexp, fileCache *[]string) (string, error) {
p.Number = 1 filePath, err := pickFile(paths, filters, sortOrder, fileCache)
if err != nil {
return "", nil
}
fileName, err := tryExtensions(p) path, err := splitPath(filePath, re)
if err != nil { if err != nil {
return "", err return "", err
} }
return fileName, nil path.Number = 1
}
func getLastFile(p *Path) (string, error) { switch {
var fileName string case sortOrder == "asc":
var err error filePath, err = tryExtensions(path)
p.Number = 1
for {
p.Increment()
fileName, err = tryExtensions(p)
if err != nil { if err != nil {
return "", err return "", err
} }
case sortOrder == "desc":
for {
path.Increment()
if fileName == "" { filePath, err = tryExtensions(path)
p.Decrement()
fileName, err = tryExtensions(p)
if err != nil { if err != nil {
return "", err return "", err
} }
break if filePath == "" {
path.Decrement()
filePath, err = tryExtensions(path)
if err != nil {
return "", err
}
break
}
} }
} }
return fileName, nil return filePath, nil
} }
func getNextFile(p *Path) (string, error) { func getNextFile(p *Path, sortOrder string) (string, error) {
p.Increment() switch {
case sortOrder == "asc":
fileName, err := tryExtensions(p) p.Increment()
if err != nil { case sortOrder == "desc":
return "", err p.Decrement()
default:
return "", nil
} }
return fileName, err
}
func getPreviousFile(p *Path) (string, error) {
p.Decrement()
fileName, err := tryExtensions(p) fileName, err := tryExtensions(p)
if err != nil { if err != nil {
return "", err return "", err
@ -497,6 +500,9 @@ func pickFile(args []string, filters *Filters, sort string, fileCache *[]string)
} }
fileCount := len(fileList) fileCount := len(fileList)
if fileCount == 0 {
return "", ErrNoImagesFound
}
r := rand.Intn(fileCount - 1) r := rand.Intn(fileCount - 1)

View File

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

View File

@ -31,19 +31,11 @@ type Filters struct {
} }
func (f *Filters) IsEmpty() bool { func (f *Filters) IsEmpty() bool {
if !(f.HasIncludes() && f.HasExcludes()) { return !(f.HasIncludes() && f.HasExcludes())
return true
}
return false
} }
func (f *Filters) HasIncludes() bool { func (f *Filters) HasIncludes() bool {
if len(f.Includes) == 0 { return len(f.Includes) != 0
return false
}
return true
} }
func (f *Filters) GetIncludes() string { func (f *Filters) GetIncludes() string {
@ -51,11 +43,7 @@ func (f *Filters) GetIncludes() string {
} }
func (f *Filters) HasExcludes() bool { func (f *Filters) HasExcludes() bool {
if len(f.Excludes) == 0 { return len(f.Excludes) != 0
return false
}
return true
} }
func (f *Filters) GetExcludes() string { func (f *Filters) GetExcludes() string {
@ -130,19 +118,45 @@ func generateQueryParams(filters *Filters, sort string) string {
return "" return ""
} }
func stripQueryParams(inUrl string) (string, error) { func stripQueryParams(u string) (string, error) {
url, err := url.Parse(inUrl) uri, err := url.Parse(u)
if err != nil { if err != nil {
return "", err return "", err
} }
url.RawQuery = "" uri.RawQuery = ""
if runtime.GOOS == "windows" { escapedUri, err := url.QueryUnescape(uri.String())
return strings.TrimPrefix(url.String(), "/"), nil if err != nil {
return "", err
} }
return url.String(), nil if runtime.GOOS == "windows" {
return strings.TrimPrefix(escapedUri, "/"), nil
}
return escapedUri, nil
}
func createFilters(includes, excludes []string) Filters {
filters := Filters{}
if Filter {
filters.Includes = includes
filters.Excludes = excludes
}
return filters
}
func generateFilePath(filePath string) string {
htmlBody := PREFIX
if runtime.GOOS == "windows" {
htmlBody += "/"
}
htmlBody += filePath
return htmlBody
} }
func refererToUri(referer string) string { func refererToUri(referer string) string {
@ -160,6 +174,11 @@ func serveHtml(w http.ResponseWriter, r *http.Request, filePath, dimensions stri
w.Header().Add("Content-Type", "text/html") w.Header().Add("Content-Type", "text/html")
filters := Filters{}
if Filter {
filters = createFilters(splitQueryParams(r.URL.Query().Get("include")), splitQueryParams(r.URL.Query().Get("exclude")))
}
htmlBody := `<html lang="en"> htmlBody := `<html lang="en">
<head> <head>
<style> <style>
@ -171,31 +190,10 @@ func serveHtml(w http.ResponseWriter, r *http.Request, filePath, dimensions stri
htmlBody += `</title> htmlBody += `</title>
</head> </head>
<body> <body>
` <a href="/`
switch { htmlBody += generateQueryParams(&filters, r.URL.Query().Get("sort"))
case Filter && Sort: htmlBody += `"><img src="`
htmlBody += fmt.Sprintf(` <a href="/?include=%v&exclude=%v&sort=%v"><img src="`, htmlBody += generateFilePath(filePath)
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
if runtime.GOOS == "windows" {
htmlBody += "/"
}
htmlBody += filePath
htmlBody += `"></img></a> htmlBody += `"></img></a>
</body> </body>
</html>` </html>`
@ -209,12 +207,7 @@ func serveHtml(w http.ResponseWriter, r *http.Request, filePath, dimensions stri
} }
func serveStaticFile(w http.ResponseWriter, r *http.Request, paths []string) error { func serveStaticFile(w http.ResponseWriter, r *http.Request, paths []string) error {
strippedUrl, err := stripQueryParams(r.URL.Path) prefixedFilePath, err := stripQueryParams(r.URL.Path)
if err != nil {
return err
}
prefixedFilePath, err := url.QueryUnescape(strippedUrl)
if err != nil { if err != nil {
return err return err
} }
@ -279,54 +272,30 @@ func serveHtmlHandler(paths []string, re regexp.Regexp, fileCache *[]string) app
return err return err
} }
filters := Filters{} filters := createFilters(splitQueryParams(r.URL.Query().Get("include")), splitQueryParams(r.URL.Query().Get("exclude")))
if Filter {
filters.Includes = splitQueryParams(r.URL.Query().Get("include"))
filters.Excludes = splitQueryParams(r.URL.Query().Get("exclude"))
}
sortOrder := "" sortOrder := r.URL.Query().Get("sort")
if Sort {
sortOrder = r.URL.Query().Get("sort")
}
switch { switch {
case r.URL.Path == "/" && sortOrder == "asc" && refererUri != "": case r.URL.Path == "/" && refererUri != "":
query, err := url.QueryUnescape(refererUri) path, err := splitPath(refererUri, re)
if err != nil { if err != nil {
return err return err
} }
path, err := splitPath(query, re) filePath, err := getNextFile(path, sortOrder)
if err != nil {
return err
}
filePath, err := getNextFile(path)
if err != nil { if err != nil {
return err return err
} }
if filePath == "" { if filePath == "" {
filePath, err = pickFile(paths, &filters, sortOrder, fileCache) filePath, err = getNewFile(paths, &filters, sortOrder, re, fileCache)
switch { switch {
case err != nil && err == ErrNoImagesFound: case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r) http.NotFound(w, r)
return nil
case err != nil: case err != nil:
return err return err
} }
path, err := splitPath(filePath, re)
if err != nil {
return err
}
filePath, err = getFirstFile(path)
if err != nil {
return err
}
} }
newUrl := fmt.Sprintf("http://%v%v%v", newUrl := fmt.Sprintf("http://%v%v%v",
@ -335,109 +304,12 @@ func serveHtmlHandler(paths []string, re regexp.Regexp, fileCache *[]string) app
generateQueryParams(&filters, sortOrder), generateQueryParams(&filters, sortOrder),
) )
http.Redirect(w, r, newUrl, RedirectStatusCode) http.Redirect(w, r, newUrl, RedirectStatusCode)
case r.URL.Path == "/" && sortOrder == "asc" && refererUri == "": case r.URL.Path == "/" && refererUri == "":
filePath, err := pickFile(paths, &filters, sortOrder, fileCache) filePath, err := getNewFile(paths, &filters, sortOrder, re, fileCache)
if err != nil && err == ErrNoImagesFound { switch {
notFound(w, r) case err != nil && err == ErrNoImagesFound:
http.NotFound(w, r)
return nil case err != nil:
} else if err != nil {
return err
}
path, err := splitPath(filePath, re)
if err != nil {
return err
}
filePath, err = getFirstFile(path)
if err != nil {
return err
}
newUrl := fmt.Sprintf("http://%v%v%v",
r.Host,
preparePath(filePath),
generateQueryParams(&filters, sortOrder),
)
http.Redirect(w, r, newUrl, RedirectStatusCode)
case r.URL.Path == "/" && sortOrder == "desc" && refererUri != "":
query, err := url.QueryUnescape(refererUri)
if err != nil {
return err
}
path, err := splitPath(query, re)
if err != nil {
return err
}
filePath, err := getPreviousFile(path)
if err != nil {
return err
}
if filePath == "" {
filePath, err = pickFile(paths, &filters, sortOrder, fileCache)
switch {
case err != nil && err == ErrNoImagesFound:
notFound(w, r)
return nil
case err != nil:
return err
}
path, err := splitPath(filePath, re)
if err != nil {
return err
}
filePath, err = getLastFile(path)
if err != nil {
return err
}
}
newUrl := fmt.Sprintf("http://%v%v%v",
r.Host,
preparePath(filePath),
generateQueryParams(&filters, sortOrder),
)
http.Redirect(w, r, newUrl, RedirectStatusCode)
case r.URL.Path == "/" && sortOrder == "desc" && refererUri == "":
filePath, err := pickFile(paths, &filters, sortOrder, fileCache)
if err != nil && err == ErrNoImagesFound {
notFound(w, r)
return nil
} else if err != nil {
return err
}
path, err := splitPath(filePath, re)
if err != nil {
return err
}
filePath, err = getLastFile(path)
if err != nil {
return err
}
newUrl := fmt.Sprintf("http://%v%v%v",
r.Host,
preparePath(filePath),
generateQueryParams(&filters, sortOrder),
)
http.Redirect(w, r, newUrl, RedirectStatusCode)
case r.URL.Path == "/":
filePath, err := pickFile(paths, &filters, sortOrder, fileCache)
if err != nil && err == ErrNoImagesFound {
notFound(w, r)
return nil
} else if err != nil {
return err return err
} }
@ -461,8 +333,6 @@ func serveHtmlHandler(paths []string, re regexp.Regexp, fileCache *[]string) app
if !exists { if !exists {
notFound(w, r) notFound(w, r)
return nil
} }
image, err := isImage(filePath) image, err := isImage(filePath)
@ -471,8 +341,6 @@ func serveHtmlHandler(paths []string, re regexp.Regexp, fileCache *[]string) app
} }
if !image { if !image {
notFound(w, r) notFound(w, r)
return nil
} }
dimensions, err := getImageDimensions(filePath) dimensions, err := getImageDimensions(filePath)