Commit acd97ebe authored by Andreas Traczyk's avatar Andreas Traczyk Committed by Ming Rui Zhang

updater: implement UI-less and scheduled updates

Change-Id: I75e8bef00ebb9ef9cb41966f0447858546805dbe
parent ec339e65
......@@ -15,86 +15,89 @@
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
#include "downloadmanger.h"
#include "downloadmanager.h"
#include "updatedownloaddialog.h"
#include "utils.h"
#include <QMessageBox>
#include <windows.h>
DownloadManager::DownloadManager(QObject* parent)
: QObject(parent)
{
//Download it into %TEMP%
downloadpath_ = WinGetEnv("TEMP");
}
DownloadManager::DownloadManager()
{}
void DownloadManager::doDownload(const QUrl& url)
void DownloadManager::downloadFile(const QUrl& fileUrl,
const QString& path,
bool withUI,
std::function<void(int)> doneCb)
{
QFileInfo fileInfo(url.path());
QString fileName = fileInfo.fileName();
if (currentDownload_ && currentDownload_->isRunning()) {
qWarning() << "DownloadManager::downloadFile - currently downloading";
return;
}
if (fileName.isEmpty())
fileName = "download";
doneCb_ = doneCb;
withUI_ = withUI;
QFileInfo fileInfo(fileUrl.path());
QString fileName = fileInfo.fileName();
file_.reset(new QFile(downloadpath_ + "/" + fileName));
file_.reset(new QFile(path + "/" + fileName));
if (!file_->open(QIODevice::WriteOnly)) {
QMessageBox::critical(0, "Error!", "Unable to Open File Path");
QMessageBox::critical(0,
tr("Update"),
tr("Unable to open file for writing"));
file_.reset(nullptr);
return;
}
QNetworkRequest request(url);
// get() method posts a request
// to obtain the contents of the target request
// and returns a new QNetworkReply object
// opened for reading which emits
// the readyRead() signal whenever new data arrives.
downloadTime_.start();
QNetworkRequest request(fileUrl);
currentDownload_ = manager_.get(request);
downloadTime_.start();
currentDownload_->disconnect();
connect(currentDownload_, SIGNAL(finished()), this, SLOT(slotDownloadFinished()));
connect(currentDownload_, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(slotDownloadProgress(qint64, qint64)));
connect(currentDownload_, SIGNAL(readyRead()), this, SLOT(slotHttpReadyRead()));
#if QT_CONFIG(ssl)
connect(currentDownload_, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(getsslErrors(QList<QSslError>)));
connect(currentDownload_, SIGNAL(sslErrors(const QList<QSslError>&)), this, SLOT(slotSslErrors(QList<QSslError>)));
#endif
//downloadProgress() signal is emitted when data is received
connect(currentDownload_, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
// This signal is emitted when the reply has finished processing.
// After this signal is emitted,
// there will be no more updates to the reply's data or metadata.
connect(currentDownload_, SIGNAL(finished()), this, SLOT(downloadFinished()));
// Whenever more data is received from the network,
// this readyRead() signal is emitted
connect(currentDownload_, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
probar_.exec();
if (withUI_) {
progressBar_.exec();
}
}
void DownloadManager::downloadFinished()
void DownloadManager::slotDownloadFinished()
{
// donload finished normally
statusCode_ = currentDownload_->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (statusCode_ != 200) {
QMessageBox::critical(0, "Error!", "DownLoad Failed!");
}
probar_.setMaximum(0);
probar_.setValue(0);
file_->flush();
file_->close();
currentDownload_->deleteLater();
currentDownload_ = nullptr;
file_->flush();
file_->close();
file_.reset(nullptr);
probar_.setValue(0);
probar_.update("0");
probar_.close();
if (withUI_) {
progressBar_.setMaximum(0);
progressBar_.setValue(0);
progressBar_.update("0");
progressBar_.close();
}
if (doneCb_)
doneCb_(statusCode_);
}
void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
void DownloadManager::slotDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
probar_.setMaximum(bytesTotal);
probar_.setValue(bytesReceived);
progressBar_.setMaximum(bytesTotal);
progressBar_.setValue(bytesReceived);
int presentTime = downloadTime_.elapsed();
// calculate the download speed
......@@ -115,10 +118,10 @@ void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
unit = "MB/s";
}
probar_.update(QString::number(speed) + " " + unit);
progressBar_.update(QString::number(speed) + " " + unit);
}
void DownloadManager::httpReadyRead()
void DownloadManager::slotHttpReadyRead()
{
// this slot gets called every time the QNetworkReply has new data.
// We read all of its new data and write it into the file.
......@@ -128,33 +131,11 @@ void DownloadManager::httpReadyRead()
file_->write(currentDownload_->readAll());
}
QString DownloadManager::versionOnline()
{
QString urlstr = "https://dl.jami.net/windows/version";
QUrl url = QUrl::fromEncoded(urlstr.toLocal8Bit());
doDownload(url);
if (statusCode_ != 200) {
QMessageBox::critical(0, "Version Check Error", "Version Cannot Be Verified");
return "Null";
}
QFile file(downloadpath_ + "/" + "version");
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::critical(0, "Version Check Error", "File cannnot be openned");
return "Null";
}
QTextStream in(&file);
QString onlineVersion = in.readLine();
file.close();
return onlineVersion;
}
void DownloadManager::getsslErrors(const QList<QSslError>& sslErrors)
void DownloadManager::slotSslErrors(const QList<QSslError>& sslErrors)
{
#if QT_CONFIG(ssl)
for (const QSslError& error : sslErrors)
QMessageBox::critical(0, "SSL Error ", error.errorString());
QMessageBox::critical(0, tr("Update"), error.errorString());
return;
#else
Q_UNUSED(sslErrors);
......@@ -165,14 +146,3 @@ int DownloadManager::getDownloadStatus()
{
return statusCode_;
}
const char* DownloadManager::WinGetEnv(const char* name)
{
const DWORD buffSize = 65535;
static char buffer[buffSize];
if (GetEnvironmentVariableA(name, buffer, buffSize)) {
return buffer;
} else {
return 0;
}
}
......@@ -29,27 +29,37 @@ class QSslError;
class DownloadManager : public QObject {
Q_OBJECT
public:
static DownloadManager& instance() {
static DownloadManager* instance_ = new DownloadManager();
return *instance_;
}
void downloadFile(const QUrl& fileUrl,
const QString& path,
bool withUI,
std::function<void(int)> doneCb = {});
int getDownloadStatus();
public slots:
void slotSslErrors(const QList<QSslError>& sslErrors);
void slotDownloadFinished();
void slotDownloadProgress(qint64 bytesRead, qint64 totalBytes);
void slotHttpReadyRead();
private:
DownloadManager();
QNetworkAccessManager manager_;
QNetworkReply* currentDownload_;
updateDownloadDialog probar_;
updateDownloadDialog progressBar_;
std::unique_ptr<QFile> file_;
QTime downloadTime_;
int previousTime_ = 0;
qint64 previousDownloadBytes_ = 0;
QString downloadpath_;
int statusCode_;
bool withUI_;
public:
explicit DownloadManager(QObject* parent = nullptr);
void doDownload(const QUrl& url);
QString versionOnline();
static const char* WinGetEnv(const char* name);
int getDownloadStatus();
std::function<void(int)> doneCb_;
public slots:
void getsslErrors(const QList<QSslError>& sslErrors);
void downloadFinished();
void downloadProgress(qint64 bytesRead, qint64 totalBytes);
void httpReadyRead();
};
......@@ -35,7 +35,7 @@
#include <ciso646>
#include "downloadmanger.h"
#include "downloadmanager.h"
#include "lrcinstance.h"
#include "pixbufmanipulator.h"
#include "runguard.h"
......@@ -265,20 +265,6 @@ main(int argc, char* argv[])
});
#endif
//Delet all logs and msi in the %TEMP% directory before launching
QString dir = QString(DownloadManager::WinGetEnv("TEMP"));
QDir log_dir(dir, {"jami*.log"});
for (const QString& filename : log_dir.entryList()) {
log_dir.remove(filename);
}
QDir msi_dir(dir, {"jami*.msi"});
for (const QString& filename : msi_dir.entryList()) {
msi_dir.remove(filename);
}
QDir version_dir(dir, {"version"});
for (const QString& filename : version_dir.entryList()) {
version_dir.remove(filename);
}
auto ret = a.exec();
#ifdef Q_OS_WIN
......
......@@ -166,6 +166,13 @@ MainWindow::MainWindow(QWidget* parent)
lastScr_ = startScreen;
// check for updates and start automatic update check
Utils::checkForUpdates(false, this);
updateTimer_ = new QTimer(this);
connect(updateTimer_, &QTimer::timeout, [this]() { Utils::checkForUpdates(false, this); });
long updateCheckDelay = 4 * 24 * 60 * 60 * 1000;
updateTimer_->start(updateCheckDelay);
#ifdef DEBUG_STYLESHEET
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout,
......@@ -187,6 +194,7 @@ MainWindow::MainWindow(QWidget* parent)
MainWindow::~MainWindow()
{
updateTimer_->stop();
delete ui;
}
......
......@@ -89,4 +89,6 @@ private:
Ui::MainWindow* ui;
QNetworkConfigurationManager netManager_;
QMetaObject::Connection screenChangedConnection_;
QTimer *updateTimer_;
};
......@@ -232,7 +232,7 @@
<ClCompile Include="currentaccountcombobox.cpp" />
<ClCompile Include="aboutdialog.cpp" />
<ClCompile Include="updatedownloaddialog.cpp" />
<ClCompile Include="downloadmanger.cpp" />
<ClCompile Include="downloadmanager.cpp" />
<ClCompile Include="accountitemdelegate.cpp" />
<ClCompile Include="accountlistmodel.cpp" />
<ClCompile Include="callwidget.cpp">
......@@ -400,7 +400,7 @@
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='ReleaseCompile|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
</QtMoc>
<QtMoc Include="downloadmanger.h">
<QtMoc Include="downloadmanager.h">
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='ReleaseCompile|x64'">.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;$(ProjectDir)..\ring-daemon\contrib\msvc\include;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\ring-lrc\src;$(ProjectDir)..\lrc\src;$(ProjectDir)winsparkle\include;$(ProjectDir)qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWebEngineWidgets;$(QTDIR)\include\QtWebChannel;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
</QtMoc>
......
......@@ -150,9 +150,6 @@
<ClCompile Include="webchathelpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="downloadmanger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="animationhelpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
......@@ -210,6 +207,9 @@
<ClCompile Include="updatedownloaddialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="downloadmanager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="aboutdialog.h">
......@@ -305,9 +305,6 @@
<QtMoc Include="animationhelpers.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="downloadmanger.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="passworddialog.h">
<Filter>Header Files</Filter>
</QtMoc>
......@@ -359,6 +356,9 @@
<QtMoc Include="updatedownloaddialog.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="downloadmanager.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
......
......@@ -36,14 +36,12 @@
#include <QtConcurrent/QtConcurrent>
#include "deleteaccountdialog.h"
#include "downloadmanger.h"
#include "nameregistrationdialog.h"
#include "passworddialog.h"
#include "settingskey.h"
#include "utils.h"
#include "deviceitemwidget.h"
#include "banneditemwidget.h"
#include "updateconfirmdialog.h"
#include "version.h"
#include "api/newdevicemodel.h"
......@@ -863,33 +861,7 @@ void SettingsWidget::slotSetClosedOrMin(bool state)
void SettingsWidget::checkForUpdateSlot()
{
DownloadManager manager;
UpdateConfirmDialog updateDialog(this);
QString onlineVersion = manager.versionOnline();
int currentVersion = QString(VERSION_STRING).toInt();
if (onlineVersion != "Null" && onlineVersion.toInt() > currentVersion) {
auto ret = updateDialog.exec();
QThread::sleep(1);
if (ret == QDialog::Accepted) {
QString urlstr = "https://dl.jami.net/windows/jami-x64.msi";
QUrl url = QUrl::fromEncoded(urlstr.toLocal8Bit());
manager.doDownload(url);
if (manager.getDownloadStatus() != 200) {
QMessageBox::critical(0, "Download Status", "Installer Download Failed, Please Contact Support");
return;
}
auto args = QString(" /passive /norestart WIXNONUILAUNCH=1");
auto dir = DownloadManager::WinGetEnv("TEMP");
auto cmd = "powershell " + QString(dir) + "\\jami-x64.msi"
+ " /L*V " + QString(dir) + "\\jami_x64_install.log" + args;
auto retq = QProcess::startDetached(cmd);
if (retq) {
QApplication::quit();
}
}
} else {
QMessageBox::information(0, "Update Status", "No New Version Detected");
}
Utils::checkForUpdates(true, this);
/*
#ifdef Q_OS_WIN
win_sparkle_check_update_with_ui();
......
......@@ -24,9 +24,6 @@ UpdateConfirmDialog::UpdateConfirmDialog(QWidget* parent)
{
ui->setupUi(this);
connect(ui->btnUpdateAccept, &QPushButton::clicked, this, &UpdateConfirmDialog::on_updateAcceptBtn_clicked);
connect(ui->btnUpdateCancel, &QPushButton::clicked, this, &UpdateConfirmDialog::on_updateCancelBtn_clicked);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
}
......
......@@ -34,8 +34,6 @@ public:
private slots:
void on_updateCancelBtn_clicked();
void on_updateAcceptBtn_clicked();
signals:
void deleteAcceptClicked();
private:
Ui::UpdateConfirmDialog* ui;
......
......@@ -10,7 +10,7 @@
<x>0</x>
<y>0</y>
<width>400</width>
<height>240</height>
<height>200</height>
</rect>
</property>
<property name="sizePolicy">
......@@ -22,22 +22,38 @@
<property name="minimumSize">
<size>
<width>400</width>
<height>240</height>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>240</height>
<height>200</height>
</size>
</property>
<property name="windowTitle">
<string>Update Confirm</string>
<string>Jami Update</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,0,0">
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,0,0,0">
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="labelDeletion">
<property name="maximumSize">
......@@ -48,11 +64,11 @@
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>New Version Detected, Do you want to update now?</string>
<string>New version detected, do you want to update now?</string>
</property>
</widget>
</item>
......@@ -62,12 +78,12 @@
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
<height>40</height>
</size>
</property>
</spacer>
......@@ -88,14 +104,14 @@
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<pointsize>10</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
<property name="text">
<string>This update will close your Jami automatically, please be aware of your unsent messages</string>
<string>This update will restart Jami automatically</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
......@@ -114,12 +130,12 @@
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
<height>40</height>
</size>
</property>
</spacer>
......@@ -152,7 +168,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnUpdateAccept">
<widget class="QPushButton" name="updateAcceptBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
......@@ -173,7 +189,7 @@
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<pointsize>10</pointsize>
</font>
</property>
<property name="toolTip">
......@@ -183,7 +199,7 @@
<string notr="true"/>
</property>
<property name="text">
<string>Yes</string>
<string>Install</string>
</property>
</widget>
</item>
......@@ -201,7 +217,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnUpdateCancel">
<widget class="QPushButton" name="updateCancelBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
......@@ -216,7 +232,7 @@
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<pointsize>10</pointsize>
</font>
</property>
<property name="toolTip">
......@@ -256,7 +272,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
<height>20</height>
</size>
</property>
</spacer>
......
......@@ -37,12 +37,16 @@
#include <QPropertyAnimation>
#include <QApplication>
#include <QFile>
#include <QMessageBox>
#include <globalinstances.h>
#include "pixbufmanipulator.h"
#include "globalsystemtray.h"
#include "lrcinstance.h"
#include "downloadmanager.h"
#include "updateconfirmdialog.h"
#include "version.h"
bool
Utils::CreateStartupLink()
......@@ -232,6 +236,117 @@ void Utils::showSystemNotification(QWidget* widget,
QApplication::alert(widget, delay);
}
const char*
Utils::WinGetEnv(const char* name)
{
const DWORD buffSize = 65535;
static char buffer[buffSize];
if (GetEnvironmentVariableA(name, buffer, buffSize)) {
return buffer;
} else {
return 0;
}
}
void
Utils::cleanUpdateFiles()
{
// Delete all logs and msi in the %TEMP% directory before launching
QString dir = QString(Utils::WinGetEnv("TEMP"));
QDir log_dir(dir, { "jami*.log" });
for (const QString& filename : log_dir.entryList()) {
log_dir.remove(filename);
}
QDir msi_dir(dir, { "jami*.msi" });
for (const QString& filename : msi_dir.entryList()) {
msi_dir.remove(filename);
}
QDir version_dir(dir, { "version" });
for (const QString& filename : version_dir.entryList()) {
version_dir.remove(filename);
}
}
void
Utils::checkForUpdates(bool withUI, QWidget* parent)
{
Utils::cleanUpdateFiles();
QString downloadpath = WinGetEnv("TEMP");
DownloadManager::instance().downloadFile(
QUrl::fromEncoded("https://dl.jami.net/windows/version"),
downloadpath,
withUI,
[parent, withUI, downloadpath](int status) {
if (status != 200) {
if (withUI)
QMessageBox::critical(0,
QObject::tr("Update"),
QObject::tr("Version cannot be verified"));
return;
}
QFile file(downloadpath + "/" + "version");
if (!file.open(QIODevice::ReadOnly)) {
if (withUI)
QMessageBox::critical(0,
QObject::tr("Update"),
QObject::tr("File cannnot be opened"));
return;
}
QTextStream in(&file);
QString onlineVersion = in.readLine();
file.close();
int currentVersion = QString(VERSION_STRING).toInt();
if (onlineVersion.isEmpty()) {
qWarning() << "No version file found";
} else if (onlineVersion.toInt() > currentVersion) {
qDebug() << "New version found";
Utils::applyUpdates(parent);
} else {
qDebug() << "No new version found";
if (withUI) {
QMessageBox::information(0,
QObject::tr("Update"),
QObject::tr("No new version found"));
}
}
});
}
void
Utils::applyUpdates(QWidget* parent)
{
if (!parent->findChild<UpdateConfirmDialog*>()) {
UpdateConfirmDialog updateDialog(parent);
auto ret = updateDialog.exec();
if (ret != QDialog::Accepted)
return;
} else
return;
DownloadManager::instance().downloadFile(
QUrl::fromEncoded("https://dl.jami.net/windows/jami-x64.msi"),
WinGetEnv("TEMP"),
true,
[parent](int status) {
if (status != 200) {
QMessageBox::critical(0,
QObject::tr("Update"),
QObject::tr("Installer download failed, please contact support"));
return;
}
auto args = QString(" /passive /norestart WIXNONUILAUNCH=1");
auto dir = Utils::WinGetEnv("TEMP");
auto cmd = "powershell " + QString(dir) + "\\jami-x64.msi"
+ " /L*V " + QString(dir) + "\\jami_x64_install.log" + args;
auto retq = QProcess::startDetached(cmd);
if (retq) {
QCoreApplication::exit();
}
});
}
// new lrc helpers
inline std::string
......
......@@ -64,6 +64,12 @@ namespace Utils
void setStackWidget(QStackedWidget *stack, QWidget *widget);
void showSystemNotification(QWidget* widget, const QString& message, long delay = 5000);
void showSystemNotification(QWidget* widget, const QString& sender, const QString& message, long delay = 5000);
const char* WinGetEnv(const char* name);
// updates
void cleanUpdateFiles();
void checkForUpdates(bool withUI, QWidget* parent = nullptr);