mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 23:34:09 +02:00
DEV-168 - add filename reporting for installed/restored backup content
This commit is contained in:
parent
5afae43051
commit
22e71115dd
15 changed files with 120 additions and 76 deletions
|
@ -1790,8 +1790,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "installed_archive",
|
"name": "installed_content",
|
||||||
"label": "Installed Archive",
|
"label": "Installed Content",
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1799,6 +1799,16 @@
|
||||||
"content_setting": true,
|
"content_setting": true,
|
||||||
"default": ""
|
"default": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"content_setting": true,
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "creation_time",
|
||||||
|
"content_setting": true,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "install_time",
|
"name": "install_time",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
|
|
|
@ -4,10 +4,11 @@ $(document).ready(function(){
|
||||||
var RESTORE_SETTINGS_FILE_ID = 'restore-settings-file';
|
var RESTORE_SETTINGS_FILE_ID = 'restore-settings-file';
|
||||||
var UPLOAD_CONTENT_ALLOWED_DIV_ID = 'upload-content-allowed';
|
var UPLOAD_CONTENT_ALLOWED_DIV_ID = 'upload-content-allowed';
|
||||||
var UPLOAD_CONTENT_RECOVERING_DIV_ID = 'upload-content-recovering';
|
var UPLOAD_CONTENT_RECOVERING_DIV_ID = 'upload-content-recovering';
|
||||||
var INSTALLED_ARCHIVE_NAME_ID = 'installed-archive-name';
|
var INSTALLED_CONTENT_FILENAME_ID = 'installed-content-filename';
|
||||||
var INSTALLED_ARCHIVE_CREATED_ID = 'installed-archive-created';
|
var INSTALLED_CONTENT_NAME_ID = 'installed-content-name';
|
||||||
var INSTALLED_ARCHIVE_INSTALLED_ID = 'installed-archive-installed';
|
var INSTALLED_CONTENT_CREATED_ID = 'installed-content-created';
|
||||||
var INSTALLED_ARCHIVE_INSTALLED_BY_ID = 'installed-archive-installed-by';
|
var INSTALLED_CONTENT_INSTALLED_ID = 'installed-content-installed';
|
||||||
|
var INSTALLED_CONTENT_INSTALLED_BY_ID = 'installed-content-installed-by';
|
||||||
|
|
||||||
var isRestoring = false;
|
var isRestoring = false;
|
||||||
var restoreErrorShown = false;
|
var restoreErrorShown = false;
|
||||||
|
@ -114,15 +115,17 @@ $(document).ready(function(){
|
||||||
function setupInstalledContentInfo() {
|
function setupInstalledContentInfo() {
|
||||||
var html = "<table class='table table-bordered'><tbody>";
|
var html = "<table class='table table-bordered'><tbody>";
|
||||||
html += "<tr class='headers'><td class='data'><strong>Name</strong></td>";
|
html += "<tr class='headers'><td class='data'><strong>Name</strong></td>";
|
||||||
|
html += "<td class='data'><strong>File Name</strong></td>";
|
||||||
html += "<td class='data'><strong>Created</strong></td>";
|
html += "<td class='data'><strong>Created</strong></td>";
|
||||||
html += "<td class='data'><strong>Installed</strong></td>";
|
html += "<td class='data'><strong>Installed</strong></td>";
|
||||||
//html += "<td class='data'><strong>Installed By</strong></td></tr>";
|
//html += "<td class='data'><strong>Installed By</strong></td></tr>";
|
||||||
html += "<tr><td class='data' id='" + INSTALLED_ARCHIVE_NAME_ID + "'/>";
|
html += "<tr><td class='data' id='" + INSTALLED_CONTENT_NAME_ID + "'/>";
|
||||||
html += "<td class='data' id='" + INSTALLED_ARCHIVE_CREATED_ID + "'/>";
|
html += "<td class='data' id='" + INSTALLED_CONTENT_FILENAME_ID + "'/>";
|
||||||
html += "<td class='data' id='" + INSTALLED_ARCHIVE_INSTALLED_ID + "'/>";
|
html += "<td class='data' id='" + INSTALLED_CONTENT_CREATED_ID + "'/>";
|
||||||
//html += "<td class='data' id='" + INSTALLED_ARCHIVE_INSTALLED_BY_ID + "'/></tr>";
|
html += "<td class='data' id='" + INSTALLED_CONTENT_INSTALLED_ID + "'/>";
|
||||||
|
//html += "<td class='data' id='" + INSTALLED_CONTENT_INSTALLED_BY_ID + "'/></tr>";
|
||||||
html += "</tbody></table>";
|
html += "</tbody></table>";
|
||||||
$('#' + Settings.INSTALLED_ARCHIVE_INFO + ' .panel-body').html(html);
|
$('#' + Settings.INSTALLED_CONTENT + ' .panel-body').html(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle content archive or entity file upload
|
// handle content archive or entity file upload
|
||||||
|
@ -360,11 +363,11 @@ $(document).ready(function(){
|
||||||
$('#' + UPLOAD_CONTENT_ALLOWED_DIV_ID).toggle(!data.status.isRecovering);
|
$('#' + UPLOAD_CONTENT_ALLOWED_DIV_ID).toggle(!data.status.isRecovering);
|
||||||
$('#' + UPLOAD_CONTENT_RECOVERING_DIV_ID).toggle(data.status.isRecovering);
|
$('#' + UPLOAD_CONTENT_RECOVERING_DIV_ID).toggle(data.status.isRecovering);
|
||||||
|
|
||||||
|
$('#' + INSTALLED_CONTENT_NAME_ID).text(data.installed_content.name);
|
||||||
$('#' + INSTALLED_ARCHIVE_NAME_ID).text(data.installed_archive.name);
|
$('#' + INSTALLED_CONTENT_FILENAME_ID).text(data.installed_content.filename);
|
||||||
$('#' + INSTALLED_ARCHIVE_CREATED_ID).text(moment(data.installed_archive.creation_time).format('lll'));
|
$('#' + INSTALLED_CONTENT_CREATED_ID).text(data.installed_content.creation_time ? moment(data.installed_content.creation_time).format('lll') : "");
|
||||||
$('#' + INSTALLED_ARCHIVE_INSTALLED_ID).text(moment(data.installed_archive.install_time).format('lll'));
|
$('#' + INSTALLED_CONTENT_INSTALLED_ID).text(data.installed_content.install_time ? moment(data.installed_content.install_time).format('lll') : "");
|
||||||
//$('#' + INSTALLED_ARCHIVE_INSTALLED_BY_ID).text(data.current_archive.installed_by);
|
//$('#' + INSTALLED_CONTENT_INSTALLED_BY_ID).text(data.installed_content.installed_by);
|
||||||
|
|
||||||
// update the progress bars for current restore status
|
// update the progress bars for current restore status
|
||||||
if (data.status.isRecovering) {
|
if (data.status.isRecovering) {
|
||||||
|
|
|
@ -57,8 +57,8 @@ $(document).ready(function(){
|
||||||
// define extra groups to add to setting panels, with their splice index
|
// define extra groups to add to setting panels, with their splice index
|
||||||
Settings.extraContentGroupsAtIndex = {
|
Settings.extraContentGroupsAtIndex = {
|
||||||
0: {
|
0: {
|
||||||
html_id: Settings.INSTALLED_ARCHIVE_INFO,
|
html_id: Settings.INSTALLED_CONTENT,
|
||||||
label: 'Installed Archive'
|
label: 'Installed Content'
|
||||||
},
|
},
|
||||||
1: {
|
1: {
|
||||||
html_id: Settings.CONTENT_ARCHIVES_PANEL_ID,
|
html_id: Settings.CONTENT_ARCHIVES_PANEL_ID,
|
||||||
|
|
|
@ -45,7 +45,7 @@ $.extend(Settings, {
|
||||||
DATA_ROW_INDEX: 'data-row-index',
|
DATA_ROW_INDEX: 'data-row-index',
|
||||||
CONTENT_ARCHIVES_PANEL_ID: 'content_archives',
|
CONTENT_ARCHIVES_PANEL_ID: 'content_archives',
|
||||||
UPLOAD_CONTENT_BACKUP_PANEL_ID: 'upload_content',
|
UPLOAD_CONTENT_BACKUP_PANEL_ID: 'upload_content',
|
||||||
INSTALLED_ARCHIVE_INFO: 'installed_archive_info'
|
INSTALLED_CONTENT: 'installed_content'
|
||||||
});
|
});
|
||||||
|
|
||||||
var URLs = {
|
var URLs = {
|
||||||
|
|
|
@ -278,7 +278,7 @@ void AssetsBackupHandler::createBackup(const QString& backupName, QuaZip& zip) {
|
||||||
_backups.emplace_back(backupName, mappings, false);
|
_backups.emplace_back(backupName, mappings, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, QString> AssetsBackupHandler::recoverBackup(const QString& backupName, QuaZip& zip) {
|
std::pair<bool, QString> AssetsBackupHandler::recoverBackup(const QString& backupName, QuaZip& zip, const QString& sourceFilename) {
|
||||||
Q_ASSERT(QThread::currentThread() == thread());
|
Q_ASSERT(QThread::currentThread() == thread());
|
||||||
|
|
||||||
if (operationInProgress()) {
|
if (operationInProgress()) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
void loadBackup(const QString& backupName, QuaZip& zip) override;
|
void loadBackup(const QString& backupName, QuaZip& zip) override;
|
||||||
void loadingComplete() override;
|
void loadingComplete() override;
|
||||||
void createBackup(const QString& backupName, QuaZip& zip) override;
|
void createBackup(const QString& backupName, QuaZip& zip) override;
|
||||||
std::pair<bool, QString> recoverBackup(const QString& backupName, QuaZip& zip) override;
|
std::pair<bool, QString> recoverBackup(const QString& backupName, QuaZip& zip, const QString& sourceFilename) override;
|
||||||
void deleteBackup(const QString& backupName) override;
|
void deleteBackup(const QString& backupName) override;
|
||||||
void consolidateBackup(const QString& backupName, QuaZip& zip) override;
|
void consolidateBackup(const QString& backupName, QuaZip& zip) override;
|
||||||
bool isCorruptedBackup(const QString& backupName) override;
|
bool isCorruptedBackup(const QString& backupName) override;
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
virtual void loadBackup(const QString& backupName, QuaZip& zip) = 0;
|
virtual void loadBackup(const QString& backupName, QuaZip& zip) = 0;
|
||||||
virtual void loadingComplete() = 0;
|
virtual void loadingComplete() = 0;
|
||||||
virtual void createBackup(const QString& backupName, QuaZip& zip) = 0;
|
virtual void createBackup(const QString& backupName, QuaZip& zip) = 0;
|
||||||
virtual std::pair<bool, QString> recoverBackup(const QString& backupName, QuaZip& zip) = 0;
|
virtual std::pair<bool, QString> recoverBackup(const QString& backupName, QuaZip& zip, const QString& sourceFilename) = 0;
|
||||||
virtual void deleteBackup(const QString& backupName) = 0;
|
virtual void deleteBackup(const QString& backupName) = 0;
|
||||||
virtual void consolidateBackup(const QString& backupName, QuaZip& zip) = 0;
|
virtual void consolidateBackup(const QString& backupName, QuaZip& zip) = 0;
|
||||||
virtual bool isCorruptedBackup(const QString& backupName) = 0;
|
virtual bool isCorruptedBackup(const QString& backupName) = 0;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "ContentSettingsBackupHandler.h"
|
#include "ContentSettingsBackupHandler.h"
|
||||||
|
#include "DomainContentBackupManager.h"
|
||||||
|
|
||||||
#if !defined(__clang__) && defined(__GNUC__)
|
#if !defined(__clang__) && defined(__GNUC__)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
@ -32,10 +33,12 @@ ContentSettingsBackupHandler::ContentSettingsBackupHandler(DomainServerSettingsM
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QString CONTENT_SETTINGS_BACKUP_FILENAME = "content-settings.json";
|
static const QString CONTENT_SETTINGS_BACKUP_FILENAME = "content-settings.json";
|
||||||
static const QString INSTALLED_ARCHIVE = "installed_archive";
|
static const QString INSTALLED_CONTENT = "installed_content";
|
||||||
static const QString INSTALLED_ARCHIVE_FILENAME = "filename";
|
static const QString INSTALLED_CONTENT_FILENAME = "filename";
|
||||||
static const QString INSTALLED_ARCHIVE_INSTALL_TIME = "install_time";
|
static const QString INSTALLED_CONTENT_NAME = "name";
|
||||||
static const QString INSTALLED_ARCHIVE_INSTALLED_BY = "installed_by";
|
static const QString INSTALLED_CONTENT_CREATION_TIME = "creation_time";
|
||||||
|
static const QString INSTALLED_CONTENT_INSTALL_TIME = "install_time";
|
||||||
|
static const QString INSTALLED_CONTENT_INSTALLED_BY = "installed_by";
|
||||||
|
|
||||||
void ContentSettingsBackupHandler::createBackup(const QString& backupName, QuaZip& zip) {
|
void ContentSettingsBackupHandler::createBackup(const QString& backupName, QuaZip& zip) {
|
||||||
|
|
||||||
|
@ -46,15 +49,26 @@ void ContentSettingsBackupHandler::createBackup(const QString& backupName, QuaZi
|
||||||
DomainServerSettingsManager::IncludeContentSettings, DomainServerSettingsManager::NoDefaultSettings,
|
DomainServerSettingsManager::IncludeContentSettings, DomainServerSettingsManager::NoDefaultSettings,
|
||||||
DomainServerSettingsManager::ForBackup
|
DomainServerSettingsManager::ForBackup
|
||||||
);
|
);
|
||||||
|
QString prefixFormat = "(" + QRegExp::escape(AUTOMATIC_BACKUP_PREFIX) + "|" + QRegExp::escape(MANUAL_BACKUP_PREFIX) + ")";
|
||||||
|
QString nameFormat = "(.+)";
|
||||||
|
QString dateTimeFormat = "(" + DATETIME_FORMAT_RE + ")";
|
||||||
|
QRegExp backupNameFormat { prefixFormat + nameFormat + "-" + dateTimeFormat + "\\.zip" };
|
||||||
|
|
||||||
// save the filename internally as it's used to determine the name/creation time
|
QString name{ "" };
|
||||||
// of the archive, and we don't want that to change if the actual file is renamed
|
QDateTime createdAt;
|
||||||
// after download.
|
|
||||||
QJsonObject installed_archive {
|
if (backupNameFormat.exactMatch(backupName)) {
|
||||||
{ INSTALLED_ARCHIVE_FILENAME, backupName },
|
name = backupNameFormat.cap(2);
|
||||||
|
auto dateTime = backupNameFormat.cap(3);
|
||||||
|
createdAt = QDateTime::fromString(dateTime, DATETIME_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject installed_content {
|
||||||
|
{ INSTALLED_CONTENT_NAME, name},
|
||||||
|
{ INSTALLED_CONTENT_CREATION_TIME, createdAt.currentMSecsSinceEpoch()}
|
||||||
};
|
};
|
||||||
|
|
||||||
contentSettingsJSON.insert(INSTALLED_ARCHIVE, installed_archive);
|
contentSettingsJSON.insert(INSTALLED_CONTENT, installed_content);
|
||||||
|
|
||||||
// make a QJsonDocument using the object
|
// make a QJsonDocument using the object
|
||||||
QJsonDocument contentSettingsDocument { contentSettingsJSON };
|
QJsonDocument contentSettingsDocument { contentSettingsJSON };
|
||||||
|
@ -76,7 +90,7 @@ void ContentSettingsBackupHandler::createBackup(const QString& backupName, QuaZi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, QString> ContentSettingsBackupHandler::recoverBackup(const QString& backupName, QuaZip& zip) {
|
std::pair<bool, QString> ContentSettingsBackupHandler::recoverBackup(const QString& backupName, QuaZip& zip, const QString& sourceFilename) {
|
||||||
if (!zip.setCurrentFile(CONTENT_SETTINGS_BACKUP_FILENAME)) {
|
if (!zip.setCurrentFile(CONTENT_SETTINGS_BACKUP_FILENAME)) {
|
||||||
QString errorStr("Failed to find " + CONTENT_SETTINGS_BACKUP_FILENAME + " while recovering backup");
|
QString errorStr("Failed to find " + CONTENT_SETTINGS_BACKUP_FILENAME + " while recovering backup");
|
||||||
qWarning() << errorStr;
|
qWarning() << errorStr;
|
||||||
|
@ -102,15 +116,17 @@ std::pair<bool, QString> ContentSettingsBackupHandler::recoverBackup(const QStri
|
||||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(rawData);
|
QJsonDocument jsonDocument = QJsonDocument::fromJson(rawData);
|
||||||
QJsonObject jsonObject = jsonDocument.object();
|
QJsonObject jsonObject = jsonDocument.object();
|
||||||
|
|
||||||
auto archiveJson = jsonObject.find(INSTALLED_ARCHIVE)->toObject();
|
auto archiveJson = jsonObject.find(INSTALLED_CONTENT)->toObject();
|
||||||
|
|
||||||
QJsonObject installed_archive {
|
QJsonObject installed_content {
|
||||||
{ INSTALLED_ARCHIVE_FILENAME, archiveJson[INSTALLED_ARCHIVE_FILENAME]},
|
{ INSTALLED_CONTENT_FILENAME, sourceFilename },
|
||||||
{ INSTALLED_ARCHIVE_INSTALL_TIME, QDateTime::currentDateTime().currentMSecsSinceEpoch() },
|
{ INSTALLED_CONTENT_NAME, archiveJson[INSTALLED_CONTENT_NAME].toString()},
|
||||||
{ INSTALLED_ARCHIVE_INSTALLED_BY, ""}
|
{ INSTALLED_CONTENT_CREATION_TIME, archiveJson[INSTALLED_CONTENT_CREATION_TIME].toVariant().toLongLong() },
|
||||||
|
{ INSTALLED_CONTENT_INSTALL_TIME, QDateTime::currentDateTime().currentMSecsSinceEpoch() },
|
||||||
|
{ INSTALLED_CONTENT_INSTALLED_BY, "" }
|
||||||
};
|
};
|
||||||
|
|
||||||
jsonObject.insert(INSTALLED_ARCHIVE, installed_archive);
|
jsonObject.insert(INSTALLED_CONTENT, installed_content);
|
||||||
|
|
||||||
if (!_settingsManager.restoreSettingsFromObject(jsonObject, ContentSettings)) {
|
if (!_settingsManager.restoreSettingsFromObject(jsonObject, ContentSettings)) {
|
||||||
QString errorStr("Failed to restore settings from " + CONTENT_SETTINGS_BACKUP_FILENAME + " in content archive");
|
QString errorStr("Failed to restore settings from " + CONTENT_SETTINGS_BACKUP_FILENAME + " in content archive");
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
|
|
||||||
void createBackup(const QString& backupName, QuaZip& zip) override;
|
void createBackup(const QString& backupName, QuaZip& zip) override;
|
||||||
|
|
||||||
std::pair<bool, QString> recoverBackup(const QString& backupName, QuaZip& zip) override;
|
std::pair<bool, QString> recoverBackup(const QString& backupName, QuaZip& zip, const QString& sourceFilename) override;
|
||||||
|
|
||||||
void deleteBackup(const QString& backupName) override {}
|
void deleteBackup(const QString& backupName) override {}
|
||||||
|
|
||||||
|
|
|
@ -42,9 +42,6 @@ const std::chrono::seconds DomainContentBackupManager::DEFAULT_PERSIST_INTERVAL
|
||||||
|
|
||||||
// Backup format looks like: daily_backup-TIMESTAMP.zip
|
// Backup format looks like: daily_backup-TIMESTAMP.zip
|
||||||
static const QString DATETIME_FORMAT { "yyyy-MM-dd_HH-mm-ss" };
|
static const QString DATETIME_FORMAT { "yyyy-MM-dd_HH-mm-ss" };
|
||||||
static const QString DATETIME_FORMAT_RE { "\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}" };
|
|
||||||
static const QString AUTOMATIC_BACKUP_PREFIX { "autobackup-" };
|
|
||||||
static const QString MANUAL_BACKUP_PREFIX { "backup-" };
|
|
||||||
static const QString PRE_UPLOAD_SUFFIX{ "pre_upload" };
|
static const QString PRE_UPLOAD_SUFFIX{ "pre_upload" };
|
||||||
static const QString MANUAL_BACKUP_NAME_RE { "[a-zA-Z0-9\\-_ ]+" };
|
static const QString MANUAL_BACKUP_NAME_RE { "[a-zA-Z0-9\\-_ ]+" };
|
||||||
|
|
||||||
|
@ -282,7 +279,7 @@ void DomainContentBackupManager::deleteBackup(MiniPromise::Promise promise, cons
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DomainContentBackupManager::recoverFromBackupZip(const QString& backupName, QuaZip& zip, bool rollingBack) {
|
bool DomainContentBackupManager::recoverFromBackupZip(const QString& backupName, QuaZip& zip, const QString& sourceFilename, bool rollingBack) {
|
||||||
if (!zip.open(QuaZip::Mode::mdUnzip)) {
|
if (!zip.open(QuaZip::Mode::mdUnzip)) {
|
||||||
qWarning() << "Failed to unzip file: " << backupName;
|
qWarning() << "Failed to unzip file: " << backupName;
|
||||||
return false;
|
return false;
|
||||||
|
@ -293,7 +290,7 @@ bool DomainContentBackupManager::recoverFromBackupZip(const QString& backupName,
|
||||||
for (auto& handler : _backupHandlers) {
|
for (auto& handler : _backupHandlers) {
|
||||||
bool success;
|
bool success;
|
||||||
QString errorStr;
|
QString errorStr;
|
||||||
std::tie(success, errorStr) = handler->recoverBackup(backupName, zip);
|
std::tie(success, errorStr) = handler->recoverBackup(backupName, zip, sourceFilename);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
if (!rollingBack) {
|
if (!rollingBack) {
|
||||||
_recoveryError = errorStr;
|
_recoveryError = errorStr;
|
||||||
|
@ -330,7 +327,7 @@ void DomainContentBackupManager::recoverFromBackup(MiniPromise::Promise promise,
|
||||||
if (backupFile.open(QIODevice::ReadOnly)) {
|
if (backupFile.open(QIODevice::ReadOnly)) {
|
||||||
QuaZip zip { &backupFile };
|
QuaZip zip { &backupFile };
|
||||||
|
|
||||||
success = recoverFromBackupZip(backupName, zip);
|
success = recoverFromBackupZip(backupName, zip, backupName);
|
||||||
|
|
||||||
backupFile.close();
|
backupFile.close();
|
||||||
} else {
|
} else {
|
||||||
|
@ -358,21 +355,21 @@ void DomainContentBackupManager::recoverFromUploadedBackup(MiniPromise::Promise
|
||||||
QuaZip uploadedZip { &uploadedBackupBuffer };
|
QuaZip uploadedZip { &uploadedBackupBuffer };
|
||||||
|
|
||||||
QString backupName = MANUAL_BACKUP_PREFIX + "uploaded.zip";
|
QString backupName = MANUAL_BACKUP_PREFIX + "uploaded.zip";
|
||||||
bool success = recoverFromBackupZip(backupName, uploadedZip);
|
bool success = recoverFromBackupZip(backupName, uploadedZip, QString());
|
||||||
|
|
||||||
promise->resolve({
|
promise->resolve({
|
||||||
{ "success", success }
|
{ "success", success }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainContentBackupManager::recoverFromUploadedFile(MiniPromise::Promise promise, QString uploadedFilename) {
|
void DomainContentBackupManager::recoverFromUploadedFile(MiniPromise::Promise promise, QString uploadedFilename, QString sourceFilename) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(this, "recoverFromUploadedFile", Q_ARG(MiniPromise::Promise, promise),
|
QMetaObject::invokeMethod(this, "recoverFromUploadedFile", Q_ARG(MiniPromise::Promise, promise),
|
||||||
Q_ARG(QString, uploadedFilename));
|
Q_ARG(QString, uploadedFilename), Q_ARG(QString, sourceFilename));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Recovering from uploaded file -" << uploadedFilename;
|
qDebug() << "Recovering from uploaded file -" << uploadedFilename << "source" << sourceFilename;
|
||||||
bool success;
|
bool success;
|
||||||
QString path;
|
QString path;
|
||||||
std::tie(success, path) = createBackup(AUTOMATIC_BACKUP_PREFIX, PRE_UPLOAD_SUFFIX);
|
std::tie(success, path) = createBackup(AUTOMATIC_BACKUP_PREFIX, PRE_UPLOAD_SUFFIX);
|
||||||
|
@ -385,7 +382,7 @@ void DomainContentBackupManager::recoverFromUploadedFile(MiniPromise::Promise pr
|
||||||
|
|
||||||
QString backupName = MANUAL_BACKUP_PREFIX + "uploaded.zip";
|
QString backupName = MANUAL_BACKUP_PREFIX + "uploaded.zip";
|
||||||
|
|
||||||
bool success = recoverFromBackupZip(backupName, uploadedZip);
|
bool success = recoverFromBackupZip(backupName, uploadedZip, sourceFilename);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
|
||||||
|
@ -397,7 +394,7 @@ void DomainContentBackupManager::recoverFromUploadedFile(MiniPromise::Promise pr
|
||||||
QuaZip uploadedZip { &uploadedFile };
|
QuaZip uploadedZip { &uploadedFile };
|
||||||
|
|
||||||
QString backupName = MANUAL_BACKUP_PREFIX + "uploaded.zip";
|
QString backupName = MANUAL_BACKUP_PREFIX + "uploaded.zip";
|
||||||
recoverFromBackupZip(backupName, uploadedZip, true);
|
recoverFromBackupZip(backupName, uploadedZip, sourceFilename, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,28 +491,40 @@ void DomainContentBackupManager::getAllBackupsAndStatus(MiniPromise::Promise pro
|
||||||
status["recoveryError"] = _recoveryError;
|
status["recoveryError"] = _recoveryError;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap currentArchive;
|
|
||||||
|
|
||||||
QString fileName = _settingsManager.valueForKeyPath(CONTENT_SETTINGS_ARCHIVE_FILENAME).toString();
|
QString filename = _settingsManager.valueForKeyPath(CONTENT_SETTINGS_INSTALLED_CONTENT_FILENAME).toString();
|
||||||
QString prefixFormat = "(" + QRegExp::escape(AUTOMATIC_BACKUP_PREFIX) + "|" + QRegExp::escape(MANUAL_BACKUP_PREFIX) + ")";
|
QString name = _settingsManager.valueForKeyPath(CONTENT_SETTINGS_INSTALLED_CONTENT_NAME).toString();
|
||||||
QString nameFormat = "(.+)";
|
auto creationTime = _settingsManager.valueForKeyPath(CONTENT_SETTINGS_INSTALLED_CONTENT_CREATION_TIME).toULongLong();
|
||||||
QString dateTimeFormat = "(" + DATETIME_FORMAT_RE + ")";
|
|
||||||
QRegExp backupNameFormat { prefixFormat + nameFormat + "-" + dateTimeFormat + "\\.zip" };
|
if (name.isEmpty() || creationTime == 0) {
|
||||||
if (backupNameFormat.exactMatch(fileName)) {
|
QString prefixFormat = "(" + QRegExp::escape(AUTOMATIC_BACKUP_PREFIX) + "|" + QRegExp::escape(MANUAL_BACKUP_PREFIX) + ")";
|
||||||
auto type = backupNameFormat.cap(1);
|
QString nameFormat = "(.+)";
|
||||||
auto name = backupNameFormat.cap(2);
|
QString dateTimeFormat = "(" + DATETIME_FORMAT_RE + ")";
|
||||||
auto dateTime = backupNameFormat.cap(3);
|
QRegExp backupNameFormat { prefixFormat + nameFormat + "-" + dateTimeFormat + "\\.zip" };
|
||||||
auto createdAt = QDateTime::fromString(dateTime, DATETIME_FORMAT);
|
|
||||||
currentArchive["name"] = name;
|
|
||||||
currentArchive["creation_time"] = createdAt.toMSecsSinceEpoch();
|
if (backupNameFormat.exactMatch(filename)) {
|
||||||
currentArchive["install_time"] = _settingsManager.valueForKeyPath(CONTENT_SETTINGS_ARCHIVE_INSTALL_TIME).toULongLong();
|
if (name.isEmpty()) {
|
||||||
currentArchive["installed_by"] = _settingsManager.valueForKeyPath(CONTENT_SETTINGS_ARCHIVE_INSTALLED_BY).toString();
|
name = backupNameFormat.cap(2);
|
||||||
|
}
|
||||||
|
if (creationTime == 0) {
|
||||||
|
auto dateTime = backupNameFormat.cap(3);
|
||||||
|
creationTime = QDateTime::fromString(dateTime, DATETIME_FORMAT).toMSecsSinceEpoch();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap currentArchive;
|
||||||
|
currentArchive["filename"] = filename;
|
||||||
|
currentArchive["name"] = name;
|
||||||
|
currentArchive["creation_time"] = creationTime;
|
||||||
|
currentArchive["install_time"] = _settingsManager.valueForKeyPath(CONTENT_SETTINGS_INSTALLED_CONTENT_INSTALL_TIME).toULongLong();
|
||||||
|
currentArchive["installed_by"] = _settingsManager.valueForKeyPath(CONTENT_SETTINGS_INSTALLED_CONTENT_INSTALLED_BY).toString();
|
||||||
|
|
||||||
QVariantMap info {
|
QVariantMap info {
|
||||||
{ "backups", variantBackups },
|
{ "backups", variantBackups },
|
||||||
{ "status", status },
|
{ "status", status },
|
||||||
{ "installed_archive", currentArchive }
|
{ "installed_content", currentArchive }
|
||||||
};
|
};
|
||||||
|
|
||||||
promise->resolve(info);
|
promise->resolve(info);
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
|
|
||||||
#include <PortableHighResolutionClock.h>
|
#include <PortableHighResolutionClock.h>
|
||||||
|
|
||||||
|
const QString DATETIME_FORMAT_RE { "\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}" };
|
||||||
|
const QString AUTOMATIC_BACKUP_PREFIX { "autobackup-" };
|
||||||
|
const QString MANUAL_BACKUP_PREFIX { "backup-" };
|
||||||
|
|
||||||
struct BackupItemInfo {
|
struct BackupItemInfo {
|
||||||
BackupItemInfo(QString pId, QString pName, QString pAbsolutePath, QDateTime pCreatedAt, bool pIsManualBackup) :
|
BackupItemInfo(QString pId, QString pName, QString pAbsolutePath, QDateTime pCreatedAt, bool pIsManualBackup) :
|
||||||
id(pId), name(pName), absolutePath(pAbsolutePath), createdAt(pCreatedAt), isManualBackup(pIsManualBackup) { };
|
id(pId), name(pName), absolutePath(pAbsolutePath), createdAt(pCreatedAt), isManualBackup(pIsManualBackup) { };
|
||||||
|
@ -87,7 +91,7 @@ public slots:
|
||||||
void createManualBackup(MiniPromise::Promise promise, const QString& name);
|
void createManualBackup(MiniPromise::Promise promise, const QString& name);
|
||||||
void recoverFromBackup(MiniPromise::Promise promise, const QString& backupName);
|
void recoverFromBackup(MiniPromise::Promise promise, const QString& backupName);
|
||||||
void recoverFromUploadedBackup(MiniPromise::Promise promise, QByteArray uploadedBackup);
|
void recoverFromUploadedBackup(MiniPromise::Promise promise, QByteArray uploadedBackup);
|
||||||
void recoverFromUploadedFile(MiniPromise::Promise promise, QString uploadedFilename);
|
void recoverFromUploadedFile(MiniPromise::Promise promise, QString uploadedFilename, QString sourceFilename);
|
||||||
void deleteBackup(MiniPromise::Promise promise, const QString& backupName);
|
void deleteBackup(MiniPromise::Promise promise, const QString& backupName);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -109,7 +113,7 @@ protected:
|
||||||
|
|
||||||
std::pair<bool, QString> createBackup(const QString& prefix, const QString& name);
|
std::pair<bool, QString> createBackup(const QString& prefix, const QString& name);
|
||||||
|
|
||||||
bool recoverFromBackupZip(const QString& backupName, QuaZip& backupZip, bool rollingBack = false);
|
bool recoverFromBackupZip(const QString& backupName, QuaZip& backupZip, const QString& sourceFilename, bool rollingBack = false);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void removeOldConsolidatedBackups();
|
void removeOldConsolidatedBackups();
|
||||||
|
|
|
@ -2591,7 +2591,7 @@ bool DomainServer::processPendingContent(HTTPConnection* connection, QString ite
|
||||||
_pendingContentFiles.erase(sessionId);
|
_pendingContentFiles.erase(sessionId);
|
||||||
});
|
});
|
||||||
|
|
||||||
_contentManager->recoverFromUploadedFile(deferred, _pendingFileContent.fileName());
|
_contentManager->recoverFromUploadedFile(deferred, _pendingFileContent.fileName(), filename);
|
||||||
}
|
}
|
||||||
} else if (filename.endsWith(".json", Qt::CaseInsensitive)
|
} else if (filename.endsWith(".json", Qt::CaseInsensitive)
|
||||||
|| filename.endsWith(".json.gz", Qt::CaseInsensitive)) {
|
|| filename.endsWith(".json.gz", Qt::CaseInsensitive)) {
|
||||||
|
|
|
@ -35,9 +35,11 @@ const QString MACHINE_FINGERPRINT_PERMISSIONS_KEYPATH = "security.machine_finger
|
||||||
const QString GROUP_PERMISSIONS_KEYPATH = "security.group_permissions";
|
const QString GROUP_PERMISSIONS_KEYPATH = "security.group_permissions";
|
||||||
const QString GROUP_FORBIDDENS_KEYPATH = "security.group_forbiddens";
|
const QString GROUP_FORBIDDENS_KEYPATH = "security.group_forbiddens";
|
||||||
const QString AUTOMATIC_CONTENT_ARCHIVES_GROUP = "automatic_content_archives";
|
const QString AUTOMATIC_CONTENT_ARCHIVES_GROUP = "automatic_content_archives";
|
||||||
const QString CONTENT_SETTINGS_ARCHIVE_FILENAME = "installed_archive.filename";
|
const QString CONTENT_SETTINGS_INSTALLED_CONTENT_FILENAME = "installed_content.filename";
|
||||||
const QString CONTENT_SETTINGS_ARCHIVE_INSTALL_TIME = "installed_archive.install_time";
|
const QString CONTENT_SETTINGS_INSTALLED_CONTENT_NAME = "installed_content.name";
|
||||||
const QString CONTENT_SETTINGS_ARCHIVE_INSTALLED_BY = "installed_archive.installed_by";
|
const QString CONTENT_SETTINGS_INSTALLED_CONTENT_CREATION_TIME = "installed_content.creation_time";
|
||||||
|
const QString CONTENT_SETTINGS_INSTALLED_CONTENT_INSTALL_TIME = "installed_content.install_time";
|
||||||
|
const QString CONTENT_SETTINGS_INSTALLED_CONTENT_INSTALLED_BY = "installed_content.installed_by";
|
||||||
|
|
||||||
using GroupByUUIDKey = QPair<QUuid, QUuid>; // groupID, rankID
|
using GroupByUUIDKey = QPair<QUuid, QUuid>; // groupID, rankID
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ void EntitiesBackupHandler::createBackup(const QString& backupName, QuaZip& zip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, QString> EntitiesBackupHandler::recoverBackup(const QString& backupName, QuaZip& zip) {
|
std::pair<bool, QString> EntitiesBackupHandler::recoverBackup(const QString& backupName, QuaZip& zip, const QString& sourceFilename) {
|
||||||
if (!zip.setCurrentFile(ENTITIES_BACKUP_FILENAME)) {
|
if (!zip.setCurrentFile(ENTITIES_BACKUP_FILENAME)) {
|
||||||
QString errorStr("Failed to find " + ENTITIES_BACKUP_FILENAME + " while recovering backup");
|
QString errorStr("Failed to find " + ENTITIES_BACKUP_FILENAME + " while recovering backup");
|
||||||
qWarning() << errorStr;
|
qWarning() << errorStr;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
void createBackup(const QString& backupName, QuaZip& zip) override;
|
void createBackup(const QString& backupName, QuaZip& zip) override;
|
||||||
|
|
||||||
// Recover from a full backup
|
// Recover from a full backup
|
||||||
std::pair<bool, QString> recoverBackup(const QString& backupName, QuaZip& zip) override;
|
std::pair<bool, QString> recoverBackup(const QString& backupName, QuaZip& zip, const QString& sourceFilename) override;
|
||||||
|
|
||||||
// Delete a skeleton backup
|
// Delete a skeleton backup
|
||||||
void deleteBackup(const QString& backupName) override {}
|
void deleteBackup(const QString& backupName) override {}
|
||||||
|
|
Loading…
Reference in a new issue