Implement external scan request (fixes #9)

This commit is contained in:
Jakob Borg 2014-08-11 20:20:01 +02:00
parent 279693078a
commit 9752ea9ac3
4 changed files with 59 additions and 3 deletions

View File

@ -126,6 +126,7 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro
postRestMux.HandleFunc("/rest/restart", restPostRestart)
postRestMux.HandleFunc("/rest/shutdown", restPostShutdown)
postRestMux.HandleFunc("/rest/upgrade", restPostUpgrade)
postRestMux.HandleFunc("/rest/scan", withModel(m, restPostScan))
// A handler that splits requests between the two above and disables
// caching
@ -530,6 +531,16 @@ func restPostUpgrade(w http.ResponseWriter, r *http.Request) {
}
}
func restPostScan(m *model.Model, w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
repo := qs.Get("repo")
sub := qs.Get("sub")
err := m.ScanRepoSub(repo, sub)
if err != nil {
http.Error(w, err.Error(), 500)
}
}
func getQR(w http.ResponseWriter, r *http.Request) {
var qs = r.URL.Query()
var text = qs.Get("text")

View File

@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
@ -744,12 +745,21 @@ func (m *Model) CleanRepos() {
}
func (m *Model) ScanRepo(repo string) error {
return m.ScanRepoSub(repo, "")
}
func (m *Model) ScanRepoSub(repo, sub string) error {
if p := filepath.Clean(filepath.Join(repo, sub)); !strings.HasPrefix(p, repo) {
return errors.New("invalid subpath")
}
m.rmut.RLock()
fs := m.repoFiles[repo]
fs, ok := m.repoFiles[repo]
dir := m.repoCfgs[repo].Directory
w := &scanner.Walker{
Dir: dir,
Sub: sub,
IgnoreFile: ".stignore",
BlockSize: scanner.StandardBlockSize,
TempNamer: defTempNamer,
@ -758,6 +768,9 @@ func (m *Model) ScanRepo(repo string) error {
IgnorePerms: m.repoCfgs[repo].IgnorePerms,
}
m.rmut.RUnlock()
if !ok {
return errors.New("no such repo")
}
m.setState(repo, RepoScanning)
fchan, _, err := w.Walk()
@ -786,7 +799,13 @@ func (m *Model) ScanRepo(repo string) error {
}
batch = batch[:0]
// TODO: We should limit the Have scanning to start at sub
seenPrefix := false
fs.WithHave(protocol.LocalNodeID, func(f protocol.FileInfo) bool {
if !strings.HasPrefix(f.Name, sub) {
return !seenPrefix
}
seenPrefix = true
if !protocol.IsDeleted(f.Flags) {
if len(batch) == batchSize {
fs.Update(protocol.LocalNodeID, batch)

View File

@ -22,6 +22,8 @@ import (
type Walker struct {
// Dir is the base directory for the walk
Dir string
// Limit walking to this path within Dir, or no limit if Sub is blank
Sub string
// BlockSize controls the size of the block used when hashing.
BlockSize int
// If IgnoreFile is not empty, it is the name used for the file that holds ignore patterns.
@ -61,7 +63,7 @@ type CurrentFiler interface {
// file system. Files are blockwise hashed.
func (w *Walker) Walk() (chan protocol.FileInfo, map[string][]string, error) {
if debug {
l.Debugln("Walk", w.Dir, w.BlockSize, w.IgnoreFile)
l.Debugln("Walk", w.Dir, w.Sub, w.BlockSize, w.IgnoreFile)
}
err := checkDir(w.Dir)
@ -77,7 +79,7 @@ func (w *Walker) Walk() (chan protocol.FileInfo, map[string][]string, error) {
go func() {
filepath.Walk(w.Dir, w.loadIgnoreFiles(w.Dir, ignore))
filepath.Walk(w.Dir, hashFiles)
filepath.Walk(filepath.Join(w.Dir, w.Sub), hashFiles)
close(files)
}()

View File

@ -29,6 +29,30 @@ var correctIgnores = map[string][]string{
".": {".*", "quux"},
}
func TestWalkSub(t *testing.T) {
w := Walker{
Dir: "testdata",
Sub: "foo",
BlockSize: 128 * 1024,
IgnoreFile: ".stignore",
}
fchan, _, err := w.Walk()
var files []protocol.FileInfo
for f := range fchan {
files = append(files, f)
}
if err != nil {
t.Fatal(err)
}
if len(files) != 1 {
t.Fatalf("Incorrect length %d != 1", len(files))
}
if files[0].Name != "foo" {
t.Errorf("Incorrect file %v != foo", files[0])
}
}
func TestWalk(t *testing.T) {
w := Walker{
Dir: "testdata",