V0.2.1 - search scope bugfix (#56)

Co-authored-by: Graham Steffaniak <graham.steffaniak@autodesk.com>
This commit is contained in:
Graham Steffaniak 2023-10-18 10:32:22 -05:00 committed by GitHub
parent 4bab354c99
commit 47e1975c12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 123 additions and 80 deletions

View File

@ -5,33 +5,45 @@
? github.com/gtsteffaniak/filebrowser/auth [no test files]
? github.com/gtsteffaniak/filebrowser/cmd [no test files]
PASS
ok github.com/gtsteffaniak/filebrowser/diskcache 0.003s
ok github.com/gtsteffaniak/filebrowser/diskcache 0.004s
? github.com/gtsteffaniak/filebrowser/errors [no test files]
? github.com/gtsteffaniak/filebrowser/files [no test files]
PASS
ok github.com/gtsteffaniak/filebrowser/fileutils 0.003s
2023/09/24 12:52:05 h: 401 <nil>
2023/09/24 12:52:05 h: 401 <nil>
2023/09/24 12:52:05 h: 401 <nil>
2023/09/24 12:52:05 h: 401 <nil>
2023/09/24 12:52:05 h: 401 <nil>
2023/09/24 12:52:05 h: 401 <nil>
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 h: 401 <nil>
2023/10/18 10:19:52 h: 401 <nil>
2023/10/18 10:19:52 h: 401 <nil>
2023/10/18 10:19:52 h: 401 <nil>
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:52 Saving new user: username
2023/10/18 10:19:53 h: 401 <nil>
2023/10/18 10:19:53 h: 401 <nil>
PASS
ok github.com/gtsteffaniak/filebrowser/http 0.094s
ok github.com/gtsteffaniak/filebrowser/http 0.208s
PASS
ok github.com/gtsteffaniak/filebrowser/img 0.144s
ok github.com/gtsteffaniak/filebrowser/img 0.124s
goos: linux
goarch: amd64
pkg: github.com/gtsteffaniak/filebrowser/index
cpu: 11th Gen Intel(R) Core(TM) i5-11320H @ 3.20GHz
BenchmarkFillIndex-8 10 3239196 ns/op 11289 B/op 448 allocs/op
BenchmarkSearchAllIndexes-8 10 6645964 ns/op 3176834 B/op 59104 allocs/op
PASS
ok github.com/gtsteffaniak/filebrowser/index 0.126s
PASS
ok github.com/gtsteffaniak/filebrowser/rules 0.002s
PASS
ok github.com/gtsteffaniak/filebrowser/runner 0.003s
goos: linux
goarch: amd64
pkg: github.com/gtsteffaniak/filebrowser/search
cpu: 11th Gen Intel(R) Core(TM) i5-11320H @ 3.20GHz
BenchmarkSearchAllIndexes-8 10 5912685 ns/op 3003976 B/op 46139 allocs/op
BenchmarkFillIndex-8 10 3157995 ns/op 18370 B/op 449 allocs/op
PASS
ok github.com/gtsteffaniak/filebrowser/search 0.116s
PASS
ok github.com/gtsteffaniak/filebrowser/settings 0.005s
? github.com/gtsteffaniak/filebrowser/share [no test files]

View File

@ -2,6 +2,7 @@ package http
import (
"net/http"
"strings"
"github.com/gtsteffaniak/filebrowser/index"
)
@ -11,8 +12,11 @@ var searchHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *dat
query := r.URL.Query().Get("query")
// Retrieve the User-Agent and X-Auth headers from the request
sessionId := r.Header.Get("SessionId")
userScope := r.Header.Get("UserScope")
index := *index.GetIndex()
results, fileTypes := index.Search(query, r.URL.Path, sessionId)
combinedScope := strings.TrimPrefix(userScope+r.URL.Path, ".")
combinedScope = strings.TrimPrefix(combinedScope, "/")
results, fileTypes := index.Search(query, combinedScope, sessionId)
for _, path := range results {
responseObj := map[string]interface{}{
"path": path,

View File

@ -8,7 +8,14 @@ import (
)
var typeRegexp = regexp.MustCompile(`type:(\S+)`)
var AllFiletypeOptions = []string{
"image",
"audio",
"archive",
"video",
"doc",
"dir",
}
var documentTypes = []string{
".word",
".pdf",

View File

@ -18,13 +18,18 @@ var (
)
func (si *Index) Search(search string, scope string, sourceSession string) ([]string, map[string]map[string]bool) {
if scope == "" {
scope = "/"
}
fileTypes := map[string]bool{}
runningHash := generateRandomHash(4)
sessionInProgress.Store(sourceSession, runningHash) // Store the value in the sync.Map
searchOptions := ParseSearch(search)
mutex.RLock()
defer mutex.RUnlock()
fileListTypes := make(map[string]map[string]bool)
var matching []string
matching := []string{}
for _, searchTerm := range searchOptions.Terms {
if searchTerm == "" {
continue
@ -42,7 +47,6 @@ func (si *Index) Search(search string, scope string, sourceSession string) ([]st
case "Files":
paths = si.Files
}
for _, path := range paths {
value, found := sessionInProgress.Load(sourceSession)
if !found || value != runningHash {
@ -55,7 +59,8 @@ func (si *Index) Search(search string, scope string, sourceSession string) ([]st
if pathName == "" {
continue
}
matches, fileType := containsSearchTerm(path, searchTerm, *searchOptions, isDir)
matches, fileType := containsSearchTerm(path, searchTerm, *searchOptions, isDir, fileTypes)
if !matches {
continue
}
@ -80,24 +85,16 @@ func (si *Index) Search(search string, scope string, sourceSession string) ([]st
func scopedPathNameFilter(pathName string, scope string) string {
scope = strings.TrimPrefix(scope, "/")
pathName = strings.TrimPrefix(pathName, "/")
if strings.HasPrefix(pathName, scope) {
pathName = strings.TrimPrefix(pathName, scope)
pathName = "/" + strings.TrimPrefix(pathName, scope)
} else {
pathName = ""
}
return pathName
}
var fileTypes = map[string]bool{
"audio": false,
"image": false,
"video": false,
"doc": false,
"archive": false,
"dir": false,
}
func containsSearchTerm(pathName string, searchTerm string, options SearchOptions, isDir bool) (bool, map[string]bool) {
func containsSearchTerm(pathName string, searchTerm string, options SearchOptions, isDir bool, fileTypes map[string]bool) (bool, map[string]bool) {
conditions := options.Conditions
path := getLastPathComponent(pathName)
// Convert to lowercase once
@ -110,11 +107,12 @@ func containsSearchTerm(pathName string, searchTerm string, options SearchOption
var fileSize int64
matchesAllConditions := true
extension := filepath.Ext(path)
for k := range fileTypes {
fileTypes[k] = IsMatchingType(extension, k)
for _, k := range AllFiletypeOptions {
if IsMatchingType(extension, k) {
fileTypes[k] = true
}
}
fileTypes["dir"] = isDir
for t, v := range conditions {
if t == "exact" {
continue

View File

@ -3,6 +3,8 @@ package index
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
)
func BenchmarkSearchAllIndexes(b *testing.B) {
@ -75,27 +77,74 @@ func TestParseSearch(t *testing.T) {
}
func TestSearchIndexes(t *testing.T) {
type args struct {
search string
scope string
sourceSession string
indexes = Index{
Dirs: []string{
"/test",
"/test/path",
"/new/test/path",
},
Files: []string{
"/test/path/file.txt",
"/test/audio1.wav",
"/new/test/audio.wav",
"/new/test/video.mp4",
"/new/test/video.MP4",
"/new/test/path/archive.zip",
},
}
tests := []struct {
name string
args args
want []string
want1 map[string]map[string]bool
search string
scope string
expectedResult []string
expectedTypes map[string]map[string]bool
}{
// TODO: Add test cases.
{
search: "audio",
scope: "/new/",
expectedResult: []string{"/test/audio.wav"},
expectedTypes: map[string]map[string]bool{
"/test/audio.wav": map[string]bool{"audio": true, "dir": false},
},
},
{
search: "test",
scope: "/",
expectedResult: []string{"/test"},
expectedTypes: map[string]map[string]bool{
"/test/": map[string]bool{"dir": true},
},
},
{
search: "archive",
scope: "/",
expectedResult: []string{"/new/test/path/archive.zip"},
expectedTypes: map[string]map[string]bool{
"/new/test/path/archive.zip": map[string]bool{"archive": true, "dir": false},
},
},
{
search: "video",
scope: "/",
expectedResult: []string{
"/new/test/video.mp4",
"/new/test/video.MP4",
},
expectedTypes: map[string]map[string]bool{
"/new/test/video.MP4": map[string]bool{"video": true, "dir": false},
"/new/test/video.mp4": map[string]bool{"video": true, "dir": false},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := indexes.Search(tt.args.search, tt.args.scope, tt.args.sourceSession)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("SearchAllIndexes() got = %v, want %v", got, tt.want)
t.Run(tt.search, func(t *testing.T) {
actualResult, actualTypes := indexes.Search(tt.search, tt.scope, "")
assert.Equal(t, tt.expectedResult, actualResult)
if len(tt.expectedTypes) > 0 {
for key, value := range tt.expectedTypes {
actualValue, exists := actualTypes[key]
assert.True(t, exists, "Expected type key '%s' not found in actual types", key)
assert.Equal(t, value, actualValue, "Type value mismatch for key '%s'", key)
}
if !reflect.DeepEqual(got1, tt.want1) {
t.Errorf("SearchAllIndexes() got1 = %v, want %v", got1, tt.want1)
}
})
}
@ -122,34 +171,6 @@ func Test_scopedPathNameFilter(t *testing.T) {
}
}
func Test_containsSearchTerm(t *testing.T) {
type args struct {
pathName string
searchTerm string
options SearchOptions
isDir bool
}
tests := []struct {
name string
args args
want bool
want1 map[string]bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := containsSearchTerm(tt.args.pathName, tt.args.searchTerm, tt.args.options, tt.args.isDir)
if got != tt.want {
t.Errorf("containsSearchTerm() got = %v, want %v", got, tt.want)
}
if !reflect.DeepEqual(got1, tt.want1) {
t.Errorf("containsSearchTerm() got1 = %v, want %v", got1, tt.want1)
}
})
}
}
func Test_isDoc(t *testing.T) {
type args struct {
extension string

View File

@ -15,6 +15,7 @@ export async function fetchURL(url, opts, auth = true) {
headers: {
"X-Auth": store.state.jwt,
"sessionId": store.state.sessionId,
"userScope": store.state.user.scope,
...headers,
},
...rest,