Browse Source

Use lowerCamelCase for the JSON API (fixes #1338)

Replace the current mix of UpperCamelCase und lowerCamelCase with
consistent lowerCamelCase keys for the JSON API. Also adapt the frontend
so it works with the changed API.

Attention: this will break existing consumers of the API.
Pascal Jungblut 10 years ago
parent
commit
49bc74e7a0

+ 8 - 8
cmd/syncthing/gui.go

@@ -46,8 +46,8 @@ import (
 )
 
 type guiError struct {
-	Time  time.Time
-	Error string
+	Time  time.Time `json:"time"`
+	Error string    `json:"error"`
 }
 
 var (
@@ -824,12 +824,12 @@ 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(),
+			"name":         file.Name,
+			"flags":        file.Flags,
+			"modified":     file.Modified,
+			"version":      file.Version,
+			"localVersion": file.LocalVersion,
+			"size":         file.Size(),
 		}
 	}
 	return output

+ 93 - 93
gui/index.html

@@ -155,7 +155,7 @@
         <div class="panel panel-warning">
           <div class="panel-heading"><h3 class="panel-title"><span class="glyphicon glyphicon-exclamation-sign"></span><span translate>Notice</span></h3></div>
           <div class="panel-body">
-            <p ng-repeat="err in errorList()"><small>{{err.Time | date:"H:mm:ss"}}:</small> {{friendlyDevices(err.Error)}}</p>
+            <p ng-repeat="err in errorList()"><small>{{err.time | date:"H:mm:ss"}}:</small> {{friendlyDevices(err.error)}}</p>
           </div>
           <div class="panel-footer">
             <button type="button" class="pull-right btn btn-sm btn-default" ng-click="clearErrors()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>OK</span></button>
@@ -176,9 +176,9 @@
         <div class="visible-xs"><h3><span translate>Folders</span></h3><hr></div>
           <div class="panel panel-default" ng-repeat="folder in folderList()">
             <div class="panel-heading" data-toggle="collapse" data-parent="#folders" href="#folder-{{$index}}" style="cursor: pointer">
-              <div class="panel-progress" ng-show="folderStatus(folder) == 'syncing'" ng-attr-style="width: {{syncPercentage(folder.ID)}}%"></div>
+              <div class="panel-progress" ng-show="folderStatus(folder) == 'syncing'" ng-attr-style="width: {{syncPercentage(folder.id)}}%"></div>
               <h3 class="panel-title">
-                <span class="glyphicon glyphicon-hdd hidden-xs"></span>{{folder.ID}}
+                <span class="glyphicon glyphicon-hdd hidden-xs"></span>{{folder.id}}
                 <span class="pull-right text-{{folderClass(folder)}}" ng-switch="folderStatus(folder)">
                   <span ng-switch-when="unknown"><span class="hidden-xs" translate>Unknown</span><span class="visible-xs">&#9724;</span></span>
                   <span ng-switch-when="unshared"><span class="hidden-xs" translate>Unshared</span><span class="visible-xs">&#9724;</span></span>
@@ -187,7 +187,7 @@
                   <span ng-switch-when="idle"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs">&#9724;</span></span>
                   <span ng-switch-when="syncing">
                     <span class="hidden-xs" translate>Syncing</span>
-                    ({{syncPercentage(folder.ID)}}%)
+                    ({{syncPercentage(folder.id)}}%)
                   </span>
                 </span>
               </h3>
@@ -198,49 +198,49 @@
                   <tbody>
                     <tr>
                       <th><span class="glyphicon glyphicon-folder-open"></span>&emsp;<span translate>Folder Path</span></th>
-                      <td class="text-right">{{folder.Path}}</td>
+                      <td class="text-right">{{folder.path}}</td>
                     </tr>
-                    <tr ng-if="model[folder.ID].invalid">
+                    <tr ng-if="model[folder.id].invalid">
                       <th><span class="glyphicon glyphicon-warning-sign"></span>&emsp;<span translate>Error</span></th>
-                      <td class="text-right">{{model[folder.ID].invalid}}</td>
+                      <td class="text-right">{{model[folder.id].invalid}}</td>
                     </tr>
                     <tr>
                       <th><span class="glyphicon glyphicon-globe"></span>&emsp;<span translate>Global State</span></th>
-                      <td class="text-right">{{model[folder.ID].globalFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.ID].globalBytes | binary}}B</td>
+                      <td class="text-right">{{model[folder.id].globalFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].globalBytes | binary}}B</td>
                     </tr>
                     <tr>
                       <th><span class="glyphicon glyphicon-home"></span>&emsp;<span translate>Local State</span></th>
-                      <td class="text-right">{{model[folder.ID].localFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.ID].localBytes | binary}}B</td>
+                      <td class="text-right">{{model[folder.id].localFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].localBytes | binary}}B</td>
                     </tr>
-                    <tr ng-if="model[folder.ID].needFiles > 0">
+                    <tr ng-if="model[folder.id].needFiles > 0">
                       <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Out Of Sync</span></th>
                       <td class="text-right">
-                        <a ng-click="showNeed(folder.ID)" href="">{{model[folder.ID].needFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.ID].needBytes | binary}}B</a>
+                        <a ng-click="showNeed(folder.id)" href="">{{model[folder.id].needFiles | alwaysNumber}} <span translate>items</span>, ~{{model[folder.id].needBytes | binary}}B</a>
                       </td>
                     </tr>
-                    <tr ng-if="folder.ReadOnly">
+                    <tr ng-if="folder.readOnly">
                       <th><span class="glyphicon glyphicon-lock"></span>&emsp;<span translate>Folder Master</span></th>
                       <td class="text-right">
                         <span translate>Yes</span>
                       </td>
                     </tr>
-                    <tr ng-if="model[folder.ID].ignorePatterns">
+                    <tr ng-if="model[folder.id].ignorePatterns">
                       <th><span class="glyphicon glyphicon-eye-close"></span>&emsp;<span translate>Ignore Patterns</span></th>
                       <td class="text-right">
                         <span translate>Yes</span>
                       </td>
                     </tr>
-                    <tr ng-if="folder.IgnorePerms">
+                    <tr ng-if="folder.ignorePerms">
                       <th><span class="glyphicon glyphicon-unchecked"></span>&emsp;<span translate>Ignore Permissions</span></th>
                       <td class="text-right">
                         <span translate>Yes</span>
                       </td>
                     </tr>
-                    <tr ng-if="folder.RescanIntervalS != 60">
+                    <tr ng-if="folder.rescanIntervalS != 60">
                       <th><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Rescan Interval</span></th>
-                      <td class="text-right">{{folder.RescanIntervalS}} s</td>
+                      <td class="text-right">{{folder.rescanIntervalS}} s</td>
                     </tr>
-                    <tr ng-if="folder.Versioning.Type">
+                    <tr ng-if="folder.versioning.type">
                       <th><span class="glyphicon glyphicon-tags"></span>&emsp;<span translate>File Versioning</span></th>
                       <td class="text-right" ng-switch="folder.Versioning.Type">
                         <span ng-switch-when="staggered" translate>Staggered File Versioning</span>
@@ -251,11 +251,11 @@
                       <th><span class="glyphicon glyphicon-share-alt"></span>&emsp;<span translate>Shared With</span></th>
                       <td class="text-right">{{sharesFolder(folder)}}</td>
                     </tr>
-                    <tr ng-if="folderStats[folder.ID].LastFile">
+                    <tr ng-if="folderStats[folder.id].lastFile">
                       <th><span class="glyphicon glyphicon-transfer"></span>&emsp;<span translate>Last File Received</span></th>
                       <td class="text-right">
-                        <span title="{{folderStats[folder.ID].LastFile.Filename}} @ {{folderStats[folder.ID].LastFile.At | date:'yyyy-MM-dd HH:mm'}}">
-                          {{folderStats[folder.ID].LastFile.Filename | basename}}
+                        <span title="{{folderStats[folder.id].lastFile.filename}} @ {{folderStats[folder.id].lastFile.at | date:'yyyy-MM-dd HH:mm'}}">
+                          {{folderStats[folder.id].lastFile.filename | basename}}
                         </span>
                       </td>
                     </tr>
@@ -263,9 +263,9 @@
                 </table>
               </div>
               <div class="panel-footer">
-                <button class="btn btn-sm btn-danger pull-left" ng-if="folder.ReadOnly && model[folder.ID].needFiles > 0" ng-click="override(folder.ID)" href=""><span class="glyphicon glyphicon-upload"></span>&emsp;<span translate>Override Changes</span></button>
+                <button class="btn btn-sm btn-danger pull-left" ng-if="folder.readOnly && model[folder.id].needFiles > 0" ng-click="override(folder.id)" href=""><span class="glyphicon glyphicon-upload"></span>&emsp;<span translate>Override Changes</span></button>
                 <span class="pull-right">
-                  <button class="btn btn-sm btn-default" href="" ng-show="folderStatus(folder) == 'idle'" ng-click="rescanFolder(folder.ID)"><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Rescan</span></button>
+                  <button class="btn btn-sm btn-default" href="" ng-show="folderStatus(folder) == 'idle'" ng-click="rescanFolder(folder.id)"><span class="glyphicon glyphicon-refresh"></span>&emsp;<span translate>Rescan</span></button>
                   <button class="btn btn-sm btn-default" href="" ng-click="editFolder(folder)"><span class="glyphicon glyphicon-pencil"></span>&emsp;<span translate>Edit</span></button>
                 </span>
                 <div class="clearfix"></div>
@@ -290,7 +290,7 @@
         <div class="panel panel-default" ng-repeat="deviceCfg in [thisDevice()]">
           <div class="panel-heading" data-toggle="collapse" href="#device-this" style="cursor: pointer">
             <h3 class="panel-title">
-              <identicon data-value="deviceCfg.DeviceID"></identicon>&emsp;{{deviceName(deviceCfg)}}
+              <identicon data-value="deviceCfg.deviceID"></identicon>&emsp;{{deviceName(deviceCfg)}}
             </h3>
           </div>
           <div id="device-this" class="panel-collapse collapse in">
@@ -299,11 +299,11 @@
                 <tbody>
                   <tr>
                     <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Download Rate</span></th>
-                    <td class="text-right">{{connections['total'].inbps | binary}}B/s ({{connections['total'].InBytesTotal | binary}}B)</td>
+                    <td class="text-right">{{connections['total'].inbps | binary}}B/s ({{connections['total'].inBytesTotal | binary}}B)</td>
                   </tr>
                   <tr>
                     <th><span class="glyphicon glyphicon-cloud-upload"></span>&emsp;<span translate>Upload Rate</span></th>
-                    <td class="text-right">{{connections['total'].outbps | binary}}B/s ({{connections['total'].OutBytesTotal | binary}}B)</td>
+                    <td class="text-right">{{connections['total'].outbps | binary}}B/s ({{connections['total'].outBytesTotal | binary}}B)</td>
                   </tr>
                   <tr>
                     <th><span class="glyphicon glyphicon-th"></span>&emsp;<span translate>RAM Utilization</span></th>
