iobroker.backitup
Version:
ioBroker.backitup allows you to backup and restore your ioBroker installation and other systems, such as databases, Zigbee, scripts and many more.
952 lines (887 loc) • 83 kB
JavaScript
// ioBroker.backitup - Copyright (c) by simatec
// Please visit https://github.com/simatec/ioBroker.backitup for licence-agreement and further information
//Settings
var $dialogCommand = null;
var $dialogDownload = null;
var $output = null;
var $dialogCommandProgress;
var lastMessage = '';
var restoreIfWait = 5000;
var storageTyp = '';
var oldJavascriptsEnabled;
var oldZigbeeEnabled;
var oldZigbee2MQTTEnabled;
var oldesphomeEnabled;
var oldNoderedEnabled;
var oldJarvisEnabled;
var oldHistoryEnabled;
var oldYahkaEnabled;
function encrypt(key, value) {
var result = '';
for (var i = 0; i < value.length; i++) {
result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
}
return result;
}
function decrypt(key, value) {
var result = '';
for (var i = 0; i < value.length; i++) {
result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
}
return result;
}
function initDialogDownload() {
$dialogDownload = $('#dialog-download');
if (!$dialogDownload.data('inited')) {
$dialogDownload.data('inited', true);
$dialogDownload.modal({
dismissible: false
});
}
$dialogDownload.modal('open');
}
function fetchMySqlConfig(isInitial) {
socket.emit('getObjectView', 'system', 'instance', { startkey: 'system.adapter.sql.', endkey: 'system.adapter.sql.\u9999', include_docs: true }, function (err, res) {
var found = false;
if (res && res.rows && res.rows.length) {
for (var i = 0; i < res.rows.length; i++) {
var common = res.rows[0].value.common;
var native = res.rows[i].value.native;
if (common.enabled && native.dbtype === 'mysql') {
$('#mySqlUser').val(native.user).trigger('change');
$('#mySqlPassword').val(native.password).trigger('change');
$('#mySqlHost').val(native.host).trigger('change');
$('#mySqlPort').val(native.port === '0' ? 3306 : native.port || 3306).trigger('change');
$('#mySqlName').val(native.dbname).trigger('change');
var id = res.rows[i].value.
found = res.rows[i].value._id;
break;
}
}
if (!found) {
for (var j = 0; j < res.rows.length; j++) {
var _native = res.rows[j].value.native;
if (_native.dbtype === 'mysql') {
$('#mySqlUser').val(_native.user).trigger('change');
$('#mySqlPassword').val(_native.password).trigger('change');
$('#mySqlHost').val(_native.host).trigger('change');
$('#mySqlName').val(_native.dbname).trigger('change');
$('#mySqlPort').val(_native.port === '0' ? 3306 : native.port || 3306).trigger('change');
found = res.rows[j].value._id;
break;
}
}
}
}
if (found) {
M.updateTextFields();
found = found.substring('system.adapter.'.length);
!isInitial && showMessage(_('Config taken from %s', found), _('BackItUp Information!'), 'info');
} else {
!isInitial && showMessage(_('No config found'), _('BackItUp Warning!'), 'info');
}
});
}
function fetchSqliteConfig(isInitial) {
socket.emit('getObjectView', 'system', 'instance', { startkey: 'system.adapter.sql.', endkey: 'system.adapter.sql.\u9999', include_docs: true }, function (err, res) {
var found = false;
if (res && res.rows && res.rows.length) {
for (var i = 0; i < res.rows.length; i++) {
var common = res.rows[0].value.common;
var native = res.rows[i].value.native;
if (common.enabled && native && native.dbtype === 'sqlite' && native.fileName) {
const pathLenght = native.fileName.split('/');
$('#sqlitePath').val(pathLenght > 1 ? native.fileName : `/opt/iobroker/iobroker-data/sqlite/${native.fileName}`).trigger('change');
var id = res.rows[i].value.
found = res.rows[i].value._id;
break;
}
}
if (!found) {
for (var j = 0; j < res.rows.length; j++) {
var _native = res.rows[j].value.native;
if (_native && _native.dbtype === 'sqlite' && _native.fileName) {
const pathLenght = _native.fileName.split('/');
$('#sqlitePath').val(pathLenght > 1 ? _native.fileName : `/opt/iobroker/iobroker-data/sqlite/${_native.fileName}`).trigger('change');
found = res.rows[j].value._id;
break;
}
}
}
}
if (found) {
M.updateTextFields();
found = found.substring('system.adapter.'.length);
!isInitial && showMessage(_('Config taken from %s', found), _('BackItUp Information!'), 'info');
} else {
!isInitial && showMessage(_('No config found'), _('BackItUp Warning!'), 'info');
}
});
}
function fetchPgSqlConfig(isInitial) {
socket.emit('getObjectView', 'system', 'instance', { startkey: 'system.adapter.sql.', endkey: 'system.adapter.sql.\u9999', include_docs: true }, function (err, res) {
var found = false;
if (res && res.rows && res.rows.length) {
for (var i = 0; i < res.rows.length; i++) {
var common = res.rows[0].value.common;
var native = res.rows[i].value.native;
if (common.enabled && native.dbtype === 'postgresql') {
$('#pgSqlUser').val(native.user).trigger('change');
$('#pgSqlPassword').val(native.password).trigger('change');
$('#pgSqlHost').val(native.host).trigger('change');
$('#pgSqlPort').val(native.port === '0' ? 5432 : native.port || 5432).trigger('change');
$('#pgSqlName').val(native.dbname).trigger('change');
var id = res.rows[i].value.
found = res.rows[i].value._id;
break;
}
}
if (!found) {
for (var j = 0; j < res.rows.length; j++) {
var _native = res.rows[j].value.native;
if (_native.dbtype === 'postgresql') {
$('#pgSqlUser').val(_native.user).trigger('change');
$('#pgSqlPassword').val(_native.password).trigger('change');
$('#pgSqlHost').val(_native.host).trigger('change');
$('#pgSqlName').val(_native.dbname).trigger('change');
$('#pgSqlPort').val(_native.port === '0' ? 5432 : native.port || 5432).trigger('change');
found = res.rows[j].value._id;
break;
}
}
}
}
if (found) {
M.updateTextFields();
found = found.substring('system.adapter.'.length);
!isInitial && showMessage(_('Config taken from %s', found), _('BackItUp Information!'), 'info');
} else {
!isInitial && showMessage(_('No config found'), _('BackItUp Warning!'), 'info');
}
});
}
function fetchInfluxDBConfig(isInitial) {
socket.emit('getObjectView', 'system', 'instance', { startkey: 'system.adapter.influxdb.', endkey: 'system.adapter.influxdb.\u9999', include_docs: true }, function (err, res) {
var found = false;
if (res && res.rows && res.rows.length) {
for (var i = 0; i < res.rows.length; i++) {
var common = res.rows[0].value.common;
var native = res.rows[i].value.native;
if (common.enabled) {
$('#influxDBHost').val(native.host).trigger('change');
$('#influxDBVersion').val(native.dbversion).trigger('change');
$('#influxDBVersion').select();
$('#influxDBProtocol').val(native.protocol).trigger('change');
$('#influxDBProtocol').select();
$('#influxDBName').val(native.dbname).trigger('change');
if (native.port && native.dbversion && native.dbversion == '2.x') {
$('#influxDBPort').val(native.port).trigger('change');
}
var id = res.rows[i].value.
found = res.rows[i].value._id;
break;
}
}
if (!found) {
for (var j = 0; j < res.rows.length; j++) {
var _native = res.rows[j].value.native;
$('#influxDBHost').val(_native.host).trigger('change');
$('#influxDBVersion').val(_native.dbversion).trigger('change');
$('#influxDBVersion').select();
$('#influxDBProtocol').val(_native.protocol).trigger('change');
$('#influxDBProtocol').select();
$('#influxDBName').val(_native.dbname).trigger('change');
if (_native.port && _native.dbversion && _native.dbversion == '2.x') {
$('#influxDBPort').val(_native.port).trigger('change');
}
found = res.rows[j].value._id;
break;
}
}
}
if (found) {
M.updateTextFields();
found = found.substring('system.adapter.'.length);
!isInitial && showMessage(_('Config taken from %s', found), _('BackItUp Information!'), 'info');
} else {
!isInitial && showMessage(_('No config found'), _('BackItUp Warning!'), 'info');
}
});
}
function fetchCcuConfig(isInitial) {
socket.emit('getObjectView', 'system', 'instance', { startkey: 'system.adapter.hm-rpc.', endkey: 'system.adapter.hm-rpc.\u9999', include_docs: true }, function (err, res) {
if (res && res.rows && res.rows.length) {
var found = false;
for (var i = 0; i < res.rows.length; i++) {
var common = res.rows[i].value.common;
if (common.enabled) {
var native = res.rows[i].value.native;
$('#ccuHost').val(native.homematicAddress).trigger('change');
$('#ccuUsehttps').prop('checked', native.useHttps);
found = res.rows[i].value._id;
break;
}
}
if (!found) {
for (var j = 0; j < res.rows.length; j++) {
var _native = res.rows[j].value.native;
$('#ccuHost').val(_native.homematicAddress).trigger('change');
$('#ccuUsehttps').prop('checked', _native.useHttps);
found = res.rows[j].value._id;
}
}
}
if (found) {
M.updateTextFields();
found = found.substring('system.adapter.'.length);
!isInitial && showMessage(_('Config taken from %s', found), _('BackItUp Information!'), 'info');
} else {
!isInitial && showMessage(_('No config found'), _('BackItUp Warning!'), 'info');
}
});
}
function fetchHistoryConfig(isInitial) {
socket.emit('getObjectView', 'system', 'instance', { startkey: 'system.adapter.history.', endkey: 'system.adapter.history.\u9999', include_docs: true }, function (err, res) {
let storeDir = '';
if (res && res.rows && res.rows.length) {
var found = false;
for (var i = 0; i < res.rows.length; i++) {
var common = res.rows[i].value.common;
if (common.enabled) {
var native = res.rows[i].value.native;
$('#historyPath').val(native.storeDir != '' && !native.storeDir.startsWith('/opt/iobroker/backups') ? native.storeDir : '/opt/iobroker/iobroker-data/history').trigger('change');
storeDir = native.storeDir;
found = res.rows[i].value._id;
break;
}
}
if (!found) {
for (var j = 0; j < res.rows.length; j++) {
var _native = res.rows[j].value.native;
$('#historyPath').val(_native.storeDir != '' && !_native.storeDir.startsWith('/opt/iobroker/backups') ? _native.storeDir : '/opt/iobroker/iobroker-data/history').trigger('change');
storeDir = _native.storeDir;
found = res.rows[j].value._id;
}
}
}
if (found && storeDir == '') {
M.updateTextFields();
found = found.substring('system.adapter.'.length);
!isInitial && showMessage(_('<br/><br/>No storage path of %s is configured.<br/>The default path of the history adapter has been set.', found), _('BackItUp Information!'), 'info');
} else if (found && storeDir !== '' && storeDir.startsWith('/opt/iobroker/backups')) {
M.updateTextFields();
found = found.substring('system.adapter.'.length);
!isInitial && showMessage(_('<br/><br/>The storage path of %s must not be identical to the path for backups.<br/>The default path of the history adapter has been set.<br/><br/>Please change the path in the history adapter!', found), _('BackItUp Information!'), 'info');
} else if (found && storeDir !== '') {
M.updateTextFields();
found = found.substring('system.adapter.'.length);
!isInitial && showMessage(_('Config taken from %s', found), _('BackItUp Information!'), 'info');
} else {
!isInitial && showMessage(_('No config found'), _('BackItUp Warning!'), 'info');
}
});
}
var ignoreMessage = [];
function cleanIgnoreMessage(name) {
for (const i in ignoreMessage) {
if (ignoreMessage[i] == name) {
ignoreMessage.splice(i, 1);
break;
}
}
}
function checkAdapterInstall(name, backitupHost) {
var ignore = false;
var adapterName = name;
if (name == 'pgsql' || name == 'mysql' || name == 'sqlite') {
adapterName = 'sql';
}
for (const i in ignoreMessage) {
if (ignoreMessage[i] == name) {
ignore = true;
break;
}
}
if (!ignore) {
socket.emit('getObjectView', 'system', 'instance', { startkey: 'system.adapter.' + adapterName + '.', endkey: 'system.adapter.' + adapterName + '.\u9999', include_docs: true }, function (err, res) {
if (res && res.rows && res.rows.length) {
for (var i = 0; i < res.rows.length; i++) {
var common = res.rows[i].value.common;
if (common.host !== backitupHost && (adapterName == 'zigbee' || adapterName == 'esphome' || adapterName == 'zigbee2mqtt' || adapterName == 'node-red' || adapterName == 'yahka' || adapterName == 'jarvis' || adapterName == 'history')) {
showMessage(_("No %s Instance found on this host. Please check your System", adapterName), _('BackItUp Warning!'), 'info');
ignoreMessage.push(name);
break;
}
}
} else if (res.rows.length == 0 && (adapterName == 'zigbee' || adapterName == 'esphome' || adapterName == 'zigbee2mqtt' || adapterName == 'node-red' || adapterName == 'yahka' || adapterName == 'jarvis' || adapterName == 'history')) {
showMessage(_("No %s Instance found on this host. Please check your System", adapterName), _('BackItUp Warning!'), 'info');
ignoreMessage.push(name);
}
});
}
}
function initDialog() {
$dialogCommand = $('#dialog-command');
$output = $dialogCommand.find('#stdout');
$dialogCommandProgress = $dialogCommand.find('.progress div');
$dialogCommand.find('.progress-dont-close input').on('change', function () {
if (typeof localStorage !== 'undefined') {
localStorage.setItem('backitup-close-on-ready', $(this).prop('checked') ? '1' : '0');
}
});
if (typeof localStorage !== 'undefined') {
if (localStorage.getItem('backitup-close-on-ready') === '0') {
$dialogCommand.find('.progress-dont-close input').prop('checked', false);
} else {
$dialogCommand.find('.progress-dont-close input').prop('checked', true);
}
}
$dialogCommand.modal({
dismissible: false
});
// workaround for materialize checkbox problem
$dialogCommand.find('input[type="checkbox"]+span').off('click').on('click', function () {
var $input = $(this).prev();
// ignore switch
if ($input.parent().parent().hasClass('switch')) return;
if (!$input.prop('disabled')) {
$input.prop('checked', !$input.prop('checked')).trigger('change');
}
});
$dialogCommand.find('.btn').on('click', function () {
$dialogCommand.modal('close');
});
}
function showDialog(type, isStopped) {
$output.val(_(`Started ${type} ...`));
$dialogCommand.modal('open');
$dialogCommand.find('.progress-dont-close').removeClass('disabled');
$dialogCommandProgress.show();
if (type === 'restore' && isStopped === true) {
showToast($dialogCommand, _('ioBroker will be stopped and started again. Please wait'), null, 10000);
}
lastMessage = '';
}
function getSize(bytes) {
if (bytes > 1024 * 1024 * 512) {
return Math.round(bytes / (1024 * 1024 * 1024) * 10) / 10 + 'GiB';
} else if (bytes > 1024 * 1024) {
return Math.round(bytes / (1024 * 1024) * 10) / 10 + 'MiB';
} else if (bytes > 1024) {
return Math.round(bytes / (1024) * 10) / 10 + 'KiB';
} else {
return bytes + ' bytes';
}
}
function getName(name) {
var parts = name.split('_');
if (parseInt(parts[0], 10).toString() !== parts[0]) {
parts.shift();
}
return new Date(
parts[0],
parseInt(parts[1], 10) - 1,
parseInt(parts[2].split('-')[0], 10),
parseInt(parts[2].split('-')[1], 10),
parseInt(parts[3], 10)).toLocaleString().replace(/:00$/, '');
}
function load(settings, onChange) {
if (!settings) return;
if (settings.redisEnabled === undefined) {
settings.redisEnabled = adapter.config.backupRedis;
}
if (settings.cifsMount === 'CIFS') {
settings.cifsMount = '';
}
$('.timepicker').timepicker({
twelveHour: false
});
oldJavascriptsEnabled = settings.javascriptsEnabled;
oldZigbeeEnabled = settings.zigbeeEnabled;
oldesphomeEnabled = settings.esphomeEnabled;
oldZigbee2MQTTEnabled = settings.zigbee2mqttEnabled;
oldNoderedEnabled = settings.noderedEnabled;
oldJarvisEnabled = settings.jarvisEnabled;
oldHistoryEnabled = settings.historyEnabled;
oldYahkaEnabled = settings.yahkaEnabled;
$('.value').each(function () {
var $key = $(this);
var id = $key.attr('id');
if ($key.attr('type') === 'checkbox') {
// do not call onChange direct, because onChange could expect some arguments
$key.prop('checked', settings[id]).on('change', function () {
showHideSettings(settings);
onChange();
});
} else {
var val = settings[id];
if (id === 'mySqlPassword' || id === 'pgSqlPassword' || id === 'webdavPassword' || id === 'ccuPassword' || id === 'ftpPassword' || id === 'cifsPassword' || id === 'grafanaPassword' || id === 'redisPassword') {
val = val ? decrypt((typeof systemConfig !== 'undefined' && systemConfig.native && systemConfig.native.secret) || 'Zgfr56gFe87jJOM', val) : '';
}
// do not call onChange direct, because onChange could expect some arguments
$key.val(val).on('change', function () {
onChange();
}).on('keyup', function () {
onChange();
});
}
});
sendTo(null, 'getFileSystemInfo', null, function (obj) {
if (obj && obj.diskState && obj.storage && obj.diskFree) {
if (obj.diskState === 'warn' && obj.storage === 'local') {
showMessage(_('<br/><br/><br/> On the host only %s MB free space is available! Please check your system!', obj.diskFree), _('BackItUp Information!'), 'info');
} else if (obj.diskState === 'error' && obj.storage === 'local') {
showMessage(_('<br/><br/><br/> On the host only %s MB free space is available! Local backups are currently not possible. <br/><br/>Please check your system!', obj.diskFree), _('BackItUp Information!'), 'warning');
}
}
});
sendTo(null, 'getSystemInfo', null, function (obj) {
if (obj && obj.systemOS === 'docker' && obj.dockerDB === false) {
var $influxDBEnabled = $('#influxDBEnabled');
var $mySqlEnabled = $('#mySqlEnabled');
var $sqliteEnabled = $('#sqliteEnabled');
var $pgSqlEnabled = $('#pgSqlEnabled');
var $startAllRestore = $('#startAllRestore');
$('#influxDBEnabled').prop('checked', false);
$('#mySqlEnabled').prop('checked', false);
$('#sqliteEnabled').prop('checked', false);
$('#pgSqlEnabled').prop('checked', false);
$('#startAllRestore').prop('checked', false);
$('#influxDBEnabled').prop('disabled', true);
$('#mySqlEnabled').prop('disabled', true);
$('#sqliteEnabled').prop('disabled', true);
$('#pgSqlEnabled').prop('disabled', true);
$('#startAllRestore').prop('disabled', true);
$influxDBEnabled.addClass('disabled');
$mySqlEnabled.addClass('disabled');
$sqliteEnabled.addClass('disabled');
$pgSqlEnabled.addClass('disabled');
$startAllRestore.addClass('disabled');
// enable only Redis Remote Backup
$('.redisDocker').hide();
$('.redisRemote').show();
$('.redisLocal').hide();
if ($('#redisType').val() != 'remote' && $('#redisEnabled').prop('checked')) {
$('#redisType').val('remote').trigger('change');
$('#redisType').select();
}
}
if (obj && obj.systemOS === 'docker') {
restoreIfWait = 10000;
} else if (obj && obj.systemOS === 'win') {
restoreIfWait = 18000;
}
});
ccuEvents = settings.ccuEvents || [];
influxDBEvents = settings.influxDBEvents || [];
mySqlEvents = settings.mySqlEvents || [];
pgSqlEvents = settings.pgSqlEvents || [];
if (pgSqlEvents && pgSqlEvents.length) {
for (var i = 0; i < pgSqlEvents.length; i++) {
var val = pgSqlEvents[i].pass ? pgSqlEvents[i].pass : '';
pgSqlEvents[i].pass = val ? decrypt((typeof systemConfig !== 'undefined' && systemConfig.native && systemConfig.native.secret) || 'Zgfr56gFe87jJOM', val) : '';
}
}
if (mySqlEvents && mySqlEvents.length) {
for (var i = 0; i < mySqlEvents.length; i++) {
var val = mySqlEvents[i].pass ? mySqlEvents[i].pass : '';
mySqlEvents[i].pass = val ? decrypt((typeof systemConfig !== 'undefined' && systemConfig.native && systemConfig.native.secret) || 'Zgfr56gFe87jJOM', val) : '';
}
}
if (ccuEvents && ccuEvents.length) {
for (var i = 0; i < ccuEvents.length; i++) {
var val = ccuEvents[i].pass ? ccuEvents[i].pass : '';
ccuEvents[i].pass = val ? decrypt((typeof systemConfig !== 'undefined' && systemConfig.native && systemConfig.native.secret) || 'Zgfr56gFe87jJOM', val) : '';
}
}
values2table('ccuEvents', ccuEvents, onChange);
values2table('influxDBEvents', influxDBEvents, onChange, tableOnReady);
values2table('mySqlEvents', mySqlEvents, onChange);
values2table('pgSqlEvents', pgSqlEvents, onChange);
$('#ccuAdded').on('click', function () {
var devices = table2values('ccuEvents');
var id = 0;
for (var i = 0; i < devices.length; i++) {
id++;
}
setTimeout(function () {
$('#ccuEvents .values-input[data-name="nameSuffix"][data-index="' + id + '"]').val(`CCU-${id + 1}`).trigger('change');
}, 250);
});
$('#influxDBAdded').on('click', function () {
var devices = table2values('influxDBEvents');
var id = 0;
for (var i = 0; i < devices.length; i++) {
id++;
}
setTimeout(function () {
$('#influxDBEvents .values-input[data-name="port"][data-index="' + id + '"]').val(8088).trigger('change');
$('#influxDBEvents .values-input[data-name="nameSuffix"][data-index="' + id + '"]').val(`influxDB-${id + 1}`).trigger('change');
$('#influxDBEvents .values-input[data-name="protocol"][data-index="' + id + '"]').val('http').trigger('change');
$('#influxDBEvents .values-input[data-name="dbversion"][data-index="' + id + '"]').val('1.x').trigger('change');
}, 250);
});
function tableOnReady() {
$('#influxDBEvents .table-values-div .table-values .values-input[data-name="dbversion"]').on('change', function () {
let id = $(this).data('index');
var dbversion = $('#influxDBEvents .values-input[data-name="dbversion"][data-index="' + id + '"]').val();
if (dbversion == '1.x') {
$('#influxDBEvents .values-input[data-name="token"][data-index="' + id + '"]').prop('disabled', true).trigger('change');
$('#influxDBEvents .values-input[data-name="token"][data-index="' + id + '"]').addClass('hiddenToken').trigger('change');
$('#influxDBEvents .values-input[data-name="port"][data-index="' + id + '"]').val(8088).trigger('change');
} else {
$('#influxDBEvents .values-input[data-name="token"][data-index="' + id + '"]').prop('disabled', false).trigger('change');
$('#influxDBEvents .values-input[data-name="token"][data-index="' + id + '"]').removeClass('hiddenToken').trigger('change');
$('#influxDBEvents .values-input[data-name="port"][data-index="' + id + '"]').val(8086).trigger('change');
}
});
var devices = table2values('influxDBEvents');
id = 0;
for (var i = 0; i < devices.length; i++) {
var dbversion = $('#influxDBEvents .values-input[data-name="dbversion"][data-index="' + id + '"]').val();
if (dbversion == '1.x') {
$('#influxDBEvents .values-input[data-name="token"][data-index="' + id + '"]').prop('disabled', true).trigger('change');
$('#influxDBEvents .values-input[data-name="token"][data-index="' + id + '"]').addClass('hiddenToken').trigger('change');
} else {
$('#influxDBEvents .values-input[data-name="token"][data-index="' + id + '"]').prop('disabled', false).trigger('change');
$('#influxDBEvents .values-input[data-name="token"][data-index="' + id + '"]').removeClass('hiddenToken').trigger('change');
}
id++;
}
}
$('#mySqlAdded').on('click', function () {
var devices = table2values('mySqlEvents');
var id = 0;
for (var i = 0; i < devices.length; i++) {
id++;
}
setTimeout(function () {
$('#mySqlEvents .values-input[data-name="port"][data-index="' + id + '"]').val(3306).trigger('change');
$('#mySqlEvents .values-input[data-name="nameSuffix"][data-index="' + id + '"]').val(`mySqlDB-${id + 1}`).trigger('change');
}, 250);
});
$('#pgSqlAdded').on('click', function () {
var devices = table2values('pgSqlEvents');
var id = 0;
for (var i = 0; i < devices.length; i++) {
id++;
}
setTimeout(function () {
$('#pgSqlEvents .values-input[data-name="port"][data-index="' + id + '"]').val(5432).trigger('change');
$('#pgSqlEvents .values-input[data-name="nameSuffix"][data-index="' + id + '"]').val(`pgSqlDB-${id + 1}`).trigger('change');
}, 250);
});
getIsAdapterAlive(function (isAlive) {
if (isAlive || common.enabled) {
$('.do-backup')
.removeClass('disabled')
.on('click', function () {
if (changed) {
showError(_('Save the configuration first'));
return;
}
var type = $(this).data('type');
socket.emit('setState', adapter + '.' + instance + '.oneClick.' + type, {
val: true,
ack: false
}, function (err) {
if (!err) {
showDialog(type, null);
showToast(null, _('Backup started'));
} else {
showError(err);
}
});
}).each(function () {
var type = $(this).data('type');
var $btn = $(this);
socket.emit('getState', adapter + '.' + instance + '.oneClick.' + type, function (err, state) {
if (state && state.val) {
$btn.addClass('disabled');
}
});
});
socket.on('stateChange', function (id, state) {
if (id === 'backitup.' + instance + '.oneClick.ccu') {
if (state && state.val) {
$('.btn-ccu').addClass('disabled');
} else {
$('.btn-ccu').removeClass('disabled');
}
} else
if (id === 'backitup.' + instance + '.oneClick.total') {
if (state && state.val) {
$('.btn-total').addClass('disabled');
} else {
$('.btn-total').removeClass('disabled');
}
} else
if (id === 'backitup.' + instance + '.oneClick.iobroker') {
if (state && state.val) {
$('.btn-iobroker').addClass('disabled');
} else {
$('.btn-iobroker').removeClass('disabled');
}
} else
if (id === 'system.adapter.backitup.' + instance + '.alive') {
if (state && state.val) {
$('.do-backup').removeClass('disabled');
} else {
$('.do-backup').addClass('disabled');
}
} else
if (id === 'backitup.' + instance + '.output.line') {
if (state && state.val && state.val !== lastMessage) {
lastMessage = state.val;
var text = $output.val();
$output.val(text + '\n' + state.val);
if (state.val.match(/^\[EXIT]/)) {
var code = state.val.match(/^\[EXIT] ([-\d]+)/);
$dialogCommandProgress.hide();
$dialogCommand.find('.progress-dont-close').addClass('disabled');
if ($dialogCommand.find('.progress-dont-close input').prop('checked') &&
(!code || code[1] === '0')) {
setTimeout(function () {
$dialogCommand.modal('close');
}, 1500);
}
}
}
}
});
if (settings.ftpEnabled === false && settings.dropboxEnabled === false && settings.onedriveEnabled === false && settings.cifsEnabled === false && settings.googledriveEnabled === false && settings.webdavEnabled === false) {
showMessage(_("<br/><br/>According to the BackItUp settings, backups are currently stored in the same local file system that is the source of the backup can be accessed more. <br/> <br/>It is recommended to use an external storage space as a backup target."), _('BackItUp Information!'), 'info');
}
socket.emit('subscribeStates', 'backitup.' + instance + '.*');
socket.emit('subscribeStates', 'system.adapter.backitup.' + instance + '.alive');
socket.on('reconnect', function () {
socket.emit('subscribeStates', 'backitup.' + instance + '.*');
socket.emit('subscribeStates', 'system.adapter.backitup.' + instance + '.alive');
});
$('#testWebDAV').on('click', function () {
getIsAdapterAlive(function (isAlive) {
if (!isAlive) {
showToast(null, _('Start or enable adapter first'));
} else {
$('#testWebDAV').addClass('disabled');
sendTo(null, 'testWebDAV', {
config: {
host: $('#webdavURL').val(),
username: $('#webdavUsername').val(),
password: $('#webdavPassword').val(),
signedCertificates: $('#webdavSignedCertificates').prop('checked') ? true : false
}
}, function (response) {
$('#testWebDAV').removeClass('disabled');
if (response.error) {
showError('Error: ' + response.error);
} else {
showMessage(_('The connection to the WebDAV server was established successfully.'), _('BackItUp Information!'), 'info');
}
});
}
});
});
$('.do-list').removeClass('disabled').on('click', function () {
$('.do-list').addClass('disabled');
$('#tab-restore').find('.root').html('');
$('.doRestore').hide();
$('.search-ready').hide();
$('.search-error').hide();
$('.progress-search').show();
console.log('Restore Type: ' + $('#restoreSource').val());
sendTo(null, 'list', $('#restoreSource').val(), function (result) {
$('.do-list').removeClass('disabled');
console.log(result);
if (result && result.error) {
$('.progress-search').hide();
$('.search-error').show();
showError(JSON.stringify(result.error));
}
if (result && result.data) {
$('.progress-search').hide();
$('.search-ready').show();
var text = '';
var data = result.data;
console.log(data);
for (var type in data) {
if (!data.hasOwnProperty(type)) continue;
// Storage Translate
switch (type) {
case 'webdav':
storageTyp = 'WebDAV';
break;
case 'nas / copy':
storageTyp = 'NAS / Copy';
break;
case 'local':
storageTyp = 'Local';
break;
case 'dropbox':
storageTyp = 'Dropbox';
break;
case 'onedrive':
storageTyp = 'Onedrive';
break;
case 'ftp':
storageTyp = 'FTP';
break;
case 'googledrive':
storageTyp = 'Google Drive';
break;
}
text += `<li><div class="collapsible-header top"><i class="material-icons">expand_more</i><h6>${_(storageTyp)}</h6></div>`;
text += `<ul class="collapsible-body collection head">`;
for (var storage in data[type]) {
if (data[type].hasOwnProperty(storage)) {
text += `<ul class="collapsible"><li><div class="collapsible-header"><i class="material-icons">expand_more</i><h6>${storage.toUpperCase()}</h6></div>`;
text += `<ul class="collapsible-body collection">`;
for (var i = data[type][storage].length - 1; i >= 0; i--) {
text += `<li title="${_('source type')}: ${_(storageTyp)}\n${_('Type')}: ${storage.charAt(0).toUpperCase() + storage.slice(1)}\n${_('backup time')}: ${getName(data[type][storage][i].name)}\n${_('filesize')}: ${getSize(data[type][storage][i].size)}\n\n${_('name')}:\n${data[type][storage][i].name}" class="collection-item">`;
text += `<div>${_('backup time')}: ${getName(data[type][storage][i].name)} | ${_('filesize')}: ${getSize(data[type][storage][i].size)}`;
text += `<a class="btn-floating secondary-content do-restore" style="height: 32.4px!important; width: 32.4px!important;" title="${_('Restore Backup File')}" data-file="${data[type][storage][i].path}" data-type="${type}"><i style="line-height: 32.4px;" class="material-icons">restore</i></a>`;
text += `<a class="btn-floating secondary-content do-download" style="height: 32.4px!important; width: 32.4px!important;" title="${_('Download Backup File')}" data-file="${data[type][storage][i].path}" data-type="${type}"><i style="line-height: 32.4px;" class="material-icons">file_download</i></a>`;
text += `</div></li>`;
}
text += '</ul></li></ul>';
}
}
text += '</ul></li>';
}
$('.doRestore').show();
var $tabRestore = $('#tab-restore');
$tabRestore
.find('.root')
.html(text);
$tabRestore.find('.collapsible').collapsible();
$tabRestore.find('.do-restore').on('click', function () {
var type = $(this).data('type');
var file = $(this).data('file');
var name = file.split('/').pop().split('_')[0];
var message = _('<br/><br/>ioBroker will be restarted during restore.<br/><br/>Confirm with \"OK\".');
var downloadPanel = false;
if ($('#restoreSource').val() === 'dropbox' || $('#restoreSource').val() === 'onedrive' || $('#restoreSource').val() === 'googledrive' || $('#restoreSource').val() === 'ftp' || $('#restoreSource').val() === 'webdav') {
message = _('<br/><br/>1. Confirm with "OK" and the download begins. Please wait until the download is finished!<br/><br/>2. After download ioBroker will be restarted during restore.');
downloadPanel = true;
}
var isStopped = false;
if (file.search('grafana') == -1 &&
file.search('jarvis') == -1 &&
file.search('javascripts') == -1 &&
file.search('mysql') == -1 &&
file.search('sqlite') == -1 &&
file.search('influxDB') == -1 &&
file.search('pgsql') == -1 &&
file.search('zigbee') == -1 &&
file.search('esphome') == -1 &&
file.search('zigbee2mqtt') == -1 &&
file.search('nodered') == -1 &&
file.search('yahka') == -1 &&
file.search('historyDB') == -1) {
isStopped = true;
} else {
if (downloadPanel) {
message = _('<br/><br/>1. Confirm with "OK" and the download begins. Please wait until the download is finished!<br/><br/>2. After the download, the restore begins without restarting ioBroker.');
} else {
message = _('<br/><br/>ioBroker will not be restarted for this restore.<br/><br/>Confirm with \"OK\".');
}
}
if (isStopped) {
message += _('<br/><br/><br/><b>After confirmation, a new tab opens with the Restore Log.</b><br/><b>If the tab does not open, please deactivate your popup blocker.</b>')
}
confirmMessage(name !== '' ? message : _('Ready'), _('Are you sure?'), null, [_('Cancel'), _('OK')], function (result) {
if (result === 1) {
if (downloadPanel) {
$('.cloudRestore').show();
} else {
$('.cloudRestore').hide();
}
$('.do-list').addClass('disabled');
$('#tab-restore').find('.do-restore').addClass('disabled').hide();
$('#tab-restore').find('.do-download').addClass('disabled').hide();
var name = file.split('/').pop().split('_')[0];
showDialog(name !== '' ? 'restore' : '', isStopped);
showToast(null, _('Restore started'));
let theme;
try {
theme = currentTheme();
} catch (e) {
// Ignore
}
sendTo(null, 'restore', { type: type, fileName: file, currentTheme: theme || 'none', currentProtocol: location.protocol, stopIOB: isStopped }, function (result) {
if (!result || result.error) {
showError('Error: ' + JSON.stringify(result.error));
} else {
console.log('Restore finish!')
if (isStopped) {
var restoreURL = `${location.protocol}//${location.hostname}:8091/backitup-restore.html`;
console.log('Restore Url: ' + restoreURL);
setTimeout(() => window.open(restoreURL, '_self'), restoreIfWait);
//setTimeout(() => $('<a href="' + restoreURL + '"> </a>')[0].click(), restoreIfWait);
}
if (downloadPanel) {
$('.cloudRestore').hide();
downloadPanel = false;
}
}
$('.do-list').removeClass('disabled');
$('#tab-restore').find('.do-restore').removeClass('disabled').show();
$('#tab-restore').find('.do-download').removeClass('disabled').show();
});
}
});
});
$tabRestore.find('.do-download').on('click', function () {
var type = $(this).data('type');
var file = $(this).data('file');
type = type == 'nas / copy' ? 'cifs' : type;
$('.downloadFinish').hide();
$('.downloadError').hide();
$('.downloadProgress').show();
$('.do-list').addClass('disabled');
$('#tab-restore').find('.do-restore').addClass('disabled').hide();
$('#tab-restore').find('.do-download').addClass('disabled').hide();
$('#backupDownload_name').text(` "${file.split(/[\\/]/).pop()}" `);
$('#backupDownload_source').text(_(storageTyp));
initDialogDownload();
sendTo(null, 'getFile', { type: type, fileName: file, protocol: location.protocol }, function (result) {
if (!result || result.error) {
$dialogDownload.modal('close');
showError('<br/><br/>Error:<br/><br/>' + JSON.stringify(result.error));
} else {
console.log('Download finish!')
const downloadLink = document.createElement('a');
downloadLink.setAttribute('href', `${location.protocol}//${location.hostname}:${result.listenPort}/${result.fileName ? result.fileName : file.split(/[\\/]/).pop()}`);
downloadLink.style.display = 'none';
document.body.appendChild(downloadLink);
try {
downloadLink.download = file.split(/[\\/]/).pop();
downloadLink.click();
document.body.removeChild(downloadLink);
} catch (e) {
console.error(`Cannot access download: ${e}`);
window.alert(_('Unfortunately your browser does not support this feature'));
$('.downloadProgress').hide();
$('.downloadError').show();
}
sendTo(null, 'serverClose', { downloadFinish: true }, function (result) {
if (result && result.serverClose) {
$('.downloadProgress').hide();
$('.downloadFinish').show();
setTimeout(() => $dialogDownload.modal('close'), 5000);
}
});
}
$('.do-list').removeClass('disabled');
$('#tab-restore').find('.do-restore').removeClass('disabled').show();
$('#tab-restore').find('.do-download').removeClass('disabled').show();
});
});
}
});
});
// Dropbox Settings
$('.get-dropbox-json').removeClass('disabled').on('click', function () {
$('.get-dropbox-json').addClass('disabled');
sendTo(null, 'authDropbox', null, function (obj) {
if (obj && obj.url && obj.code_challenge) {