make more efficient
This commit is contained in:
parent
fedc6b7d46
commit
afd930262d
|
@ -4,5 +4,5 @@
|
||||||
"address": "",
|
"address": "",
|
||||||
"log": "stdout",
|
"log": "stdout",
|
||||||
"database": "./database.db",
|
"database": "./database.db",
|
||||||
"root": "./srv"
|
"root": "/srv"
|
||||||
}
|
}
|
|
@ -52,7 +52,6 @@ override the options.`,
|
||||||
Port: mustGetString(flags, "port"),
|
Port: mustGetString(flags, "port"),
|
||||||
Log: mustGetString(flags, "log"),
|
Log: mustGetString(flags, "log"),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := d.store.Settings.Save(s)
|
err := d.store.Settings.Save(s)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
err = d.store.Settings.SaveServer(ser)
|
err = d.store.Settings.SaveServer(ser)
|
||||||
|
|
|
@ -49,9 +49,6 @@ func init() {
|
||||||
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
|
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
|
||||||
|
|
||||||
flags := rootCmd.Flags()
|
flags := rootCmd.Flags()
|
||||||
// initialize indexing and schedule indexing ever n minutes (default 5)
|
|
||||||
indexingInterval := getEnvVariableAsUint32("INDEXING_INTERVAL")
|
|
||||||
go search.InitializeIndex(indexingInterval)
|
|
||||||
|
|
||||||
persistent := rootCmd.PersistentFlags()
|
persistent := rootCmd.PersistentFlags()
|
||||||
|
|
||||||
|
@ -153,6 +150,9 @@ user created with the credentials from options "username" and "password".`,
|
||||||
}
|
}
|
||||||
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
||||||
}
|
}
|
||||||
|
// initialize indexing and schedule indexing ever n minutes (default 5)
|
||||||
|
indexingInterval := getEnvVariableAsUint32("INDEXING_INTERVAL")
|
||||||
|
go search.InitializeIndex(indexingInterval)
|
||||||
|
|
||||||
server := getRunParams(cmd.Flags(), d.store)
|
server := getRunParams(cmd.Flags(), d.store)
|
||||||
setupLog(server.Log)
|
setupLog(server.Log)
|
||||||
|
@ -376,7 +376,6 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
||||||
Address: getParam(flags, "address"),
|
Address: getParam(flags, "address"),
|
||||||
Root: getParam(flags, "root"),
|
Root: getParam(flags, "root"),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Settings.SaveServer(ser)
|
err = d.store.Settings.SaveServer(ser)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
|
@ -1,78 +1,62 @@
|
||||||
package search
|
package search
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mime"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var typeRegexp = regexp.MustCompile(`type:(\w+)`)
|
||||||
typeRegexp = regexp.MustCompile(`type:(\w+)`)
|
|
||||||
)
|
var documentTypes = []string{
|
||||||
|
".word",
|
||||||
|
".pdf",
|
||||||
|
".txt",
|
||||||
|
}
|
||||||
|
|
||||||
|
var compressedFile = []string{
|
||||||
|
".7z",
|
||||||
|
".rar",
|
||||||
|
".zip",
|
||||||
|
".tar",
|
||||||
|
".tar.gz",
|
||||||
|
".tar.xz",
|
||||||
|
}
|
||||||
|
|
||||||
type searchOptions struct {
|
type searchOptions struct {
|
||||||
CaseSensitive bool
|
Conditions map[string]bool
|
||||||
Conditions []condition
|
|
||||||
Terms []string
|
Terms []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type condition func(path string) bool
|
|
||||||
|
|
||||||
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 {
|
func ParseSearch(value string) *searchOptions {
|
||||||
opts := &searchOptions{
|
opts := &searchOptions{
|
||||||
CaseSensitive: strings.Contains(value, "case:sensitive"),
|
Conditions: map[string]bool{
|
||||||
Conditions: []condition{},
|
"exact": strings.Contains(value, "case:exact"),
|
||||||
|
},
|
||||||
Terms: []string{},
|
Terms: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes the options from the value
|
// removes the options from the value
|
||||||
value = strings.Replace(value, "case:insensitive", "", -1)
|
value = strings.Replace(value, "case:exact", "", -1)
|
||||||
value = strings.Replace(value, "case:sensitive", "", -1)
|
value = strings.Replace(value, "case:exact", "", -1)
|
||||||
value = strings.TrimSpace(value)
|
value = strings.TrimSpace(value)
|
||||||
|
|
||||||
types := typeRegexp.FindAllStringSubmatch(value, -1)
|
types := typeRegexp.FindAllStringSubmatch(value, -1)
|
||||||
for _, t := range types {
|
for _, filterType := range types {
|
||||||
if len(t) == 1 {
|
if len(filterType) == 1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch t[1] {
|
switch filterType[1] {
|
||||||
case "image":
|
case "image":
|
||||||
opts.Conditions = append(opts.Conditions, imageCondition)
|
opts.Conditions["image"] = true
|
||||||
case "audio", "music":
|
case "audio", "music":
|
||||||
opts.Conditions = append(opts.Conditions, audioCondition)
|
opts.Conditions["audio"] = true
|
||||||
case "video":
|
case "video":
|
||||||
opts.Conditions = append(opts.Conditions, videoCondition)
|
opts.Conditions["video"] = true
|
||||||
default:
|
case "doc":
|
||||||
opts.Conditions = append(opts.Conditions, extensionCondition(t[1]))
|
opts.Conditions["doc"] = true
|
||||||
|
case "zip":
|
||||||
|
opts.Conditions["zip"] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,14 +65,6 @@ func ParseSearch(value string) *searchOptions {
|
||||||
value = typeRegexp.ReplaceAllString(value, "")
|
value = typeRegexp.ReplaceAllString(value, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's case insensitive, put everything in lowercase.
|
|
||||||
if !opts.CaseSensitive {
|
|
||||||
value = strings.ToLower(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the spaces from the search value.
|
|
||||||
value = strings.TrimSpace(value)
|
|
||||||
|
|
||||||
if value == "" {
|
if value == "" {
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"mime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rootPath = "/srv" // DO NOT include trailing slash
|
rootPath string = "/srv"
|
||||||
indexes map[string][]string
|
indexes map[string][]string
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
lastIndexed time.Time
|
lastIndexed time.Time
|
||||||
|
@ -111,6 +112,9 @@ func SearchAllIndexes(search string, scope string) ([]string, []string) {
|
||||||
maximum := 100
|
maximum := 100
|
||||||
count := 0
|
count := 0
|
||||||
for _, searchTerm := range searchOptions.Terms {
|
for _, searchTerm := range searchOptions.Terms {
|
||||||
|
if searchTerm == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// Iterate over the indexes
|
// Iterate over the indexes
|
||||||
for dirName, v := range indexes {
|
for dirName, v := range indexes {
|
||||||
if count > maximum {
|
if count > maximum {
|
||||||
|
@ -126,7 +130,7 @@ func SearchAllIndexes(search string, scope string) ([]string, []string) {
|
||||||
pathName = dirName + "/" + pathName
|
pathName = dirName + "/" + pathName
|
||||||
}
|
}
|
||||||
// Check if the path name contains the search term
|
// Check if the path name contains the search term
|
||||||
if !containsSearchTerm(pathName, searchTerm, searchOptions.conditions) {
|
if !containsSearchTerm(pathName, searchTerm, searchOptions.Conditions) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pathName = scopedPathNameFilter(pathName, scope)
|
pathName = scopedPathNameFilter(pathName, scope)
|
||||||
|
@ -137,7 +141,7 @@ func SearchAllIndexes(search string, scope string) ([]string, []string) {
|
||||||
matchingFiles = append(matchingFiles, pathName)
|
matchingFiles = append(matchingFiles, pathName)
|
||||||
}
|
}
|
||||||
// Check if the path name contains the search term
|
// Check if the path name contains the search term
|
||||||
if !containsSearchTerm(dirName, searchTerm, searchOptions.conditions) {
|
if !containsSearchTerm(dirName, searchTerm, searchOptions.Conditions) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pathName := scopedPathNameFilter(dirName, scope)
|
pathName := scopedPathNameFilter(dirName, scope)
|
||||||
|
@ -173,13 +177,51 @@ func scopedPathNameFilter(pathName string, scope string) string {
|
||||||
return pathName
|
return pathName
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsSearchTerm(pathName string, searchTerm string, conditions []string) bool {
|
func containsSearchTerm(pathName string, searchTerm string, conditions map[string]bool) bool {
|
||||||
path := getLastPathComponent(pathName)
|
path := getLastPathComponent(pathName)
|
||||||
// Perform case-insensitive search
|
if !conditions["exact"] {
|
||||||
pathNameLower := strings.ToLower(path)
|
path = strings.ToLower(path)
|
||||||
searchTermLower := strings.ToLower(searchTerm)
|
searchTerm = strings.ToLower(searchTerm)
|
||||||
|
}
|
||||||
return strings.Contains(pathNameLower, searchTermLower)
|
matchesCondition := true
|
||||||
|
if conditions["audio"] {
|
||||||
|
extension := filepath.Ext(path)
|
||||||
|
mimetype := mime.TypeByExtension(extension)
|
||||||
|
matchesCondition = strings.HasPrefix(mimetype, "audio")
|
||||||
|
}
|
||||||
|
if conditions["video"] {
|
||||||
|
extension := filepath.Ext(path)
|
||||||
|
mimetype := mime.TypeByExtension(extension)
|
||||||
|
matchesCondition = strings.HasPrefix(mimetype, "video")
|
||||||
|
}
|
||||||
|
if conditions["image"] {
|
||||||
|
extension := filepath.Ext(path)
|
||||||
|
mimetype := mime.TypeByExtension(extension)
|
||||||
|
matchesCondition = strings.HasPrefix(mimetype, "image")
|
||||||
|
}
|
||||||
|
if conditions["doc"] {
|
||||||
|
extension := filepath.Ext(path)
|
||||||
|
for _, typefile := range documentTypes {
|
||||||
|
if extension == typefile {
|
||||||
|
matchesCondition = true
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
matchesCondition = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if conditions["zip"] {
|
||||||
|
extension := filepath.Ext(path)
|
||||||
|
for _, typefile := range compressedFile {
|
||||||
|
if extension == typefile {
|
||||||
|
matchesCondition = true
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
matchesCondition = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Contains(path, searchTerm) && matchesCondition
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLastPathComponent(path string) string {
|
func getLastPathComponent(path string) string {
|
||||||
|
|
Loading…
Reference in New Issue