@@ -341,13 +341,13 @@
         <div class="panel-group" id="devices">
           <div class="panel panel-default" ng-repeat="deviceCfg in otherDevices()">
             <div class="panel-heading" data-toggle="collapse" data-parent="#devices" href="#device-{{$index}}" style="cursor: pointer">
-              <div class="panel-progress" ng-show="deviceStatus(deviceCfg) == 'syncing'" ng-attr-style="width: {{completion[deviceCfg.DeviceID]._total | number:0}}%"></div>
+              <div class="panel-progress" ng-show="deviceStatus(deviceCfg) == 'syncing'" ng-attr-style="width: {{completion[deviceCfg.deviceID]._total | number:0}}%"></div>
               <h3 class="panel-title">
-                <identicon data-value="deviceCfg.DeviceID"></identicon>&emsp;{{deviceName(deviceCfg)}}
+                <identicon data-value="deviceCfg.deviceID"></identicon>&emsp;{{deviceName(deviceCfg)}}
                 <span ng-switch="deviceStatus(deviceCfg)" class="pull-right text-{{deviceClass(deviceCfg)}}">
                   <span ng-switch-when="insync"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs">&#9724;</span></span>
                   <span ng-switch-when="syncing">
-                    <span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.DeviceID]._total | number:0}}%)
+                    <span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | number:0}}%)
                   </span>
                   <span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs">&#9724;</span></span>
                   <span ng-switch-when="unused"><span class="hidden-xs" translate>Unused</span><span class="visible-xs">&#9724;</span></span>
@@ -358,37 +358,37 @@
               <div class="panel-body">
                 <table class="table table-condensed table-striped">
                   <tbody>
-                    <tr ng-if="connections[deviceCfg.DeviceID]">
+                    <tr ng-if="connections[deviceCfg.deviceID]">
                       <th><span class="glyphicon glyphicon-cloud-download"></span>&emsp;<span translate>Download Rate</span></th>
-                      <td class="text-right">{{connections[deviceCfg.DeviceID].inbps | binary}}B/s ({{connections[deviceCfg.DeviceID].InBytesTotal | binary}}B)</td>
+                      <td class="text-right">{{connections[deviceCfg.deviceID].inbps | binary}}B/s ({{connections[deviceCfg.deviceID].inBytesTotal | binary}}B)</td>
                     </tr>
-                    <tr ng-if="connections[deviceCfg.DeviceID]">
+                    <tr ng-if="connections[deviceCfg.deviceID]">
                       <th><span class="glyphicon glyphicon-cloud-upload"></span>&emsp;<span translate>Upload Rate</span></th>
-                      <td class="text-right">{{connections[deviceCfg.DeviceID].outbps | binary}}B/s ({{connections[deviceCfg.DeviceID].OutBytesTotal | binary}}B)</td>
+                      <td class="text-right">{{connections[deviceCfg.deviceID].outbps | binary}}B/s ({{connections[deviceCfg.deviceID].outBytesTotal | binary}}B)</td>
                     </tr>
                     <tr>
                       <th><span class="glyphicon glyphicon-link"></span>&emsp;<span translate>Address</span></th>
                       <td class="text-right">{{deviceAddr(deviceCfg)}}</td>
                     </tr>
-                    <tr ng-if="deviceCfg.Compression != 'metadata'">
+                    <tr ng-if="deviceCfg.compression != 'metadata'">
                       <th><span class="glyphicon glyphicon-compressed"></span>&emsp;<span translate>Compression</span></th>
                       <td class="text-right">
-                        <span ng-if="deviceCfg.Compression == 'always'" translate>All Data</span>
-                        <span ng-if="deviceCfg.Compression == 'never'" translate>Off</span>
+                        <span ng-if="deviceCfg.compression == 'always'" translate>All Data</span>
+                        <span ng-if="deviceCfg.compression == 'never'" translate>Off</span>
                       </td>
                     </tr>
-                    <tr ng-if="deviceCfg.Introducer">
+                    <tr ng-if="deviceCfg.introducer">
                       <th><span class="glyphicon glyphicon-thumbs-up"></span>&emsp;<span translate>Introducer</span></th>
                       <td translate class="text-right">Yes</td>
                     </tr>
-                    <tr ng-if="connections[deviceCfg.DeviceID]">
+                    <tr ng-if="connections[deviceCfg.deviceID]">
                       <th><span class="glyphicon glyphicon-tag"></span>&emsp;<span translate>Version</span></th>
-                      <td class="text-right">{{connections[deviceCfg.DeviceID].ClientVersion}}</td>
+                      <td class="text-right">{{connections[deviceCfg.deviceID].clientVersion}}</td>
                     </tr>
-                    <tr ng-if="!connections[deviceCfg.DeviceID]">
+                    <tr ng-if="!connections[deviceCfg.deviceID]">
                       <th><span class="glyphicon glyphicon-eye-open"></span>&emsp;<span translate>Last seen</span></th>
-                      <td translate ng-if="!deviceStats[deviceCfg.DeviceID].LastSeenDays || deviceStats[deviceCfg.DeviceID].LastSeenDays >= 365" class="text-right">Never</td>
-                      <td ng-if="deviceStats[deviceCfg.DeviceID].LastSeenDays < 365" class="text-right">{{deviceStats[deviceCfg.DeviceID].LastSeen | date:"yyyy-MM-dd HH:mm"}}</td>
+                      <td translate ng-if="!deviceStats[deviceCfg.deviceID].lastSeenDays || deviceStats[deviceCfg.deviceID].lastSeenDays >= 365" class="text-right">Never</td>
+                      <td ng-if="deviceStats[deviceCfg.deviceID].lastSeenDays < 365" class="text-right">{{deviceStats[deviceCfg.deviceID].lastSeen | date:"yyyy-MM-dd HH:mm"}}</td>
                     </tr>
                     <tr ng-if="deviceFolders(deviceCfg).length > 0">
                       <th><span class="glyphicon glyphicon-hdd"></span>&emsp;<span translate>Folders</span></th>
@@ -481,11 +481,11 @@
           <form role="form" name="deviceEditor">
             <div class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}">
               <label translate for="deviceID">Device ID</label>
-              <input ng-if="!editingExisting" name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.DeviceID" required valid-deviceid list="discovery-list" />
+              <input ng-if="!editingExisting" name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.deviceID" required valid-deviceid list="discovery-list" />
               <datalist id="discovery-list" ng-if="!editingExisting">
                 <option ng-repeat="(id,address) in discovery" value="{{ id }}" />
               </datalist>
-              <div ng-if="editingExisting" class="well well-sm text-monospace">{{currentDevice.DeviceID}}</div>
+              <div ng-if="editingExisting" class="well well-sm text-monospace">{{currentDevice.deviceID}}</div>
               <p class="help-block">
                 <span translate ng-if="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">The device ID to enter here can be found in the "Edit > Show ID" dialog on the other device. Spaces and dashes are optional (ignored).</span>
                 <span translate ng-show="!editingExisting && (deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine)">When adding a new device, keep in mind that this device must be added on the other side too.</span>
@@ -495,18 +495,18 @@
             </div>
             <div class="form-group">
               <label translate for="name">Device Name</label>
-              <input id="name" class="form-control" type="text" ng-model="currentDevice.Name"></input>
-              <p translate ng-if="currentDevice.DeviceID == myID" class="help-block">Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.</p>
-              <p translate ng-if="currentDevice.DeviceID != myID" class="help-block">Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.</p>
+              <input id="name" class="form-control" type="text" ng-model="currentDevice.name"></input>
+              <p translate ng-if="currentDevice.deviceID == myID" class="help-block">Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.</p>
+              <p translate ng-if="currentDevice.deviceID != myID" class="help-block">Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.</p>
             </div>
             <div class="form-group">
               <label translate for="addresses">Addresses</label>
-              <input ng-disabled="currentDevice.DeviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice.AddressesStr"></input>
+              <input ng-disabled="currentDevice.deviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice.addressesStr"></input>
               <p translate class="help-block">Enter comma separated "ip:port" addresses or "dynamic" to perform automatic discovery of the address.</p>
             </div>
             <div ng-if="!editingSelf" class="form-group">
               <label translate>Compression</label>
-              <select class="form-control" ng-model="currentDevice.Compression">
+              <select class="form-control" ng-model="currentDevice.compression">
                 <option value="always" translate>All Data</option>
                 <option value="metadata" translate>Metadata Only</option>
                 <option value="never" translate>Off</option>
@@ -515,7 +515,7 @@
             <div ng-if="!editingSelf" class="form-group">
               <div class="checkbox">
                 <label>
-                  <input type="checkbox" ng-model="currentDevice.Introducer"> <span translate>Introducer</span>
+                  <input type="checkbox" ng-model="currentDevice.introducer"> <span translate>Introducer</span>
                 </label>
                 <p translate class="help-block">Any devices configured on an introducer device will be added to this device as well.</p>
               </div>
@@ -529,7 +529,7 @@
                   <div class="three-columns">
                     <div class="checkbox" ng-repeat="folder in folderList()">
                       <label>
-                        <input type="checkbox" ng-model="currentDevice.selectedFolders[folder.ID]"> {{folder.ID}}
+                        <input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]"> {{folder.id}}
                       </label>
                     </div>
                   </div>
@@ -563,7 +563,7 @@
               <div class="col-md-12">
                 <div class="form-group" ng-class="{'has-error': folderEditor.folderID.$invalid && folderEditor.folderID.$dirty}">
                   <label for="folderID"><span translate>Folder ID</span></label>
-                  <input name="folderID" ng-readonly="editingExisting" id="folderID" class="form-control" type="text" ng-model="currentFolder.ID" required unique-folder ng-pattern="/^[a-zA-Z0-9-_.]{1,64}$/"></input>
+                  <input name="folderID" ng-readonly="editingExisting" id="folderID" class="form-control" type="text" ng-model="currentFolder.id" required unique-folder ng-pattern="/^[a-zA-Z0-9-_.]{1,64}$/"></input>
                   <p class="help-block">
                     <span translate ng-if="folderEditor.folderID.$valid || folderEditor.folderID.$pristine">Short identifier for the folder. Must be the same on all cluster devices.</span>
                     <span translate ng-if="folderEditor.folderID.$error.uniqueFolder">The folder ID must be unique.</span>
@@ -573,7 +573,7 @@
                 </div>
                 <div class="form-group" ng-class="{'has-error': folderEditor.folderPath.$invalid && folderEditor.folderPath.$dirty}">
                   <label translate for="folderPath">Folder Path</label>
-                  <input name="folderPath" ng-readonly="editingExisting" id="folderPath" class="form-control" type="text" ng-model="currentFolder.Path" list="directory-list" required />
+                  <input name="folderPath" ng-readonly="editingExisting" id="folderPath" class="form-control" type="text" ng-model="currentFolder.path" list="directory-list" required />
                   <datalist id="directory-list">
                     <option ng-repeat="directory in directoryList" value="{{ directory }}" />
                   </datalist>
