1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Add an option for auto-updates on Windows

With the update server hosted on my laptop...

Fun fact: Updates are really easy to mess up right now. If I forget to update the update server, everyone gets downgraded. Upload a bad file and everyone will crash. Fun stuff.

Upates Are Experimental™ and off by default.
This commit is contained in:
Tux3 / Mlkj / !Lev.uXFMLA 2014-11-10 00:31:29 +01:00
parent 45e20187cc
commit 0054787826
No known key found for this signature in database
GPG Key ID: 7E086DD661263264
9 changed files with 87 additions and 2 deletions

View File

@ -18,12 +18,15 @@
#include "src/autoupdate.h" #include "src/autoupdate.h"
#include "src/misc/serialize.h" #include "src/misc/serialize.h"
#include "src/misc/settings.h" #include "src/misc/settings.h"
#include "src/widget/widget.h"
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QCoreApplication> #include <QCoreApplication>
#include <QFile> #include <QFile>
#include <QDir> #include <QDir>
#include <QProcess> #include <QProcess>
#include <QtConcurrent/QtConcurrent>
#include <QMessageBox>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <windows.h> #include <windows.h>
@ -37,7 +40,7 @@ const QString AutoUpdater::updaterBin = "qtox-updater.exe";
const QString AutoUpdater::platform; const QString AutoUpdater::platform;
const QString AutoUpdater::updaterBin; const QString AutoUpdater::updaterBin;
#endif #endif
const QString AutoUpdater::updateServer = "http://127.0.0.1"; const QString AutoUpdater::updateServer = "http://mlkj.bounceme.net";
const QString AutoUpdater::checkURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/version"; const QString AutoUpdater::checkURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/version";
const QString AutoUpdater::flistURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/flist"; const QString AutoUpdater::flistURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/flist";
const QString AutoUpdater::filesURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/files/"; const QString AutoUpdater::filesURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/files/";
@ -392,3 +395,20 @@ fail:
QDir(updateDirStr).removeRecursively(); QDir(updateDirStr).removeRecursively();
exit(-1); exit(-1);
} }
void AutoUpdater::checkUpdatesAsyncInteractive()
{
QtConcurrent::run(&AutoUpdater::checkUpdatesAsyncInteractiveWorker);
}
void AutoUpdater::checkUpdatesAsyncInteractiveWorker()
{
if (!isUpdateAvailable())
return;
if (Widget::getInstance()->askMsgboxQuestion(QObject::tr("Update", "The title of a message box"),
QObject::tr("An update is available, do you want to download it now ?\nIt will be installed when qTox restarts.")))
{
downloadUpdate();
}
}

View File

@ -57,6 +57,10 @@ public:
}; };
public: public:
/// Connects to the qTox update server, if an updat is found shows a dialog to the user asking to download it
/// Runs asynchronously in its own thread, and will return immediatly
/// Will call isUpdateAvailable, and as such may processEvents
static void checkUpdatesAsyncInteractive();
/// Connects to the qTox update server, returns true if an update is available for download /// Connects to the qTox update server, returns true if an update is available for download
/// Will call getUpdateVersion, and as such may block and processEvents /// Will call getUpdateVersion, and as such may block and processEvents
static bool isUpdateAvailable(); static bool isUpdateAvailable();
@ -90,6 +94,9 @@ protected:
/// Note that a file with an empty but non-null QByteArray is not an error, merely a file of size 0. /// Note that a file with an empty but non-null QByteArray is not an error, merely a file of size 0.
/// Will try to follow qTox's proxy settings, may block and processEvents /// Will try to follow qTox's proxy settings, may block and processEvents
static UpdateFile getUpdateFile(UpdateFileMeta fileMeta); static UpdateFile getUpdateFile(UpdateFileMeta fileMeta);
/// Does the actual work for checkUpdatesAsyncInteractive
/// Blocking, but otherwise has the same properties than checkUpdatesAsyncInteractive
static void checkUpdatesAsyncInteractiveWorker();
private: private:
AutoUpdater() = delete; AutoUpdater() = delete;

