Created
August 26, 2015 06:09
-
-
Save Kreozot/46f58d9f9cf2a08b7fd8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Создание бэкапа Битрикса | |
* | |
* Требуется файл secret.json, в котором будут храниться данные пользователя Битрикса и URL локального проекта: | |
* { | |
* "bitrix": { | |
* "username": "v.pupkin", | |
* "password": "mySecretPassword" | |
* }, | |
* "localUrl": "http://mysite.local/" | |
* } | |
* Кроме того подразумевается, что у вас уже поднят локальный сервер, адрес которого прописан в localUrl (secret.json), а корень находится в папке c текущим скриптом | |
*/ | |
var Nightmare = require('nightmare'), | |
config = require('./package.json').config, | |
secret = require('./secret.json'), | |
http = require('http'), | |
fs = require('fs'), | |
Q = require('q'), | |
ProgressBar = require('progress'); | |
var bitrixUrl = config.urls.dev.replace('.com', '.int') + 'bitrix/'; | |
var dbConfig; | |
function makeBackup() { | |
return Q.Promise(function (resolve, reject, notify) { | |
var backupLink, | |
restoreUrl; | |
new Nightmare({ | |
timeout: 240000 | |
}) | |
.goto(bitrixUrl + 'admin/dump.php?lang=ru') | |
.type('input.login-input[name="USER_LOGIN"]', secret.bitrix.username) | |
.type('input.login-input[name="USER_PASSWORD"]', secret.bitrix.password) | |
.click('input[type="submit"]') | |
.wait(7000) | |
.click('#dump_bucket_id_0') // Размещение резервной копии: в папке сайта | |
.click('#tab_cont_expert') // Параметры | |
.wait(1000) | |
.click('#dump_expert') // Включить экспертные настройки создания резервной копии | |
.type('input[name="dump_archive_size_limit"]', '2047') // Максимальный размер несжатых данных в одной части архива (МБ): 2047 | |
.check('input[name="dump_file_public"]') // Архивировать публичную часть | |
.check('input[name="skip_mask"]') // Исключить из архива файлы и директории по маске | |
.click('#start_button') // Создать резервную копию | |
.wait('.adm-info-message-icon') | |
.goto(bitrixUrl + 'admin/dump_list.php?lang=ru') // Список резервных копий | |
.click('div.adm-info-message>a:nth-child(1)') // Ячейка с названием последней резервной копии | |
// Получить название файла резервной копии | |
.evaluate(function () { | |
return '' + document.evaluate( | |
'//table[@id="tbl_dump"]/tbody/tr[1]/td[3]', | |
document, | |
null, | |
XPathResult.ORDERED_NODE_ITERATOR_TYPE, | |
null).iterateNext().innerText; | |
}, function (result) { | |
backupLink = result; | |
}) | |
// Скачать restore.php | |
.evaluate(function () { | |
var restoreUrl = '' + document.evaluate( | |
'//div[@class="adm-info-message"]/a', | |
document, | |
null, | |
XPathResult.ORDERED_NODE_ITERATOR_TYPE, | |
null).iterateNext().href; | |
var xhr = new XMLHttpRequest(); | |
xhr.open("GET", restoreUrl, false); | |
xhr.overrideMimeType("text/plain; charset=x-user-defined"); | |
xhr.send(); | |
return xhr.responseText; | |
}, function (result) { | |
fs.writeFileSync("restore.php", result, "binary"); | |
console.log('restore.php downloaded'); | |
}) | |
// Файл настроек БД | |
.goto(bitrixUrl + 'admin/fileman_file_edit.php?path=%2Fbitrix%2Fphp_interface%2Fdbconn.php&full_src=Y&site=s1&lang=ru') | |
.evaluate(function () { | |
var settings = '' + document.querySelector('.bxce-highlight').innerText; | |
var dbConfig = {}; | |
dbConfig.login = settings.match(/\$DBLogin = "([\S]+)";/)[1]; | |
dbConfig.password = settings.match(/\$DBPassword = "([\S]+)";/)[1]; | |
dbConfig.name = settings.match(/\$DBName = "([\S]+)";/)[1]; | |
return dbConfig; | |
}, function (result) { | |
dbConfig = result; | |
dbConfig.host = config.urls.dev | |
.replace('.com', '.int') | |
.replace('http://', '') | |
.replace('/', ''); | |
}) | |
.run(function (err, nightmare) { | |
if (err) { | |
reject(err); | |
} else { | |
console.log('Backup saved in bitrix as ' + backupLink); | |
resolve(backupLink); | |
}; | |
}); | |
}); | |
} | |
function downloadBackup(filename) { | |
return Q.Promise(function (resolve, reject, notify) { | |
var backupUrl = bitrixUrl + 'backup/' + filename; | |
var file = fs.createWriteStream(filename); | |
var req = http.get(backupUrl, function (res) { | |
var len = parseInt(res.headers['content-length'], 10); | |
console.log(); | |
var bar = new ProgressBar(' downloading [:bar] :percent :etas', { | |
complete: '=', | |
incomplete: ' ', | |
width: 30, | |
total: len | |
}); | |
res.on('data', function (chunk) { | |
bar.tick(chunk.length); | |
}); | |
res.on('end', function () { | |
console.log('\n'); | |
resolve(filename); | |
}); | |
res.pipe(file); | |
}) | |
.on('error', function (err) { | |
reject(err); | |
}); | |
}); | |
} | |
function restoreBackup(filename) { | |
return Q.Promise(function (resolve, reject, notify) { | |
nightmare = new Nightmare({ | |
timeout: 240000 | |
}); | |
var skip = false; | |
nightmare | |
.goto(secret.localUrl + 'restore.php?lang=ru') | |
.click('input[value="Далее"]') // Далее | |
.wait(2000) | |
.click('input[onclick="div_show(3)"]') // Архив загружен в корневую папку сервера | |
.select('select[name="arc_name"]', filename) | |
.click('input[value="Далее"]') // Далее | |
.on('loadFinished', function (status) { | |
if (!skip) { | |
nightmare | |
.evaluate(function () { | |
var valueDiv = document.querySelector('div[align="center"]'); | |
if (valueDiv) { | |
return '' + valueDiv.innerText; | |
} else { | |
return false; | |
} | |
return value; | |
}, function (result) { | |
if (result) { | |
console.log(result); | |
} | |
}) | |
.evaluate(function () { | |
document.isReloaded = true; | |
if (document.querySelector('input[value="Пропустить"]')) { | |
return 'skip'; | |
} else if (document.querySelector('input[name="DBHost"]')) { | |
return 'db'; | |
} else { | |
return false; | |
} | |
}, function (result) { | |
if (result == 'skip') { | |
nightmare | |
.click('input[value="Пропустить"]') | |
// Ожидание перезагрузки страницы | |
.wait(function () { | |
return !document.isReloaded; | |
}, true) | |
// Проверка, существует ли div с процентом выполнения | |
.evaluate(function () { | |
var centerDiv = document.querySelector('div[align="center"]'); | |
if (centerDiv) { | |
document.isReloaded = true; | |
return true; | |
} else { | |
document.isReloaded = true; | |
return false; | |
} | |
}, function (result) { | |
// Если div не найден, то запускаем ещё одно ожидание перезагрузки | |
if (!result) { | |
console.log('complete. moving on...') | |
nightmare | |
.wait(function () { | |
return !document.isReloaded; | |
}, true); | |
} | |
}); | |
} else if (result == 'db') { | |
console.log('Canceling DB restore'); | |
skip = true; | |
nightmare | |
.click('input[value="Пропустить восстановление базы"]') | |
.wait(2000); | |
} else { | |
nightmare | |
// Ожидание перезагрузки страницы | |
.wait(function () { | |
return !document.isReloaded; | |
}, true) | |
// Проверка, существует ли форма с данными БД | |
.evaluate(function () { | |
var hostInput = document.querySelector('input[name="DBHost"]'); | |
if (hostInput) { | |
document.isReloaded = true; | |
return true; | |
} else { | |
document.isReloaded = true; | |
return false; | |
} | |
}, function (result) { | |
// Если не существует, запускаем ещё одно ожидание | |
if (!result) { | |
nightmare | |
.wait(function () { | |
return !document.isReloaded; | |
}, true); | |
} | |
}); | |
} | |
}); | |
} | |
}) | |
.wait(5000) | |
.run(function (err, nightmare) { | |
if (err) { | |
reject(err); | |
} else { | |
console.log('Backup restored'); | |
resolve(true); | |
}; | |
}); | |
}); | |
} | |
function writeDBConfigInSettings() { | |
return Q.Promise(function (resolve, reject, notify) { | |
console.log('Writing DB config in .settings.php'); | |
var filepath = './bitrix/.settings.php'; | |
fs.readFile(filepath, 'utf8', function(err, data) { | |
if (err) { | |
reject(err); | |
} | |
var result = data | |
.replace(/'host' => '[\S]+'/, "'host' => '" + dbConfig.host + "'") | |
.replace(/'database' => '[\S]+'/, "'database' => '" + dbConfig.name + "'") | |
.replace(/'login' => '[\S]+'/, "'login' => '" + dbConfig.login + "'") | |
.replace(/'password' => '[\S]+'/, "'password' => '" + dbConfig.password + "'"); | |
fs.writeFile(filepath, result, 'utf8', function(err) { | |
if (err) { | |
reject(err); | |
} else { | |
console.log('Done'); | |
resolve(true); | |
} | |
}); | |
}); | |
}); | |
} | |
function writeDBConfigInDBConn() { | |
return Q.Promise(function (resolve, reject, notify) { | |
console.log('Writing DB config in php_interface/dbconn.php'); | |
var filepath = './bitrix/php_interface/dbconn.php'; | |
fs.readFile(filepath, 'utf8', function(err, data) { | |
if (err) { | |
reject(err); | |
} | |
var result = data | |
.replace(/\$DBHost = "[\S]+"/, '$DBHost = "' + dbConfig.host + '"') | |
.replace(/\$DBLogin = "[\S]+"/, '$DBLogin = "' + dbConfig.login + '"') | |
.replace(/\$DBPassword = "[\S]+"/, '$DBPassword = "' + dbConfig.password + '"') | |
.replace(/\$DBName = "[\S]+"/, '$DBName = "' + dbConfig.name + '"'); | |
fs.writeFile(filepath, result, 'utf8', function(err) { | |
if (err) { | |
reject(err); | |
} else { | |
console.log('Done'); | |
resolve(true); | |
} | |
}); | |
}); | |
}); | |
} | |
makeBackup() | |
.then(function (backupFilename) { | |
return downloadBackup(backupFilename); | |
}) | |
.then(function (backupFilename) { | |
return restoreBackup(backupFilename) | |
}) | |
.then(function() { | |
writeDBConfigInSettings(); | |
}) | |
.then(function() { | |
writeDBConfigInDBConn(); | |
}) | |
.catch(function (error) { | |
console.log('Error: ' + error); | |
}) | |
.done(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment