mirror of
https://github.com/syncthing/syncthing.git
synced 2026-01-03 11:29:10 -05:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
271d7eedc4 | ||
|
|
ab8482a424 | ||
|
|
c8a14d1c3d | ||
|
|
8974c33f2f | ||
|
|
ed675a61d7 | ||
|
|
60b00af0bb | ||
|
|
0ceddc4fa3 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,3 @@
|
||||
syncthing
|
||||
*.tar.gz
|
||||
build
|
||||
dist
|
||||
|
||||
13
build.sh
13
build.sh
@@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
version=$(git describe --always)
|
||||
buildDir=dist
|
||||
|
||||
if [[ -z $1 ]] ; then
|
||||
go build -ldflags "-X main.Version $version" \
|
||||
@@ -8,8 +9,8 @@ if [[ -z $1 ]] ; then
|
||||
else
|
||||
go test ./... || exit 1
|
||||
|
||||
rm -rf build
|
||||
mkdir -p build || exit 1
|
||||
rm -rf "$buildDir"
|
||||
mkdir -p "$buildDir" || exit 1
|
||||
|
||||
for goos in darwin linux freebsd ; do
|
||||
for goarch in amd64 386 ; do
|
||||
@@ -20,10 +21,10 @@ else
|
||||
go build -ldflags "-X main.Version $version" \
|
||||
&& nrsc syncthing gui \
|
||||
&& mkdir -p "$name" \
|
||||
&& cp syncthing "build/$name" \
|
||||
&& cp syncthing "$buildDir/$name" \
|
||||
&& cp README.md LICENSE "$name" \
|
||||
&& mv syncthing "$name" \
|
||||
&& tar zcf "build/$name.tar.gz" "$name" \
|
||||
&& tar zcf "$buildDir/$name.tar.gz" "$name" \
|
||||
&& rm -r "$name"
|
||||
done
|
||||
done
|
||||
@@ -37,9 +38,9 @@ else
|
||||
go build -ldflags "-X main.Version $version" \
|
||||
&& nrsc syncthing.exe gui \
|
||||
&& mkdir -p "$name" \
|
||||
&& cp syncthing.exe "build/$name.exe" \
|
||||
&& cp syncthing.exe "$buildDir/$name.exe" \
|
||||
&& cp README.md LICENSE "$name" \
|
||||
&& zip -qr "build/$name.zip" "$name" \
|
||||
&& zip -qr "$buildDir/$name.zip" "$name" \
|
||||
&& rm -r "$name"
|
||||
done
|
||||
done
|
||||
|
||||
16
gui.go
16
gui.go
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
func startGUI(addr string, m *Model) {
|
||||
router := martini.NewRouter()
|
||||
router.Get("/", getRoot)
|
||||
router.Get("/rest/version", restGetVersion)
|
||||
router.Get("/rest/model", restGetModel)
|
||||
router.Get("/rest/connections", restGetConnections)
|
||||
@@ -31,6 +32,10 @@ func startGUI(addr string, m *Model) {
|
||||
}()
|
||||
}
|
||||
|
||||
func getRoot(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/index.html", 302)
|
||||
}
|
||||
|
||||
func restGetVersion() string {
|
||||
return Version
|
||||
}
|
||||
@@ -38,8 +43,15 @@ func restGetVersion() string {
|
||||
func restGetModel(m *Model, w http.ResponseWriter) {
|
||||
var res = make(map[string]interface{})
|
||||
|
||||
res["globalFiles"], res["globalDeleted"], res["globalBytes"] = m.GlobalSize()
|
||||
res["localFiles"], res["localDeleted"], res["localBytes"] = m.LocalSize()
|
||||
globalFiles, globalDeleted, globalBytes := m.GlobalSize()
|
||||
res["globalFiles"], res["globalDeleted"], res["globalBytes"] = globalFiles, globalDeleted, globalBytes
|
||||
|
||||
localFiles, localDeleted, localBytes := m.LocalSize()
|
||||
res["localFiles"], res["localDeleted"], res["localBytes"] = localFiles, localDeleted, localBytes
|
||||
|
||||
inSyncFiles, inSyncBytes := m.InSyncSize()
|
||||
res["inSyncFiles"], res["inSyncBytes"] = inSyncFiles, inSyncBytes
|
||||
|
||||
files, total := m.NeedFiles()
|
||||
res["needFiles"], res["needBytes"] = len(files), total
|
||||
|
||||
|
||||
15
gui/app.js
15
gui/app.js
@@ -28,10 +28,23 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
|
||||
data[id].outbps = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.connections = data;
|
||||
});
|
||||
$http.get("/rest/need").success(function (data) {
|
||||
var i, name;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
name = data[i].Name.split("/");
|
||||
data[i].ShortName = name[name.length-1];
|
||||
}
|
||||
data.sort(function (a, b) {
|
||||
if (a.ShortName < b.ShortName) {
|
||||
return -1;
|
||||
}
|
||||
if (a.ShortName > b.ShortName) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
$scope.need = data;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -37,9 +37,12 @@ body {
|
||||
<div class="col-md-12">
|
||||
<h2>Synchronization</h2>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" ng-class="{'progress-bar-success': model.needBytes === 0, 'progress-bar-info': model.needBytes !== 0}" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: {{100 * model.localFiles / (model.localFiles + model.needFiles) | number:2}}%;"></div>
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"
|
||||
ng-class="{'progress-bar-success': model.needBytes === 0, 'progress-bar-info': model.needBytes !== 0}"
|
||||
style="width: {{100 * model.inSyncBytes / model.globalBytes | number:2}}%;">
|
||||
{{100 * model.inSyncBytes / model.globalBytes | number:0}}%
|
||||
</div>
|
||||
</div>
|
||||
<p class="pull-right">{{100 * model.localFiles / (model.localFiles + model.needFiles) | number:2}}%</p>
|
||||
<p ng-show="model.needBytes > 0">Need {{model.needFiles | alwaysNumber}} files, {{model.needBytes | binary}}B</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,10 +59,10 @@ body {
|
||||
|
||||
<div ng-show="model.needFiles > 0">
|
||||
<h2>Files to Synchronize</h2>
|
||||
<table class="table table-condesed table-striped">
|
||||
<table class="table table-condensed table-striped">
|
||||
<tr ng-repeat="file in need track by $index">
|
||||
<td>{{file.Name}}</td>
|
||||
<td>{{file.Size | binary}}B</td>
|
||||
<td><abbr title="{{file.Name}}">{{file.ShortName}}</abbr></td>
|
||||
<td class="text-right">{{file.Size | binary}}B</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
1
main.go
1
main.go
@@ -40,6 +40,7 @@ type DebugOptions struct {
|
||||
TraceFile bool `long:"trace-file"`
|
||||
TraceNet bool `long:"trace-net"`
|
||||
TraceIdx bool `long:"trace-idx"`
|
||||
TraceNeed bool `long:"trace-need"`
|
||||
Profiler string `long:"profiler" value-name:"ADDR"`
|
||||
}
|
||||
|
||||
|
||||
28
model.go
28
model.go
@@ -132,6 +132,19 @@ func (m *Model) LocalSize() (files, deleted, bytes int) {
|
||||
return
|
||||
}
|
||||
|
||||
func (m *Model) InSyncSize() (files, bytes int) {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
|
||||
for n, f := range m.local {
|
||||
if gf, ok := m.global[n]; ok && f.Modified == gf.Modified {
|
||||
files++
|
||||
bytes += f.Size()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type FileInfo struct {
|
||||
Name string
|
||||
Size int
|
||||
@@ -161,10 +174,6 @@ func (m *Model) Index(nodeID string, fs []protocol.FileInfo) {
|
||||
|
||||
m.remote[nodeID] = make(map[string]File)
|
||||
for _, f := range fs {
|
||||
if f.Flags&FlagDeleted != 0 && !opts.Delete {
|
||||
// Files marked as deleted do not even enter the model
|
||||
continue
|
||||
}
|
||||
m.remote[nodeID][f.Name] = fileFromFileInfo(f)
|
||||
}
|
||||
|
||||
@@ -443,6 +452,17 @@ func (m *Model) recomputeNeed() {
|
||||
for n, f := range m.global {
|
||||
hf, ok := m.local[n]
|
||||
if !ok || f.Modified > hf.Modified {
|
||||
if f.Flags&FlagDeleted != 0 && !opts.Delete {
|
||||
// Don't want to delete files, so forget this need
|
||||
continue
|
||||
}
|
||||
if f.Flags&FlagDeleted != 0 && !ok {
|
||||
// Don't have the file, so don't need to delete it
|
||||
continue
|
||||
}
|
||||
if opts.Debug.TraceNeed {
|
||||
debugln("NEED:", ok, hf, f)
|
||||
}
|
||||
m.need[n] = true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user