Standalone downloader + update process tweaking...
This commit is contained in:
parent
1f420ee5cf
commit
475ab5e0bf
|
@ -147,11 +147,6 @@ configure_file (
|
|||
${CMAKE_CURRENT_BINARY_DIR}/src/definitions/definitions.h
|
||||
)
|
||||
|
||||
configure_file (
|
||||
${PROJECT_SOURCE_DIR}/src/updater/definitions.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/updater/definitions.h
|
||||
)
|
||||
|
||||
# Define some useful DEBUG for, ehrm, debug build.
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "release" OR CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RELEASE")
|
||||
message(STATUS "[${APP_LOW_NAME}] A release build (non-debug) is chosen. Debugging outputs are silently ignored.")
|
||||
|
|
|
@ -20,12 +20,6 @@
|
|||
|
||||
#include <QtGlobal>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <qwebkitglobal.h>
|
||||
#else
|
||||
#include <qwebkitversion.h>
|
||||
#endif
|
||||
|
||||
#define CMAKE_VERSION "@CMAKE_VERSION@"
|
||||
#define CMAKE_SYSTEM "@CMAKE_SYSTEM@"
|
||||
|
||||
|
@ -39,7 +33,7 @@
|
|||
#define APP_URL_ISSUES "@APP_URL_ISSUES@"
|
||||
#define APP_URL_ISSUES_NEW "@APP_URL_ISSUES_NEW@"
|
||||
#define APP_VERSION "@APP_VERSION@"
|
||||
#define APP_USERAGENT QString("@APP_NAME@/@APP_VERSION@ (@APP_URL@) on @CMAKE_SYSTEM@; Webkit/") + qWebKitVersion()
|
||||
#define APP_USERAGENT QString("@APP_NAME@/@APP_VERSION@ (@APP_URL@) on @CMAKE_SYSTEM@")
|
||||
|
||||
#define RELEASES_LIST "https://bitbucket.org/skunkos/rssguard/raw/master/resources/text/UPDATES?at=master"
|
||||
#define DEFAULT_LOCALE "en_GB"
|
||||
|
@ -175,6 +169,8 @@
|
|||
#define APP_ICON_PLAIN_PATH APP_PREFIX + QString("/share/rssguard/icons/@APP_LOW_NAME@_plain.png")
|
||||
#elif defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
#define APP_UPDATER_EXECUTABLE "rssguard_updater.exe"
|
||||
#define APP_7ZA_EXECUTABLE "7za.exe"
|
||||
|
||||
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/l10n")
|
||||
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins")
|
||||
#define APP_INFO_PATH QApplication::applicationDirPath()
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "miscellaneous/iconfactory.h"
|
||||
#include "network-web/networkfactory.h"
|
||||
#include "network-web/webfactory.h"
|
||||
#include "network-web/downloader.h"
|
||||
#include "gui/messagebox.h"
|
||||
#include "gui/systemtrayicon.h"
|
||||
|
||||
|
@ -104,8 +105,9 @@ void FormUpdate::checkForUpdates() {
|
|||
|
||||
void FormUpdate::startUpdate() {
|
||||
QString url_file;
|
||||
bool update_for_this_system = isUpdateForThisSystem();
|
||||
|
||||
if (isUpdateForThisSystem()) {
|
||||
if (update_for_this_system) {
|
||||
url_file = m_updateInfo.m_urls.value(OS_ID).m_fileUrl;
|
||||
}
|
||||
else {
|
||||
|
@ -113,57 +115,13 @@ void FormUpdate::startUpdate() {
|
|||
}
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
|
||||
// On Windows/OS2 we can update the application right away.
|
||||
// Download the files.
|
||||
QByteArray output;
|
||||
QNetworkReply::NetworkError download_result = NetworkFactory::downloadFeedFile(url_file,
|
||||
10 * DOWNLOAD_TIMEOUT,
|
||||
output);
|
||||
Downloader *down = new Downloader(this);
|
||||
|
||||
#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)) {
|
||||
output_file.write(output);
|
||||
output_file.flush();
|
||||
output_file.close();
|
||||
|
||||
// TODO: spustit updater
|
||||
// pouzit qprocess, nebo neco multiplatformniho
|
||||
// nebo z quiterss shellexecuter
|
||||
// program obcas pada, to je mozna zpusobeny tim
|
||||
// ze je otevreny modalni okno.
|
||||
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 {
|
||||
// TODO: chyba - nelze zapisovat do souboru
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// TODO: chyba - nelze ulozit soubor.
|
||||
}
|
||||
connect(down, SIGNAL(completed(QNetworkReply::NetworkError,QByteArray)),
|
||||
this, SLOT(finish(QNetworkReply::NetworkError,QByteArray)));
|
||||
|
||||
// TODO: tady jen zavolat updater a ten by si to mohl stahnout sam.
|
||||
down->downloadFile(url_file);
|
||||
#else
|
||||
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {
|
||||
if (SystemTrayIcon::isSystemTrayActivated()) {
|
||||
|
@ -182,3 +140,48 @@ void FormUpdate::startUpdate() {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FormUpdate::finish(QNetworkReply::NetworkError err, QByteArray arr)
|
||||
{
|
||||
// TODO: presunou do updatera.
|
||||
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)) {
|
||||
output_file.write(arr);
|
||||
output_file.flush();
|
||||
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 {
|
||||
// TODO: chyba - nelze zapisovat do souboru
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// TODO: chyba - nelze ulozit soubor.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ class FormUpdate : public QDialog {
|
|||
void checkForUpdates();
|
||||
void startUpdate();
|
||||
|
||||
void finish(QNetworkReply::NetworkError err, QByteArray arr);
|
||||
|
||||
private:
|
||||
Ui::FormUpdate *m_ui;
|
||||
UpdateInfo m_updateInfo;
|
||||
|
|
|
@ -53,8 +53,6 @@ class MessagesToolBar : public BaseToolBar {
|
|||
void loadChangeableActions(const QStringList &actions);
|
||||
|
||||
signals:
|
||||
// TODO: sem pridat este mozna mode: wildcard, regexp, fixed text.
|
||||
// na tuto udalost se navaze filtrovani
|
||||
void messageSearchPatternChanged(const QString &pattern);
|
||||
|
||||
// Emitted if message filter is changed.
|
||||
|
|
|
@ -88,8 +88,6 @@ void ToolBarEditor::loadFromToolBar(BaseToolBar* tool_bar) {
|
|||
}
|
||||
|
||||
void ToolBarEditor::saveToolBar() {
|
||||
// TODO: ulozit actiony nastaveny v tomdl
|
||||
// e nastavovacim dialogu do prirazenyho toolbaru
|
||||
QStringList action_names;
|
||||
|
||||
for (int i = 0; i < m_ui->m_listActivatedActions->count(); i++) {
|
||||
|
|
|
@ -1,8 +1,94 @@
|
|||
#include "network-web/downloader.h"
|
||||
|
||||
#include "network-web/silentnetworkaccessmanager.h"
|
||||
|
||||
Downloader::Downloader(QObject *parent) : QObject(parent) {
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
Downloader::Downloader(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_activeReply(NULL),
|
||||
m_downloadManager(new SilentNetworkAccessManager(this)),
|
||||
m_timer(new QTimer(this)) {
|
||||
|
||||
m_timer->setInterval(2000);
|
||||
m_timer->setSingleShot(true);
|
||||
|
||||
connect(m_timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
||||
connect(m_downloadManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*)));
|
||||
}
|
||||
|
||||
Downloader::~Downloader() {
|
||||
m_downloadManager->deleteLater();
|
||||
}
|
||||
|
||||
void Downloader::downloadFile(const QString &url, bool protected_contents,
|
||||
const QString &username, const QString &password) {
|
||||
QNetworkRequest request;
|
||||
QObject originatingObject;
|
||||
|
||||
// Set credential information as originating object.
|
||||
originatingObject.setProperty("protected", protected_contents);
|
||||
originatingObject.setProperty("username", username);
|
||||
originatingObject.setProperty("password", password);
|
||||
request.setOriginatingObject(&originatingObject);
|
||||
|
||||
// Set url for this reques.
|
||||
request.setUrl(url);
|
||||
|
||||
runRequest(request);
|
||||
}
|
||||
|
||||
void Downloader::finished(QNetworkReply *reply) {
|
||||
m_timer->stop();
|
||||
|
||||
// In this phase, some part of downloading process is completed.
|
||||
QUrl redirection_url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||
|
||||
if (redirection_url.isValid()) {
|
||||
// Communication indicates that HTTP redirection is needed.
|
||||
// Setup redirection URL and download again.
|
||||
QNetworkRequest request = reply->request();
|
||||
request.setUrl(redirection_url);
|
||||
|
||||
m_activeReply->deleteLater();
|
||||
m_activeReply = NULL;
|
||||
|
||||
runRequest(request);
|
||||
}
|
||||
else {
|
||||
// No redirection is indicated. Final file is obtained
|
||||
// in our "reply" object.
|
||||
|
||||
// Read the data into output buffer.
|
||||
QByteArray output = reply->readAll();
|
||||
QNetworkReply::NetworkError reply_error = reply->error();
|
||||
|
||||
m_activeReply->deleteLater();
|
||||
m_activeReply = NULL;
|
||||
|
||||
emit completed(reply_error, output);
|
||||
}
|
||||
}
|
||||
|
||||
void Downloader::progressInternal(qint64 bytes_received, qint64 bytes_total) {
|
||||
if (m_timer->interval() > 0) {
|
||||
m_timer->start();
|
||||
}
|
||||
|
||||
emit progress(bytes_received, bytes_total);
|
||||
}
|
||||
|
||||
void Downloader::timeout() {
|
||||
if (m_activeReply != NULL) {
|
||||
m_activeReply->abort();
|
||||
}
|
||||
}
|
||||
|
||||
void Downloader::runRequest(const QNetworkRequest &request) {
|
||||
m_timer->start();
|
||||
m_activeReply = m_downloadManager->get(request);
|
||||
|
||||
connect(m_activeReply, SIGNAL(downloadProgress(qint64,qint64)),
|
||||
this, SLOT(progressInternal(qint64,qint64)));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QSslError>
|
||||
|
||||
#include "definitions/definitions.h"
|
||||
|
||||
|
||||
class SilentNetworkAccessManager;
|
||||
class QTimer;
|
||||
|
||||
class Downloader : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -12,13 +20,37 @@ class Downloader : public QObject {
|
|||
explicit Downloader(QObject *parent = 0);
|
||||
virtual ~Downloader();
|
||||
|
||||
// TODO: zakladni downloader s timeoutem a signalem kerej informuje o prubehu
|
||||
// stahovani
|
||||
public slots:
|
||||
// Performs asynchronous download of given file.
|
||||
// Redirections are handled.
|
||||
void downloadFile(const QString &url,
|
||||
bool protected_contents = false,
|
||||
const QString &username = QString(),
|
||||
const QString &password = QString());
|
||||
|
||||
signals:
|
||||
// Emitted when new progress is known.
|
||||
void progress(qint64 bytes_received, qint64 bytes_total);
|
||||
void completed(QNetworkReply::NetworkError status, QByteArray contents = QByteArray());
|
||||
|
||||
public slots:
|
||||
private slots:
|
||||
// Called when current reply is processed.
|
||||
void finished(QNetworkReply *reply);
|
||||
|
||||
// Called when progress of downloaded file changes.
|
||||
void progressInternal(qint64 bytes_received, qint64 bytes_total);
|
||||
|
||||
// Called when current operation times out.
|
||||
void timeout();
|
||||
|
||||
private:
|
||||
void runRequest(const QNetworkRequest &request);
|
||||
|
||||
private:
|
||||
QNetworkReply *m_activeReply;
|
||||
|
||||
SilentNetworkAccessManager *m_downloadManager;
|
||||
QTimer *m_timer;
|
||||
};
|
||||
|
||||
#endif // DOWNLOADER_H
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2011-2014 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
//
|
||||
// RSS Guard is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// RSS Guard is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef DEFINITIONS_H_IN
|
||||
#define DEFINITIONS_H_IN
|
||||
|
||||
#define RSSGUARD_LOW_NAME "@APP_LOW_NAME@"
|
||||
|
||||
#define UPDATER_QUIT_INSTANCE "app_quit"
|
||||
#define UPDATER_IS_RUNNING "app_is_running"
|
||||
#define EXECUTABLE_7ZA "7za.exe"
|
||||
|
||||
#endif // DEFINITIONS_H_IN
|
|
@ -16,7 +16,7 @@
|
|||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "qtsingleapplication/qtsinglecoreapplication.h"
|
||||
#include "updater/definitions.h"
|
||||
#include "definitions/definitions.h"
|
||||
|
||||
#include <QTranslator>
|
||||
#include <QDebug>
|
||||
|
@ -86,7 +86,7 @@ bool copyPath(QString src, QString dst) {
|
|||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Instantiate base application object.
|
||||
QtSingleCoreApplication application(RSSGUARD_LOW_NAME, argc, argv);
|
||||
QtSingleCoreApplication application(APP_LOW_NAME, argc, argv);
|
||||
|
||||
if (argc != 4) {
|
||||
qDebug("Insufficient arguments passed. Update process cannot proceed.");
|
||||
|
@ -111,7 +111,7 @@ int main(int argc, char *argv[]) {
|
|||
qDebug("\n===== directories & files =====\n");
|
||||
|
||||
// Check if main RSS Guard instance is running.
|
||||
if (application.sendMessage(UPDATER_QUIT_INSTANCE)) {
|
||||
if (application.sendMessage(APP_QUIT_INSTANCE)) {
|
||||
qDebug("RSS Guard application is running. Quitting it.");
|
||||
}
|
||||
|
||||
|
@ -127,9 +127,9 @@ int main(int argc, char *argv[]) {
|
|||
qDebug().nospace() << "Running updater in thread: \'" <<
|
||||
QThread::currentThreadId() << "\'.";
|
||||
|
||||
QString extractor_program(EXECUTABLE_7ZA);
|
||||
QString extractor_program(APP_7ZA_EXECUTABLE);
|
||||
QStringList arguments;
|
||||
QString output_temp_directory = temp_directory + QDir::separator() + RSSGUARD_LOW_NAME;
|
||||
QString output_temp_directory = temp_directory + QDir::separator() + APP_LOW_NAME;
|
||||
|
||||
// Remove old folders.
|
||||
if (QDir(output_temp_directory).exists()) {
|
||||
|
@ -190,10 +190,6 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
QString rssguard_single_temp_root = rssguard_temp_root.at(0).absoluteFilePath();
|
||||
|
||||
|
||||
// TODO: upravit copyPath aby prepisoval soubory kdyz je kopiruje
|
||||
// a to udelat tak ze se ten cilovej soubor pokusi smazat
|
||||
// a az pak nakopiruje.
|
||||
if (!copyPath(rssguard_single_temp_root, rssguard_path)) {
|
||||
qDebug("Critical error appeared during copying of application files.");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue