Browse Source

Show current repository state (fixes #89)

Jakob Borg 11 years ago
parent
commit
48bfc2d9ed
6 changed files with 85 additions and 5 deletions
  1. 0 0
      auto/gui.files.go
  2. 2 0
      cmd/syncthing/gui.go
  3. 45 1
      cmd/syncthing/model.go
  4. 5 0
      cmd/syncthing/puller.go
  5. 30 0
      gui/app.js
  6. 3 4
      gui/index.html

File diff suppressed because it is too large
+ 0 - 0
auto/gui.files.go


+ 2 - 0
cmd/syncthing/gui.go

@@ -88,6 +88,8 @@ func restGetModel(m *Model, w http.ResponseWriter, params martini.Params) {
 
 	res["inSyncFiles"], res["inSyncBytes"] = globalFiles-needFiles, globalBytes-needBytes
 
+	res["state"] = m.State(repo)
+
 	w.Header().Set("Content-Type", "application/json")
 	json.NewEncoder(w).Encode(res)
 }

+ 45 - 1
cmd/syncthing/model.go

@@ -20,11 +20,21 @@ import (
 	"github.com/calmh/syncthing/scanner"
 )
 
+type repoState int
+
+const (
+	RepoIdle repoState = iota
+	RepoScanning
+	RepoSyncing
+	RepoCleaning
+)
+
 type Model struct {
 	repoDirs  map[string]string     // repo -> dir
 	repoFiles map[string]*files.Set // repo -> files
 	repoNodes map[string][]string   // repo -> nodeIDs
 	nodeRepos map[string][]string   // nodeID -> repos
+	repoState map[string]repoState  // repo -> state
 	rmut      sync.RWMutex          // protects the above
 
 	cm *cid.Map
@@ -54,6 +64,7 @@ func NewModel(maxChangeBw int) *Model {
 		repoFiles: make(map[string]*files.Set),
 		repoNodes: make(map[string][]string),
 		nodeRepos: make(map[string][]string),
+		repoState: make(map[string]repoState),
 		cm:        cid.NewMap(),
 		protoConn: make(map[string]protocol.Connection),
 		rawConn:   make(map[string]io.Closer),
@@ -536,14 +547,20 @@ func (m *Model) AddRepo(id, dir string, nodes []NodeConfiguration) {
 
 func (m *Model) ScanRepos() {
 	m.rmut.RLock()
+	var repos = make([]string, 0, len(m.repoDirs))
 	for repo := range m.repoDirs {
-		m.ScanRepo(repo)
+		repos = append(repos, repo)
 	}
 	m.rmut.RUnlock()
+
+	for _, repo := range repos {
+		m.ScanRepo(repo)
+	}
 }
 
 func (m *Model) ScanRepo(repo string) {
 	sup := &suppressor{threshold: int64(cfg.Options.MaxChangeKbps)}
+	m.rmut.Lock()
 	w := &scanner.Walker{
 		Dir:          m.repoDirs[repo],
 		IgnoreFile:   ".stignore",
@@ -552,8 +569,11 @@ func (m *Model) ScanRepo(repo string) {
 		Suppressor:   sup,
 		CurrentFiler: cFiler{m, repo},
 	}
+	m.rmut.Unlock()
+	m.setState(repo, RepoScanning)
 	fs, _ := w.Walk()
 	m.ReplaceLocal(repo, fs)
+	m.setState(repo, RepoIdle)
 }
 
 func (m *Model) SaveIndexes(dir string) {
@@ -647,3 +667,27 @@ func (m *Model) clusterConfig(node string) protocol.ClusterConfigMessage {
 
 	return cm
 }
+
+func (m *Model) setState(repo string, state repoState) {
+	m.rmut.Lock()
+	m.repoState[repo] = state
+	m.rmut.Unlock()
+}
+
+func (m *Model) State(repo string) string {
+	m.rmut.Lock()
+	state := m.repoState[repo]
+	m.rmut.Unlock()
+	switch state {
+	case RepoIdle:
+		return "idle"
+	case RepoScanning:
+		return "scanning"
+	case RepoCleaning:
+		return "cleaning"
+	case RepoSyncing:
+		return "syncing"
+	default:
+		return "unknown"
+	}
+}

+ 5 - 0
cmd/syncthing/puller.go

@@ -127,11 +127,13 @@ func (p *puller) run() {
 		for {
 			select {
 			case res := <-p.requestResults:
+				p.model.setState(p.repo, RepoSyncing)
 				changed = true
 				p.requestSlots <- true
 				p.handleRequestResult(res)
 
 			case b := <-p.blocks:
+				p.model.setState(p.repo, RepoSyncing)
 				changed = true
 				p.handleBlock(b)
 
@@ -155,10 +157,13 @@ func (p *puller) run() {
 		}
 
 		if changed {
+			p.model.setState(p.repo, RepoCleaning)
 			p.fixupDirectories()
 			changed = false
 		}
 
+		p.model.setState(p.repo, RepoIdle)
+
 		// Do a rescan if it's time for it
 		select {
 		case <-walkTicker:

+ 30 - 0
gui/app.js

@@ -108,6 +108,36 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
         });
     };
 
+    $scope.repoStatus = function (repo) {
+        if (typeof $scope.model[repo] === 'undefined') {
+            return 'Unknown';
+        }
+
+        var state = '' + $scope.model[repo].state;
+        state = state[0].toUpperCase() + state.substr(1);
+
+        if (state == "Syncing" || state == "Idle") {
+            state += " (" + $scope.syncPercentage(repo) + "%)";
+        }
+
+        return state;
+    }
+
+    $scope.repoClass = function (repo) {
+        if (typeof $scope.model[repo] === 'undefined') {
+            return 'text-info';
+        }
+
+        var state = '' + $scope.model[repo].state;
+        if (state == 'idle') {
+            return 'text-success';
+        }
+        if (state == 'syncing') {
+            return 'text-primary';
+        }
+        return 'text-info';
+    }
+
     $scope.syncPercentage = function (repo) {
         if (typeof $scope.model[repo] === 'undefined') {
             return 100;

+ 3 - 4
gui/index.html

@@ -137,9 +137,8 @@
                       <span class="data">{{repo.ID}}</span>
                     </div>
                     <div class="li-column">
-                      <span class="text-muted glyphicon glyphicon-home"></span>
-                      <span class="data text-success" ng-show="syncPercentage(repo.ID) == 100">In Sync</span>
-                      <span class="data text-primary" ng-hide="syncPercentage(repo.ID) == 100">Syncing ({{syncPercentage(repo.ID)}}%)</span>
+                      <span class="text-muted glyphicon glyphicon-comment"></span>
+                      <span class="data" ng-class="repoClass(repo.ID)">{{repoStatus(repo.ID)}}</span>
                     </div>
                   </li>
                   <li>
@@ -191,7 +190,7 @@
                       <span class="data">{{nodeAddr(nodeCfg)}}</span>
                     </div>
                     <div class="li-column">
-                      <span class="text-muted glyphicon glyphicon-dashboard"></span>
+                      <span class="text-muted glyphicon glyphicon-comment"></span>
                       <span class="data text-{{nodeClass(nodeCfg)}}">{{nodeStatus(nodeCfg)}}</span>
                     </div>
                   </li>

Some files were not shown because too many files changed in this diff