Compare commits

...
12 Commits
Author SHA1 Message Date
Jakob Borg b35958d024 Avoid spurious request for /qr?text={{myID}} (fixes #1679) 2015-04-22 09:37:18 +09:00
Audrius Butkevicius 9ee3541655 Merge pull request #1673 from calmh/filestatus-json
Clean up REST JSON a little further
2015-04-21 17:11:06 +01:00
Jakob Borg bf7d84c12a Clean up REST JSON a little further 2015-04-21 23:28:58 +09:00
Audrius Butkevicius 34c691087e Merge pull request #1674 from calmh/rc-upgrade
Loosen the requirements on what can be upgraded to what
2015-04-21 08:42:33 +01:00
Jakob Borg 08c383012f Loosen the requirements on what can be upgraded to what 2015-04-21 09:06:10 +09:00
Jakob Borg e2420495f3 Fix type in device sort (fixes #1668) 2015-04-20 22:18:19 +09:00
Audrius Butkevicius d530c5eda7 Merge pull request #1665 from calmh/wat
Don't initialize subscription in init()
2015-04-20 08:12:58 +01:00
Audrius Butkevicius ef7420ecf6 Merge pull request #1666 from calmh/cpu-remind
Reminder in debug output to explain high CPU usage
2015-04-20 08:09:56 +01:00
Jakob Borg c905a41e2a Reminder in debug output to explain high CPU usage 2015-04-20 14:29:38 +09:00
Jakob Borg 42ff4b5bf0 changelog.go should not be built 2015-04-20 14:03:50 +09:00
Jakob Borg 4fb74a32cc Don't initialize subscription in init()
By doing it init(), the monitor process also gets a subscription thing
running, which is unnecessary (and really confused me when seeing it in
the debug output).
2015-04-20 12:58:58 +09:00
Jakob Borg c741465328 Use versionString() in about modal (fixes #1663) 2015-04-20 08:23:59 +09:00
9 changed files with 92 additions and 58 deletions
+2
View File
@@ -4,6 +4,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
// +build ignore
package main
import (
+51 -27
View File
@@ -57,14 +57,12 @@ var (
lastEventRequestMut sync.Mutex
)
func init() {
func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) error {
var err error
l.AddHandler(logger.LevelWarn, showGuiError)
sub := events.Default.Subscribe(events.AllEvents)
eventSub = events.NewBufferedSubscription(sub, 1000)
}
func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) error {
var err error
cert, err := tls.LoadX509KeyPair(locations[locHTTPSCertFile], locations[locHTTPSKeyFile])
if err != nil {
@@ -111,7 +109,7 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro
// The GET handlers
getRestMux := http.NewServeMux()
getRestMux.HandleFunc("/rest/db/completion", withModel(m, restGetDBCompletion)) // device folder
getRestMux.HandleFunc("/rest/db/file", withModel(m, restGetDBFile)) // folder file [blocks]
getRestMux.HandleFunc("/rest/db/file", withModel(m, restGetDBFile)) // folder file
getRestMux.HandleFunc("/rest/db/ignores", withModel(m, restGetDBIgnores)) // folder
getRestMux.HandleFunc("/rest/db/need", withModel(m, restGetDBNeed)) // folder
getRestMux.HandleFunc("/rest/db/status", withModel(m, restGetDBStatus)) // folder
@@ -386,7 +384,7 @@ func restGetDBNeed(m *model.Model, w http.ResponseWriter, r *http.Request) {
progress, queued, rest := m.NeedFolderFiles(folder, 100)
// Convert the struct to a more loose structure, and inject the size.
output := map[string][]map[string]interface{}{
output := map[string][]jsonDBFileInfo{
"progress": toNeedSlice(progress),
"queued": toNeedSlice(queued),
"rest": toNeedSlice(rest),
@@ -418,19 +416,13 @@ func restGetDBFile(m *model.Model, w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
folder := qs.Get("folder")
file := qs.Get("file")
withBlocks := qs.Get("blocks") != ""
gf, _ := m.CurrentGlobalFile(folder, file)
lf, _ := m.CurrentFolderFile(folder, file)
if !withBlocks {
gf.Blocks = nil
lf.Blocks = nil
}
av := m.Availability(folder, file)
json.NewEncoder(w).Encode(map[string]interface{}{
"global": gf,
"local": lf,
"global": jsonFileInfo(gf),
"local": jsonFileInfo(lf),
"availability": av,
})
}
@@ -912,17 +904,49 @@ func mimeTypeForFile(file string) string {
}
}
func toNeedSlice(fs []db.FileInfoTruncated) []map[string]interface{} {
output := make([]map[string]interface{}, len(fs))
for i, file := range fs {
output[i] = map[string]interface{}{
"name": file.Name,
"flags": file.Flags,
"modified": file.Modified,
"version": file.Version,
"localVersion": file.LocalVersion,
"size": file.Size(),
}
func toNeedSlice(fs []db.FileInfoTruncated) []jsonDBFileInfo {
res := make([]jsonDBFileInfo, len(fs))
for i, f := range fs {
res[i] = jsonDBFileInfo(f)
}
return output
return res
}
// Type wrappers for nice JSON serialization
type jsonFileInfo protocol.FileInfo
func (f jsonFileInfo) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"name": f.Name,
"size": protocol.FileInfo(f).Size(),
"flags": fmt.Sprintf("%#o", f.Flags),
"modified": time.Unix(f.Modified, 0),
"localVersion": f.LocalVersion,
"numBlocks": len(f.Blocks),
"version": jsonVersionVector(f.Version),
})
}
type jsonDBFileInfo db.FileInfoTruncated
func (f jsonDBFileInfo) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"name": f.Name,
"size": db.FileInfoTruncated(f).Size(),
"flags": fmt.Sprintf("%#o", f.Flags),
"modified": time.Unix(f.Modified, 0),
"localVersion": f.LocalVersion,
"version": jsonVersionVector(f.Version),
})
}
type jsonVersionVector protocol.Vector
func (v jsonVersionVector) MarshalJSON() ([]byte, error) {
res := make([]string, len(v))
for i, c := range v {
res[i] = fmt.Sprintf("%d:%d", c.ID, c.Value)
}
return json.Marshal(res)
}
+4
View File
@@ -42,6 +42,10 @@ func basicAuthAndSessionMiddleware(cfg config.GUIConfiguration, next http.Handle
}
}
if debugHTTP {
l.Debugln("Sessionless HTTP request with authentication; this is expensive.")
}
error := func() {
time.Sleep(time.Duration(rand.Intn(100)+100) * time.Millisecond)
w.Header().Set("WWW-Authenticate", "Basic realm=\"Authorization Required\"")
+8 -3
View File
@@ -78,10 +78,15 @@ func init() {
}
}
// Check for a clean release build.
exp := regexp.MustCompile(`^v\d+\.\d+\.\d+(-beta[\d\.]+)?$`)
// Check for a clean release build. A release is something like "v0.1.2",
// with an optional suffix of letters and dot separated numbers like
// "-beta3.47". If there's more stuff, like a plus sign and a commit hash
// and so on, then it's not a release. If there's a dash anywhere in
// there, it's some kind of beta or prerelease version.
exp := regexp.MustCompile(`^v\d+\.\d+\.\d+(-[a-z]+[\d\.]+)?$`)
IsRelease = exp.MatchString(Version)
IsBeta = strings.Contains(Version, "beta")
IsBeta = strings.Contains(Version, "-")
stamp, _ := strconv.Atoi(BuildStamp)
BuildDate = time.Unix(int64(stamp), 0)
+2 -2
View File
@@ -463,7 +463,7 @@
<modal id="idqr" large="yes" status="info" close="yes" icon="qrcode" title="{{'Device Identification' | translate}} &mdash; {{deviceName(thisDevice())}}">
<div class="well well-sm text-monospace text-center">{{myID}}</div>
<img ng-if="myID" class="center-block img-thumbnail" src="qr/?text={{myID}}"/>
<img ng-if="myID" class="center-block img-thumbnail" ng-src="qr/?text={{myID}}"/>
</modal>
<!-- Device editor modal -->
@@ -945,7 +945,7 @@
<!-- About modal -->
<modal id="about" large="yes" close="yes" status="info" title="{{'About' | translate}}">
<h1 class="text-center"><img alt="Syncthing" title="Syncthing" src="assets/img/logo-horizontal.svg" style="vertical-align: -16px" height="100" width="366"/><br/><small>{{version}}</small></h1>
<h1 class="text-center"><img alt="Syncthing" title="Syncthing" src="assets/img/logo-horizontal.svg" style="vertical-align: -16px" height="100" width="366"/><br/><small>{{versionString()}}</small></h1>
<hr/>
<p translate>Copyright &copy; 2015 the following Contributors:</p>
+1 -1
View File
@@ -52,7 +52,7 @@ function deviceCompare(a, b) {
if (typeof a.name !== 'undefined' && typeof b.name !== 'undefined') {
if (a.name < b.name)
return -1;
return a.name > b.bame;
return a.name > b.name;
}
if (a.deviceID < b.deviceID) {
return -1;
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1482,8 +1482,8 @@ func (m *Model) GlobalDirectoryTree(folder, prefix string, levels int, dirsonly
}
if !dirsonly && base != "" {
last[base] = []int64{
f.Modified, f.Size(),
last[base] = []interface{}{
time.Unix(f.Modified, 0), f.Size(),
}
}
+19 -20
View File
@@ -14,7 +14,6 @@ import (
"math/rand"
"os"
"path/filepath"
"reflect"
"strconv"
"testing"
"time"
@@ -775,7 +774,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
}
}
filedata := []int64{0x666, 0xa}
filedata := []interface{}{time.Unix(0x666, 0), 0xa}
testdata := []protocol.FileInfo{
b(false, "another"),
@@ -847,13 +846,13 @@ func TestGlobalDirectoryTree(t *testing.T) {
result := m.GlobalDirectoryTree("default", "", -1, false)
if !reflect.DeepEqual(result, expectedResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(expectedResult))
if mm(result) != mm(expectedResult) {
t.Errorf("Does not match:\n%#v\n%#v", result, expectedResult)
}
result = m.GlobalDirectoryTree("default", "another", -1, false)
if !reflect.DeepEqual(result, expectedResult["another"]) {
if mm(result) != mm(expectedResult["another"]) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(expectedResult["another"]))
}
@@ -865,7 +864,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
"rootfile": filedata,
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -886,7 +885,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
"rootfile": filedata,
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -916,7 +915,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -935,7 +934,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -945,7 +944,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
"file": filedata,
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -954,7 +953,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
"with": map[string]interface{}{},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -965,7 +964,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -978,7 +977,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -991,7 +990,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -999,7 +998,7 @@ func TestGlobalDirectoryTree(t *testing.T) {
result = m.GlobalDirectoryTree("default", "som", -1, false)
currentResult = map[string]interface{}{}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
}
@@ -1024,7 +1023,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
}
}
filedata := []int64{0x666, 0xa}
filedata := []interface{}{time.Unix(0x666, 0).Format(time.RFC3339), 0xa}
testdata := []protocol.FileInfo{
b(true, "another", "directory", "afile"),
@@ -1105,7 +1104,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
result := m.GlobalDirectoryTree("default", "", -1, false)
if !reflect.DeepEqual(result, expectedResult) {
if mm(result) != mm(expectedResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(expectedResult))
}
@@ -1116,7 +1115,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -1125,7 +1124,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
"invalid": map[string]interface{}{},
}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
@@ -1134,7 +1133,7 @@ func TestGlobalDirectorySelfFixing(t *testing.T) {
result = m.GlobalDirectoryTree("default", "xthis", 1, false)
currentResult = map[string]interface{}{}
if !reflect.DeepEqual(result, currentResult) {
if mm(result) != mm(currentResult) {
t.Errorf("Does not match:\n%s\n%s", mm(result), mm(currentResult))
}
}