mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-22 14:48:30 +00:00
Implement external scan request (fixes #9)
This commit is contained in:
parent
279693078a
commit
9752ea9ac3
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}()
|
||||
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user