754 lines
25 KiB
JavaScript
754 lines
25 KiB
JavaScript
backupApp.service('AppUtils', function($rootScope, $timeout, $cookies, DialogService, gettextCatalog) {
|
|
|
|
var apputils = this;
|
|
|
|
this.exampleOptionString = '--dblock-size=100MB';
|
|
|
|
function setMomentLocale() {
|
|
try {
|
|
var browser_lang = navigator.languages ?
|
|
navigator.languages[0] :
|
|
(navigator.language || navigator.userLanguage);
|
|
moment.locale($cookies.get('ui-locale') ? $cookies.get('ui-locale') : browser_lang);
|
|
} catch (e) {
|
|
}
|
|
}
|
|
setMomentLocale();
|
|
$rootScope.$on('ui_language_changed', setMomentLocale);
|
|
|
|
this.formatSizeString = function(val) {
|
|
var formatSizes = ['TB', 'GB', 'MB', 'KB'];
|
|
val = parseInt(val || 0);
|
|
var max = formatSizes.length;
|
|
for(var i = 0; i < formatSizes.length; i++) {
|
|
var m = Math.pow(1024, max - i);
|
|
if (val > m) {
|
|
return (val / m).toFixed(2) + ' ' + formatSizes[i];
|
|
}
|
|
}
|
|
|
|
return val + ' bytes';
|
|
};
|
|
|
|
this.watch = function(scope, m) {
|
|
scope.$on('apputillookupschanged', function() {
|
|
if (m) m();
|
|
|
|
$timeout(function() {
|
|
scope.$digest();
|
|
});
|
|
});
|
|
|
|
if (m) $timeout(m);
|
|
};
|
|
|
|
this.getEntryTypeFromIconCls = function(cls)
|
|
{
|
|
// Entry type is used in as the ALT entry,
|
|
// to guide screen reading software for visually
|
|
// impaired users
|
|
|
|
var res = gettextCatalog.getString('Folder');
|
|
|
|
if (cls == 'x-tree-icon-mydocuments')
|
|
res = gettextCatalog.getString('My Documents');
|
|
else if (cls == 'x-tree-icon-mymusic')
|
|
res = gettextCatalog.getString('My Music');
|
|
else if (cls == 'x-tree-icon-mypictures')
|
|
res = gettextCatalog.getString('My Pictures');
|
|
else if (cls == 'x-tree-icon-desktop')
|
|
res = gettextCatalog.getString('Desktop');
|
|
else if (cls == 'x-tree-icon-home')
|
|
res = gettextCatalog.getString('Home');
|
|
else if (cls == 'x-tree-icon-hypervmachine')
|
|
res = gettextCatalog.getString('Hyper-V Machine');
|
|
else if (cls == 'x-tree-icon-hyperv')
|
|
res = gettextCatalog.getString('Hyper-V Machines');
|
|
else if (cls == 'x-tree-icon-broken')
|
|
res = gettextCatalog.getString('Broken access');
|
|
else if (cls == 'x-tree-icon-locked')
|
|
res = gettextCatalog.getString('Access denied');
|
|
else if (cls == 'x-tree-icon-symlink')
|
|
res = gettextCatalog.getString('Symbolic link');
|
|
else if (cls == 'x-tree-icon-leaf')
|
|
res = gettextCatalog.getString('File');
|
|
|
|
return res;
|
|
};
|
|
|
|
function reloadTexts() {
|
|
apputils.fileSizeMultipliers = [
|
|
{name: gettextCatalog.getString('byte'), value: 'b'},
|
|
{name: gettextCatalog.getString('KByte'), value: 'KB'},
|
|
{name: gettextCatalog.getString('MByte'), value: 'MB'},
|
|
{name: gettextCatalog.getString('GByte'), value: 'GB'},
|
|
{name: gettextCatalog.getString('TByte'), value: 'TB'}
|
|
];
|
|
|
|
apputils.timerangeMultipliers = [
|
|
{name: gettextCatalog.getString('Minutes'), value: 'm'},
|
|
{name: gettextCatalog.getString('Hours'), value: 'h'},
|
|
{name: gettextCatalog.getString('Days'), value: 'D'},
|
|
{name: gettextCatalog.getString('Weeks'), value: 'W'},
|
|
{name: gettextCatalog.getString('Months'), value: 'M'},
|
|
{name: gettextCatalog.getString('Years'), value: 'Y'}
|
|
];
|
|
|
|
apputils.shorttimerangeMultipliers = [
|
|
{name: gettextCatalog.getString('Seconds'), value: 's'},
|
|
{name: gettextCatalog.getString('Minutes'), value: 'm'},
|
|
{name: gettextCatalog.getString('Hours'), value: 'h'}
|
|
];
|
|
|
|
apputils.daysOfWeek = [
|
|
{name: gettextCatalog.getString('Mon'), value: 'mon'},
|
|
{name: gettextCatalog.getString('Tue'), value: 'tue'},
|
|
{name: gettextCatalog.getString('Wed'), value: 'wed'},
|
|
{name: gettextCatalog.getString('Thu'), value: 'thu'},
|
|
{name: gettextCatalog.getString('Fri'), value: 'fri'},
|
|
{name: gettextCatalog.getString('Sat'), value: 'sat'},
|
|
{name: gettextCatalog.getString('Sun'), value: 'sun'}
|
|
];
|
|
|
|
apputils.speedMultipliers = [
|
|
{name: gettextCatalog.getString('byte/s'), value: 'b'},
|
|
{name: gettextCatalog.getString('KByte/s'), value: 'KB'},
|
|
{name: gettextCatalog.getString('MByte/s'), value: 'MB'},
|
|
{name: gettextCatalog.getString('GByte/s'), value: 'GB'},
|
|
{name: gettextCatalog.getString('TByte/s'), value: 'TB'}
|
|
];
|
|
|
|
|
|
apputils.exampleOptionString = gettextCatalog.getString('Enter one option per line in command-line format, eg. {0}');
|
|
|
|
apputils.filterClasses = [{
|
|
name: gettextCatalog.getString('Exclude directories whose names contain'),
|
|
key: '-dir*',
|
|
prefix: '-*',
|
|
suffix: '*!',
|
|
rx: '\\-\\*([^\\!]+)\\*\\!'
|
|
}, {
|
|
name: gettextCatalog.getString('Exclude files whose names contain'),
|
|
key: '-file*',
|
|
prefix: '-[.*',
|
|
suffix: '[^\\!]*]', // Escape dirsep inside regexp. Required on Windows, no effect on other platforms.
|
|
rx: '\\-\\[\\.\\*[\\^\\!\\]\\*\\]'
|
|
}, {
|
|
name: gettextCatalog.getString('Exclude folder'),
|
|
key: '-folder',
|
|
prefix: '-',
|
|
suffix: '!',
|
|
stripSep: true,
|
|
rx: '\\-(.*)\\!'
|
|
}, {
|
|
name: gettextCatalog.getString('Exclude file'),
|
|
key: '-path',
|
|
prefix: '-',
|
|
stripSep: true,
|
|
exclude: ['*', '?', '{'],
|
|
rx: '\\-([^\\[\\{\\*\\?]+)'
|
|
}, {
|
|
name: gettextCatalog.getString('Exclude file extension'),
|
|
key: '-ext',
|
|
rx: '\\-\\*\.(.*)',
|
|
prefix: '-*.'
|
|
}, {
|
|
name: gettextCatalog.getString('Exclude regular expression'),
|
|
key: '-[]',
|
|
prefix: '-[',
|
|
suffix: ']'
|
|
}, {
|
|
name: gettextCatalog.getString('Include regular expression'),
|
|
key: '+[]',
|
|
prefix: '+[',
|
|
suffix: ']'
|
|
}, {
|
|
name: gettextCatalog.getString('Exclude filter group'),
|
|
key: '-{}',
|
|
prefix: '-{',
|
|
suffix: '}'
|
|
}, {
|
|
//// Since all the current filter groups are intended for exclusion, there isn't a reason to show the 'Include group' section in the UI yet.
|
|
// name: gettextCatalog.getString('Include filter group'),
|
|
// key: '+{}',
|
|
// prefix: '+{',
|
|
// suffix: '}'
|
|
//}, {
|
|
name: gettextCatalog.getString('Include expression'),
|
|
key: '+',
|
|
prefix: '+'
|
|
}, {
|
|
name: gettextCatalog.getString('Exclude expression'),
|
|
key: '-',
|
|
prefix: '-'
|
|
}];
|
|
|
|
apputils.filterGroups = [{
|
|
name: gettextCatalog.getString('Default excludes'),
|
|
value: 'DefaultExcludes'
|
|
}, {
|
|
//// As the DefaultIncludes are currently empty, we don't need to include them in the UI yet.
|
|
// name: gettextCatalog.getString('Default includes'),
|
|
// value: 'DefaultIncludes'
|
|
//}, {
|
|
name: gettextCatalog.getString('System Files'),
|
|
value: 'SystemFiles'
|
|
}, {
|
|
name: gettextCatalog.getString('Operating System'),
|
|
value: 'OperatingSystem'
|
|
}, {
|
|
name: gettextCatalog.getString('Cache Files'),
|
|
value: 'CacheFiles'
|
|
}, {
|
|
name: gettextCatalog.getString('Temporary Files'),
|
|
value: 'TemporaryFiles'
|
|
}, {
|
|
name: gettextCatalog.getString('Applications'),
|
|
value: 'Applications'
|
|
}];
|
|
|
|
apputils.filterTypeMap = {};
|
|
for (var i = apputils.filterClasses.length - 1; i >= 0; i--)
|
|
apputils.filterTypeMap[apputils.filterClasses[i].key] = apputils.filterClasses[i];
|
|
|
|
$rootScope.$broadcast('apputillookupschanged');
|
|
};
|
|
|
|
reloadTexts();
|
|
$rootScope.$on('gettextLanguageChanged', reloadTexts);
|
|
|
|
this.parseBoolString = function(txt, def) {
|
|
txt = (txt || '').toLowerCase();
|
|
if (txt == '0' || txt == 'false' || txt == 'off' || txt == 'no' || txt == 'f')
|
|
return false;
|
|
else if (txt == '1' || txt == 'true' || txt == 'on' || txt == 'yes' || txt == 't')
|
|
return true;
|
|
else
|
|
return def === undefined ? false : def;
|
|
};
|
|
|
|
|
|
this.splitSizeString = function(val) {
|
|
var m = (/(\d*)(\w*)/mg).exec(val);
|
|
var mul = null;
|
|
if (!m)
|
|
return [parseInt(val), null];
|
|
else
|
|
return [parseInt(m[1]), m[2]];
|
|
}
|
|
|
|
|
|
this.toDisplayDateAndTime = function(dt) {
|
|
return moment(dt).format('lll');
|
|
};
|
|
|
|
this.parseDate = function(dt) {
|
|
if (typeof(dt) == typeof('')) {
|
|
var msec = Date.parse(dt);
|
|
if (isNaN(msec)) {
|
|
if (dt.length == 16 && dt[8] == 'T' && dt[15] == 'Z') {
|
|
dt = dt.substr(0, 4) + '-' + dt.substr(4, 2) + '-' + dt.substr(6, 2) + 'T' +
|
|
dt.substr(9, 2) + ':' + dt.substr(11, 2) + ':' + dt.substr(13, 2) + 'Z';
|
|
}
|
|
return new Date(dt);
|
|
} else {
|
|
return new Date(msec);
|
|
}
|
|
}
|
|
else
|
|
return new Date(dt);
|
|
};
|
|
|
|
this.parseOptionStrings = function (val, dict, validateCallback) {
|
|
// Parse options and return a dict with dict['--key']=value options
|
|
// Include and exclude filters are returned as arrays in dict['include'], dict['exclude'] if present
|
|
dict = dict || {};
|
|
|
|
var lines = null;
|
|
|
|
if (val != null && Array.isArray(val))
|
|
lines = val;
|
|
else
|
|
lines = this.replace_all(val || '', '\r', '\n').split('\n');
|
|
|
|
for(var i in lines) {
|
|
var line = lines[i].trim();
|
|
if (line != '' && line[0] != '#') {
|
|
if (line.indexOf('--') == 0) {
|
|
line = line.substr(2);
|
|
}
|
|
|
|
var eqpos = line.indexOf('=');
|
|
var key = line;
|
|
var value = true;
|
|
if (eqpos > 0) {
|
|
key = line.substr(0, eqpos).trim();
|
|
value = line.substr(eqpos + 1).trim();
|
|
if (value == '')
|
|
value = true;
|
|
}
|
|
|
|
if (validateCallback)
|
|
if (!validateCallback(dict, key, value))
|
|
return null;
|
|
// Special handing for --include and --exclude, which are the only options that can appear multiple times (compare FilterCollector.DoExtractOptions)
|
|
// In all other cases, the last value overrides the earlier values
|
|
var lower = key.toLowerCase();
|
|
if (lower == 'include' || lower == 'exclude') {
|
|
if (!Array.isArray(dict[lower])) {
|
|
dict[lower] = [value];
|
|
} else {
|
|
dict[lower].push(value);
|
|
}
|
|
} else {
|
|
dict['--' + key] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return dict;
|
|
};
|
|
|
|
this.parse_extra_options = function(str, dict) {
|
|
return this.parseOptionStrings(str, dict, function(d, k, v) {
|
|
if (d['--' + k] !== undefined) {
|
|
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Duplicate option {{opt}}', { opt: k }));
|
|
return false;
|
|
} else if (k == 'include' || k == 'exclude') {
|
|
// Cannot specify filters in extra options
|
|
// Not sure that this is really called.
|
|
DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Cannot specify filter include or excludes in extra options'));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}) != null;
|
|
};
|
|
|
|
this.serializeAdvancedOptions = function(opts) {
|
|
return this.serializeAdvancedOptionsToArray(opts).join('\n');
|
|
};
|
|
|
|
this.serializeAdvancedOptionsToArray = function(opts) {
|
|
var res = [];
|
|
for(var n in opts)
|
|
if (n.indexOf('--') == 0)
|
|
res.push(n + '=' + opts[n]);
|
|
|
|
return res;
|
|
};
|
|
|
|
this.mergeAdvancedOptions = function(advStr, target, source) {
|
|
var adv = {}
|
|
if (!this.parse_extra_options(advStr, adv))
|
|
return false;
|
|
|
|
angular.extend(target, adv);
|
|
|
|
// Remove advanced options, no longer in the list
|
|
for(var n in source)
|
|
if (n.indexOf('--') == 0)
|
|
if (target[n] === undefined)
|
|
target[n] = null;
|
|
|
|
};
|
|
|
|
this.notifyInputError = function(msg) {
|
|
DialogService.dialog('Error', msg);
|
|
return false;
|
|
};
|
|
|
|
this.connectionError = function(txt, msg) {
|
|
if (typeof(txt) == typeof('')) {
|
|
if (msg == null)
|
|
return function (msg) {
|
|
var msgText = AppService.responseErrorMessage(msg);
|
|
DialogService.dialog(gettextCatalog.getString('Error'), txt + msgText);
|
|
};
|
|
} else {
|
|
msg = txt;
|
|
txt = '';
|
|
}
|
|
|
|
var msgText = AppService.responseErrorMessage(msg);
|
|
DialogService.dialog(gettextCatalog.getString('Error'), txt + msgText);
|
|
};
|
|
|
|
this.generatePassphrase = function() {
|
|
var specials = '!@#$%^&*()_+{}:"<>?[];\',./';
|
|
var lowercase = 'abcdefghijklmnopqrstuvwxyz';
|
|
var uppercase = lowercase.toUpperCase();
|
|
var numbers = '0123456789';
|
|
var all = specials + lowercase + uppercase + numbers;
|
|
|
|
function choose(str, n) {
|
|
var res = '';
|
|
for (var i = 0; i < n; i++) {
|
|
res += str.charAt(Math.floor(Math.random() * str.length));
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
var pwd = (
|
|
choose(specials, 2) +
|
|
choose(lowercase, 2) +
|
|
choose(uppercase, 2) +
|
|
choose(numbers, 2) +
|
|
choose(all, (Math.random()*5) + 5)
|
|
).split('');
|
|
|
|
for(var i = 0; i < pwd.length; i++) {
|
|
var pos = parseInt(Math.random() * pwd.length);
|
|
var t = pwd[i]
|
|
pwd[i] = pwd[pos];
|
|
pwd[pos] = t;
|
|
}
|
|
|
|
return pwd.join('');
|
|
}
|
|
|
|
this.nl2br = function(str, is_xhtml) {
|
|
var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';
|
|
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
|
|
};
|
|
|
|
this.preg_quote = function( str ) {
|
|
// http://kevin.vanzonneveld.net
|
|
// + original by: booeyOH
|
|
// + improved by: Ates Goral (http://magnetiq.com)
|
|
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
// + bugfixed by: Onno Marsman
|
|
// * example 1: preg_quote("$40");
|
|
// * returns 1: '\$40'
|
|
// * example 2: preg_quote("*RRRING* Hello?");
|
|
// * returns 2: '\*RRRING\* Hello\?'
|
|
// * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
|
|
// * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:'
|
|
|
|
return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
|
|
}
|
|
|
|
this.replace_all_insensitive = function(str, pattern, replacement) {
|
|
return str.replace( new RegExp( "(" + this.preg_quote(pattern) + ")" , 'gi' ), replacement );
|
|
};
|
|
|
|
this.replace_all = function(str, pattern, replacement) {
|
|
return str.replace( new RegExp( "(" + this.preg_quote(pattern) + ")" , 'g' ), replacement );
|
|
};
|
|
|
|
this.globToRegexp = function (str) {
|
|
// Escape special chars, except ? and *
|
|
str = (str + '').replace(/([\\\.\+\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
|
|
// Replace ? and * with .? and .*
|
|
return str.replace(/(\?|\*)/g, ".$1");
|
|
};
|
|
|
|
this.format = function() {
|
|
if (arguments == null || arguments.length < 1)
|
|
return null;
|
|
|
|
if (arguments.length == 1)
|
|
return arguments[0];
|
|
|
|
var msg = arguments[0];
|
|
|
|
for(var i = 1; i < arguments.length; i++)
|
|
msg = this.replace_all(msg, '{' + (i-1) + '}', arguments[i]);
|
|
|
|
return msg;
|
|
};
|
|
|
|
this.encodeDictAsUrl = function(obj) {
|
|
if (obj == null)
|
|
return '';
|
|
|
|
var str = [];
|
|
for(var p in obj) {
|
|
var x = encodeURIComponent(p);
|
|
if (obj[p] != null)
|
|
x += "=" + encodeURIComponent(obj[p]);
|
|
str.push(x);
|
|
}
|
|
|
|
if (str.length == 0)
|
|
return '';
|
|
|
|
return '?' + str.join("&");
|
|
};
|
|
|
|
var URL_REGEXP_FIELDS = ['source_uri', 'backend-type', '--auth-username', '--auth-password', 'server-name', 'server-port', 'server-path', 'querystring'];
|
|
var URL_REGEXP = /([^:]+)\:\/\/(?:(?:([^\:]+)(?:\:?:([^@]*))?\@))?(?:([^\/\?\:]*)(?:\:(\d+))?)(?:\/([^\?]*))?(?:\?(.+))?/;
|
|
var QUERY_REGEXP = /(?:^|&)([^&=]*)=?([^&]*)/g;
|
|
|
|
this.decode_uri = function(uri, backendlist) {
|
|
|
|
var i = URL_REGEXP_FIELDS.length + 1;
|
|
var res = {};
|
|
|
|
var m = URL_REGEXP.exec(uri);
|
|
|
|
// Invalid URI
|
|
if (!m)
|
|
return res;
|
|
|
|
while (i--) {
|
|
res[URL_REGEXP_FIELDS[i]] = m[i] || "";
|
|
}
|
|
|
|
res.querystring.replace(QUERY_REGEXP, function(str, key, val) {
|
|
if (key)
|
|
res['--' + key] = decodeURIComponent((val || '').replace(/\+/g, '%20'));
|
|
});
|
|
|
|
var backends = {};
|
|
for(var i in backendlist)
|
|
backends[backendlist[i].Key] = true;
|
|
|
|
var scheme = res['backend-type'];
|
|
|
|
if (scheme && scheme[scheme.length - 1] == 's' && !backends[scheme] && backends[scheme.substr(0, scheme.length-1)]) {
|
|
res['backend-type'] = scheme.substr(0, scheme.length-1);
|
|
res['--use-ssl'] = true;
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
this.find_scheme = function(uri, backendlist) {
|
|
if (!uri || uri.length == 0)
|
|
return null;
|
|
|
|
uri = uri.trim().toLowerCase();
|
|
var ix = uri.indexOf('://');
|
|
if (ix <= 0) {
|
|
for(var i in backendlist)
|
|
if (backendlist[i].Key == 'file')
|
|
return 'file';
|
|
|
|
return backendlist[0];
|
|
}
|
|
|
|
return (EDIT_URI.decode_uri(uri)['backend-type'] || '').toLowerCase()
|
|
};
|
|
|
|
this.contains_value = function(dict, value) {
|
|
for(var k in dict)
|
|
if (dict[k] == value)
|
|
return true;
|
|
|
|
return false;
|
|
};
|
|
|
|
this.contains_key = function(dict, key, keyname) {
|
|
for(var i in dict)
|
|
if (keyname == null ? i == key : dict[i][keyname] == key)
|
|
return true;
|
|
|
|
return false;
|
|
};
|
|
|
|
|
|
this.removeEmptyEntries = function(x) {
|
|
for (var i = x.length - 1; i >= 0; i--) {
|
|
if (x[i] == null || x[i] == '')
|
|
x.splice(i, 1);
|
|
};
|
|
|
|
return x;
|
|
};
|
|
|
|
this.splitFilterIntoTypeAndBody = function(src, dirsep) {
|
|
if (src == null)
|
|
return null;
|
|
|
|
if (dirsep == null) {
|
|
throw new Error('No dirsep provided!');
|
|
}
|
|
|
|
function matches(txt, n) {
|
|
var pre = apputils.replace_all(n.prefix || '', '!', dirsep);
|
|
var suf = apputils.replace_all(n.suffix || '', '!', dirsep);
|
|
|
|
if (txt.indexOf(pre) != 0 || txt.lastIndexOf(suf) != txt.length - suf.length)
|
|
return null;
|
|
|
|
var type = n.key;
|
|
var body = txt.substr(pre.length);
|
|
body = body.substr(0, body.length - suf.length);
|
|
|
|
if (body.length >= 2 && body[1] == '[') {
|
|
body = body.substr(1, body.length - 2);
|
|
}
|
|
|
|
if (n.exclude != null) {
|
|
for (var i = n.exclude.length - 1; i >= 0; i--)
|
|
if (body.indexOf(apputils.replace_all(n.exclude[i] || '', '!', dirsep)) >= 0)
|
|
return null;
|
|
}
|
|
|
|
return [type, body];
|
|
}
|
|
|
|
var m = [];
|
|
for (var i in this.filterClasses) {
|
|
var n = matches(src, this.filterClasses[i]);
|
|
if (n != null)
|
|
m.push(n);
|
|
}
|
|
if (m.length == 0) {
|
|
return null;
|
|
}
|
|
// Select match with shortest body, meaning longest prefix and suffix
|
|
var shortestIdx = 0;
|
|
var shortestLen = src.length;
|
|
for (i = 0; i < m.length; ++i) {
|
|
if (m[i][1].length < shortestLen) {
|
|
shortestIdx = i;
|
|
shortestLen = m[i][1].length;
|
|
}
|
|
}
|
|
return m[shortestIdx];
|
|
};
|
|
|
|
this.buildFilter = function(type, body, dirsep) {
|
|
if (type == null || this.filterTypeMap[type] == null)
|
|
return body;
|
|
|
|
body = body || '';
|
|
|
|
var f = this.filterTypeMap[type];
|
|
var pre = this.replace_all(f.prefix || '', '!', dirsep);
|
|
var suf = this.replace_all(f.suffix || '', '!', dirsep);
|
|
|
|
if (pre.length >= 2 && pre[1] == '[') {
|
|
//Regexp encode body ....
|
|
}
|
|
if (f.stripSep == true && body[body.length - 1] == dirsep) {
|
|
// Remove trailing dirsep
|
|
body = body.slice(0, -1);
|
|
}
|
|
return pre + body + suf;
|
|
};
|
|
|
|
this.filterListToRegexps = function(filters, caseSensitive) {
|
|
var res = [];
|
|
|
|
for(var i = 0; i < filters.length; i++) {
|
|
var f = filters[i];
|
|
|
|
if (f == null || f.length == 0)
|
|
continue;
|
|
|
|
var flag = f.substr(0, 1);
|
|
var filter = f.substr(1);
|
|
var rx = filter.substr(0, 1) == '[' && filter.substr(filter.length - 1, 1) == ']';
|
|
if (rx)
|
|
filter = filter.substr(1, filter.length - 2);
|
|
else
|
|
filter = this.globToRegexp(filter);
|
|
|
|
try {
|
|
res.push([flag == '+', new RegExp(filter, caseSensitive ? 'g' : 'gi')]);
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
this.evalFilter = function(path, filters, include) {
|
|
for (var i = 0; i < filters.length; i++) {
|
|
var m = path.match(filters[i][1]);
|
|
// Regex such as '.*' might match empty string at the end which is unwanted
|
|
// Check that the first match covers the full string
|
|
if (m && m.length >= 1 && m[0].length == path.length)
|
|
return filters[i][0];
|
|
}
|
|
|
|
return include === undefined ? true : include;
|
|
};
|
|
|
|
this.buildOptionList = function(sysinfo, encmodule, compmodule, backmodule) {
|
|
if (sysinfo == null || sysinfo.Options == null)
|
|
return null;
|
|
|
|
var items = angular.copy(sysinfo.Options);
|
|
for(var n in items)
|
|
items[n].Category = gettextCatalog.getString('Core options');
|
|
|
|
function copyToList(lst, key) {
|
|
if (key != null && typeof(key) != typeof(''))
|
|
key = null;
|
|
|
|
for(var n in lst)
|
|
{
|
|
if (key == null || key.toLowerCase() == lst[n].Key.toLowerCase())
|
|
{
|
|
var m = angular.copy(lst[n].Options);
|
|
for(var i in m)
|
|
m[i].Category = lst[n].DisplayName;
|
|
items.push.apply(items, m);
|
|
}
|
|
}
|
|
}
|
|
|
|
copyToList(sysinfo.GenericModules);
|
|
|
|
if (encmodule !== false)
|
|
copyToList(sysinfo.EncryptionModules, encmodule);
|
|
if (compmodule !== false)
|
|
copyToList(sysinfo.CompressionModules, compmodule);
|
|
if (backmodule !== false)
|
|
copyToList(sysinfo.BackendModules, backmodule);
|
|
|
|
return items;
|
|
};
|
|
|
|
this.extractServerModuleOptions = function(advOptionsList, servermodulelist, servermodulesettings, optionlistname) {
|
|
if (optionlistname == null)
|
|
optionlistname = 'SupportedCommands';
|
|
|
|
for(var mix in servermodulelist) {
|
|
var mod = servermodulelist[mix];
|
|
for(var oix in mod[optionlistname]) {
|
|
var opt = mod[optionlistname][oix];
|
|
var prefixstr = '--' + opt.Name + '=';
|
|
for (var i = advOptionsList.length - 1; i >= 0; i--) {
|
|
if (advOptionsList[i].indexOf(prefixstr) == 0) {
|
|
servermodulesettings[opt.Name] = advOptionsList[i].substr(prefixstr.length);
|
|
advOptionsList.splice(i, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
this.formatDuration = function(duration) {
|
|
// duration is a timespan string in format (dd.)hh:mm:ss.sss
|
|
// the part (dd.) is as indicated optional
|
|
|
|
if (duration == null) {
|
|
return;
|
|
}
|
|
|
|
var timespanArray = duration.split(':');
|
|
|
|
if (timespanArray.length < 3) {
|
|
return;
|
|
}
|
|
|
|
if (timespanArray[0].indexOf('.') > 0) {
|
|
timespanArray[0] = timespanArray[0].replace('.', " day(s) and ");
|
|
}
|
|
|
|
// round second according to ms
|
|
timespanArray[2] = Math.round(parseFloat(timespanArray[2])).toString();
|
|
// zero-padding
|
|
if (timespanArray[2].length == 1) timespanArray[2] = '0' + timespanArray[2];
|
|
|
|
return timespanArray.join(':');
|
|
};
|
|
|
|
});
|