@@ -584,7 +584,7 @@
                 </div>
                 <div class="form-group" ng-class="{'has-error': folderEditor.rescanIntervalS.$invalid && folderEditor.rescanIntervalS.$dirty}">
                   <label for="rescanIntervalS"><span translate>Rescan Interval</span> (s)</label>
-                  <input name="rescanIntervalS" id="rescanIntervalS" class="form-control" type="number" ng-model="currentFolder.RescanIntervalS" required min="0"></input>
+                  <input name="rescanIntervalS" id="rescanIntervalS" class="form-control" type="number" ng-model="currentFolder.rescanIntervalS" required min="0"></input>
                   <p class="help-block">
                     <span translate ng-if="!folderEditor.rescanIntervalS.$valid && folderEditor.rescanIntervalS.$dirty">The rescan interval must be a non-negative number of seconds.</span>
                   </p>
@@ -596,7 +596,7 @@
                 <div class="form-group">
                   <div class="checkbox">
                     <label>
-                      <input type="checkbox" ng-model="currentFolder.ReadOnly"> <span translate>Folder Master</span>
+                      <input type="checkbox" ng-model="currentFolder.readOnly"> <span translate>Folder Master</span>
                     </label>
                   </div>
                   <p translate class="help-block">Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.</p>
@@ -604,7 +604,7 @@
                 <div class="form-group">
                   <div class="checkbox">
                     <label>
-                      <input type="checkbox" ng-model="currentFolder.IgnorePerms"> <span translate>Ignore Permissions</span>
+                      <input type="checkbox" ng-model="currentFolder.ignorePerms"> <span translate>Ignore Permissions</span>
                     </label>
                   </div>
                   <p translate class="help-block">File permission bits are ignored when looking for changes. Use on FAT filesystems.</p>
@@ -615,21 +615,21 @@
                   <label translate>File Versioning</label>
                   <div class="radio">
                     <label>
-                      <input type="radio" ng-model="currentFolder.FileVersioningSelector" value="none"> <span translate>No File Versioning</span>
+                      <input type="radio" ng-model="currentFolder.fileVersioningSelector" value="none"> <span translate>No File Versioning</span>
                     </label>
                   </div>
                   <div class="radio">
                     <label>
-                      <input type="radio" ng-model="currentFolder.FileVersioningSelector" value="simple"> <span translate>Simple File Versioning</span>
+                      <input type="radio" ng-model="currentFolder.fileVersioningSelector" value="simple"> <span translate>Simple File Versioning</span>
                     </label>
                   </div>
                   <div class="radio">
                     <label>
-                      <input type="radio" ng-model="currentFolder.FileVersioningSelector" value="staggered"> <span translate>Staggered File Versioning</span>
+                      <input type="radio" ng-model="currentFolder.fileVersioningSelector" value="staggered"> <span translate>Staggered File Versioning</span>
                     </label>
                   </div>
                 </div>
-                <div class="form-group" ng-if="currentFolder.FileVersioningSelector=='simple'" ng-class="{'has-error': folderEditor.simpleKeep.$invalid && folderEditor.simpleKeep.$dirty}">
+                <div class="form-group" ng-if="currentFolder.fileVersioningSelector=='simple'" ng-class="{'has-error': folderEditor.simpleKeep.$invalid && folderEditor.simpleKeep.$dirty}">
                   <p translate class="help-block">Files are moved to date stamped versions in a .stversions folder when replaced or deleted by syncthing.</p>
                   <label translate for="simpleKeep">Keep Versions</label>
                   <input name="simpleKeep" id="simpleKeep" class="form-control" type="number" ng-model="currentFolder.simpleKeep" required min="1"></input>
@@ -639,7 +639,7 @@
                     <span translate ng-if="folderEditor.simpleKeep.$error.min && folderEditor.simpleKeep.$dirty">You must keep at least one version.</span>
                   </p>
                 </div>
-                <div class="form-group" ng-if="currentFolder.FileVersioningSelector=='staggered'" ng-class="{'has-error': folderEditor.staggeredMaxAge.$invalid && folderEditor.staggeredMaxAge.$dirty}">
+                <div class="form-group" ng-if="currentFolder.fileVersioningSelector=='staggered'" ng-class="{'has-error': folderEditor.staggeredMaxAge.$invalid && folderEditor.staggeredMaxAge.$dirty}">
                   <p class="help-block"><span translate>Files are moved to date stamped versions in a .stversions folder when replaced or deleted by syncthing.</span> <span translate>Versions are automatically deleted if they are older than the maximum age or exceed the number of files allowed in an interval.</span></p>
                   <p translate class="help-block">The following intervals are used: for the first hour a version is kept every 30 seconds, for the first day a version is kept every hour, for the first 30 days a version is kept every day, until the maximum age a version is kept every week.</p>
                   <label translate for="staggeredMaxAge">Maximum Age</label>
@@ -649,7 +649,7 @@
                     <span translate ng-if="folderEditor.staggeredMaxAge.$error.required && folderEditor.staggeredMaxAge.$dirty">The maximum age must be a number and cannot be blank.</span>
                   </p>
                 </div>
-                <div class="form-group" ng-if="currentFolder.FileVersioningSelector == 'staggered'">
+                <div class="form-group" ng-if="currentFolder.fileVersioningSelector == 'staggered'">
                   <label translate for="staggeredVersionsPath">Versions Path</label>
                   <input name="staggeredVersionsPath" id="staggeredVersionsPath" class="form-control" type="text" ng-model="currentFolder.staggeredVersionsPath"></input>
                   <p translate class="help-block">Path where versions should be stored (leave empty for the default .stversions folder in the folder).</p>
@@ -665,7 +665,7 @@
                   <div class="three-columns">
                     <div class="checkbox" ng-repeat="device in otherDevices()">
                       <label>
-                        <input type="checkbox" ng-model="currentFolder.selectedDevices[device.DeviceID]"> {{deviceName(device)}}
+                        <input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]"> {{deviceName(device)}}
                       </label>
                     </div>
                   </div>
@@ -709,7 +709,7 @@
           </dl>
         </div>
         <div class="modal-footer">
-          <div class="pull-left"><span translate>Editing</span> <code>{{currentFolder.Path}}{{system.pathSeparator}}.stignore</code></div>
+          <div class="pull-left"><span translate>Editing</span> <code>{{currentFolder.path}}{{system.pathSeparator}}.stignore</code></div>
           <button type="button" class="btn btn-primary btn-sm" data-dismiss="modal" ng-click="saveIgnores()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
           <button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
         </div>
@@ -732,32 +732,32 @@
               <div class="col-md-6">
                 <div class="form-group">
                   <label translate for="DeviceName">Device Name</label>
-                  <input id="DeviceName" class="form-control" type="text" ng-model="tmpOptions.DeviceName">
+                  <input id="DeviceName" class="form-control" type="text" ng-model="tmpOptions.deviceName">
                 </div>
                 <div class="form-group">
                   <label translate for="ListenAddressStr">Sync Protocol Listen Addresses</label>
-                  <input id="ListenAddressStr" class="form-control" type="text" ng-model="tmpOptions.ListenAddressStr">
+                  <input id="ListenAddressStr" class="form-control" type="text" ng-model="tmpOptions.listenAddressStr">
                 </div>
                 <div class="form-group">
                   <label translate for="MaxRecvKbps">Incoming Rate Limit (KiB/s)</label>
-                  <input id="MaxRecvKbps" class="form-control" type="number" ng-model="tmpOptions.MaxRecvKbps">
+                  <input id="MaxRecvKbps" class="form-control" type="number" ng-model="tmpOptions.maxRecvKbps">
                 </div>
                 <div class="form-group">
                   <label translate for="MaxSendKbps">Outgoing Rate Limit (KiB/s)</label>
-                  <input id="MaxSendKbps" class="form-control" type="number" ng-model="tmpOptions.MaxSendKbps">
+                  <input id="MaxSendKbps" class="form-control" type="number" ng-model="tmpOptions.maxSendKbps">
                 </div>
                 <div class="col-md-6">
                   <div class="form-group">
                     <div class="checkbox">
                       <label>
-                        <input id="UPnPEnabled" type="checkbox" ng-model="tmpOptions.UPnPEnabled"> <span translate>Enable UPnP</span>
+                        <input id="UPnPEnabled" type="checkbox" ng-model="tmpOptions.upnpEnabled"> <span translate>Enable UPnP</span>
                       </label>
                     </div>
                   </div>
                   <div class="form-group">
                     <div class="checkbox">
                       <label>
-                        <input id="GlobalAnnEnabled" type="checkbox" ng-model="tmpOptions.GlobalAnnEnabled"> <span translate>Global Discovery</span>
+                        <input id="GlobalAnnEnabled" type="checkbox" ng-model="tmpOptions.globalAnnounceEnabled"> <span translate>Global Discovery</span>
                       </label>
                     </div>
                   </div>
@@ -766,55 +766,55 @@
                   <div class="form-group">
                     <div class="checkbox">
                       <label ng-if="upgradeInfo">
-                        <input id="AutoUpgradeEnabled" type="checkbox" ng-model="tmpOptions.AutoUpgradeEnabled"> <span translate>Automatic upgrades</span>
+                        <input id="AutoUpgradeEnabled" type="checkbox" ng-model="tmpOptions.autoUpgradeEnabled"> <span translate>Automatic upgrades</span>
                       </label>
                     </div>
                   </div>
                   <div class="form-group">
                     <div class="checkbox">
                       <label>
-                        <input id="LocalAnnEnabled" type="checkbox" ng-model="tmpOptions.LocalAnnEnabled"> <span translate>Local Discovery</span>
+                        <input id="LocalAnnEnabled" type="checkbox" ng-model="tmpOptions.localAnnounceEnabled"> <span translate>Local Discovery</span>
                       </label>
                     </div>
                   </div>
                 </div>
                 <div class="form-group">
                   <label translate for="GlobalAnnServersStr">Global Discovery Server</label>
-                  <input ng-disabled="!tmpOptions.GlobalAnnEnabled" id="GlobalAnnServersStr" class="form-control" type="text" ng-model="tmpOptions.GlobalAnnServersStr">
+                  <input ng-disabled="!tmpOptions.globalAnnounceEnabled" id="GlobalAnnServersStr" class="form-control" type="text" ng-model="tmpOptions.globalAnnounceServersStr">
                 </div>
               </div>
 
               <div class="col-md-6">
                 <div class="form-group">
                   <label translate for="Address">GUI Listen Addresses</label>
-                  <input id="Address" class="form-control" type="text" ng-model="tmpGUI.Address">
+                  <input id="Address" class="form-control" type="text" ng-model="tmpGUI.address">
                 </div>
                 <div class="form-group">
                   <label translate for="User">GUI Authentication User</label>
-                  <input id="User" class="form-control" type="text" ng-model="tmpGUI.User">
+                  <input id="User" class="form-control" type="text" ng-model="tmpGUI.user">
                 </div>
                 <div class="form-group">
                   <label translate for="Password">GUI Authentication Password</label>
-                  <input id="Password" class="form-control" type="password" ng-model="tmpGUI.Password">
+                  <input id="Password" class="form-control" type="password" ng-model="tmpGUI.password">
                 </div>
                 <div class="form-group">
                   <div class="checkbox">
                     <label>
-                      <input id="UseTLS" type="checkbox" ng-model="tmpGUI.UseTLS"> <span translate>Use HTTPS for GUI</span>
+                      <input id="UseTLS" type="checkbox" ng-model="tmpGUI.useTLS"> <span translate>Use HTTPS for GUI</span>
                     </label>
                   </div>
                 </div>
                 <div class="form-group">
                   <div class="checkbox">
                     <label>
-                      <input id="StartBrowser" type="checkbox" ng-model="tmpOptions.StartBrowser"> <span translate>Start Browser</span>
+                      <input id="StartBrowser" type="checkbox" ng-model="tmpOptions.startBrowser"> <span translate>Start Browser</span>
                     </label>
                   </div>
                 </div>
                 <div class="form-group">
                   <div class="checkbox">
                     <label>
-                      <input id="UREnabled" type="checkbox" ng-model="tmpOptions.UREnabled"> <span translate>Anonymous Usage Reporting</span> (<a translate ng-click="showURPreview()" href="#">Preview</a>)
+                      <input id="UREnabled" type="checkbox" ng-model="tmpOptions.urEnabled"> <span translate>Anonymous Usage Reporting</span> (<a translate ng-click="showURPreview()" href="#">Preview</a>)
                     </label>
                   </div>
                 </div>
@@ -823,7 +823,7 @@
 
                 <div class="form-group">
                   <label><span translate>API Key</span></label>
-                  <div class="well well-sm text-monospace">{{tmpGUI.APIKey || "-"}}</div>
+                  <div class="well well-sm text-monospace">{{tmpGUI.apiKey || "-"}}</div>
                   <button translate type="button" class="btn btn-sm btn-default" ng-click="setAPIKey(tmpGUI)">Generate</button>
                 </div>
               </div>
@@ -897,34 +897,34 @@
     <table class="table table-striped table-condensed">
       <tr ng-repeat="f in needed.progress" ng-init="a = needAction(f)">
         <td class="small-data"><span class="glyphicon glyphicon-{{needIcons[a]}}"></span> {{needActions[a]}}</td>
-        <td title="{{f.Name}}">{{f.Name | basename}}</td>
-        <td ng-if="a == 'sync' && progress[neededFolder] && progress[neededFolder][f.Name]">
+        <td title="{{f.name}}">{{f.name | basename}}</td>
+        <td ng-if="a == 'sync' && progress[neededFolder] && progress[neededFolder][f.name]">
           <div class="progress">
-            <div class="progress-bar progress-bar-success" style="width: {{progress[neededFolder][f.Name].Reused}}%"></div>
-            <div class="progress-bar" style="width: {{progress[neededFolder][f.Name].CopiedFromOrigin}}%"></div>
-            <div class="progress-bar progress-bar-info" style="width: {{progress[neededFolder][f.Name].CopiedFromElsewhere}}%"></div>
-            <div class="progress-bar progress-bar-warning" style="width: {{progress[neededFolder][f.Name].Pulled}}%"></div>
-            <div class="progress-bar progress-bar-danger progress-bar-striped active" style="width: {{progress[neededFolder][f.Name].Pulling}}%"></div>
+            <div class="progress-bar progress-bar-success" style="width: {{progress[neededFolder][f.name].reused}}%"></div>
+            <div class="progress-bar" style="width: {{progress[neededFolder][f.name].copiedFromOrigin}}%"></div>
+            <div class="progress-bar progress-bar-info" style="width: {{progress[neededFolder][f.name].copiedFromElsewhere}}%"></div>
+            <div class="progress-bar progress-bar-warning" style="width: {{progress[neededFolder][f.name].pulled}}%"></div>
+            <div class="progress-bar progress-bar-danger progress-bar-striped active" style="width: {{progress[neededFolder][f.name].pulling}}%"></div>
             <span class="show frontal">
-              {{progress[neededFolder][f.Name].BytesDone | binary}}B / {{progress[neededFolder][f.Name].BytesTotal | binary}}B
+              {{progress[neededFolder][f.name].bytesDone | binary}}B / {{progress[neededFolder][f.name].bytesTotal | binary}}B
             </span>
           </div>
         </td>
-        <td class="text-right small-data" ng-if="a != 'sync' || !progress[neededFolder] || !progress[neededFolder][f.Name]">
-          <span ng-if="f.Size > 0">{{f.Size | binary}}B</span>
+        <td class="text-right small-data" ng-if="a != 'sync' || !progress[neededFolder] || !progress[neededFolder][f.name]">
+          <span ng-if="f.size > 0">{{f.size | binary}}B</span>
         </td>
       </tr>
       <tr ng-repeat="f in needed.queued" ng-init="a = needAction(f)">
         <td class="small-data"><span class="glyphicon glyphicon-{{needIcons[a]}}"></span> {{needActions[a]}}</td>
-        <td><a href="" ng-if="$index != 0" ng-click="bumpFile(neededFolder, f.Name)" title="{{'Move to top of queue' | translate}}"><span class="glyphicon glyphicon-eject"></span></a><span ng-if="$index != 0">&ensp;</span><span title="{{f.Name}}">{{f.Name | basename}}</span></td>
+        <td><a href="" ng-if="$index != 0" ng-click="bumpFile(neededFolder, f.name)" title="{{'Move to top of queue' | translate}}"><span class="glyphicon glyphicon-eject"></span></a><span ng-if="$index != 0">&ensp;</span><span title="{{f.name}}">{{f.name | basename}}</span></td>
         <td class="text-right small-data">
-          <span ng-if="f.Size > 0">{{f.Size | binary}}B</span>
+          <span ng-if="f.size > 0">{{f.size | binary}}B</span>
          </td>
       </tr>
       <tr ng-repeat="f in needed.rest" ng-init="a = needAction(f)">
         <td class="small-data"><span class="glyphicon glyphicon-{{needIcons[a]}}"></span> {{needActions[a]}}</td>
-        <td title="{{f.Name}}">{{f.Name | basename}}</td>
-        <td class="text-right small-data"><span ng-if="f.Size > 0">{{f.Size | binary}}B</span></td>
+        <td title="{{f.name}}">{{f.name | basename}}</td>
+        <td class="text-right small-data"><span ng-if="f.size > 0">{{f.size | binary}}B</span></td>
       </tr>
     </table>
 

+ 1 - 1
gui/scripts/syncthing/app.js

@@ -78,7 +78,7 @@ function folderCompare(a, b) {
 function folderMap(l) {
     var m = {};
     l.forEach(function (r) {
-        m[r.ID] = r;
+        m[r.id] = r;
     });
     return m;
 }

+ 156 - 157
gui/scripts/syncthing/core/controllers/syncthingController.js

@@ -141,8 +141,8 @@ angular.module('syncthing.core')
             refreshFolderStats();
 
             // Update completion status for all devices that we share this folder with.
-            $scope.folders[data.folder].Devices.forEach(function (deviceCfg) {
-                refreshCompletion(deviceCfg.DeviceID, data.folder);
+            $scope.folders[data.folder].devices.forEach(function (deviceCfg) {
+                refreshCompletion(deviceCfg.deviceID, data.folder);
             });
         });
 
@@ -162,9 +162,9 @@ angular.module('syncthing.core')
                 $scope.connections[arg.data.id] = {
                     inbps: 0,
                     outbps: 0,
-                    InBytesTotal: 0,
-                    OutBytesTotal: 0,
-                    Address: arg.data.addr
+                    inBytesTotal: 0,
+                    outBytesTotal: 0,
+                    address: arg.data.addr
                 };
                 $scope.completion[arg.data.id] = {
                     _total: 100
@@ -173,7 +173,7 @@ angular.module('syncthing.core')
         });
 
         $scope.$on('ConfigLoaded', function (event) {
-            if ($scope.config.Options.URAccepted === 0) {
+            if ($scope.config.options.urAccepted === 0) {
                 // If usage reporting has been neither accepted nor declined,
                 // we want to ask the user to make a choice. But we don't want
                 // to bug them during initial setup, so we set a cookie with
@@ -216,23 +216,23 @@ angular.module('syncthing.core')
                 progress[folder] = {};
                 for (var file in stats[folder]) {
                     var s = stats[folder][file];
-                    var reused = 100 * s.Reused / s.Total;
-                    var copiedFromOrigin = 100 * s.CopiedFromOrigin / s.Total;
-                    var copiedFromElsewhere = 100 * s.CopiedFromElsewhere / s.Total;
-                    var pulled = 100 * s.Pulled / s.Total;
-                    var pulling = 100 * s.Pulling / s.Total;
+                    var reused = 100 * s.reused / s.total;
+                    var copiedFromOrigin = 100 * s.copiedFromOrigin / s.total;
+                    var copiedFromElsewhere = 100 * s.copiedFromElsewhere / s.total;
+                    var pulled = 100 * s.pulled / s.total;
+                    var pulling = 100 * s.pulling / s.total;
                     // We try to round up pulling to atleast a percent so that it would be atleast a bit visible.
                     if (pulling < 1 && pulled + copiedFromElsewhere + copiedFromOrigin + reused <= 99) {
                         pulling = 1;
                     }
                     progress[folder][file] = {
-                        Reused: reused,
-                        CopiedFromOrigin: copiedFromOrigin,
-                        CopiedFromElsewhere: copiedFromElsewhere,
-                        Pulled: pulled,
-                        Pulling: pulling,
-                        BytesTotal: s.BytesTotal,
-                        BytesDone: s.BytesDone,
+                        reused: reused,
+                        copiedFromOrigin: copiedFromOrigin,
+                        copiedFromElsewhere: copiedFromElsewhere,
+                        pulled: pulled,
+                        pulling: pulling,
+                        bytesTotal: s.bytesTotal,
+                        bytesDone: s.bytesDone,
                     };
                 }
             }
@@ -278,22 +278,21 @@ angular.module('syncthing.core')
             var hasConfig = !isEmptyObject($scope.config);
 
             $scope.config = config;
-            $scope.config.Options.ListenAddressStr = $scope.config.Options.ListenAddress.join(', ');
-            $scope.config.Options.GlobalAnnServersStr = $scope.config.Options.GlobalAnnServers.join(', ');
+            $scope.config.options.listenAddressStr = $scope.config.options.listenAddress.join(', ');
+            $scope.config.options.globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', ');
 
-            $scope.devices = $scope.config.Devices;
+            $scope.devices = $scope.config.devices;
             $scope.devices.forEach(function (deviceCfg) {
-                $scope.completion[deviceCfg.DeviceID] = {
+                $scope.completion[deviceCfg.deviceID] = {
                     _total: 100
                 };
             });
             $scope.devices.sort(deviceCompare);
-
-            $scope.folders = folderMap($scope.config.Folders);
+            $scope.folders = folderMap($scope.config.folders);
             Object.keys($scope.folders).forEach(function (folder) {
                 refreshFolder(folder);
-                $scope.folders[folder].Devices.forEach(function (deviceCfg) {
-                    refreshCompletion(deviceCfg.DeviceID, folder);
+                $scope.folders[folder].devices.forEach(function (deviceCfg) {
+                    refreshCompletion(deviceCfg.deviceID, folder);
                 });
             });
 
@@ -362,8 +361,8 @@ angular.module('syncthing.core')
                         continue;
                     }
                     try {
-                        data[id].inbps = Math.max(0, (data[id].InBytesTotal - $scope.connections[id].InBytesTotal) / td);
-                        data[id].outbps = Math.max(0, (data[id].OutBytesTotal - $scope.connections[id].OutBytesTotal) / td);
+                        data[id].inbps = Math.max(0, (data[id].inBytesTotal - $scope.connections[id].inBytesTotal) / td);
+                        data[id].outbps = Math.max(0, (data[id].outBytesTotal - $scope.connections[id].outBytesTotal) / td);
                     } catch (e) {
                         data[id].inbps = 0;
                         data[id].outbps = 0;
@@ -405,8 +404,8 @@ angular.module('syncthing.core')
             $http.get(urlbase + "/stats/device").success(function (data) {
                 $scope.deviceStats = data;
                 for (var device in $scope.deviceStats) {
-                    $scope.deviceStats[device].LastSeen = new Date($scope.deviceStats[device].LastSeen);
-                    $scope.deviceStats[device].LastSeenDays = (new Date() - $scope.deviceStats[device].LastSeen) / 1000 / 86400;
+                    $scope.deviceStats[device].lastSeen = new Date($scope.deviceStats[device].lastSeen);
+                    $scope.deviceStats[device].lastSeenDays = (new Date() - $scope.deviceStats[device].lastSeen) / 1000 / 86400;
                 }
                 console.log("refreshDeviceStats", data);
             }).error($scope.emitHTTPError);
@@ -416,8 +415,8 @@ angular.module('syncthing.core')
             $http.get(urlbase + "/stats/folder").success(function (data) {
                 $scope.folderStats = data;
                 for (var folder in $scope.folderStats) {
-                    if ($scope.folderStats[folder].LastFile) {
-                        $scope.folderStats[folder].LastFile.At = new Date($scope.folderStats[folder].LastFile.At);
+                    if ($scope.folderStats[folder].lastFile) {
+                        $scope.folderStats[folder].lastFile.at = new Date($scope.folderStats[folder].lastFile.at);
                     }
                 }
                 console.log("refreshfolderStats", data);
@@ -431,38 +430,38 @@ angular.module('syncthing.core')
         };
 
         $scope.folderStatus = function (folderCfg) {
-            if (typeof $scope.model[folderCfg.ID] === 'undefined') {
+            if (typeof $scope.model[folderCfg.id] === 'undefined') {
                 return 'unknown';
             }
 
-            if (folderCfg.Devices.length <= 1) {
+            if (folderCfg.devices.length <= 1) {
                 return 'unshared';
             }
 
-            if ($scope.model[folderCfg.ID].invalid !== '') {
+            if ($scope.model[folderCfg.id].invalid !== '') {
                 return 'stopped';
             }
 
-            return '' + $scope.model[folderCfg.ID].state;
+            return '' + $scope.model[folderCfg.id].state;
         };
 
         $scope.folderClass = function (folderCfg) {
-            if (typeof $scope.model[folderCfg.ID] === 'undefined') {
+            if (typeof $scope.model[folderCfg.id] === 'undefined') {
                 // Unknown
                 return 'info';
             }
 
-            if (folderCfg.Devices.length <= 1) {
+            if (folderCfg.devices.length <= 1) {
                 // Unshared
                 return 'warning';
             }
 
-            if ($scope.model[folderCfg.ID].invalid !== '') {
+            if ($scope.model[folderCfg.id].invalid !== '') {
                 // Errored
                 return 'danger';
             }
 
-            var state = '' + $scope.model[folderCfg.ID].state;
+            var state = '' + $scope.model[folderCfg.id].state;
             if (state == 'idle') {
                 return 'success';
             }
@@ -488,8 +487,8 @@ angular.module('syncthing.core')
         };
 
         $scope.deviceIcon = function (deviceCfg) {
-            if ($scope.connections[deviceCfg.DeviceID]) {
-                if ($scope.completion[deviceCfg.DeviceID] && $scope.completion[deviceCfg.DeviceID]._total === 100) {
+            if ($scope.connections[deviceCfg.deviceID]) {
+                if ($scope.completion[deviceCfg.deviceID] && $scope.completion[deviceCfg.deviceID]._total === 100) {
                     return 'ok';
                 } else {
                     return 'refresh';
@@ -504,8 +503,8 @@ angular.module('syncthing.core')
                 return 'unused';
             }
 
-            if ($scope.connections[deviceCfg.DeviceID]) {
-                if ($scope.completion[deviceCfg.DeviceID] && $scope.completion[deviceCfg.DeviceID]._total === 100) {
+            if ($scope.connections[deviceCfg.deviceID]) {
+                if ($scope.completion[deviceCfg.deviceID] && $scope.completion[deviceCfg.deviceID]._total === 100) {
                     return 'insync';
                 } else {
                     return 'syncing';
@@ -522,8 +521,8 @@ angular.module('syncthing.core')
                 return 'warning';
             }
 
-            if ($scope.connections[deviceCfg.DeviceID]) {
-                if ($scope.completion[deviceCfg.DeviceID] && $scope.completion[deviceCfg.DeviceID]._total === 100) {
+            if ($scope.connections[deviceCfg.deviceID]) {
+                if ($scope.completion[deviceCfg.deviceID] && $scope.completion[deviceCfg.deviceID]._total === 100) {
                     return 'success';
                 } else {
                     return 'primary';
@@ -535,24 +534,24 @@ angular.module('syncthing.core')
         };
 
         $scope.deviceAddr = function (deviceCfg) {
-            var conn = $scope.connections[deviceCfg.DeviceID];
+            var conn = $scope.connections[deviceCfg.deviceID];
             if (conn) {
-                return conn.Address;
+                return conn.address;
             }
             return '?';
         };
 
         $scope.deviceCompletion = function (deviceCfg) {
-            var conn = $scope.connections[deviceCfg.DeviceID];
+            var conn = $scope.connections[deviceCfg.deviceID];
             if (conn) {
-                return conn.Completion + '%';
+                return conn.completion + '%';
             }
             return '';
         };
 
         $scope.findDevice = function (deviceID) {
             var matches = $scope.devices.filter(function (n) {
-                return n.DeviceID == deviceID;
+                return n.deviceID == deviceID;
             });
             if (matches.length != 1) {
                 return undefined;
@@ -564,10 +563,10 @@ angular.module('syncthing.core')
             if (typeof deviceCfg === 'undefined') {
                 return "";
             }
-            if (deviceCfg.Name) {
-                return deviceCfg.Name;
+            if (deviceCfg.name) {
+                return deviceCfg.name;
             }
-            return deviceCfg.DeviceID.substr(0, 6);
+            return deviceCfg.deviceID.substr(0, 6);
         };
 
         $scope.thisDeviceName = function () {
@@ -575,19 +574,19 @@ angular.module('syncthing.core')
             if (typeof device === 'undefined') {
                 return "(unknown device)";
             }
-            if (device.Name) {
-                return device.Name;
+            if (device.name) {
+                return device.name;
             }
-            return device.DeviceID.substr(0, 6);
+            return device.deviceID.substr(0, 6);
         };
 
         $scope.editSettings = function () {
             // Make a working copy
-            $scope.tmpOptions = angular.copy($scope.config.Options);
-            $scope.tmpOptions.UREnabled = ($scope.tmpOptions.URAccepted > 0);
-            $scope.tmpOptions.DeviceName = $scope.thisDevice().Name;
-            $scope.tmpOptions.AutoUpgradeEnabled = ($scope.tmpOptions.AutoUpgradeIntervalH > 0);
-            $scope.tmpGUI = angular.copy($scope.config.GUI);
+            $scope.tmpOptions = angular.copy($scope.config.options);
+            $scope.tmpOptions.urEnabled = ($scope.tmpOptions.urAccepted > 0);
+            $scope.tmpOptions.deviceName = $scope.thisDevice().name;
+            $scope.tmpOptions.autoUpgradeEnabled = ($scope.tmpOptions.autoUpgradeIntervalH > 0);
+            $scope.tmpGUI = angular.copy($scope.config.gui);
             $('#settings').modal();
         };
 
@@ -607,34 +606,34 @@ angular.module('syncthing.core')
 
         $scope.saveSettings = function () {
             // Make sure something changed
-            var changed = !angular.equals($scope.config.Options, $scope.tmpOptions) || !angular.equals($scope.config.GUI, $scope.tmpGUI);
+            var changed = !angular.equals($scope.config.options, $scope.tmpOptions) || !angular.equals($scope.config.gui, $scope.tmpGUI);
             if (changed) {
                 // Check if usage reporting has been enabled or disabled
-                if ($scope.tmpOptions.UREnabled && $scope.tmpOptions.URAccepted <= 0) {
-                    $scope.tmpOptions.URAccepted = 1000;
-                } else if (!$scope.tmpOptions.UREnabled && $scope.tmpOptions.URAccepted > 0) {
-                    $scope.tmpOptions.URAccepted = -1;
+                if ($scope.tmpOptions.urEnabled && $scope.tmpOptions.urAccepted <= 0) {
+                    $scope.tmpOptions.urAccepted = 1000;
+                } else if (!$scope.tmpOptions.urEnabled && $scope.tmpOptions.urAccepted > 0) {
+                    $scope.tmpOptions.urAccepted = -1;
                 }
 
                 // Check if auto-upgrade has been enabled or disabled
-                if ($scope.tmpOptions.AutoUpgradeEnabled) {
-                    $scope.tmpOptions.AutoUpgradeIntervalH = $scope.tmpOptions.AutoUpgradeIntervalH || 12;
+                if ($scope.tmpOptions.autoUpgradeEnabled) {
+                    $scope.tmpOptions.autoUpgradeIntervalH = $scope.tmpOptions.autoUpgradeIntervalH || 12;
                 } else {
-                    $scope.tmpOptions.AutoUpgradeIntervalH = 0;
+                    $scope.tmpOptions.autoUpgradeIntervalH = 0;
                 }
 
                 // Check if protocol will need to be changed on restart
-                if ($scope.config.GUI.UseTLS !== $scope.tmpGUI.UseTLS) {
+                if ($scope.config.gui.useTLS !== $scope.tmpGUI.useTLS) {
                     $scope.protocolChanged = true;
                 }
 
                 // Apply new settings locally
-                $scope.thisDevice().Name = $scope.tmpOptions.DeviceName;
-                $scope.config.Options = angular.copy($scope.tmpOptions);
-                $scope.config.GUI = angular.copy($scope.tmpGUI);
+                $scope.thisDevice().name = $scope.tmpOptions.deviceName;
+                $scope.config.options = angular.copy($scope.tmpOptions);
+                $scope.config.gui = angular.copy($scope.tmpGUI);
 
-                ['ListenAddress', 'GlobalAnnServers'].forEach(function (key) {
-                    $scope.config.Options[key] = $scope.config.Options[key + "Str"].split(/[ ,]+/).map(function (x) {
+                ['listenAddress', 'globalAnnounceServers'].forEach(function (key) {
+                    $scope.config.options[key] = $scope.config.options[key + "Str"].split(/[ ,]+/).map(function (x) {
                         return x.trim();
                     });
                 });
@@ -655,7 +654,7 @@ angular.module('syncthing.core')
             if ($scope.protocolChanged) {
                 var protocol = 'http';
 
-                if ($scope.config.GUI.UseTLS) {
+                if ($scope.config.gui.useTLS) {
                     protocol = 'https';
                 }
 
@@ -689,8 +688,8 @@ angular.module('syncthing.core')
         $scope.editDevice = function (deviceCfg) {
             $scope.currentDevice = $.extend({}, deviceCfg);
             $scope.editingExisting = true;
-            $scope.editingSelf = (deviceCfg.DeviceID == $scope.myID);
-            $scope.currentDevice.AddressesStr = deviceCfg.Addresses.join(', ');
+            $scope.editingSelf = (deviceCfg.deviceID == $scope.myID);
+            $scope.currentDevice.addressesStr = deviceCfg.addresses.join(', ');
             if (!$scope.editingSelf) {
                 $scope.currentDevice.selectedFolders = {};
                 $scope.deviceFolders($scope.currentDevice).forEach(function (folder) {
@@ -712,9 +711,9 @@ angular.module('syncthing.core')
                 })
                 .then(function () {
                     $scope.currentDevice = {
-                        AddressesStr: 'dynamic',
-                        Compression: 'metadata',
-                        Introducer: false,
+                        addressesStr: 'dynamic',
+                        compression: 'metadata',
+                        introducer: false,
                         selectedFolders: {}
                     };
                     $scope.editingExisting = false;
@@ -731,18 +730,18 @@ angular.module('syncthing.core')
             }
 
             $scope.devices = $scope.devices.filter(function (n) {
-                return n.DeviceID !== $scope.currentDevice.DeviceID;
+                return n.deviceID !== $scope.currentDevice.deviceID;
             });
-            $scope.config.Devices = $scope.devices;
+            $scope.config.devices = $scope.devices;
             // In case we later added the device manually, remove the ignoral
             // record.
-            $scope.config.IgnoredDevices = $scope.config.IgnoredDevices.filter(function (id) {
-                return id !== $scope.currentDevice.DeviceID;
+            $scope.config.ignoredDevices = $scope.config.ignoredDevices.filter(function (id) {
+                return id !== $scope.currentDevice.deviceID;
             });
 
             for (var id in $scope.folders) {
-                $scope.folders[id].Devices = $scope.folders[id].Devices.filter(function (n) {
-                    return n.DeviceID !== $scope.currentDevice.DeviceID;
+                $scope.folders[id].devices = $scope.folders[id].devices.filter(function (n) {
+                    return n.deviceID !== $scope.currentDevice.deviceID;
                 });
             }
 
@@ -756,10 +755,10 @@ angular.module('syncthing.core')
 
         $scope.addNewDeviceID = function (device) {
             var deviceCfg = {
-                DeviceID: device,
-                AddressesStr: 'dynamic',
-                Compression: 'metadata',
-                Introducer: false,
+                deviceID: device,
+                addressesStr: 'dynamic',
+                compression: 'metadata',
+                introducer: false,
                 selectedFolders: {}
             };
             $scope.saveDeviceConfig(deviceCfg);
@@ -768,13 +767,13 @@ angular.module('syncthing.core')
 
         $scope.saveDeviceConfig = function (deviceCfg) {
             var done, i;
-            deviceCfg.Addresses = deviceCfg.AddressesStr.split(',').map(function (x) {
+            deviceCfg.addresses = deviceCfg.addressesStr.split(',').map(function (x) {
                 return x.trim();
             });
 
             done = false;
             for (i = 0; i < $scope.devices.length; i++) {
-                if ($scope.devices[i].DeviceID === deviceCfg.DeviceID) {
+                if ($scope.devices[i].deviceID === deviceCfg.deviceID) {
                     $scope.devices[i] = deviceCfg;
                     done = true;
                     break;
@@ -786,32 +785,32 @@ angular.module('syncthing.core')
             }
 
             $scope.devices.sort(deviceCompare);
-            $scope.config.Devices = $scope.devices;
+            $scope.config.devices = $scope.devices;
             // In case we are adding the device manually, remove the ignoral
             // record.
-            $scope.config.IgnoredDevices = $scope.config.IgnoredDevices.filter(function (id) {
-                return id !== deviceCfg.DeviceID;
+            $scope.config.ignoredDevices = $scope.config.ignoredDevices.filter(function (id) {
+                return id !== deviceCfg.deviceID;
             });
 
             if (!$scope.editingSelf) {
                 for (var id in deviceCfg.selectedFolders) {
                     if (deviceCfg.selectedFolders[id]) {
                         var found = false;
-                        for (i = 0; i < $scope.folders[id].Devices.length; i++) {
-                            if ($scope.folders[id].Devices[i].DeviceID == deviceCfg.DeviceID) {
+                        for (i = 0; i < $scope.folders[id].devices.length; i++) {
+                            if ($scope.folders[id].devices[i].deviceID == deviceCfg.deviceID) {
                                 found = true;
                                 break;
                             }
                         }
 
                         if (!found) {
-                            $scope.folders[id].Devices.push({
-                                DeviceID: deviceCfg.DeviceID
+                            $scope.folders[id].devices.push({
+                                deviceID: deviceCfg.deviceID
                             });
                         }
                     } else {
-                        $scope.folders[id].Devices = $scope.folders[id].Devices.filter(function (n) {
-                            return n.DeviceID != deviceCfg.DeviceID;
+                        $scope.folders[id].devices = $scope.folders[id].devices.filter(function (n) {
+                            return n.deviceID != deviceCfg.deviceID;
                         });
                     }
                 }
@@ -825,14 +824,14 @@ angular.module('syncthing.core')
         };
 
         $scope.ignoreRejectedDevice = function (device) {
-            $scope.config.IgnoredDevices.push(device);
+            $scope.config.ignoredDevices.push(device);
             $scope.saveConfig();
             $scope.dismissDeviceRejection(device);
         };
 
         $scope.otherDevices = function () {
             return $scope.devices.filter(function (n) {
-                return n.DeviceID !== $scope.myID;
+                return n.deviceID !== $scope.myID;
             });
         };
 
@@ -841,7 +840,7 @@ angular.module('syncthing.core')
 
             for (i = 0; i < $scope.devices.length; i++) {
                 n = $scope.devices[i];
-                if (n.DeviceID === $scope.myID) {
+                if (n.deviceID === $scope.myID) {
                     return n;
                 }
             }
@@ -855,19 +854,19 @@ angular.module('syncthing.core')
 
         $scope.errorList = function () {
             return $scope.errors.filter(function (e) {
-                return e.Time > $scope.seenError;
+                return e.time > $scope.seenError;
             });
         };
 
         $scope.clearErrors = function () {
-            $scope.seenError = $scope.errors[$scope.errors.length - 1].Time;
+            $scope.seenError = $scope.errors[$scope.errors.length - 1].time;
             $http.post(urlbase + '/error/clear');
         };
 
         $scope.friendlyDevices = function (str) {
             for (var i = 0; i < $scope.devices.length; i++) {
                 var cfg = $scope.devices[i];
-                str = str.replace(cfg.DeviceID, $scope.deviceName(cfg));
+                str = str.replace(cfg.deviceID, $scope.deviceName(cfg));
             }
             return str;
         };
@@ -878,7 +877,7 @@ angular.module('syncthing.core')
 
         $scope.directoryList = [];
 
-        $scope.$watch('currentFolder.Path', function (newvalue) {
+        $scope.$watch('currentFolder.path', function (newvalue) {
             $http.get(urlbase + '/autocomplete/directory', {
                 params: { current: newvalue }
             }).success(function (data) {
@@ -888,25 +887,25 @@ angular.module('syncthing.core')
 
         $scope.editFolder = function (folderCfg) {
             $scope.currentFolder = angular.copy(folderCfg);
-            if ($scope.currentFolder.Path.slice(-1) == $scope.system.pathSeparator) {
-                $scope.currentFolder.Path = $scope.currentFolder.Path.slice(0, -1);
+            if ($scope.currentFolder.path.slice(-1) == $scope.system.pathSeparator) {
+                $scope.currentFolder.path = $scope.currentFolder.path.slice(0, -1);
             }
             $scope.currentFolder.selectedDevices = {};
-            $scope.currentFolder.Devices.forEach(function (n) {
-                $scope.currentFolder.selectedDevices[n.DeviceID] = true;
+            $scope.currentFolder.devices.forEach(function (n) {
+                $scope.currentFolder.selectedDevices[n.deviceID] = true;
             });
-            if ($scope.currentFolder.Versioning && $scope.currentFolder.Versioning.Type === "simple") {
+            if ($scope.currentFolder.versioning && $scope.currentFolder.versioning.type === "simple") {
                 $scope.currentFolder.simpleFileVersioning = true;
-                $scope.currentFolder.FileVersioningSelector = "simple";
-                $scope.currentFolder.simpleKeep = +$scope.currentFolder.Versioning.Params.keep;
-            } else if ($scope.currentFolder.Versioning && $scope.currentFolder.Versioning.Type === "staggered") {
+                $scope.currentFolder.fileVersioningSelector = "simple";
+                $scope.currentFolder.simpleKeep = +$scope.currentFolder.versioning.params.keep;
+            } else if ($scope.currentFolder.versioning && $scope.currentFolder.versioning.type === "staggered") {
                 $scope.currentFolder.staggeredFileVersioning = true;
-                $scope.currentFolder.FileVersioningSelector = "staggered";
-                $scope.currentFolder.staggeredMaxAge = Math.floor(+$scope.currentFolder.Versioning.Params.maxAge / 86400);
-                $scope.currentFolder.staggeredCleanInterval = +$scope.currentFolder.Versioning.Params.cleanInterval;
-                $scope.currentFolder.staggeredVersionsPath = $scope.currentFolder.Versioning.Params.versionsPath;
+                $scope.currentFolder.fileVersioningSelector = "staggered";
+                $scope.currentFolder.staggeredMaxAge = Math.floor(+$scope.currentFolder.versioning.params.maxAge / 86400);
+                $scope.currentFolder.staggeredCleanInterval = +$scope.currentFolder.versioning.params.cleanInterval;
+                $scope.currentFolder.staggeredVersionsPath = $scope.currentFolder.versioning.params.versionsPath;
             } else {
-                $scope.currentFolder.FileVersioningSelector = "none";
+                $scope.currentFolder.fileVersioningSelector = "none";
             }
             $scope.currentFolder.simpleKeep = $scope.currentFolder.simpleKeep || 5;
             $scope.currentFolder.staggeredCleanInterval = $scope.currentFolder.staggeredCleanInterval || 3600;
@@ -928,8 +927,8 @@ angular.module('syncthing.core')
             $scope.currentFolder = {
                 selectedDevices: {}
             };
-            $scope.currentFolder.RescanIntervalS = 60;
-            $scope.currentFolder.FileVersioningSelector = "none";
+            $scope.currentFolder.rescanIntervalS = 60;
+            $scope.currentFolder.fileVersioningSelector = "none";
             $scope.currentFolder.simpleKeep = 5;
             $scope.currentFolder.staggeredMaxAge = 365;
             $scope.currentFolder.staggeredCleanInterval = 3600;
@@ -947,8 +946,8 @@ angular.module('syncthing.core')
             };
             $scope.currentFolder.selectedDevices[device] = true;
 
-            $scope.currentFolder.RescanIntervalS = 60;
-            $scope.currentFolder.FileVersioningSelector = "none";
+            $scope.currentFolder.rescanIntervalS = 60;
+            $scope.currentFolder.fileVersioningSelector = "none";
             $scope.currentFolder.simpleKeep = 5;
             $scope.currentFolder.staggeredMaxAge = 365;
             $scope.currentFolder.staggeredCleanInterval = 3600;
@@ -959,10 +958,10 @@ angular.module('syncthing.core')
         };
 
         $scope.shareFolderWithDevice = function (folder, device) {
-            $scope.folders[folder].Devices.push({
-                DeviceID: device
+            $scope.folders[folder].devices.push({
+                deviceID: device
             });
-            $scope.config.Folders = folderList($scope.folders);
+            $scope.config.folders = folderList($scope.folders);
             $scope.saveConfig();
             $scope.dismissFolderRejection(folder, device);
         };
@@ -972,19 +971,19 @@ angular.module('syncthing.core')
 
             $('#editFolder').modal('hide');
             folderCfg = $scope.currentFolder;
-            folderCfg.Devices = [];
+            folderCfg.devices = [];
             folderCfg.selectedDevices[$scope.myID] = true;
             for (var deviceID in folderCfg.selectedDevices) {
                 if (folderCfg.selectedDevices[deviceID] === true) {
-                    folderCfg.Devices.push({
-                        DeviceID: deviceID
+                    folderCfg.devices.push({
+                        deviceID: deviceID
                     });
                 }
             }
             delete folderCfg.selectedDevices;
 
-            if (folderCfg.FileVersioningSelector === "simple") {
-                folderCfg.Versioning = {
+            if (folderCfg.fileVersioningSelector === "simple") {
+                folderCfg.versioning = {
                     'Type': 'simple',
                     'Params': {
                         'keep': '' + folderCfg.simpleKeep
@@ -992,10 +991,10 @@ angular.module('syncthing.core')
                 };
                 delete folderCfg.simpleFileVersioning;
                 delete folderCfg.simpleKeep;
-            } else if (folderCfg.FileVersioningSelector === "staggered") {
-                folderCfg.Versioning = {
-                    'Type': 'staggered',
-                    'Params': {
+            } else if (folderCfg.fileVersioningSelector === "staggered") {
+                folderCfg.versioning = {
+                    'type': 'staggered',
+                    'params': {
                         'maxAge': '' + (folderCfg.staggeredMaxAge * 86400),
                         'cleanInterval': '' + folderCfg.staggeredCleanInterval,
                         'versionsPath': '' + folderCfg.staggeredVersionsPath
@@ -1007,11 +1006,11 @@ angular.module('syncthing.core')
                 delete folderCfg.staggeredVersionsPath;
 
             } else {
-                delete folderCfg.Versioning;
+                delete folderCfg.versioning;
             }
 
-            $scope.folders[folderCfg.ID] = folderCfg;
-            $scope.config.Folders = folderList($scope.folders);
+            $scope.folders[folderCfg.id] = folderCfg;
+            $scope.config.folders = folderList($scope.folders);
 
             $scope.saveConfig();
         };
@@ -1022,9 +1021,9 @@ angular.module('syncthing.core')
 
         $scope.sharesFolder = function (folderCfg) {
             var names = [];
-            folderCfg.Devices.forEach(function (device) {
-                if (device.DeviceID != $scope.myID) {
-                    names.push($scope.deviceName($scope.findDevice(device.DeviceID)));
+            folderCfg.devices.forEach(function (device) {
+                if (device.deviceID != $scope.myID) {
+                    names.push($scope.deviceName($scope.findDevice(device.deviceID)));
                 }
             });
             names.sort();
@@ -1034,9 +1033,9 @@ angular.module('syncthing.core')
         $scope.deviceFolders = function (deviceCfg) {
             var folders = [];
             for (var folderID in $scope.folders) {
-                var devices = $scope.folders[folderID].Devices
+                var devices = $scope.folders[folderID].devices
                 for (var i = 0; i < devices.length; i++) {
-                    if (devices[i].DeviceID == deviceCfg.DeviceID) {
+                    if (devices[i].deviceID == deviceCfg.deviceID) {
                         folders.push(folderID);
                         break;
                     }
@@ -1053,8 +1052,8 @@ angular.module('syncthing.core')
                 return;
             }
 
-            delete $scope.folders[$scope.currentFolder.ID];
-            $scope.config.Folders = folderList($scope.folders);
+            delete $scope.folders[$scope.currentFolder.id];
+            $scope.config.folders = folderList($scope.folders);
 
             $scope.saveConfig();
         };
@@ -1065,7 +1064,7 @@ angular.module('syncthing.core')
             }
 
             $('#editIgnoresButton').attr('disabled', 'disabled');
-            $http.get(urlbase + '/ignores?folder=' + encodeURIComponent($scope.currentFolder.ID))
+            $http.get(urlbase + '/ignores?folder=' + encodeURIComponent($scope.currentFolder.id))
                 .success(function (data) {
                     data.ignore = data.ignore || [];
 
@@ -1092,13 +1091,13 @@ angular.module('syncthing.core')
                 return;
             }
 
-            $http.post(urlbase + '/ignores?folder=' + encodeURIComponent($scope.currentFolder.ID), {
+            $http.post(urlbase + '/ignores?folder=' + encodeURIComponent($scope.currentFolder.id), {
                 ignore: $('#editIgnores textarea').val().split('\n')
             });
         };
 
         $scope.setAPIKey = function (cfg) {
-            cfg.APIKey = randomString(32);
+            cfg.apiKey = randomString(32);
         };
 
         $scope.showURPreview = function () {
@@ -1109,13 +1108,13 @@ angular.module('syncthing.core')
         };
 
         $scope.acceptUR = function () {
-            $scope.config.Options.URAccepted = 1000; // Larger than the largest existing report version
+            $scope.config.options.urAccepted = 1000; // Larger than the largest existing report version
             $scope.saveConfig();
             $('#ur').modal('hide');
         };
 
         $scope.declineUR = function () {
-            $scope.config.Options.URAccepted = -1;
+            $scope.config.options.urAccepted = -1;
             $scope.saveConfig();
             $('#ur').modal('hide');
         };
@@ -1133,11 +1132,11 @@ angular.module('syncthing.core')
             var fDelete = 4096;
             var fDirectory = 16384;
 
-            if ((file.Flags & (fDelete + fDirectory)) === fDelete + fDirectory) {
+            if ((file.flags & (fDelete + fDirectory)) === fDelete + fDirectory) {
                 return 'rmdir';
-            } else if ((file.Flags & fDelete) === fDelete) {
+            } else if ((file.flags & fDelete) === fDelete) {
                 return 'rm';
-            } else if ((file.Flags & fDirectory) === fDirectory) {
+            } else if ((file.flags & fDirectory) === fDirectory) {
                 return 'touch';
             } else {
                 return 'sync';

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


+ 56 - 56
internal/config/config.go

@@ -39,12 +39,12 @@ var l = logger.DefaultLogger
 const CurrentVersion = 9
 
 type Configuration struct {
-	Version        int                   `xml:"version,attr"`
-	Folders        []FolderConfiguration `xml:"folder"`
-	Devices        []DeviceConfiguration `xml:"device"`
-	GUI            GUIConfiguration      `xml:"gui"`
-	Options        OptionsConfiguration  `xml:"options"`
-	IgnoredDevices []protocol.DeviceID   `xml:"ignoredDevice"`
+	Version        int                   `xml:"version,attr" json:"version"`
+	Folders        []FolderConfiguration `xml:"folder" json:"folders"`
+	Devices        []DeviceConfiguration `xml:"device" json:"devices"`
+	GUI            GUIConfiguration      `xml:"gui" json:"gui"`
+	Options        OptionsConfiguration  `xml:"options" json:"options"`
+	IgnoredDevices []protocol.DeviceID   `xml:"ignoredDevice" json:"ignoredDevices"`
 	XMLName        xml.Name              `xml:"configuration" json:"-"`
 
 	OriginalVersion         int                   `xml:"-" json:"-"` // The version we read from disk, before any conversion
@@ -53,19 +53,19 @@ type Configuration struct {
 }
 
 type FolderConfiguration struct {
-	ID              string                      `xml:"id,attr"`
-	Path            string                      `xml:"path,attr"`
-	Devices         []FolderDeviceConfiguration `xml:"device"`
-	ReadOnly        bool                        `xml:"ro,attr"`
-	RescanIntervalS int                         `xml:"rescanIntervalS,attr" default:"60"`
-	IgnorePerms     bool                        `xml:"ignorePerms,attr"`
-	Versioning      VersioningConfiguration     `xml:"versioning"`
-	LenientMtimes   bool                        `xml:"lenientMtimes"`
-	Copiers         int                         `xml:"copiers" default:"1"`  // This defines how many files are handled concurrently.
-	Pullers         int                         `xml:"pullers" default:"16"` // Defines how many blocks are fetched at the same time, possibly between separate copier routines.
-	Hashers         int                         `xml:"hashers" default:"0"`  // Less than one sets the value to the number of cores. These are CPU bound due to hashing.
-
-	Invalid string `xml:"-"` // Set at runtime when there is an error, not saved
+	ID              string                      `xml:"id,attr" json:"id"`
+	Path            string                      `xml:"path,attr" json:"path"`
+	Devices         []FolderDeviceConfiguration `xml:"device" json:"devices"`
+	ReadOnly        bool                        `xml:"ro,attr" json:"readOnly"`
+	RescanIntervalS int                         `xml:"rescanIntervalS,attr" json:"rescanIntervalS" default:"60"`
+	IgnorePerms     bool                        `xml:"ignorePerms,attr" json:"ignorePerms"`
+	Versioning      VersioningConfiguration     `xml:"versioning" json:"versioning"`
+	LenientMtimes   bool                        `xml:"lenientMtimes" json:"lenientMTimes"`
+	Copiers         int                         `xml:"copiers" json:"copiers" default:"1"`  // This defines how many files are handled concurrently.
+	Pullers         int                         `xml:"pullers" json:"pullers" default:"16"` // Defines how many blocks are fetched at the same time, possibly between separate copier routines.
+	Hashers         int                         `xml:"hashers" json:"hashers" default:"0"`  // Less than one sets the value to the number of cores. These are CPU bound due to hashing.
+
+	Invalid string `xml:"-" json:"invalid"` // Set at runtime when there is an error, not saved
 
 	deviceIDs []protocol.DeviceID
 
@@ -105,8 +105,8 @@ func (f *FolderConfiguration) DeviceIDs() []protocol.DeviceID {
 }
 
 type VersioningConfiguration struct {
-	Type   string `xml:"type,attr"`
-	Params map[string]string
+	Type   string            `xml:"type,attr" json:"type"`
+	Params map[string]string `json:"params"`
 }
 
 type InternalVersioningConfiguration struct {
@@ -146,44 +146,44 @@ func (c *VersioningConfiguration) UnmarshalXML(d *xml.Decoder, start xml.StartEl
 }
 
 type DeviceConfiguration struct {
-	DeviceID    protocol.DeviceID    `xml:"id,attr"`
-	Name        string               `xml:"name,attr,omitempty"`
-	Addresses   []string             `xml:"address,omitempty"`
-	Compression protocol.Compression `xml:"compression,attr"`
-	CertName    string               `xml:"certName,attr,omitempty"`
-	Introducer  bool                 `xml:"introducer,attr"`
+	DeviceID    protocol.DeviceID    `xml:"id,attr" json:"deviceID"`
+	Name        string               `xml:"name,attr,omitempty" json:"name"`
+	Addresses   []string             `xml:"address,omitempty" json:"addresses"`
+	Compression protocol.Compression `xml:"compression,attr" json:"compression"`
+	CertName    string               `xml:"certName,attr,omitempty" json:"certName"`
+	Introducer  bool                 `xml:"introducer,attr" json:"introducer"`
 }
 
 type FolderDeviceConfiguration struct {
-	DeviceID protocol.DeviceID `xml:"id,attr"`
+	DeviceID protocol.DeviceID `xml:"id,attr" json:"deviceID"`
 
 	Deprecated_Name      string   `xml:"name,attr,omitempty" json:"-"`
 	Deprecated_Addresses []string `xml:"address,omitempty" json:"-"`
 }
 
 type OptionsConfiguration struct {
-	ListenAddress           []string `xml:"listenAddress" default:"0.0.0.0:22000"`
-	GlobalAnnServers        []string `xml:"globalAnnounceServer" default:"udp4://announce.syncthing.net:22026, udp6://announce-v6.syncthing.net:22026"`
-	GlobalAnnEnabled        bool     `xml:"globalAnnounceEnabled" default:"true"`
-	LocalAnnEnabled         bool     `xml:"localAnnounceEnabled" default:"true"`
-	LocalAnnPort            int      `xml:"localAnnouncePort" default:"21025"`
-	LocalAnnMCAddr          string   `xml:"localAnnounceMCAddr" default:"[ff32::5222]:21026"`
-	MaxSendKbps             int      `xml:"maxSendKbps"`
-	MaxRecvKbps             int      `xml:"maxRecvKbps"`
-	ReconnectIntervalS      int      `xml:"reconnectionIntervalS" default:"60"`
-	StartBrowser            bool     `xml:"startBrowser" default:"true"`
-	UPnPEnabled             bool     `xml:"upnpEnabled" default:"true"`
-	UPnPLease               int      `xml:"upnpLeaseMinutes" default:"0"`
-	UPnPRenewal             int      `xml:"upnpRenewalMinutes" default:"30"`
-	URAccepted              int      `xml:"urAccepted"` // Accepted usage reporting version; 0 for off (undecided), -1 for off (permanently)
-	URUniqueID              string   `xml:"urUniqueID"` // Unique ID for reporting purposes, regenerated when UR is turned on.
-	RestartOnWakeup         bool     `xml:"restartOnWakeup" default:"true"`
-	AutoUpgradeIntervalH    int      `xml:"autoUpgradeIntervalH" default:"12"` // 0 for off
-	KeepTemporariesH        int      `xml:"keepTemporariesH" default:"24"`     // 0 for off
-	CacheIgnoredFiles       bool     `xml:"cacheIgnoredFiles" default:"true"`
-	ProgressUpdateIntervalS int      `xml:"progressUpdateIntervalS" default:"5"`
-	SymlinksEnabled         bool     `xml:"symlinksEnabled" default:"true"`
-	LimitBandwidthInLan     bool     `xml:"limitBandwidthInLan" default:"false"`
+	ListenAddress           []string `xml:"listenAddress" json:"listenAddress" default:"0.0.0.0:22000"`
+	GlobalAnnServers        []string `xml:"globalAnnounceServer" json:"globalAnnounceServers" json:"globalAnnounceServer" default:"udp4://announce.syncthing.net:22026, udp6://announce-v6.syncthing.net:22026"`
+	GlobalAnnEnabled        bool     `xml:"globalAnnounceEnabled" json:"globalAnnounceEnabled" default:"true"`
+	LocalAnnEnabled         bool     `xml:"localAnnounceEnabled" json:"localAnnounceEnabled" default:"true"`
+	LocalAnnPort            int      `xml:"localAnnouncePort" json:"localAnnouncePort" default:"21025"`
+	LocalAnnMCAddr          string   `xml:"localAnnounceMCAddr" json:"localAnnounceMCAddr" default:"[ff32::5222]:21026"`
+	MaxSendKbps             int      `xml:"maxSendKbps" json:"maxSendKbps"`
+	MaxRecvKbps             int      `xml:"maxRecvKbps" json:"maxRecvKbps"`
+	ReconnectIntervalS      int      `xml:"reconnectionIntervalS" json:"reconnectionIntervalS" default:"60"`
+	StartBrowser            bool     `xml:"startBrowser" json:"startBrowser" default:"true"`
+	UPnPEnabled             bool     `xml:"upnpEnabled" json:"upnpEnabled" default:"true"`
+	UPnPLease               int      `xml:"upnpLeaseMinutes" json:"upnpLeaseMinutes" default:"0"`
+	UPnPRenewal             int      `xml:"upnpRenewalMinutes" json:"upnpRenewalMinutes" default:"30"`
+	URAccepted              int      `xml:"urAccepted" json:"urAccepted"` // Accepted usage reporting version; 0 for off (undecided), -1 for off (permanently)
+	URUniqueID              string   `xml:"urUniqueID" json:"urUniqueId"` // Unique ID for reporting purposes, regenerated when UR is turned on.
+	RestartOnWakeup         bool     `xml:"restartOnWakeup" json:"restartOnWakeup" default:"true"`
+	AutoUpgradeIntervalH    int      `xml:"autoUpgradeIntervalH" json:"autoUpgradeIntervalH" default:"12"` // 0 for off
+	KeepTemporariesH        int      `xml:"keepTemporariesH" json:"keepTemporariesH" default:"24"`         // 0 for off
+	CacheIgnoredFiles       bool     `xml:"cacheIgnoredFiles" json:"cacheIgnoredFiles" default:"true"`
+	ProgressUpdateIntervalS int      `xml:"progressUpdateIntervalS" json:"progressUpdateIntervalS" default:"5"`
+	SymlinksEnabled         bool     `xml:"symlinksEnabled" json:"symlinksEnabled" default:"true"`
+	LimitBandwidthInLan     bool     `xml:"limitBandwidthInLan" json:"limitBandwidthInLan" default:"false"`
 
 	Deprecated_RescanIntervalS int    `xml:"rescanIntervalS,omitempty" json:"-"`
 	Deprecated_UREnabled       bool   `xml:"urEnabled,omitempty" json:"-"`
@@ -194,12 +194,12 @@ type OptionsConfiguration struct {
 }
 
 type GUIConfiguration struct {
-	Enabled  bool   `xml:"enabled,attr" default:"true"`
-	Address  string `xml:"address" default:"127.0.0.1:8080"`
-	User     string `xml:"user,omitempty"`
-	Password string `xml:"password,omitempty"`
-	UseTLS   bool   `xml:"tls,attr"`
-	APIKey   string `xml:"apikey,omitempty"`
+	Enabled  bool   `xml:"enabled,attr" json:"enabled" default:"true"`
+	Address  string `xml:"address" json:"address" default:"127.0.0.1:8080"`
+	User     string `xml:"user,omitempty" json:"user"`
+	Password string `xml:"password,omitempty" json:"password"`
+	UseTLS   bool   `xml:"tls,attr" json:"useTLS"`
+	APIKey   string `xml:"apikey,omitempty" json:"apiKey"`
 }
 
 func New(myID protocol.DeviceID) Configuration {

+ 11 - 0
internal/model/model.go

@@ -18,6 +18,7 @@ package model
 import (
 	"bufio"
 	"crypto/tls"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
@@ -241,6 +242,16 @@ type ConnectionInfo struct {
 	ClientVersion string
 }
 
+func (info ConnectionInfo) MarshalJSON() ([]byte, error) {
+	return json.Marshal(map[string]interface{}{
+		"at":            info.At,
+		"inBytesTotal":  info.InBytesTotal,
+		"outBytesTotal": info.OutBytesTotal,
+		"address":       info.Address,
+		"clientVersion": info.ClientVersion,
+	})
+}
+
 // ConnectionStats returns a map with connection statistics for each connected device.
 func (m *Model) ConnectionStats() map[string]ConnectionInfo {
 	type remoteAddrer interface {

+ 8 - 8
internal/model/sharedpullerstate.go

@@ -49,14 +49,14 @@ type sharedPullerState struct {
 
 // A momentary state representing the progress of the puller
 type pullerProgress struct {
-	Total               int
-	Reused              int
-	CopiedFromOrigin    int
-	CopiedFromElsewhere int
-	Pulled              int
-	Pulling             int
-	BytesDone           int64
-	BytesTotal          int64
+	Total               int   `json:"total"`
+	Reused              int   `json:"reused"`
+	CopiedFromOrigin    int   `json:"copiedFromOrigin"`
+	CopiedFromElsewhere int   `json:"copiedFromElsewhere"`
+	Pulled              int   `json:"pulled"`
+	Pulling             int   `json:"pulling"`
+	BytesDone           int64 `json:"bytesDone"`
+	BytesTotal          int64 `json:"bytesTotal"`
 }
 
 // A lockedWriterAt synchronizes WriteAt calls with an external mutex.

+ 1 - 1
internal/stats/device.go

@@ -24,7 +24,7 @@ import (
 )
 
 type DeviceStatistics struct {
-	LastSeen time.Time
+	LastSeen time.Time `json:"lastSeen"`
 }
 
 type DeviceStatisticsReference struct {

+ 3 - 3
internal/stats/folder.go

@@ -23,7 +23,7 @@ import (
 )
 
 type FolderStatistics struct {
-	LastFile LastFile
+	LastFile LastFile `json:"lastFile"`
 }
 
 type FolderStatisticsReference struct {
@@ -32,8 +32,8 @@ type FolderStatisticsReference struct {
 }
 
 type LastFile struct {
-	At       time.Time
-	Filename string
+	At       time.Time `json:"at"`
+	Filename string    `json:"filename"`
 }
 
 func NewFolderStatisticsReference(ldb *leveldb.DB, folder string) *FolderStatisticsReference {

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