diff --git a/src/backend/.filebrowser.json b/src/backend/.filebrowser.json index 70b42d51..885ddf54 100644 --- a/src/backend/.filebrowser.json +++ b/src/backend/.filebrowser.json @@ -4,5 +4,5 @@ "address": "", "log": "stdout", "database": "./database.db", - "root": "./srv" + "root": "/srv" } \ No newline at end of file diff --git a/src/backend/cmd/config_init.go b/src/backend/cmd/config_init.go index 9e3773fc..4f3b4050 100644 --- a/src/backend/cmd/config_init.go +++ b/src/backend/cmd/config_init.go @@ -52,7 +52,6 @@ override the options.`, Port: mustGetString(flags, "port"), Log: mustGetString(flags, "log"), } - err := d.store.Settings.Save(s) checkErr(err) err = d.store.Settings.SaveServer(ser) diff --git a/src/backend/cmd/root.go b/src/backend/cmd/root.go index deb9a525..9191df22 100644 --- a/src/backend/cmd/root.go +++ b/src/backend/cmd/root.go @@ -49,9 +49,6 @@ func init() { rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n") flags := rootCmd.Flags() - // initialize indexing and schedule indexing ever n minutes (default 5) - indexingInterval := getEnvVariableAsUint32("INDEXING_INTERVAL") - go search.InitializeIndex(indexingInterval) persistent := rootCmd.PersistentFlags() @@ -153,6 +150,9 @@ user created with the credentials from options "username" and "password".`, } 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) setupLog(server.Log) @@ -376,7 +376,6 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) { Address: getParam(flags, "address"), Root: getParam(flags, "root"), } - err = d.store.Settings.SaveServer(ser) checkErr(err) diff --git a/src/backend/filebrowser b/src/backend/filebrowser new file mode 100755 index 00000000..690fd9be Binary files /dev/null and b/src/backend/filebrowser differ diff --git a/src/backend/frontend/dist/.gitignore b/src/backend/frontend/dist/.gitignore new file mode 100644 index 00000000..86d0cb27 --- /dev/null +++ b/src/backend/frontend/dist/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/src/backend/search/conditions.go b/src/backend/search/conditions.go index 8778d378..9c7e3a58 100644 --- a/src/backend/search/conditions.go +++ b/src/backend/search/conditions.go @@ -1,78 +1,62 @@ package search import ( - "mime" - "path/filepath" "regexp" "strings" ) -var ( - typeRegexp = regexp.MustCompile(`type:(\w+)`) -) +var 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 { - CaseSensitive bool - Conditions []condition + Conditions map[string]bool 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 { opts := &searchOptions{ - CaseSensitive: strings.Contains(value, "case:sensitive"), - Conditions: []condition{}, + Conditions: map[string]bool{ + "exact": strings.Contains(value, "case:exact"), + }, Terms: []string{}, } // removes the options from the value - value = strings.Replace(value, "case:insensitive", "", -1) - value = strings.Replace(value, "case:sensitive", "", -1) + value = strings.Replace(value, "case:exact", "", -1) + value = strings.Replace(value, "case:exact", "", -1) value = strings.TrimSpace(value) types := typeRegexp.FindAllStringSubmatch(value, -1) - for _, t := range types { - if len(t) == 1 { + for _, filterType := range types { + if len(filterType) == 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])) + + switch filterType[1] { + case "image": + opts.Conditions["image"] = true + case "audio", "music": + opts.Conditions["audio"] = true + case "video": + opts.Conditions["video"] = true + case "doc": + opts.Conditions["doc"] = true + case "zip": + opts.Conditions["zip"] = true } } @@ -81,14 +65,6 @@ func ParseSearch(value string) *searchOptions { 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 == "" { return opts } diff --git a/src/backend/search/indexing.go b/src/backend/search/indexing.go index cb34121a..21d70335 100644 --- a/src/backend/search/indexing.go +++ b/src/backend/search/indexing.go @@ -8,10 +8,11 @@ import ( "strings" "sync" "time" + "mime" ) var ( - rootPath = "/srv" // DO NOT include trailing slash + rootPath string = "/srv" indexes map[string][]string mutex sync.RWMutex lastIndexed time.Time @@ -111,6 +112,9 @@ func SearchAllIndexes(search string, scope string) ([]string, []string) { maximum := 100 count := 0 for _, searchTerm := range searchOptions.Terms { + if searchTerm == "" { + continue + } // Iterate over the indexes for dirName, v := range indexes { if count > maximum { @@ -126,7 +130,7 @@ func SearchAllIndexes(search string, scope string) ([]string, []string) { pathName = dirName + "/" + pathName } // Check if the path name contains the search term - if !containsSearchTerm(pathName, searchTerm, searchOptions.conditions) { + if !containsSearchTerm(pathName, searchTerm, searchOptions.Conditions) { continue } pathName = scopedPathNameFilter(pathName, scope) @@ -137,7 +141,7 @@ func SearchAllIndexes(search string, scope string) ([]string, []string) { matchingFiles = append(matchingFiles, pathName) } // Check if the path name contains the search term - if !containsSearchTerm(dirName, searchTerm, searchOptions.conditions) { + if !containsSearchTerm(dirName, searchTerm, searchOptions.Conditions) { continue } pathName := scopedPathNameFilter(dirName, scope) @@ -173,13 +177,51 @@ func scopedPathNameFilter(pathName string, scope string) string { return pathName } -func containsSearchTerm(pathName string, searchTerm string, conditions []string) bool { - path := getLastPathComponent(pathName) - // Perform case-insensitive search - pathNameLower := strings.ToLower(path) - searchTermLower := strings.ToLower(searchTerm) - - return strings.Contains(pathNameLower, searchTermLower) +func containsSearchTerm(pathName string, searchTerm string, conditions map[string]bool) bool { + path := getLastPathComponent(pathName) + if !conditions["exact"] { + path = strings.ToLower(path) + searchTerm = strings.ToLower(searchTerm) + } + 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 {