make more efficient

This commit is contained in:
Graham Steffaniak 2023-07-04 18:55:15 -05:00
parent fedc6b7d46
commit afd930262d
7 changed files with 96 additions and 76 deletions

View File

@ -4,5 +4,5 @@
"address": "", "address": "",
"log": "stdout", "log": "stdout",
"database": "./database.db", "database": "./database.db",
"root": "./srv" "root": "/srv"
} }

View File

@ -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)

View File

@ -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)

BIN
src/backend/filebrowser Executable file

Binary file not shown.

4
src/backend/frontend/dist/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

View File

@ -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
} }

View File

@ -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 {