V0.2.1 - search scope bugfix (#56)
Co-authored-by: Graham Steffaniak <graham.steffaniak@autodesk.com>
This commit is contained in:
parent
4bab354c99
commit
47e1975c12
|
@ -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]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
if !reflect.DeepEqual(got1, tt.want1) {
|
||||
t.Errorf("SearchAllIndexes() got1 = %v, want %v", got1, tt.want1)
|
||||
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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue