From 3bf19713958788aa566b37c4ebae2147ef340f08 Mon Sep 17 00:00:00 2001 From: Peter Sykora Date: Tue, 1 May 2018 16:31:07 +0200 Subject: [PATCH] [impl] Logging, Better progress tracking --- CCEngine/CCEngine.ui | 8 +-- CCEngine/CCEngine.vcxproj | 3 + CCEngine/src/CCEngine.cpp | 60 +++++++++++++++++-- CCEngine/src/CCEngine.h | 3 + CCEngine/src/CCLicenseController.cpp | 90 +++++++++++++++++++++++++++- CCEngine/src/CCLicenseController.h | 6 +- CCEngine/src/main.cpp | 31 ++++++++++ CCEngineLoader/CCEngineLoader.cpp | 7 ++- CCEngineLoader/CCEngineLoader.h | 2 +- CCEngineLoader/UpdateWorker.cpp | 9 ++- CCEngineLoader/UpdateWorker.h | 5 +- 11 files changed, 206 insertions(+), 18 deletions(-) diff --git a/CCEngine/CCEngine.ui b/CCEngine/CCEngine.ui index 147a000..a28aa07 100644 --- a/CCEngine/CCEngine.ui +++ b/CCEngine/CCEngine.ui @@ -59,7 +59,7 @@ - 140 + 160 20 70 20 @@ -78,7 +78,7 @@ - 220 + 240 20 70 20 @@ -148,7 +148,7 @@ - 140 + 160 50 101 20 @@ -199,7 +199,7 @@ - 140 + 160 20 101 20 diff --git a/CCEngine/CCEngine.vcxproj b/CCEngine/CCEngine.vcxproj index 26a62c1..db7e1b2 100644 --- a/CCEngine/CCEngine.vcxproj +++ b/CCEngine/CCEngine.vcxproj @@ -144,6 +144,9 @@ {51345e59-83e5-4389-93a9-0131b40522b7} + + {b12702ad-abfb-343a-a199-8e24837244a3} + diff --git a/CCEngine/src/CCEngine.cpp b/CCEngine/src/CCEngine.cpp index 194cf18..4db178b 100644 --- a/CCEngine/src/CCEngine.cpp +++ b/CCEngine/src/CCEngine.cpp @@ -7,7 +7,8 @@ #include #include #include -#include +#include +#include #include @@ -40,10 +41,12 @@ CCEngine::CCEngine( timer->start(0); // Connect UI + connect(ui.btnActivate, SIGNAL(clicked(bool)), this, SLOT(onActivate(bool))); connect(ui.btnActivationDetail, SIGNAL(clicked(bool)), this, SLOT(onActivationDetail(bool))); connect(ui.btnRestartServer, SIGNAL(clicked(bool)), this, SLOT(onRestartServer(bool))); connect(ui.btnOpenBrowser, SIGNAL(clicked(bool)), this, SLOT(onOpenBrowser(bool))); connect(ui.btnUpdatesCheck, SIGNAL(clicked(bool)), this, SLOT(onCheckForUpdates(bool))); + connect(ui.btnUpdate, SIGNAL(clicked(bool)), this, SLOT(onInstallUpdates(bool))); } CCEngine::~CCEngine() @@ -96,6 +99,18 @@ void CCEngine::onLoad() m_licenseController.init(m_appPath); } +void CCEngine::onActivate(bool) +{ + bool ok; + QString text = QInputDialog::getText(this, tr("Enter license number"), + tr("License number (example. ABC1-DEF2-GHI3-JKL4-MNO5-PQR6):"), QLineEdit::Normal, QString(), &ok,Qt::WindowFlags(), Qt::ImhPreferUppercase | Qt::ImhNoPredictiveText); + + if (ok && !text.isEmpty()) + { + m_licenseController.activate(text); + } +} + void CCEngine::onRestartServer(bool) { if (m_licenseController.isActivated()) @@ -131,6 +146,19 @@ void CCEngine::onCheckForUpdates(bool) } } +void CCEngine::onInstallUpdates(bool) +{ + if (m_licenseController.isActivated()) + { + auto reply = QMessageBox::question(this, "Confirm", "Are you sure to download and install updates?
After the downloades are updated the application might need to be restarted. Please confirm to continue.", + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::Yes) + { + m_licenseController.installUpdates(m_appPath); + } + } +} + void CCEngine::onParamsLoaded(SystemParams hashedParams, SystemParams origParams) { @@ -147,11 +175,11 @@ void CCEngine::onActivationStatusChanged(ActivationStatus activationStatus) color = "green"; break; case ActivationStatus::checkingPreactivation: - textStatus = tr("Checking"); + textStatus = tr("Checking..."); color = "orange"; break; case ActivationStatus::checkingActivation: - textStatus = tr("Verifying license"); + textStatus = tr("Verifying license..."); color = "orange"; break; case ActivationStatus::notActive: @@ -199,7 +227,7 @@ void CCEngine::onUpdatesStatusChanged(UpdatesStatus updatesStatus) color = "green"; break; case UpdatesStatus::checking: - textStatus = tr("Checking"); + textStatus = tr("Checking..."); color = "orange"; break; case UpdatesStatus::updatesAvailable: @@ -207,6 +235,14 @@ void CCEngine::onUpdatesStatusChanged(UpdatesStatus updatesStatus) color = "orange"; updateEnabled = true; break; + case UpdatesStatus::downloadingUpdates: + textStatus = tr("Downloading..."); + color = "orange"; + break; + case UpdatesStatus::installingUpdates: + textStatus = tr("Installing..."); + color = "orange"; + break; default: textStatus = tr("Unknown"); color = "black"; @@ -220,6 +256,19 @@ void CCEngine::onUpdates(int count, bool restartRequired) { ui.lblUpdatesPendingVal->setText(QString("%1").arg(count)); ui.lblUpdatesPendingVal->setStyleSheet(QString("QLabel { color: %1; }").arg((count > 0) ? "orange" : "green")); + + if (count > 0) + { + if (qApp->activeWindow() == nullptr && qApp->focusWidget() == nullptr) + { + trayIcon->showMessage("CCEngine", tr("Updates found. Please open the application and click \"Update\" to install them.")); + } + } +} + +void CCEngine::onShutdownRequest() +{ + qApp->quit(); } void CCEngine::iconActivated(QSystemTrayIcon::ActivationReason reason) @@ -280,4 +329,7 @@ void CCEngine::connectLicenseController() connect( &m_licenseController, SIGNAL(updates(int, bool)), this, SLOT(onUpdates(int, bool))); + connect( + &m_licenseController, SIGNAL(shutdownRequest()), + this, SLOT(onShutdownRequest())); } diff --git a/CCEngine/src/CCEngine.h b/CCEngine/src/CCEngine.h index 868259c..3478f16 100644 --- a/CCEngine/src/CCEngine.h +++ b/CCEngine/src/CCEngine.h @@ -33,10 +33,12 @@ private slots: void iconActivated(QSystemTrayIcon::ActivationReason reason); void onCCServerStatusUpdate(CCServerStatus serverStatus); void onLoad(); + void onActivate(bool); void onActivationDetail(bool); void onRestartServer(bool); void onOpenBrowser(bool); void onCheckForUpdates(bool); + void onInstallUpdates(bool); // License controller signal handlers void onParamsLoaded(SystemParams hashedParams, SystemParams origParams); @@ -45,6 +47,7 @@ private slots: void onActivated(QString activationNumber); void onUpdatesStatusChanged(UpdatesStatus updatesStatus); void onUpdates(int count, bool restartRequired); + void onShutdownRequest(); private: void createActions(); diff --git a/CCEngine/src/CCLicenseController.cpp b/CCEngine/src/CCLicenseController.cpp index 238efbe..c7f18ee 100644 --- a/CCEngine/src/CCLicenseController.cpp +++ b/CCEngine/src/CCLicenseController.cpp @@ -1,9 +1,17 @@ #include "CCLicenseController.h" +#include "CachedDownloader.h" #include "JSONModuleDatabase.h" +#include "JSONSerialization.h" +#include "ProcessUtils.h" #include +namespace +{ + static const std::string updateCacheFolder = ".upd"; +} + CCLicenseController::CCLicenseController() {} @@ -21,7 +29,7 @@ void CCLicenseController::init(const boost::filesystem::path& appDir) { m_workerThread.join(); } - m_workerThread = std::thread([&]() + m_workerThread = std::thread([this, appDir]() { std::lock_guard lockGuard(m_exclusiveWorkerMutex); try @@ -69,7 +77,7 @@ void CCLicenseController::activate(const QString &licenseNumber) { m_workerThread.join(); } - m_workerThread = std::thread([&]() + m_workerThread = std::thread([this, licenseNumber]() { std::lock_guard lockGuard(m_exclusiveWorkerMutex); @@ -116,7 +124,7 @@ void CCLicenseController::checkForUpdates() { m_workerThread.join(); } - m_workerThread = std::thread([&]() + m_workerThread = std::thread([this]() { std::lock_guard lockGuard(m_exclusiveWorkerMutex); @@ -145,7 +153,83 @@ void CCLicenseController::checkForUpdates() catch (CouldNotConnectException&) { BOOST_LOG_TRIVIAL(error) << "The application could not check for updates. Probably the computer is offline"; + emit updatesStatusChanged(UpdatesStatus::unknown); emit errorMessage("Could not check for updates as the computer seem offline. Please try again later."); } + catch (std::runtime_error& e) + { + BOOST_LOG_TRIVIAL(error) << "Error during checking for updates: " << e.what(); + emit updatesStatusChanged(UpdatesStatus::unknown); + emit errorMessage("Could not check for updates. Please contact support!"); + } + }); +} + +void CCLicenseController::installUpdates(const boost::filesystem::path& appDir) +{ + if (m_workerThread.joinable()) + { + m_workerThread.join(); + } + m_workerThread = std::thread([this, appDir]() + { + std::lock_guard lockGuard(m_exclusiveWorkerMutex); + + if (m_moduleUpdates.size() < 0) + { + return; + } + emit updatesStatusChanged(UpdatesStatus::downloadingUpdates); + try + { + CachedDownloader cachedDownloader(appDir / updateCacheFolder, m_httpClient); + for (const auto& update : m_moduleUpdates) + { + cachedDownloader.download(update.updateUri); + } + BOOST_LOG_TRIVIAL(info) << "Updates downloaded successfully"; + } + catch (CouldNotConnectException&) + { + BOOST_LOG_TRIVIAL(error) << "Could not download updates. Probably the computer is offline"; + emit errorMessage("The updates could not be downloaded probably due to not working internet connection!"); + } + + { + emit updatesStatusChanged(UpdatesStatus::installingUpdates); + + { + std::ofstream os((appDir / updateCacheFolder / ".updates.json").native()); + ::serialize(os, m_moduleUpdates); + } + + std::ostringstream command; + command << (appDir / "CCEngineLoader.exe") << " " << getCurrentProcessId(); + + auto stdOutPipe = createAnonymousPipe(false, true); + auto updProcess = createPipedProcess(command.str(), nullptr, std::move(stdOutPipe)); + + while (!updProcess.processHandle->waitForExit(std::chrono::milliseconds(0))) + { + auto line = updProcess.readLine(); + std::cout << line << std::endl; + if (line == "RestartRequired") + { + emit shutdownRequest(); + } + if (line == "Done") + { + BOOST_LOG_TRIVIAL(info) << "The system has been updated successfully"; + emit updatesStatusChanged(UpdatesStatus::upToDate); + emit updates(0, false); + updProcess.processHandle->waitForExit(); + return; + } + } + + emit updatesStatusChanged(UpdatesStatus::unknown); + BOOST_LOG_TRIVIAL(error) << "Failure happend during updates installation"; + } + }); } diff --git a/CCEngine/src/CCLicenseController.h b/CCEngine/src/CCLicenseController.h index c757bb6..5570141 100644 --- a/CCEngine/src/CCLicenseController.h +++ b/CCEngine/src/CCLicenseController.h @@ -27,7 +27,9 @@ enum class UpdatesStatus unknown, checking, upToDate, - updatesAvailable + updatesAvailable, + downloadingUpdates, + installingUpdates }; Q_DECLARE_METATYPE(UpdatesStatus); @@ -45,6 +47,7 @@ public: void activate(const QString& licenseNumber); bool isActivated(); void checkForUpdates(); + void installUpdates(const boost::filesystem::path& appDir); public: signals: @@ -54,6 +57,7 @@ signals: void activated(QString activationNumber); void updatesStatusChanged(UpdatesStatus updatesStatus); void updates(int count, bool restartRequired); + void shutdownRequest(); private: std::unique_ptr m_systemParamsProvider; diff --git a/CCEngine/src/main.cpp b/CCEngine/src/main.cpp index 9c80cf1..a2bb05e 100644 --- a/CCEngine/src/main.cpp +++ b/CCEngine/src/main.cpp @@ -1,9 +1,38 @@ #include "CCEngine.h" #include "PlatformInit.h" +#include "OSUtils.h" #include #include +#include +#include +#include +#include +#include +#include + namespace fs = boost::filesystem; +namespace logging = boost::log; +namespace expr = boost::log::expressions; +namespace keywords = boost::log::keywords; + +void initLogging() +{ + auto logPath = ensureLogFolder("CCEngine"); + logging::add_file_log( + keywords::file_name = (logPath / "CCEngine.log").native(), + keywords::format = ( + expr::stream + << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S") + << ": <" << logging::trivial::severity + << "> " << expr::smessage) + ); + logging::core::get()->set_filter + ( + logging::trivial::severity >= logging::trivial::info + ); + logging::add_common_attributes(); +} int main(int argc, char *argv[]) { @@ -11,6 +40,8 @@ int main(int argc, char *argv[]) auto appDir = fs::system_complete(a.arguments().at(0).toStdString()).parent_path(); + initLogging(); + bool justUpdated = false; for (int i = 1; i < a.arguments().size(); ++i) { diff --git a/CCEngineLoader/CCEngineLoader.cpp b/CCEngineLoader/CCEngineLoader.cpp index 7936194..c1ddee8 100644 --- a/CCEngineLoader/CCEngineLoader.cpp +++ b/CCEngineLoader/CCEngineLoader.cpp @@ -25,9 +25,14 @@ CCEngineLoader::CCEngineLoader( timer->start(0); } -void CCEngineLoader::onProgressChanged(QString info) +void CCEngineLoader::onProgressChanged(UpdateStatus status, QString info) { ui.lblInformation->setText(info); + + if (status == UpdateStatus::done) + { + qApp->quit(); + } } void CCEngineLoader::onStartWorker() diff --git a/CCEngineLoader/CCEngineLoader.h b/CCEngineLoader/CCEngineLoader.h index cabfdef..667ec3d 100644 --- a/CCEngineLoader/CCEngineLoader.h +++ b/CCEngineLoader/CCEngineLoader.h @@ -16,7 +16,7 @@ public: QWidget *parent = Q_NULLPTR); private slots: - void onProgressChanged(QString info); + void onProgressChanged(UpdateStatus, QString info); void onStartWorker(); private: diff --git a/CCEngineLoader/UpdateWorker.cpp b/CCEngineLoader/UpdateWorker.cpp index af9bf61..2ea7db9 100644 --- a/CCEngineLoader/UpdateWorker.cpp +++ b/CCEngineLoader/UpdateWorker.cpp @@ -90,7 +90,9 @@ namespace UpdateWorkerThread::UpdateWorkerThread(const boost::filesystem::path& appDir, unsigned parentProcessId) : m_appDir(appDir) , m_parentProcessId(parentProcessId) -{} +{ + qRegisterMetaType(); +} void UpdateWorkerThread::run() { @@ -119,10 +121,11 @@ void UpdateWorkerThread::run() } std::cout << "Done" << std::endl; - emit progressChanged(UpdateStatus::updatesInstalled, QString("Updated successfully")); - if (isRestartRequired) { + emit progressChanged(UpdateStatus::restartingApp, QString("Restarting application")); runApp((m_appDir / "CCEngine.exe").string() + " --updated", false); } + + emit progressChanged(UpdateStatus::done, QString("Updated successfully")); } diff --git a/CCEngineLoader/UpdateWorker.h b/CCEngineLoader/UpdateWorker.h index fd9db32..8099e90 100644 --- a/CCEngineLoader/UpdateWorker.h +++ b/CCEngineLoader/UpdateWorker.h @@ -9,9 +9,12 @@ enum class UpdateStatus loadingUpdateDefinitions, installingUpdates, waitingForAppToExit, - updatesInstalled, + restartingApp, + done }; +Q_DECLARE_METATYPE(UpdateStatus); + class UpdateWorkerThread : public QThread { Q_OBJECT