View File

@ -119,6 +119,7 @@ void Settings::load()
proxyPort = s.value("proxyPort", 0).toInt(); proxyPort = s.value("proxyPort", 0).toInt();
currentProfile = s.value("currentProfile", "").toString(); currentProfile = s.value("currentProfile", "").toString();
autoAwayTime = s.value("autoAwayTime", 10).toInt(); autoAwayTime = s.value("autoAwayTime", 10).toInt();
checkUpdates = s.value("checkUpdates", false).toBool();
s.endGroup(); s.endGroup();
s.beginGroup("Widgets"); s.beginGroup("Widgets");
@ -255,6 +256,7 @@ void Settings::save(QString path)
s.setValue("proxyPort", proxyPort); s.setValue("proxyPort", proxyPort);
s.setValue("currentProfile", currentProfile); s.setValue("currentProfile", currentProfile);
s.setValue("autoAwayTime", autoAwayTime); s.setValue("autoAwayTime", autoAwayTime);
s.setValue("checkUpdates", checkUpdates);
s.endGroup(); s.endGroup();
s.beginGroup("Widgets"); s.beginGroup("Widgets");
@ -727,6 +729,16 @@ void Settings::setWindowState(const QByteArray &value)
windowState = value; windowState = value;
} }
bool Settings::getCheckUpdates() const
{
return checkUpdates;
}
void Settings::setCheckUpdates(bool newValue)
{
checkUpdates = newValue;
}
QByteArray Settings::getSplitterState() const QByteArray Settings::getSplitterState() const
{ {
return splitterState; return splitterState;

View File

@ -99,6 +99,9 @@ public:
int getAutoAwayTime() const; int getAutoAwayTime() const;
void setAutoAwayTime(int newValue); void setAutoAwayTime(int newValue);
bool getCheckUpdates() const;
void setCheckUpdates(bool newValue);
QPixmap getSavedAvatar(const QString& ownerId); QPixmap getSavedAvatar(const QString& ownerId);
void saveAvatar(QPixmap& pic, const QString& ownerId); void saveAvatar(QPixmap& pic, const QString& ownerId);
@ -219,6 +222,7 @@ private:
bool closeToTray; bool closeToTray;
bool minimizeToTray; bool minimizeToTray;
bool useEmoticons; bool useEmoticons;
bool checkUpdates;
bool forceTCP; bool forceTCP;

View File

@ -27,6 +27,8 @@
#include <QFileDialog> #include <QFileDialog>
#include <QStandardPaths> #include <QStandardPaths>
#include "src/autoupdate.h"
static QStringList locales = {"bg", "de", "en", "fr", "it", "mannol", "pirate", "pl", "ru", "fi", "sv", "uk"}; static QStringList locales = {"bg", "de", "en", "fr", "it", "mannol", "pirate", "pl", "ru", "fi", "sv", "uk"};
static QStringList langs = {"Български", "Deustch", "English", "Français", "Italiano", "mannol", "Pirate", "Polski", "Русский", "Suomi", "Svenska", "Українська"}; static QStringList langs = {"Български", "Deustch", "English", "Français", "Italiano", "mannol", "Pirate", "Polski", "Русский", "Suomi", "Svenska", "Українська"};
@ -40,6 +42,9 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) :
bodyUI = new Ui::GeneralSettings; bodyUI = new Ui::GeneralSettings;
bodyUI->setupUi(this); bodyUI->setupUi(this);
bodyUI->checkUpdates->setVisible(AUTOUPDATE_ENABLED);
bodyUI->checkUpdates->setChecked(Settings::getInstance().getCheckUpdates());
bodyUI->cbEnableIPv6->setChecked(Settings::getInstance().getEnableIPv6()); bodyUI->cbEnableIPv6->setChecked(Settings::getInstance().getEnableIPv6());
for (int i = 0; i < langs.size(); i++) for (int i = 0; i < langs.size(); i++)
bodyUI->transComboBox->insertItem(i, langs[i]); bodyUI->transComboBox->insertItem(i, langs[i]);
@ -93,6 +98,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) :
onUseProxyUpdated(); onUseProxyUpdated();
//general //general
connect(bodyUI->checkUpdates, &QCheckBox::stateChanged, this, &GeneralForm::onCheckUpdateChanged);
connect(bodyUI->transComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onTranslationUpdated())); connect(bodyUI->transComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onTranslationUpdated()));
connect(bodyUI->cbMakeToxPortable, &QCheckBox::stateChanged, this, &GeneralForm::onMakeToxPortableUpdated); connect(bodyUI->cbMakeToxPortable, &QCheckBox::stateChanged, this, &GeneralForm::onMakeToxPortableUpdated);
connect(bodyUI->startInTray, &QCheckBox::stateChanged, this, &GeneralForm::onSetAutostartInTray); connect(bodyUI->startInTray, &QCheckBox::stateChanged, this, &GeneralForm::onSetAutostartInTray);
@ -280,3 +286,8 @@ void GeneralForm::reloadSmiles()
bodyUI->smile4->setToolTip(smiles[3]); bodyUI->smile4->setToolTip(smiles[3]);
bodyUI->smile5->setToolTip(smiles[4]); bodyUI->smile5->setToolTip(smiles[4]);
} }
void GeneralForm::onCheckUpdateChanged()
{
Settings::getInstance().setCheckUpdates(bodyUI->checkUpdates->isChecked());
}

View File

@ -51,6 +51,7 @@ private slots:
void onReconnectClicked(); void onReconnectClicked();
void onAutoAcceptFileChange(); void onAutoAcceptFileChange();
void onAutoSaveDirChange(); void onAutoSaveDirChange();
void onCheckUpdateChanged();
private: private:
Ui::GeneralSettings *bodyUI; Ui::GeneralSettings *bodyUI;

View File

@ -40,7 +40,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>511</width> <width>511</width>
<height>739</height> <height>720</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,1"> <layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,1">
@ -121,6 +121,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="checkUpdates">
<property name="text">
<string>Check for updates on startup (unstable)</string>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item alignment="Qt::AlignLeft"> <item alignment="Qt::AlignLeft">

View File

@ -245,6 +245,11 @@ void Widget::init()
coreThread->start(); coreThread->start();
addFriendForm->show(*ui); addFriendForm->show(*ui);
#if (AUTOUPDATE_ENABLED)
if (Settings::getInstance().getCheckUpdates())
AutoUpdater::checkUpdatesAsyncInteractive();
#endif
} }
void Widget::setTranslation() void Widget::setTranslation()
@ -1096,3 +1101,20 @@ void Widget::setEnabledThreadsafe(bool enabled)
return setEnabled(enabled); return setEnabled(enabled);
} }
} }
bool Widget::askMsgboxQuestion(const QString& title, const QString& msg)
{
// We can only display widgets from the GUI thread
if (QThread::currentThread() != qApp->thread())
{
bool ret;
QMetaObject::invokeMethod(this, "askMsgboxQuestion", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(const QString&, title), Q_ARG(const QString&, msg));
return ret;
}
else
{
return QMessageBox::question(this, title, msg) == QMessageBox::StandardButton::Yes;
}
}

View File

@ -67,6 +67,7 @@ public:
Q_INVOKABLE QMessageBox::StandardButton showWarningMsgBox(const QString& title, const QString& msg, Q_INVOKABLE QMessageBox::StandardButton showWarningMsgBox(const QString& title, const QString& msg,
QMessageBox::StandardButtons buttonss = QMessageBox::Ok); QMessageBox::StandardButtons buttonss = QMessageBox::Ok);
Q_INVOKABLE void setEnabledThreadsafe(bool enabled); Q_INVOKABLE void setEnabledThreadsafe(bool enabled);
Q_INVOKABLE bool askMsgboxQuestion(const QString& title, const QString& msg);
~Widget(); ~Widget();
virtual void closeEvent(QCloseEvent *event); virtual void closeEvent(QCloseEvent *event);