Search by type

Former-commit-id: 6d0ea8a6b661cef0a456c622d0a4b8fa6252f562 [formerly 135ecb5636bb5ced2eb4f21c104b6d34bc4d267f] [formerly c62017f660b5ee6acddab0e35a97d03a18e2668d [formerly a3447bf232]]
Former-commit-id: ad0aaa54b887fdabed54127113fee389255b3621 [formerly 1aeda20fcdb5e6f172b8ce5f6df8e5585aeca9da]
Former-commit-id: 72c5bb017241c7f5fcfafd9aae7d79f0f527515a
This commit is contained in:
Henrique Dias 2017-07-25 16:15:40 +01:00
parent 38ef96b5f3
commit 4b2caeabd0

View File

@ -2,10 +2,12 @@ package filemanager
import (
"bytes"
"mime"
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"
@ -135,14 +137,50 @@ func command(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, er
return 0, nil
}
var (
typeRegexp = regexp.MustCompile(`type:(\w+)`)
)
type condition func(path string) bool
type searchOptions struct {
CaseInsensitive bool
Conditions []condition
Terms []string
}
func extensionCondition(extension string) condition {
return func(path string) bool {
return filepath.Ext(path) == "."+extension
}
}
func imageCondition(path string) bool {
extension := filepath.Ext(path)
mimetype := mime.TypeByExtension(extension)
return strings.HasPrefix(mimetype, "image")
}
func audioCondition(path string) bool {
extension := filepath.Ext(path)
mimetype := mime.TypeByExtension(extension)
return strings.HasPrefix(mimetype, "audio")
}
func videoCondition(path string) bool {
extension := filepath.Ext(path)
mimetype := mime.TypeByExtension(extension)
return strings.HasPrefix(mimetype, "video")
}
func parseSearch(value string) *searchOptions {
opts := &searchOptions{
CaseInsensitive: strings.Contains(value, "case:insensitive"),
Conditions: []condition{},
Terms: []string{},
}
// removes the options from the value
@ -150,10 +188,41 @@ func parseSearch(value string) *searchOptions {
value = strings.Replace(value, "case:sensitive", "", -1)
value = strings.TrimSpace(value)
types := typeRegexp.FindAllStringSubmatch(value, -1)
for _, t := range types {
if len(t) == 1 {
continue
}
switch t[1] {
case "image":
opts.Conditions = append(opts.Conditions, imageCondition)
case "audio", "music":
opts.Conditions = append(opts.Conditions, audioCondition)
case "video":
opts.Conditions = append(opts.Conditions, videoCondition)
default:
opts.Conditions = append(opts.Conditions, extensionCondition(t[1]))
}
}
if len(types) > 0 {
// Remove the fields from the search value.
value = typeRegexp.ReplaceAllString(value, "")
}
// If it's canse insensitive, put everything in lowercase.
if opts.CaseInsensitive {
value = strings.ToLower(value)
}
// Remove the spaces from the search value.
value = strings.TrimSpace(value)
if value == "" {
return opts
}
// if the value starts with " and finishes what that character, we will
// only search for that term
if value[0] == '"' && value[len(value)-1] == '"' {
@ -211,24 +280,45 @@ func search(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, err
path = strings.TrimPrefix(path, scope)
path = strings.TrimPrefix(path, "/")
path = strings.Replace(path, "\\", "/", -1)
is := false
for _, term := range search.Terms {
if is {
break
// Only execute if there are conditions to meet.
if len(search.Conditions) > 0 {
match := false
for _, t := range search.Conditions {
if t(path) {
match = true
break
}
}
if strings.Contains(path, term) {
if !c.User.Allowed(path) {
return nil
}
is = true
// If doesn't meet the condition, go to the next.
if !match {
return nil
}
}
if !is {
return nil
if len(search.Terms) > 0 {
is := false
// Checks if matches the terms and if it is allowed.
for _, term := range search.Terms {
if is {
break
}
if strings.Contains(path, term) {
if !c.User.Allowed(path) {
return nil
}
is = true
}
}
if !is {
return nil
}
}
return conn.WriteMessage(websocket.TextMessage, []byte(path))