improve search #88
parent
de480c25bb
commit
1ff0c6cb68
22
README.md
22
README.md
|
@ -141,6 +141,28 @@ filemanager /admin {
|
|||
}
|
||||
```
|
||||
|
||||
## About Search
|
||||
|
||||
FileManager allows you to search through your files and it has some options. By default, your search will be something like this:
|
||||
|
||||
```
|
||||
this are keywords
|
||||
```
|
||||
|
||||
If you search for that it will look at every file that contains "this", "are" and "keywords" on their name. If you want to search for an exact term, you should surround your search by double quotes:
|
||||
|
||||
```
|
||||
"this is the name"
|
||||
```
|
||||
|
||||
That will search for any file that contains "this is the name" on its name. It won't search for each separated term this time.
|
||||
|
||||
By default, every search will be case sensitive. Although, you can make a case insensitive search by adding `case:insensitive` to the search terms, like this:
|
||||
|
||||
```
|
||||
this are keywords case:insensitive
|
||||
```
|
||||
|
||||
## Developers
|
||||
|
||||
If you want to build Caddy from source with this plugin, you should take the following steps:
|
||||
|
|
|
@ -10,6 +10,39 @@ import (
|
|||
"github.com/hacdias/caddy-filemanager/config"
|
||||
)
|
||||
|
||||
type searchOptions struct {
|
||||
CaseInsensitive bool
|
||||
Terms []string
|
||||
}
|
||||
|
||||
func parseSearch(value string) *searchOptions {
|
||||
opts := &searchOptions{
|
||||
CaseInsensitive: strings.Contains(value, "case:insensitive"),
|
||||
}
|
||||
|
||||
// removes the options from the value
|
||||
value = strings.Replace(value, "case:insensitive", "", -1)
|
||||
value = strings.Replace(value, "case:sensitive", "", -1)
|
||||
value = strings.TrimSpace(value)
|
||||
|
||||
if opts.CaseInsensitive {
|
||||
value = strings.ToLower(value)
|
||||
}
|
||||
|
||||
// if the value starts with " and finishes what that character, we will
|
||||
// only search for that term
|
||||
if value[0] == '"' && value[len(value)-1] == '"' {
|
||||
unique := strings.TrimPrefix(value, "\"")
|
||||
unique = strings.TrimSuffix(unique, "\"")
|
||||
|
||||
opts.Terms = []string{unique}
|
||||
return opts
|
||||
}
|
||||
|
||||
opts.Terms = strings.Split(value, " ")
|
||||
return opts
|
||||
}
|
||||
|
||||
// Search ...
|
||||
func Search(w http.ResponseWriter, r *http.Request, c *config.Config, u *config.User) (int, error) {
|
||||
// Upgrades the connection to a websocket and checks for errors.
|
||||
|
@ -20,12 +53,11 @@ func Search(w http.ResponseWriter, r *http.Request, c *config.Config, u *config.
|
|||
defer conn.Close()
|
||||
|
||||
var (
|
||||
search string
|
||||
value string
|
||||
search *searchOptions
|
||||
message []byte
|
||||
)
|
||||
|
||||
caseInsensitive := (r.URL.Query().Get("insensitive") == "true")
|
||||
|
||||
// Starts an infinite loop until a valid command is captured.
|
||||
for {
|
||||
_, message, err = conn.ReadMessage()
|
||||
|
@ -34,15 +66,12 @@ func Search(w http.ResponseWriter, r *http.Request, c *config.Config, u *config.
|
|||
}
|
||||
|
||||
if len(message) != 0 {
|
||||
search = string(message)
|
||||
value = string(message)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if caseInsensitive {
|
||||
search = strings.ToLower(search)
|
||||
}
|
||||
|
||||
search = parseSearch(value)
|
||||
scope := strings.Replace(r.URL.Path, c.BaseURL, "", 1)
|
||||
scope = strings.TrimPrefix(scope, "/")
|
||||
scope = "/" + scope
|
||||
|
@ -51,22 +80,25 @@ func Search(w http.ResponseWriter, r *http.Request, c *config.Config, u *config.
|
|||
scope = filepath.Clean(scope)
|
||||
|
||||
err = filepath.Walk(scope, func(path string, f os.FileInfo, err error) error {
|
||||
if caseInsensitive {
|
||||
if search.CaseInsensitive {
|
||||
path = strings.ToLower(path)
|
||||
}
|
||||
|
||||
if strings.Contains(path, search) {
|
||||
if !u.Allowed(path) {
|
||||
return nil
|
||||
}
|
||||
path = strings.Replace(path, "\\", "/", -1)
|
||||
|
||||
path = strings.TrimPrefix(path, scope)
|
||||
path = strings.Replace(path, "\\", "/", -1)
|
||||
path = strings.TrimPrefix(path, "/")
|
||||
for _, term := range search.Terms {
|
||||
if strings.Contains(path, term) {
|
||||
if !u.Allowed(path) {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = conn.WriteMessage(websocket.TextMessage, []byte(path))
|
||||
if err != nil {
|
||||
return err
|
||||
path = strings.TrimPrefix(path, scope)
|
||||
path = strings.TrimPrefix(path, "/")
|
||||
|
||||
err = conn.WriteMessage(websocket.TextMessage, []byte(path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue