mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 14:50:56 +00:00
Add folder label in addition to ID (fixes #966)
An auto generated ID is suggested on folder creation to reduce conflicts with folders created on other devices.
This commit is contained in:
parent
1875f7287e
commit
16c3d39fd2
@ -141,6 +141,10 @@ table.table-condensed td {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.table-condensed td.no-overflow-ellipse {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
.folder-advanced{
|
.folder-advanced{
|
||||||
background-color: hsla(0,0%,99%,1);
|
background-color: hsla(0,0%,99%,1);
|
||||||
border: 1px solid hsla(0, 0%, 95%, 1);
|
border: 1px solid hsla(0, 0%, 95%, 1);
|
||||||
|
@ -165,16 +165,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p>
|
<p>
|
||||||
<span translate translate-value-device="{{ deviceName(findDevice(event.data.device)) }}" translate-value-folder="{{ event.data.folder }}">
|
<span ng-if="event.data.folderLabel.length == 0" translate translate-value-device="{{ deviceName(findDevice(event.data.device)) }}" translate-value-folder="{{ event.data.folder }}">
|
||||||
{%device%} wants to share folder "{%folder%}".
|
{%device%} wants to share folder "{%folder%}".
|
||||||
</span>
|
</span>
|
||||||
|
<span ng-if="event.data.folderLabel.length != 0" translate translate-value-device="{{ deviceName(findDevice(event.data.device)) }}" translate-value-folder="{{ event.data.folder }}" translate-value-folderLabel="{{ event.data.folderLabel }}">
|
||||||
|
{%device%} wants to share folder "{%folderLabel%}" ({%folder%}).
|
||||||
|
</span>
|
||||||
<span translate ng-if="folders[event.data.folder]">Share this folder?</span>
|
<span translate ng-if="folders[event.data.folder]">Share this folder?</span>
|
||||||
<span translate ng-if="!folders[event.data.folder]">Add new folder?</span>
|
<span translate ng-if="!folders[event.data.folder]">Add new folder?</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-footer clearfix">
|
<div class="panel-footer clearfix">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<button type="button" class="btn btn-sm btn-success" ng-click="addFolderAndShare(event.data.folder, event.data.device)" ng-if="!folders[event.data.folder]">
|
<button type="button" class="btn btn-sm btn-success" ng-click="addFolderAndShare(event.data.folder, event.data.folderLabel, event.data.device)" ng-if="!folders[event.data.folder]">
|
||||||
<span class="fa fa-check"></span> <span translate>Add</span>
|
<span class="fa fa-check"></span> <span translate>Add</span>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-success" ng-click="shareFolderWithDevice(event.data.folder, event.data.device)" ng-if="folders[event.data.folder]">
|
<button type="button" class="btn btn-sm btn-success" ng-click="shareFolderWithDevice(event.data.folder, event.data.device)" ng-if="folders[event.data.folder]">
|
||||||
@ -222,7 +225,9 @@
|
|||||||
<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>
|
||||||
<div class="panel-progress" ng-show="folderStatus(folder) == 'scanning' && scanProgress[folder.id] != undefined" ng-attr-style="width: {{scanPercentage(folder.id)}}%"></div>
|
<div class="panel-progress" ng-show="folderStatus(folder) == 'scanning' && scanProgress[folder.id] != undefined" ng-attr-style="width: {{scanPercentage(folder.id)}}%"></div>
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
<span class="fa hidden-xs fa-fw" ng-class="[folder.readOnly ? 'fa-lock' : 'fa-folder']"></span>{{folder.id}}
|
<span class="fa hidden-xs fa-fw" ng-class="[folder.readOnly ? 'fa-lock' : 'fa-folder']"></span>
|
||||||
|
<span ng-show="folder.label.length == 0">{{folder.id}}</span>
|
||||||
|
<span title="{{folder.id}}" ng-show="folder.label.length != 0">{{folder.label}}</span>
|
||||||
<span class="pull-right text-{{folderClass(folder)}}" ng-switch="folderStatus(folder)">
|
<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">◼</span></span>
|
<span ng-switch-when="unknown"><span class="hidden-xs" translate>Unknown</span><span class="visible-xs">◼</span></span>
|
||||||
<span ng-switch-when="unshared"><span class="hidden-xs" translate>Unshared</span><span class="visible-xs">◼</span></span>
|
<span ng-switch-when="unshared"><span class="hidden-xs" translate>Unshared</span><span class="visible-xs">◼</span></span>
|
||||||
@ -247,6 +252,10 @@
|
|||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table table-condensed table-striped">
|
<table class="table table-condensed table-striped">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
<tr ng-show="folder.label != undefined && folder.label.length > 0">
|
||||||
|
<th><span class="fa fa-fw fa-folder-open"></span> <span translate>Folder ID</span></th>
|
||||||
|
<td class="text-right no-overflow-ellipse">{{folder.id}}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="fa fa-fw fa-folder-open"></span> <span translate>Folder Path</span></th>
|
<th><span class="fa fa-fw fa-folder-open"></span> <span translate>Folder Path</span></th>
|
||||||
<td class="text-right" title="{{folder.path}}">{{folder.path}}</td>
|
<td class="text-right" title="{{folder.path}}">{{folder.path}}</td>
|
||||||
@ -583,6 +592,7 @@
|
|||||||
<script src="vendor/jquery/jquery-2.0.3.min.js"></script>
|
<script src="vendor/jquery/jquery-2.0.3.min.js"></script>
|
||||||
<script src="vendor/angular/angular.min.js"></script>
|
<script src="vendor/angular/angular.min.js"></script>
|
||||||
<script src="vendor/angular/angular-translate.min.js"></script>
|
<script src="vendor/angular/angular-translate.min.js"></script>
|
||||||
|
<script src="vendor/angular/angular-translate-handler-log.min.js"></script>
|
||||||
<script src="vendor/angular/angular-translate-loader.min.js"></script>
|
<script src="vendor/angular/angular-translate-loader.min.js"></script>
|
||||||
<script src="vendor/angular/angular-dirPagination.js"></script>
|
<script src="vendor/angular/angular-dirPagination.js"></script>
|
||||||
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>
|
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||||
|
@ -29,8 +29,6 @@ syncthing.config(function ($httpProvider, $translateProvider, LocaleServiceProvi
|
|||||||
return {
|
return {
|
||||||
response: function onResponse(response) {
|
response: function onResponse(response) {
|
||||||
var headers = response.headers();
|
var headers = response.headers();
|
||||||
var responseVersion;
|
|
||||||
var deviceIdShort;
|
|
||||||
|
|
||||||
// angular template cache sends no headers
|
// angular template cache sends no headers
|
||||||
if(Object.keys(headers).length === 0) {
|
if(Object.keys(headers).length === 0) {
|
||||||
@ -40,7 +38,7 @@ syncthing.config(function ($httpProvider, $translateProvider, LocaleServiceProvi
|
|||||||
if (!deviceId) {
|
if (!deviceId) {
|
||||||
deviceId = headers['x-syncthing-id'];
|
deviceId = headers['x-syncthing-id'];
|
||||||
if (deviceId) {
|
if (deviceId) {
|
||||||
deviceIdShort = deviceId.substring(0, 5);
|
var deviceIdShort = deviceId.substring(0, 5);
|
||||||
$httpProvider.defaults.xsrfHeaderName = 'X-CSRF-Token-' + deviceIdShort;
|
$httpProvider.defaults.xsrfHeaderName = 'X-CSRF-Token-' + deviceIdShort;
|
||||||
$httpProvider.defaults.xsrfCookieName = 'CSRF-Token-' + deviceIdShort;
|
$httpProvider.defaults.xsrfCookieName = 'CSRF-Token-' + deviceIdShort;
|
||||||
}
|
}
|
||||||
@ -57,6 +55,7 @@ syncthing.config(function ($httpProvider, $translateProvider, LocaleServiceProvi
|
|||||||
prefix: 'assets/lang/lang-',
|
prefix: 'assets/lang/lang-',
|
||||||
suffix: '.json'
|
suffix: '.json'
|
||||||
});
|
});
|
||||||
|
$translateProvider.useMissingTranslationHandlerLog();
|
||||||
|
|
||||||
LocaleServiceProvider.setAvailableLocales(validLangs);
|
LocaleServiceProvider.setAvailableLocales(validLangs);
|
||||||
LocaleServiceProvider.setDefaultLocale('en');
|
LocaleServiceProvider.setDefaultLocale('en');
|
||||||
@ -114,9 +113,14 @@ function decimals(val, num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function randomString(len) {
|
function randomString(len) {
|
||||||
var i, result = '', chars = '01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-';
|
var chars = '01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-';
|
||||||
for (i = 0; i < len; i++) {
|
return randomStringFromCharset(len, chars);
|
||||||
result += chars[Math.round(Math.random() * (chars.length - 1))];
|
}
|
||||||
|
|
||||||
|
function randomStringFromCharset(len, charset) {
|
||||||
|
var result = '';
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
result += charset[Math.round(Math.random() * (charset.length - 1))];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -150,7 +154,6 @@ function debounce(func, wait) {
|
|||||||
context = this;
|
context = this;
|
||||||
args = arguments;
|
args = arguments;
|
||||||
timestamp = Date.now();
|
timestamp = Date.now();
|
||||||
var callNow = !timeout;
|
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
timeout = setTimeout(later, wait);
|
timeout = setTimeout(later, wait);
|
||||||
result = func.apply(context, args);
|
result = func.apply(context, args);
|
||||||
|
@ -90,7 +90,7 @@ angular.module('syncthing.core')
|
|||||||
refreshFolderStats();
|
refreshFolderStats();
|
||||||
|
|
||||||
$http.get(urlbase + '/system/version').success(function (data) {
|
$http.get(urlbase + '/system/version').success(function (data) {
|
||||||
if ($scope.version.version && $scope.version.version != data.version) {
|
if ($scope.version.version && $scope.version.version !== data.version) {
|
||||||
// We already have a version response, but it differs from
|
// We already have a version response, but it differs from
|
||||||
// the new one. Reload the full GUI in case it's changed.
|
// the new one. Reload the full GUI in case it's changed.
|
||||||
document.location.reload(true);
|
document.location.reload(true);
|
||||||
@ -271,10 +271,10 @@ angular.module('syncthing.core')
|
|||||||
}
|
}
|
||||||
for (var folder in $scope.progress) {
|
for (var folder in $scope.progress) {
|
||||||
if (!(folder in progress)) {
|
if (!(folder in progress)) {
|
||||||
if ($scope.neededFolder == folder) {
|
if ($scope.neededFolder === folder) {
|
||||||
refreshNeed(folder);
|
refreshNeed(folder);
|
||||||
}
|
}
|
||||||
} else if ($scope.neededFolder == folder) {
|
} else if ($scope.neededFolder === folder) {
|
||||||
for (file in $scope.progress[folder]) {
|
for (file in $scope.progress[folder]) {
|
||||||
if (!(file in progress[folder])) {
|
if (!(file in progress[folder])) {
|
||||||
refreshNeed(folder);
|
refreshNeed(folder);
|
||||||
@ -322,7 +322,7 @@ angular.module('syncthing.core')
|
|||||||
$scope.scanProgress[data.folder] = {
|
$scope.scanProgress[data.folder] = {
|
||||||
current: data.current,
|
current: data.current,
|
||||||
total: data.total,
|
total: data.total,
|
||||||
rate: data.rate,
|
rate: data.rate
|
||||||
};
|
};
|
||||||
console.log("FolderScanProgress", data);
|
console.log("FolderScanProgress", data);
|
||||||
});
|
});
|
||||||
@ -374,8 +374,8 @@ angular.module('syncthing.core')
|
|||||||
// authentication configured, and the magic setting to silence the
|
// authentication configured, and the magic setting to silence the
|
||||||
// warning isn't set, then yell at the user.
|
// warning isn't set, then yell at the user.
|
||||||
var guiCfg = $scope.config.gui;
|
var guiCfg = $scope.config.gui;
|
||||||
$scope.openNoAuth = guiCfg.address.substr(0, 4) != "127."
|
$scope.openNoAuth = guiCfg.address.substr(0, 4) !== "127."
|
||||||
&& guiCfg.address.substr(0, 6) != "[::1]:"
|
&& guiCfg.address.substr(0, 6) !== "[::1]:"
|
||||||
&& (!guiCfg.user || !guiCfg.password)
|
&& (!guiCfg.user || !guiCfg.password)
|
||||||
&& !guiCfg.insecureAdminAccess;
|
&& !guiCfg.insecureAdminAccess;
|
||||||
|
|
||||||
@ -509,7 +509,7 @@ angular.module('syncthing.core')
|
|||||||
url += "&page=" + $scope.neededCurrentPage;
|
url += "&page=" + $scope.neededCurrentPage;
|
||||||
url += "&perpage=" + $scope.neededPageSize;
|
url += "&perpage=" + $scope.neededPageSize;
|
||||||
$http.get(url).success(function (data) {
|
$http.get(url).success(function (data) {
|
||||||
if ($scope.neededFolder == folder) {
|
if ($scope.neededFolder === folder) {
|
||||||
console.log("refreshNeed", folder, data);
|
console.log("refreshNeed", folder, data);
|
||||||
parseNeeded(data);
|
parseNeeded(data);
|
||||||
}
|
}
|
||||||
@ -631,10 +631,10 @@ angular.module('syncthing.core')
|
|||||||
$scope.folderClass = function (folderCfg) {
|
$scope.folderClass = function (folderCfg) {
|
||||||
var status = $scope.folderStatus(folderCfg);
|
var status = $scope.folderStatus(folderCfg);
|
||||||
|
|
||||||
if (status == 'idle') {
|
if (status === 'idle') {
|
||||||
return 'success';
|
return 'success';
|
||||||
}
|
}
|
||||||
if (status == 'syncing' || status == 'scanning') {
|
if (status === 'syncing' || status === 'scanning') {
|
||||||
return 'primary';
|
return 'primary';
|
||||||
}
|
}
|
||||||
if (status === 'unknown') {
|
if (status === 'unknown') {
|
||||||
@ -668,14 +668,14 @@ angular.module('syncthing.core')
|
|||||||
}
|
}
|
||||||
var pct = 100 * $scope.scanProgress[folder].current / $scope.scanProgress[folder].total;
|
var pct = 100 * $scope.scanProgress[folder].current / $scope.scanProgress[folder].total;
|
||||||
return Math.floor(pct);
|
return Math.floor(pct);
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.scanRate = function (folder) {
|
$scope.scanRate = function (folder) {
|
||||||
if (!$scope.scanProgress[folder]) {
|
if (!$scope.scanProgress[folder]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return $scope.scanProgress[folder].rate;
|
return $scope.scanProgress[folder].rate;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.scanRemaining = function (folder) {
|
$scope.scanRemaining = function (folder) {
|
||||||
// Formats the remaining scan time as a string. Includes days and
|
// Formats the remaining scan time as a string. Includes days and
|
||||||
@ -685,23 +685,22 @@ angular.module('syncthing.core')
|
|||||||
// 2h 32m
|
// 2h 32m
|
||||||
// 4d 2h
|
// 4d 2h
|
||||||
|
|
||||||
var res = [];
|
|
||||||
|
|
||||||
if (!$scope.scanProgress[folder]) {
|
if (!$scope.scanProgress[folder]) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate remaining bytes and seconds based on our current
|
// Calculate remaining bytes and seconds based on our current
|
||||||
// rate.
|
// rate.
|
||||||
|
|
||||||
var remainingBytes = $scope.scanProgress[folder].total - $scope.scanProgress[folder].current;
|
var remainingBytes = $scope.scanProgress[folder].total - $scope.scanProgress[folder].current;
|
||||||
var seconds = remainingBytes / $scope.scanProgress[folder].rate;
|
var seconds = remainingBytes / $scope.scanProgress[folder].rate;
|
||||||
|
|
||||||
// Round up to closest ten seconds to avoid flapping too much to
|
// Round up to closest ten seconds to avoid flapping too much to
|
||||||
// and fro.
|
// and fro.
|
||||||
|
|
||||||
seconds = Math.ceil(seconds / 10) * 10;
|
seconds = Math.ceil(seconds / 10) * 10;
|
||||||
|
|
||||||
// Separate out the number of days.
|
// Separate out the number of days.
|
||||||
var days = 0;
|
var days = 0;
|
||||||
|
var res = [];
|
||||||
if (seconds >= 86400) {
|
if (seconds >= 86400) {
|
||||||
days = Math.floor(seconds / 86400);
|
days = Math.floor(seconds / 86400);
|
||||||
res.push('' + days + 'd')
|
res.push('' + days + 'd')
|
||||||
@ -718,20 +717,20 @@ angular.module('syncthing.core')
|
|||||||
|
|
||||||
var d = new Date(1970, 0, 1).setSeconds(seconds);
|
var d = new Date(1970, 0, 1).setSeconds(seconds);
|
||||||
|
|
||||||
if (days == 0) {
|
if (days === 0) {
|
||||||
// Format minutes only if we're within a day of completion.
|
// Format minutes only if we're within a day of completion.
|
||||||
var f = $filter('date')(d, "m'm'");
|
var f = $filter('date')(d, "m'm'");
|
||||||
res.push(f);
|
res.push(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (days == 0 && hours == 0) {
|
if (days === 0 && hours === 0) {
|
||||||
// Format seconds only when we're within an hour of completion.
|
// Format seconds only when we're within an hour of completion.
|
||||||
var f = $filter('date')(d, "ss's'");
|
var f = $filter('date')(d, "ss's'");
|
||||||
res.push(f);
|
res.push(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.join(' ');
|
return res.join(' ');
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.deviceStatus = function (deviceCfg) {
|
$scope.deviceStatus = function (deviceCfg) {
|
||||||
if ($scope.deviceFolders(deviceCfg).length === 0) {
|
if ($scope.deviceFolders(deviceCfg).length === 0) {
|
||||||
@ -802,9 +801,9 @@ angular.module('syncthing.core')
|
|||||||
|
|
||||||
$scope.findDevice = function (deviceID) {
|
$scope.findDevice = function (deviceID) {
|
||||||
var matches = $scope.devices.filter(function (n) {
|
var matches = $scope.devices.filter(function (n) {
|
||||||
return n.deviceID == deviceID;
|
return n.deviceID === deviceID;
|
||||||
});
|
});
|
||||||
if (matches.length != 1) {
|
if (matches.length !== 1) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return matches[0];
|
return matches[0];
|
||||||
@ -1029,17 +1028,15 @@ angular.module('syncthing.core')
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.saveDeviceConfig = function (deviceCfg) {
|
$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();
|
return x.trim();
|
||||||
});
|
});
|
||||||
|
|
||||||
done = false;
|
var done = false;
|
||||||
for (i = 0; i < $scope.devices.length; i++) {
|
for (var i = 0; i < $scope.devices.length && !done; i++) {
|
||||||
if ($scope.devices[i].deviceID === deviceCfg.deviceID) {
|
if ($scope.devices[i].deviceID === deviceCfg.deviceID) {
|
||||||
$scope.devices[i] = deviceCfg;
|
$scope.devices[i] = deviceCfg;
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1059,7 +1056,7 @@ angular.module('syncthing.core')
|
|||||||
if (deviceCfg.selectedFolders[id]) {
|
if (deviceCfg.selectedFolders[id]) {
|
||||||
var found = false;
|
var found = false;
|
||||||
for (i = 0; i < $scope.folders[id].devices.length; i++) {
|
for (i = 0; i < $scope.folders[id].devices.length; i++) {
|
||||||
if ($scope.folders[id].devices[i].deviceID == deviceCfg.deviceID) {
|
if ($scope.folders[id].devices[i].deviceID === deviceCfg.deviceID) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1072,7 +1069,7 @@ angular.module('syncthing.core')
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$scope.folders[id].devices = $scope.folders[id].devices.filter(function (n) {
|
$scope.folders[id].devices = $scope.folders[id].devices.filter(function (n) {
|
||||||
return n.deviceID != deviceCfg.deviceID;
|
return n.deviceID !== deviceCfg.deviceID;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1097,10 +1094,8 @@ angular.module('syncthing.core')
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.thisDevice = function () {
|
$scope.thisDevice = function () {
|
||||||
var i, n;
|
for (var i = 0; i < $scope.devices.length; i++) {
|
||||||
|
var n = $scope.devices[i];
|
||||||
for (i = 0; i < $scope.devices.length; i++) {
|
|
||||||
n = $scope.devices[i];
|
|
||||||
if (n.deviceID === $scope.myID) {
|
if (n.deviceID === $scope.myID) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@ -1142,7 +1137,7 @@ angular.module('syncthing.core')
|
|||||||
$scope.directoryList = [];
|
$scope.directoryList = [];
|
||||||
|
|
||||||
$scope.$watch('currentFolder.path', function (newvalue) {
|
$scope.$watch('currentFolder.path', function (newvalue) {
|
||||||
if (newvalue && newvalue.trim().charAt(0) == '~') {
|
if (newvalue && newvalue.trim().charAt(0) === '~') {
|
||||||
$scope.currentFolder.path = $scope.system.tilde + newvalue.trim().substring(1);
|
$scope.currentFolder.path = $scope.system.tilde + newvalue.trim().substring(1);
|
||||||
}
|
}
|
||||||
$http.get(urlbase + '/system/browse', {
|
$http.get(urlbase + '/system/browse', {
|
||||||
@ -1154,7 +1149,7 @@ angular.module('syncthing.core')
|
|||||||
|
|
||||||
$scope.editFolder = function (folderCfg) {
|
$scope.editFolder = function (folderCfg) {
|
||||||
$scope.currentFolder = angular.copy(folderCfg);
|
$scope.currentFolder = angular.copy(folderCfg);
|
||||||
if ($scope.currentFolder.path.slice(-1) == $scope.system.pathSeparator) {
|
if ($scope.currentFolder.path.slice(-1) === $scope.system.pathSeparator) {
|
||||||
$scope.currentFolder.path = $scope.currentFolder.path.slice(0, -1);
|
$scope.currentFolder.path = $scope.currentFolder.path.slice(0, -1);
|
||||||
}
|
}
|
||||||
$scope.currentFolder.selectedDevices = {};
|
$scope.currentFolder.selectedDevices = {};
|
||||||
@ -1202,30 +1197,8 @@ angular.module('syncthing.core')
|
|||||||
|
|
||||||
$scope.addFolder = function () {
|
$scope.addFolder = function () {
|
||||||
$scope.currentFolder = {
|
$scope.currentFolder = {
|
||||||
selectedDevices: {}
|
|
||||||
};
|
|
||||||
$scope.currentFolder.rescanIntervalS = 60;
|
|
||||||
$scope.currentFolder.minDiskFreePct = 1;
|
|
||||||
$scope.currentFolder.maxConflicts = 10;
|
|
||||||
$scope.currentFolder.order = "random";
|
|
||||||
$scope.currentFolder.fileVersioningSelector = "none";
|
|
||||||
$scope.currentFolder.trashcanClean = 0;
|
|
||||||
$scope.currentFolder.simpleKeep = 5;
|
|
||||||
$scope.currentFolder.staggeredMaxAge = 365;
|
|
||||||
$scope.currentFolder.staggeredCleanInterval = 3600;
|
|
||||||
$scope.currentFolder.staggeredVersionsPath = "";
|
|
||||||
$scope.currentFolder.externalCommand = "";
|
|
||||||
$scope.currentFolder.autoNormalize = true;
|
|
||||||
$scope.editingExisting = false;
|
|
||||||
$scope.folderEditor.$setPristine();
|
|
||||||
$('#editFolder').modal();
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.addFolderAndShare = function (folder, device) {
|
|
||||||
$scope.dismissFolderRejection(folder, device);
|
|
||||||
$scope.currentFolder = {
|
|
||||||
id: folder,
|
|
||||||
selectedDevices: {},
|
selectedDevices: {},
|
||||||
|
id: $scope.createRandomFolderId(),
|
||||||
rescanIntervalS: 60,
|
rescanIntervalS: 60,
|
||||||
minDiskFreePct: 1,
|
minDiskFreePct: 1,
|
||||||
maxConflicts: 10,
|
maxConflicts: 10,
|
||||||
@ -1239,6 +1212,33 @@ angular.module('syncthing.core')
|
|||||||
externalCommand: "",
|
externalCommand: "",
|
||||||
autoNormalize: true
|
autoNormalize: true
|
||||||
};
|
};
|
||||||
|
$scope.editingExisting = false;
|
||||||
|
$scope.folderEditor.$setPristine();
|
||||||
|
$('#editFolder').modal();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addFolderAndShare = function (folder, folderLabel, device) {
|
||||||
|
$scope.dismissFolderRejection(folder, device);
|
||||||
|
$scope.currentFolder = {
|
||||||
|
id: folder,
|
||||||
|
label: folderLabel,
|
||||||
|
selectedDevices: {},
|
||||||
|
rescanIntervalS: 60,
|
||||||
|
minDiskFreePct: 1,
|
||||||
|
maxConflicts: 10,
|
||||||
|
order: "random",
|
||||||
|
fileVersioningSelector: "none",
|
||||||
|
trashcanClean: 0,
|
||||||
|
simpleKeep: 5,
|
||||||
|
staggeredMaxAge: 365,
|
||||||
|
staggeredCleanInterval: 3600,
|
||||||
|
staggeredVersionsPath: "",
|
||||||
|
externalCommand: "",
|
||||||
|
autoNormalize: true,
|
||||||
|
viewFlags: {
|
||||||
|
importFromOtherDevice: true
|
||||||
|
}
|
||||||
|
};
|
||||||
$scope.currentFolder.selectedDevices[device] = true;
|
$scope.currentFolder.selectedDevices[device] = true;
|
||||||
|
|
||||||
$scope.editingExisting = false;
|
$scope.editingExisting = false;
|
||||||
@ -1256,10 +1256,8 @@ angular.module('syncthing.core')
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.saveFolder = function () {
|
$scope.saveFolder = function () {
|
||||||
var folderCfg, done, i;
|
|
||||||
|
|
||||||
$('#editFolder').modal('hide');
|
$('#editFolder').modal('hide');
|
||||||
folderCfg = $scope.currentFolder;
|
var folderCfg = $scope.currentFolder;
|
||||||
folderCfg.devices = [];
|
folderCfg.devices = [];
|
||||||
folderCfg.selectedDevices[$scope.myID] = true;
|
folderCfg.selectedDevices[$scope.myID] = true;
|
||||||
for (var deviceID in folderCfg.selectedDevices) {
|
for (var deviceID in folderCfg.selectedDevices) {
|
||||||
@ -1329,7 +1327,7 @@ angular.module('syncthing.core')
|
|||||||
$scope.sharesFolder = function (folderCfg) {
|
$scope.sharesFolder = function (folderCfg) {
|
||||||
var names = [];
|
var names = [];
|
||||||
folderCfg.devices.forEach(function (device) {
|
folderCfg.devices.forEach(function (device) {
|
||||||
if (device.deviceID != $scope.myID) {
|
if (device.deviceID !== $scope.myID) {
|
||||||
names.push($scope.deviceName($scope.findDevice(device.deviceID)));
|
names.push($scope.deviceName($scope.findDevice(device.deviceID)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1342,8 +1340,9 @@ angular.module('syncthing.core')
|
|||||||
for (var folderID in $scope.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++) {
|
for (var i = 0; i < devices.length; i++) {
|
||||||
if (devices[i].deviceID == deviceCfg.deviceID) {
|
if (devices[i].deviceID === deviceCfg.deviceID) {
|
||||||
folders.push(folderID);
|
var label = $scope.folders[folderID].label;
|
||||||
|
folders.push(label.length > 0 ? label : folderID);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1445,7 +1444,7 @@ angular.module('syncthing.core')
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.showFailed = function (folder) {
|
$scope.showFailed = function (folder) {
|
||||||
$scope.failedCurrent = $scope.failed[folder]
|
$scope.failedCurrent = $scope.failed[folder];
|
||||||
$('#failed').modal().on('hidden.bs.modal', function () {
|
$('#failed').modal().on('hidden.bs.modal', function () {
|
||||||
$scope.failedCurrent = undefined;
|
$scope.failedCurrent = undefined;
|
||||||
});
|
});
|
||||||
@ -1455,10 +1454,10 @@ angular.module('syncthing.core')
|
|||||||
if (!$scope.failed[folder]) {
|
if (!$scope.failed[folder]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ($scope.failed[folder].length == 0) {
|
if ($scope.failed[folder].length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.override = function (folder) {
|
$scope.override = function (folder) {
|
||||||
@ -1492,7 +1491,7 @@ angular.module('syncthing.core')
|
|||||||
url += "&page=" + $scope.neededCurrentPage;
|
url += "&page=" + $scope.neededCurrentPage;
|
||||||
url += "&perpage=" + $scope.neededPageSize;
|
url += "&perpage=" + $scope.neededPageSize;
|
||||||
$http.post(url).success(function (data) {
|
$http.post(url).success(function (data) {
|
||||||
if ($scope.neededFolder == folder) {
|
if ($scope.neededFolder === folder) {
|
||||||
console.log("bumpFile", folder, data);
|
console.log("bumpFile", folder, data);
|
||||||
parseNeeded(data);
|
parseNeeded(data);
|
||||||
}
|
}
|
||||||
@ -1512,7 +1511,7 @@ angular.module('syncthing.core')
|
|||||||
'netbsd': 'NetBSD',
|
'netbsd': 'NetBSD',
|
||||||
'linux': 'Linux',
|
'linux': 'Linux',
|
||||||
'windows': 'Windows',
|
'windows': 'Windows',
|
||||||
'solaris': 'Solaris',
|
'solaris': 'Solaris'
|
||||||
}[$scope.version.os] || $scope.version.os;
|
}[$scope.version.os] || $scope.version.os;
|
||||||
|
|
||||||
var arch ={
|
var arch ={
|
||||||
@ -1521,7 +1520,7 @@ angular.module('syncthing.core')
|
|||||||
'arm': 'ARM',
|
'arm': 'ARM',
|
||||||
'arm64': 'AArch64',
|
'arm64': 'AArch64',
|
||||||
'ppc64': 'PowerPC',
|
'ppc64': 'PowerPC',
|
||||||
'ppc64le': 'PowerPC (LE)',
|
'ppc64le': 'PowerPC (LE)'
|
||||||
}[$scope.version.arch] || $scope.version.arch;
|
}[$scope.version.arch] || $scope.version.arch;
|
||||||
|
|
||||||
return $scope.version.version + ', ' + os + ' (' + arch + ')';
|
return $scope.version.version + ', ' + os + ' (' + arch + ')';
|
||||||
@ -1546,6 +1545,11 @@ angular.module('syncthing.core')
|
|||||||
return 'text';
|
return 'text';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.createRandomFolderId = function(){
|
||||||
|
var charset = '2345679abcdefghijkmnopqrstuvwxyzACDEFGHJKLMNPQRSTUVWXYZ';
|
||||||
|
return randomStringFromCharset(5, charset) + "-" + randomStringFromCharset(5, charset);
|
||||||
|
};
|
||||||
|
|
||||||
// pseudo main. called on all definitions assigned
|
// pseudo main. called on all definitions assigned
|
||||||
initController();
|
initController();
|
||||||
});
|
});
|
||||||
|
@ -60,8 +60,11 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4" ng-repeat="folder in folderList()">
|
<div class="col-md-4" ng-repeat="folder in folderList()">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label ng-if="folder.label.length == 0">
|
||||||
<input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]"> {{folder.id}}
|
<input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]"> {{folder.id}}
|
||||||
|
</label>
|
||||||
|
<label ng-if="folder.label.length != 0">
|
||||||
|
<input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]"> <span title="{{folder.id}}">{{folder.label}}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,11 +11,18 @@
|
|||||||
<form role="form" name="folderEditor">
|
<form role="form" name="folderEditor">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
<div class="form-group" ng-class="{'has-error': folderEditor.folderLabel.$invalid && folderEditor.folderLabel.$dirty}">
|
||||||
|
<label for="folderLabel"><span translate>Folder Label</span></label>
|
||||||
|
<input name="folderLabel" id="folderLabel" class="form-control" type="text" ng-model="currentFolder.label" value="{{currentFolder.label}}"/>
|
||||||
|
<p class="help-block">
|
||||||
|
<span translate ng-if="folderEditor.folderLabel.$valid || folderEditor.folderLabel.$pristine">Optional descriptive label for the folder. Can be different on each device.</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<div class="form-group" ng-class="{'has-error': folderEditor.folderID.$invalid && folderEditor.folderID.$dirty}">
|
<div class="form-group" ng-class="{'has-error': folderEditor.folderID.$invalid && folderEditor.folderID.$dirty}">
|
||||||
<label for="folderID"><span translate>Folder ID</span></label>
|
<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>
|
<input name="folderID" ng-readonly="editingExisting || (!editingExisting && currentFolder.viewFlags.importFromOtherDevice)" id="folderID" class="form-control" type="text" ng-model="currentFolder.id" required unique-folder value="{{currentFolder.id}}"/>
|
||||||
<p class="help-block">
|
<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.$valid || folderEditor.folderID.$pristine">Required 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>
|
<span translate ng-if="folderEditor.folderID.$error.uniqueFolder">The folder ID must be unique.</span>
|
||||||
<span translate ng-if="folderEditor.folderID.$error.required && folderEditor.folderID.$dirty">The folder ID cannot be blank.</span>
|
<span translate ng-if="folderEditor.folderID.$error.required && folderEditor.folderID.$dirty">The folder ID cannot be blank.</span>
|
||||||
</p>
|
</p>
|
||||||
|
@ -51,8 +51,11 @@
|
|||||||
|
|
||||||
<div class="panel panel-default" ng-repeat="folder in advancedConfig.folders">
|
<div class="panel panel-default" ng-repeat="folder in advancedConfig.folders">
|
||||||
<div class="panel-heading" role="tab" id="folder{{$index}}Heading" data-toggle="collapse" data-parent="#advancedAccordion" href="#folder{{$index}}Config" aria-expanded="true" aria-controls="folder{{$index}}Config" style="cursor: pointer">
|
<div class="panel-heading" role="tab" id="folder{{$index}}Heading" data-toggle="collapse" data-parent="#advancedAccordion" href="#folder{{$index}}Config" aria-expanded="true" aria-controls="folder{{$index}}Config" style="cursor: pointer">
|
||||||
<h4 class="panel-title">
|
<h4 ng-if="folder.label.length == 0" class="panel-title">
|
||||||
<span translate>Folder</span> "{{folder.id}}"
|
<span translate>Folder</span> "{{folder.id}}"
|
||||||
|
</h4>
|
||||||
|
<h4 ng-if="folder.label.length != 0" class="panel-title">
|
||||||
|
<span translate>Folder</span> "{{folder.label}}" ({{folder.id}})
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div id="folder{{$index}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="folder{{$index}}Heading">
|
<div id="folder{{$index}}Config" class="panel-collapse collapse" role="tabpanel" aria-labelledby="folder{{$index}}Heading">
|
||||||
|
6
gui/default/vendor/angular/angular-translate-handler-log.min.js
vendored
Normal file
6
gui/default/vendor/angular/angular-translate-handler-log.min.js
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* angular-translate - v2.10.0 - 2016-02-28
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 The angular-translate team, Pascal Precht; Licensed MIT
|
||||||
|
*/
|
||||||
|
!function(a,b){"function"==typeof define&&define.amd?define([],function(){return b()}):"object"==typeof exports?module.exports=b():b()}(this,function(){function a(a){"use strict";return function(b){a.warn("Translation for "+b+" doesn't exist")}}return angular.module("pascalprecht.translate").factory("$translateMissingTranslationHandlerLog",a),a.$inject=["$log"],a.displayName="$translateMissingTranslationHandlerLog","pascalprecht.translate"});
|
File diff suppressed because one or more lines are too long
@ -18,6 +18,7 @@ import (
|
|||||||
|
|
||||||
type FolderConfiguration struct {
|
type FolderConfiguration struct {
|
||||||
ID string `xml:"id,attr" json:"id"`
|
ID string `xml:"id,attr" json:"id"`
|
||||||
|
Label string `xml:"label,attr" json:"label"`
|
||||||
RawPath string `xml:"path,attr" json:"path"`
|
RawPath string `xml:"path,attr" json:"path"`
|
||||||
Devices []FolderDeviceConfiguration `xml:"device" json:"devices"`
|
Devices []FolderDeviceConfiguration `xml:"device" json:"devices"`
|
||||||
ReadOnly bool `xml:"ro,attr" json:"readOnly"`
|
ReadOnly bool `xml:"ro,attr" json:"readOnly"`
|
||||||
|
@ -650,8 +650,9 @@ nextFolder:
|
|||||||
|
|
||||||
if !m.folderSharedWithUnlocked(folder.ID, deviceID) {
|
if !m.folderSharedWithUnlocked(folder.ID, deviceID) {
|
||||||
events.Default.Log(events.FolderRejected, map[string]string{
|
events.Default.Log(events.FolderRejected, map[string]string{
|
||||||
"folder": folder.ID,
|
"folder": folder.ID,
|
||||||
"device": deviceID.String(),
|
"folderLabel": folder.Label,
|
||||||
|
"device": deviceID.String(),
|
||||||
})
|
})
|
||||||
l.Infof("Unexpected folder ID %q sent from device %q; ensure that the folder exists and that this device is selected under \"Share With\" in the folder configuration.", folder.ID, deviceID)
|
l.Infof("Unexpected folder ID %q sent from device %q; ensure that the folder exists and that this device is selected under \"Share With\" in the folder configuration.", folder.ID, deviceID)
|
||||||
continue
|
continue
|
||||||
@ -1530,7 +1531,7 @@ func (m *Model) numHashers(folder string) int {
|
|||||||
// generateClusterConfig returns a ClusterConfigMessage that is correct for
|
// generateClusterConfig returns a ClusterConfigMessage that is correct for
|
||||||
// the given peer device
|
// the given peer device
|
||||||
func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.ClusterConfigMessage {
|
func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.ClusterConfigMessage {
|
||||||
cm := protocol.ClusterConfigMessage{
|
message := protocol.ClusterConfigMessage{
|
||||||
DeviceName: m.deviceName,
|
DeviceName: m.deviceName,
|
||||||
ClientName: m.clientName,
|
ClientName: m.clientName,
|
||||||
ClientVersion: m.clientVersion,
|
ClientVersion: m.clientVersion,
|
||||||
@ -1539,8 +1540,9 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
|
|||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
for _, folder := range m.deviceFolders[device] {
|
for _, folder := range m.deviceFolders[device] {
|
||||||
folderCfg := m.cfg.Folders()[folder]
|
folderCfg := m.cfg.Folders()[folder]
|
||||||
cr := protocol.Folder{
|
protocolFolder := protocol.Folder{
|
||||||
ID: folder,
|
ID: folder,
|
||||||
|
Label: folderCfg.Label,
|
||||||
}
|
}
|
||||||
var flags uint32
|
var flags uint32
|
||||||
if folderCfg.ReadOnly {
|
if folderCfg.ReadOnly {
|
||||||
@ -1552,7 +1554,7 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
|
|||||||
if folderCfg.IgnoreDelete {
|
if folderCfg.IgnoreDelete {
|
||||||
flags |= protocol.FlagFolderIgnoreDelete
|
flags |= protocol.FlagFolderIgnoreDelete
|
||||||
}
|
}
|
||||||
cr.Flags = flags
|
protocolFolder.Flags = flags
|
||||||
for _, device := range m.folderDevices[folder] {
|
for _, device := range m.folderDevices[folder] {
|
||||||
// DeviceID is a value type, but with an underlying array. Copy it
|
// DeviceID is a value type, but with an underlying array. Copy it
|
||||||
// so we don't grab aliases to the same array later on in device[:]
|
// so we don't grab aliases to the same array later on in device[:]
|
||||||
@ -1560,7 +1562,7 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
|
|||||||
// TODO: Set read only bit when relevant, and when we have per device
|
// TODO: Set read only bit when relevant, and when we have per device
|
||||||
// access controls.
|
// access controls.
|
||||||
deviceCfg := m.cfg.Devices()[device]
|
deviceCfg := m.cfg.Devices()[device]
|
||||||
cn := protocol.Device{
|
protocolDevice := protocol.Device{
|
||||||
ID: device[:],
|
ID: device[:],
|
||||||
Name: deviceCfg.Name,
|
Name: deviceCfg.Name,
|
||||||
Addresses: deviceCfg.Addresses,
|
Addresses: deviceCfg.Addresses,
|
||||||
@ -1570,15 +1572,15 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
|
|||||||
}
|
}
|
||||||
|
|
||||||
if deviceCfg.Introducer {
|
if deviceCfg.Introducer {
|
||||||
cn.Flags |= protocol.FlagIntroducer
|
protocolDevice.Flags |= protocol.FlagIntroducer
|
||||||
}
|
}
|
||||||
cr.Devices = append(cr.Devices, cn)
|
protocolFolder.Devices = append(protocolFolder.Devices, protocolDevice)
|
||||||
}
|
}
|
||||||
cm.Folders = append(cm.Folders, cr)
|
message.Folders = append(message.Folders, protocolFolder)
|
||||||
}
|
}
|
||||||
m.fmut.RUnlock()
|
m.fmut.RUnlock()
|
||||||
|
|
||||||
return cm
|
return message
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) State(folder string) (string, time.Time, error) {
|
func (m *Model) State(folder string) (string, time.Time, error) {
|
||||||
|
@ -143,6 +143,7 @@ func (o *ClusterConfigMessage) GetOption(key string) string {
|
|||||||
|
|
||||||
type Folder struct {
|
type Folder struct {
|
||||||
ID string // max:256
|
ID string // max:256
|
||||||
|
Label string // max:256
|
||||||
Devices []Device // max:1000000
|
Devices []Device // max:1000000
|
||||||
Flags uint32
|
Flags uint32
|
||||||
Options []Option // max:64
|
Options []Option // max:64
|
||||||
|
@ -656,6 +656,10 @@ Folder Structure:
|
|||||||
\ ID (length + padded data) \
|
\ ID (length + padded data) \
|
||||||
/ /
|
/ /
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
/ /
|
||||||
|
\ Label (length + padded data) \
|
||||||
|
/ /
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Number of Devices |
|
| Number of Devices |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
/ /
|
/ /
|
||||||
@ -674,6 +678,7 @@ Folder Structure:
|
|||||||
|
|
||||||
struct Folder {
|
struct Folder {
|
||||||
string ID<256>;
|
string ID<256>;
|
||||||
|
string Label<256>;
|
||||||
Device Devices<1000000>;
|
Device Devices<1000000>;
|
||||||
unsigned int Flags;
|
unsigned int Flags;
|
||||||
Option Options<64>;
|
Option Options<64>;
|
||||||
@ -683,6 +688,7 @@ struct Folder {
|
|||||||
|
|
||||||
func (o Folder) XDRSize() int {
|
func (o Folder) XDRSize() int {
|
||||||
return 4 + len(o.ID) + xdr.Padding(len(o.ID)) +
|
return 4 + len(o.ID) + xdr.Padding(len(o.ID)) +
|
||||||
|
4 + len(o.Label) + xdr.Padding(len(o.Label)) +
|
||||||
4 + xdr.SizeOfSlice(o.Devices) + 4 +
|
4 + xdr.SizeOfSlice(o.Devices) + 4 +
|
||||||
4 + xdr.SizeOfSlice(o.Options)
|
4 + xdr.SizeOfSlice(o.Options)
|
||||||
}
|
}
|
||||||
@ -706,6 +712,10 @@ func (o Folder) MarshalXDRInto(m *xdr.Marshaller) error {
|
|||||||
return xdr.ElementSizeExceeded("ID", l, 256)
|
return xdr.ElementSizeExceeded("ID", l, 256)
|
||||||
}
|
}
|
||||||
m.MarshalString(o.ID)
|
m.MarshalString(o.ID)
|
||||||
|
if l := len(o.Label); l > 256 {
|
||||||
|
return xdr.ElementSizeExceeded("Label", l, 256)
|
||||||
|
}
|
||||||
|
m.MarshalString(o.Label)
|
||||||
if l := len(o.Devices); l > 1000000 {
|
if l := len(o.Devices); l > 1000000 {
|
||||||
return xdr.ElementSizeExceeded("Devices", l, 1000000)
|
return xdr.ElementSizeExceeded("Devices", l, 1000000)
|
||||||
}
|
}
|
||||||
@ -734,6 +744,7 @@ func (o *Folder) UnmarshalXDR(bs []byte) error {
|
|||||||
}
|
}
|
||||||
func (o *Folder) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
func (o *Folder) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
|
||||||
o.ID = u.UnmarshalStringMax(256)
|
o.ID = u.UnmarshalStringMax(256)
|
||||||
|
o.Label = u.UnmarshalStringMax(256)
|
||||||
_DevicesSize := int(u.UnmarshalUint32())
|
_DevicesSize := int(u.UnmarshalUint32())
|
||||||
if _DevicesSize < 0 {
|
if _DevicesSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Devices", _DevicesSize, 1000000)
|
return xdr.ElementSizeExceeded("Devices", _DevicesSize, 1000000)
|
||||||
|
Loading…
Reference in New Issue
Block a user