Updater works...
This commit is contained in:
parent
050bb4b601
commit
615f27f94c
@ -30,14 +30,16 @@
|
||||
#include <QDesktopServices>
|
||||
#include <QProcess>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include "qt_windows.h"
|
||||
#endif
|
||||
|
||||
FormUpdate::FormUpdate(QWidget *parent)
|
||||
: QDialog(parent), m_ui(new Ui::FormUpdate) {
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
m_downloader = NULL;
|
||||
m_readyToInstall = false;
|
||||
#endif
|
||||
|
||||
// Set flags and attributes.
|
||||
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog);
|
||||
setWindowIcon(IconFactory::instance()->fromTheme("application-about"));
|
||||
@ -84,6 +86,8 @@ void FormUpdate::checkForUpdates() {
|
||||
m_ui->m_txtChanges->setText(update.first.m_changes);
|
||||
|
||||
if (update.first.m_availableVersion >= APP_VERSION) {
|
||||
bool update_for_this_system = isUpdateForThisSystem();
|
||||
|
||||
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok,
|
||||
tr("New release available."),
|
||||
tr("This is new version which can be\ndownloaded and installed."));
|
||||
@ -92,6 +96,10 @@ void FormUpdate::checkForUpdates() {
|
||||
tr("Download installation file for your OS.") :
|
||||
tr("Installation file is not available directly.\n"
|
||||
"Go to application website to obtain it manually."));
|
||||
|
||||
if (update_for_this_system) {
|
||||
m_btnUpdate->setText(tr("Download update"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Warning,
|
||||
@ -103,6 +111,74 @@ void FormUpdate::checkForUpdates() {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) {
|
||||
qApp->processEvents();
|
||||
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Information,
|
||||
tr("Downloaded %1% (update size is %2 kB).").arg(QString::number((bytes_received * 100.0) / bytes_total,
|
||||
'f',
|
||||
2),
|
||||
QString::number(bytes_total / 1000,
|
||||
'f',
|
||||
2)),
|
||||
tr("Downloading update..."));
|
||||
}
|
||||
|
||||
void FormUpdate::saveUpdateFile(const QByteArray &file_contents) {
|
||||
QString url_file = m_updateInfo.m_urls.value(OS_ID).m_fileUrl;;
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
QString temp_directory = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
||||
#else
|
||||
QString temp_directory = QDesktopServices::storageLocation(QDesktopServices::TempLocation);
|
||||
#endif
|
||||
|
||||
if (!temp_directory.isEmpty()) {
|
||||
QString output_file_name = url_file.mid(url_file.lastIndexOf('/') + 1);
|
||||
QFile output_file(temp_directory + QDir::separator() + output_file_name);
|
||||
|
||||
if (output_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
qDebug("Storing update file to temporary location '%s'.",
|
||||
qPrintable(output_file_name));
|
||||
|
||||
output_file.write(file_contents);
|
||||
output_file.flush();
|
||||
output_file.close();
|
||||
|
||||
qDebug("Update file contents was successfuly saved.");
|
||||
|
||||
m_updateFilePath = output_file.fileName();
|
||||
m_readyToInstall = true;
|
||||
}
|
||||
else {
|
||||
qDebug("Cannot save downloaded update file because target temporary file '%s' cannot be "
|
||||
"opened for writing.", output_file_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
qDebug("Cannot save downloaded update file because no TEMP folder is available.");
|
||||
}
|
||||
}
|
||||
|
||||
void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, QByteArray contents) {
|
||||
qDebug("Download of application update file was completed with code '%s'.",
|
||||
status);
|
||||
|
||||
switch (status) {
|
||||
case QNetworkReply::NoError:
|
||||
saveUpdateFile(contents);
|
||||
|
||||
m_btnUpdate->setText(tr("Install update"));
|
||||
m_btnUpdate->setEnabled(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
m_btnUpdate->setText(tr("Error occured"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void FormUpdate::startUpdate() {
|
||||
QString url_file;
|
||||
bool update_for_this_system = isUpdateForThisSystem();
|
||||
@ -115,35 +191,71 @@ void FormUpdate::startUpdate() {
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
Downloader *downloader = new Downloader(this);
|
||||
if (m_readyToInstall) {
|
||||
close();
|
||||
|
||||
connect(downloader, SIGNAL(completed(QNetworkReply::NetworkError,QByteArray)),
|
||||
this, SLOT(finish(QNetworkReply::NetworkError,QByteArray)));
|
||||
qDebug("Preparing to launch external updater '%s'.", APP_UPDATER_EXECUTABLE);
|
||||
|
||||
// TODO: tady jen zavolat updater a ten by si to mohl stahnout sam.
|
||||
downloader->downloadFile(url_file);
|
||||
#else
|
||||
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {
|
||||
if (SystemTrayIcon::isSystemTrayActivated()) {
|
||||
SystemTrayIcon::instance()->showMessage(tr("Cannot update application"),
|
||||
tr("Cannot navigate to installation file. Check new installation downloads "
|
||||
"manually on project website."),
|
||||
QSystemTrayIcon::Warning);
|
||||
if (!QProcess::startDetached(APP_UPDATER_EXECUTABLE,
|
||||
QStringList() <<
|
||||
APP_VERSION <<
|
||||
m_updateInfo.m_availableVersion <<
|
||||
QDir::toNativeSeparators(qApp->applicationFilePath()) <<
|
||||
QDir::toNativeSeparators(m_updateFilePath))) {
|
||||
qDebug("External updater was not launched due to error.");
|
||||
|
||||
if (SystemTrayIcon::isSystemTrayActivated()) {
|
||||
SystemTrayIcon::instance()->showMessage(tr("Cannot update application"),
|
||||
tr("Cannot launch external updater. Update application manually."),
|
||||
QSystemTrayIcon::Warning);
|
||||
}
|
||||
else {
|
||||
MessageBox::show(this,
|
||||
QMessageBox::Warning,
|
||||
tr("Cannot update application"),
|
||||
tr("Cannot launch external updater. Update application manually."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
MessageBox::show(this,
|
||||
QMessageBox::Warning,
|
||||
tr("Cannot update application"),
|
||||
tr("Cannot navigate to installation file. Check new installation downloads "
|
||||
"manually on project website."));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (update_for_this_system) {
|
||||
if (m_downloader == NULL) {
|
||||
// Initialie downloader.
|
||||
m_downloader = new Downloader(this);
|
||||
|
||||
connect(m_downloader, SIGNAL(progress(qint64,qint64)),
|
||||
this, SLOT(updateProgress(qint64,qint64)));
|
||||
connect(m_downloader, SIGNAL(completed(QNetworkReply::NetworkError,QByteArray)),
|
||||
this, SLOT(updateCompleted(QNetworkReply::NetworkError,QByteArray)));
|
||||
}
|
||||
|
||||
m_btnUpdate->setText(tr("Downloading update..."));
|
||||
m_btnUpdate->setEnabled(false);
|
||||
|
||||
m_downloader->downloadFile(url_file);
|
||||
|
||||
} else {
|
||||
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {
|
||||
if (SystemTrayIcon::isSystemTrayActivated()) {
|
||||
SystemTrayIcon::instance()->showMessage(tr("Cannot update application"),
|
||||
tr("Cannot navigate to installation file. Check new installation downloads "
|
||||
"manually on project website."),
|
||||
QSystemTrayIcon::Warning);
|
||||
}
|
||||
else {
|
||||
MessageBox::show(this,
|
||||
QMessageBox::Warning,
|
||||
tr("Cannot update application"),
|
||||
tr("Cannot navigate to installation file. Check new installation downloads "
|
||||
"manually on project website."));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
void FormUpdate::finish(QNetworkReply::NetworkError err, QByteArray arr)
|
||||
{
|
||||
/*
|
||||
* // TODO: http://pastebin.com/Lvb1bsJP
|
||||
// chyba od elberta
|
||||
// TODO: presunou do updatera.
|
||||
QString url_file = m_updateInfo.m_urls.value(OS_ID).m_fileUrl;;
|
||||
|
||||
@ -163,27 +275,23 @@ void FormUpdate::finish(QNetworkReply::NetworkError err, QByteArray arr)
|
||||
output_file.close();
|
||||
|
||||
close();
|
||||
|
||||
QProcess::startDetached(APP_UPDATER_EXECUTABLE,
|
||||
QStringList() << temp_directory <<qApp->applicationFilePath() << output_file.fileName());
|
||||
|
||||
//ShellExecute(0,
|
||||
// 0,
|
||||
// (wchar_t *) QString(APP_UPDATER_EXECUTABLE).utf16(),
|
||||
// (wchar_t *) QString("\"%1\" \"%2\" \"%3\"").arg(temp_directory,
|
||||
// qApp->applicationFilePath(),
|
||||
// output_file.fileName()).utf16(),
|
||||
// 0,
|
||||
// SW_SHOWNORMAL);
|
||||
|
||||
}
|
||||
}*/
|
||||
#else
|
||||
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {
|
||||
if (SystemTrayIcon::isSystemTrayActivated()) {
|
||||
SystemTrayIcon::instance()->showMessage(tr("Cannot update application"),
|
||||
tr("Cannot navigate to installation file. Check new installation downloads "
|
||||
"manually on project website."),
|
||||
QSystemTrayIcon::Warning);
|
||||
}
|
||||
else {
|
||||
// TODO: chyba - nelze zapisovat do souboru
|
||||
MessageBox::show(this,
|
||||
QMessageBox::Warning,
|
||||
tr("Cannot update application"),
|
||||
tr("Cannot navigate to installation file. Check new installation downloads "
|
||||
"manually on project website."));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// TODO: chyba - nelze ulozit soubor.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include <QDialog>
|
||||
#include <QPushButton>
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
#include <QNetworkReply>
|
||||
#endif
|
||||
|
||||
#include "ui_formupdate.h"
|
||||
|
||||
#include "miscellaneous/systemfactory.h"
|
||||
@ -30,6 +34,10 @@ namespace Ui {
|
||||
class FormUpdate;
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
class Downloader;
|
||||
#endif
|
||||
|
||||
class FormUpdate : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
@ -48,10 +56,16 @@ class FormUpdate : public QDialog {
|
||||
void startUpdate();
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
void finish(QNetworkReply::NetworkError err, QByteArray arr);
|
||||
#endif
|
||||
void updateProgress(qint64 bytes_received, qint64 bytes_total);
|
||||
void updateCompleted(QNetworkReply::NetworkError status, QByteArray contents);
|
||||
void saveUpdateFile(const QByteArray &file_contents);
|
||||
|
||||
private:
|
||||
Downloader *m_downloader;
|
||||
bool m_readyToInstall;
|
||||
QString m_updateFilePath;
|
||||
#endif
|
||||
|
||||
Ui::FormUpdate *m_ui;
|
||||
UpdateInfo m_updateInfo;
|
||||
QPushButton *m_btnUpdate;
|
||||
|
@ -34,7 +34,8 @@ bool removeDir(const QString & dirName) {
|
||||
QDir dir(dirName);
|
||||
|
||||
if (dir.exists(dirName)) {
|
||||
foreach (QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
|
||||
foreach (QFileInfo info,
|
||||
dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
|
||||
if (info.isDir()) {
|
||||
result = removeDir(info.absoluteFilePath());
|
||||
}
|
||||
@ -55,6 +56,7 @@ bool removeDir(const QString & dirName) {
|
||||
|
||||
bool copyPath(QString src, QString dst) {
|
||||
QDir dir(src);
|
||||
|
||||
if (! dir.exists()) {
|
||||
return false;
|
||||
}
|
||||
@ -71,25 +73,34 @@ bool copyPath(QString src, QString dst) {
|
||||
|
||||
if (!QFile::exists(destination_file) || QFile::remove(destination_file)) {
|
||||
if (QFile::copy(src + QDir::separator() + f, destination_file)) {
|
||||
qDebug("Copied %s", qPrintable(f));
|
||||
qDebug("Copied file '%s'.", qPrintable(f));
|
||||
}
|
||||
else {
|
||||
qDebug("Failed to copy file '%s'", qPrintable(original_file));
|
||||
qDebug("Failed to copy file '%s'.", qPrintable(original_file));
|
||||
}
|
||||
}
|
||||
else {
|
||||
qDebug("Failed to remove file '%s'", qPrintable(original_file));
|
||||
qDebug("Failed to remove file '%s'.", qPrintable(original_file));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Main entry point to "rssguard_updater.exe".
|
||||
// It expects 4 ARGUMENTS:
|
||||
// 0) - the actual path of this process,
|
||||
// 1) - string with current version,
|
||||
// 2) - string with future version,
|
||||
// 3) - path to RSS Guard ("rssguard.exe") file,
|
||||
// 4) - path to update file (stored in TEMP folder).
|
||||
int main(int argc, char *argv[]) {
|
||||
// Instantiate base application object.
|
||||
QtSingleCoreApplication application(APP_LOW_NAME, argc, argv);
|
||||
|
||||
if (argc != 4) {
|
||||
qDebug("\n===== RSS Guard updater ====\n");
|
||||
|
||||
if (argc != 5) {
|
||||
qDebug("Insufficient arguments passed. Update process cannot proceed.");
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
@ -98,6 +109,162 @@ int main(int argc, char *argv[]) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
QString this_process_path = QDir::toNativeSeparators(application.applicationFilePath());
|
||||
QString current_version(argv[1]);
|
||||
QString next_version(argv[2]);
|
||||
QString rssguard_executable_path(argv[3]);
|
||||
QString rssguard_path = QDir::toNativeSeparators(QFileInfo(rssguard_executable_path).absolutePath());
|
||||
QString update_file_path(argv[4]);
|
||||
QString temp_path = QDir::toNativeSeparators(QFileInfo(update_file_path).absolutePath());
|
||||
QString output_temp_path = temp_path + QDir::separator() + APP_LOW_NAME;
|
||||
|
||||
qDebug("Starting updater.");
|
||||
qDebug("Version changes from %s to %s.",
|
||||
qPrintable(current_version),
|
||||
qPrintable(next_version));
|
||||
|
||||
qDebug("\n===== Files & versions ====\n");
|
||||
|
||||
qDebug("This process:\n\t %s", qPrintable(this_process_path));
|
||||
qDebug("Application executable:\n\t %s", qPrintable(rssguard_executable_path));
|
||||
qDebug("TEMP path:\n\t %s", qPrintable(temp_path));
|
||||
|
||||
qDebug("\n===== Update file metadata ====\n");
|
||||
|
||||
bool update_file_exists = QFile::exists(update_file_path);
|
||||
|
||||
qDebug("Update file exists:\n\t %s", update_file_exists ? "yes" : "no");
|
||||
qDebug("Update file path:\n\t %s", qPrintable(update_file_path));
|
||||
qDebug("Update file size:\n\t %d bytes", QFileInfo(update_file_path).size());
|
||||
|
||||
if (!update_file_exists) {
|
||||
qDebug("\nUpdate file does NOT exist. Updater cannot proceed.");
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Check if main RSS Guard instance is running.
|
||||
if (application.sendMessage(APP_QUIT_INSTANCE)) {
|
||||
qDebug("RSS Guard application is running. Quitting it.");
|
||||
}
|
||||
|
||||
qDebug("\n===== Cleanup ====\n");
|
||||
|
||||
// Remove old folders.
|
||||
if (QDir(output_temp_path).exists()) {
|
||||
if (!removeDir(output_temp_path)) {
|
||||
qDebug("Cleanup of old temporary files failed.");
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug("Old files removed.");
|
||||
|
||||
qDebug("Update files are ready. Press any key to proceed...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
QString extractor(APP_7ZA_EXECUTABLE);
|
||||
QStringList extractor_arguments;
|
||||
|
||||
extractor_arguments << "x" << update_file_path << "-r" <<
|
||||
"-y" << QString("-o%1").arg(output_temp_path);
|
||||
|
||||
qDebug("\n===== Decompression =====\n");
|
||||
|
||||
switch (QProcess::execute(extractor, extractor_arguments)) {
|
||||
case -1:
|
||||
qDebug("\nDecompressor crashed. Upgrading process failed.");
|
||||
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
return EXIT_FAILURE;
|
||||
|
||||
case -2:
|
||||
qDebug("\nDecompressor was not started successfully. Upgrading process failed.");
|
||||
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
return EXIT_FAILURE;
|
||||
|
||||
case 0:
|
||||
qDebug("\nDecompression is done. Proceeding to copying files to application directory.");
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug("\nUnspecified error occured.");
|
||||
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
qDebug("\n===== Copying =====\n");
|
||||
|
||||
// Find "rssguard" subfolder path in
|
||||
QFileInfoList rssguard_temp_root = QDir(output_temp_path).entryInfoList(QDir::Dirs |
|
||||
QDir::NoDotAndDotDot |
|
||||
QDir::NoSymLinks);
|
||||
|
||||
if (rssguard_temp_root.size() != 1) {
|
||||
qDebug("Could not find root of downloaded application data.");
|
||||
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
QString rssguard_single_temp_root = rssguard_temp_root.at(0).absoluteFilePath();
|
||||
|
||||
if (!copyPath(rssguard_single_temp_root, rssguard_path)) {
|
||||
qDebug("Critical error appeared during copying of application files.");
|
||||
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
qDebug("\n===== Cleanup =====\n");
|
||||
|
||||
removeDir(output_temp_path);
|
||||
QFile::remove(update_file_path);
|
||||
|
||||
qDebug("Temporary files removed.");
|
||||
|
||||
qDebug("Press any key to exit updater and start RSS Guard.");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
if (!QProcess::startDetached(rssguard_executable_path)) {
|
||||
qDebug("RSS Guard was not started successfully. Start it manually.");
|
||||
|
||||
qDebug("Press any key to exit updater...");
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
/*
|
||||
QString temp_directory = QDir::toNativeSeparators(argv[1]);
|
||||
QString rssguard_executable = QDir::toNativeSeparators(argv[2]);
|
||||
QString rssguard_path = QDir::toNativeSeparators(QFileInfo(rssguard_executable).absolutePath());
|
||||
@ -209,7 +376,6 @@ int main(int argc, char *argv[]) {
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
QProcess::startDetached(rssguard_executable);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
*/
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user