Merge pull request #1530 from Zillode/multi-scan

Support multiple scan query strings at the same time
This commit is contained in:
Jakob Borg 2015-03-29 16:02:45 +02:00
commit ba575f55ec
4 changed files with 50 additions and 23 deletions

View File

@ -685,8 +685,8 @@ func restPostScan(m *model.Model, w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query() qs := r.URL.Query()
folder := qs.Get("folder") folder := qs.Get("folder")
if folder != "" { if folder != "" {
sub := qs.Get("sub") subs := qs["sub"]
err := m.ScanFolderSub(folder, sub) err := m.ScanFolderSubs(folder, subs)
if err != nil { if err != nil {
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), 500)
} }

View File

@ -1114,14 +1114,17 @@ func (m *Model) ScanFolders() map[string]error {
} }
func (m *Model) ScanFolder(folder string) error { func (m *Model) ScanFolder(folder string) error {
return m.ScanFolderSub(folder, "") return m.ScanFolderSubs(folder, nil)
} }
func (m *Model) ScanFolderSub(folder, sub string) error { func (m *Model) ScanFolderSubs(folder string, subs []string) error {
for i, sub := range subs {
sub = osutil.NativeFilename(sub) sub = osutil.NativeFilename(sub)
if p := filepath.Clean(filepath.Join(folder, sub)); !strings.HasPrefix(p, folder) { if p := filepath.Clean(filepath.Join(folder, sub)); !strings.HasPrefix(p, folder) {
return errors.New("invalid subpath") return errors.New("invalid subpath")
} }
subs[i] = sub
}
m.fmut.Lock() m.fmut.Lock()
fs := m.folderFiles[folder] fs := m.folderFiles[folder]
@ -1141,6 +1144,9 @@ func (m *Model) ScanFolderSub(folder, sub string) error {
// Required to make sure that we start indexing at a directory we're already // Required to make sure that we start indexing at a directory we're already
// aware off. // aware off.
var unifySubs []string
nextSub:
for _, sub := range subs {
for sub != "" { for sub != "" {
if _, ok = fs.Get(protocol.LocalDeviceID, sub); ok { if _, ok = fs.Get(protocol.LocalDeviceID, sub); ok {
break break
@ -1150,10 +1156,18 @@ func (m *Model) ScanFolderSub(folder, sub string) error {
sub = "" sub = ""
} }
} }
for _, us := range unifySubs {
if strings.HasPrefix(sub, us) {
continue nextSub
}
}
unifySubs = append(unifySubs, sub)
}
subs = unifySubs
w := &scanner.Walker{ w := &scanner.Walker{
Dir: folderCfg.Path, Dir: folderCfg.Path,
Sub: sub, Subs: subs,
Matcher: ignores, Matcher: ignores,
BlockSize: protocol.BlockSize, BlockSize: protocol.BlockSize,
TempNamer: defTempNamer, TempNamer: defTempNamer,
@ -1196,10 +1210,17 @@ func (m *Model) ScanFolderSub(folder, sub string) error {
seenPrefix := false seenPrefix := false
fs.WithHaveTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool { fs.WithHaveTruncated(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
f := fi.(db.FileInfoTruncated) f := fi.(db.FileInfoTruncated)
if !strings.HasPrefix(f.Name, sub) { hasPrefix := len(subs) == 0
for _, sub := range subs {
if strings.HasPrefix(f.Name, sub) {
hasPrefix = true
break
}
}
// Return true so that we keep iterating, until we get to the part // Return true so that we keep iterating, until we get to the part
// of the tree we are interested in. Then return false so we stop // of the tree we are interested in. Then return false so we stop
// iterating when we've passed the end of the subtree. // iterating when we've passed the end of the subtree.
if !hasPrefix {
return !seenPrefix return !seenPrefix
} }

View File

@ -39,8 +39,8 @@ func init() {
type Walker struct { type Walker struct {
// Dir is the base directory for the walk // Dir is the base directory for the walk
Dir string Dir string
// Limit walking to this path within Dir, or no limit if Sub is blank // Limit walking to these paths within Dir, or no limit if Sub is empty
Sub string Subs []string
// BlockSize controls the size of the block used when hashing. // BlockSize controls the size of the block used when hashing.
BlockSize int BlockSize int
// If Matcher is not nil, it is used to identify files to ignore which were specified by the user. // If Matcher is not nil, it is used to identify files to ignore which were specified by the user.
@ -80,7 +80,7 @@ type CurrentFiler interface {
// file system. Files are blockwise hashed. // file system. Files are blockwise hashed.
func (w *Walker) Walk() (chan protocol.FileInfo, error) { func (w *Walker) Walk() (chan protocol.FileInfo, error) {
if debug { if debug {
l.Debugln("Walk", w.Dir, w.Sub, w.BlockSize, w.Matcher) l.Debugln("Walk", w.Dir, w.Subs, w.BlockSize, w.Matcher)
} }
err := checkDir(w.Dir) err := checkDir(w.Dir)
@ -99,7 +99,13 @@ func (w *Walker) Walk() (chan protocol.FileInfo, error) {
go func() { go func() {
hashFiles := w.walkAndHashFiles(files) hashFiles := w.walkAndHashFiles(files)
filepath.Walk(filepath.Join(w.Dir, w.Sub), hashFiles) if len(w.Subs) == 0 {
filepath.Walk(w.Dir, hashFiles)
} else {
for _, sub := range w.Subs {
filepath.Walk(filepath.Join(w.Dir, sub), hashFiles)
}
}
close(files) close(files)
}() }()

View File

@ -60,7 +60,7 @@ func TestWalkSub(t *testing.T) {
w := Walker{ w := Walker{
Dir: "testdata", Dir: "testdata",
Sub: "dir2", Subs: []string{"dir2"},
BlockSize: 128 * 1024, BlockSize: 128 * 1024,
Matcher: ignores, Matcher: ignores,
} }