From 2529196df07a1b726ca017698317f9a0629079bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sat, 2 Jul 2022 14:23:13 +0200 Subject: [PATCH] Remove direct download from update check (#2989) Hardcoded prediction of filenames for future releases is too prone to break, which is what happened with v2.1.0. So better to provide the link to the release page only. --- src/common/UpdateWorker.cpp | 124 ++---------------------------------- src/common/UpdateWorker.h | 64 ++----------------- 2 files changed, 9 insertions(+), 179 deletions(-) diff --git a/src/common/UpdateWorker.cpp b/src/common/UpdateWorker.cpp index 1514bc38..065e19c2 100644 --- a/src/common/UpdateWorker.cpp +++ b/src/common/UpdateWorker.cpp @@ -52,29 +52,6 @@ void UpdateWorker::checkCurrentVersion(time_t timeoutMs) pending = true; } -void UpdateWorker::download(QString filename, QString version) -{ - downloadFile.setFileName(filename); - downloadFile.open(QIODevice::WriteOnly); - - QNetworkRequest request; -# if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) && QT_VERSION < QT_VERSION_CHECK(5, 9, 0) - request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); -# elif QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) - request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, - QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); -# endif - QUrl url(QString("https://github.com/rizinorg/cutter/releases/" - "download/v%1/%2") - .arg(version) - .arg(getRepositoryFileName())); - request.setUrl(url); - - downloadReply = nm.get(request); - connect(downloadReply, &QNetworkReply::downloadProgress, this, &UpdateWorker::process); - connect(downloadReply, &QNetworkReply::finished, this, &UpdateWorker::serveDownloadFinish); -} - void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton) { QMessageBox mb; @@ -82,69 +59,23 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton) mb.setText(tr("There is an update available for Cutter.
") + "" + tr("Current version:") + " " CUTTER_VERSION_FULL "
" + "" + tr("Latest version:") + " " + latestVersion.toString() + "

" - + tr("For update, please check the link:
") + + tr("To update, please check the link:
") + QString("" "https://github.com/rizinorg/cutter/releases/tag/v%1
") - .arg(latestVersion.toString()) - + tr("or click \"Download\" to download latest version of Cutter.")); + .arg(latestVersion.toString())); if (showDontCheckForUpdatesButton) { - mb.setStandardButtons(QMessageBox::Save | QMessageBox::Reset | QMessageBox::Ok); - mb.button(QMessageBox::Reset)->setText(tr("Don't check for updates")); + mb.setStandardButtons(QMessageBox::Reset | QMessageBox::Ok); + mb.button(QMessageBox::Reset)->setText(tr("Don't check for updates automatically")); } else { - mb.setStandardButtons(QMessageBox::Save | QMessageBox::Ok); + mb.setStandardButtons(QMessageBox::Ok); } - mb.button(QMessageBox::Save)->setText(tr("Download")); mb.setDefaultButton(QMessageBox::Ok); int ret = mb.exec(); if (ret == QMessageBox::Reset) { Config()->setAutoUpdateEnabled(false); - } else if (ret == QMessageBox::Save) { - QString fullFileName = QFileDialog::getSaveFileName( - nullptr, tr("Choose directory for downloading"), - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QDir::separator() - + getRepositoryFileName(), - QString("%1 (*.%1)").arg(getRepositeryExt())); - if (!fullFileName.isEmpty()) { - QProgressDialog progressDial(tr("Downloading update..."), tr("Cancel"), 0, 100); - connect(this, &UpdateWorker::downloadProcess, &progressDial, - [&progressDial](size_t curr, size_t total) { - progressDial.setValue(100.0f * curr / total); - }); - connect(&progressDial, &QProgressDialog::canceled, this, &UpdateWorker::abortDownload); - connect(this, &UpdateWorker::downloadFinished, &progressDial, &QProgressDialog::cancel); - connect(this, &UpdateWorker::downloadFinished, this, [](QString filePath) { - QMessageBox info(QMessageBox::Information, tr("Download finished!"), - tr("Latest version of Cutter was succesfully downloaded!"), - QMessageBox::Yes | QMessageBox::Open | QMessageBox::Ok, nullptr); - info.button(QMessageBox::Open)->setText(tr("Open file")); - info.button(QMessageBox::Yes)->setText(tr("Open download folder")); - int r = info.exec(); - if (r == QMessageBox::Open) { - QDesktopServices::openUrl(filePath); - } else if (r == QMessageBox::Yes) { - auto path = filePath.split('/'); - path.removeLast(); - QDesktopServices::openUrl(path.join('/')); - } - }); - download(fullFileName, latestVersion.toString()); - // Calling show() before exec() is only way make dialog non-modal - // it seems weird, but it works - progressDial.show(); - progressDial.exec(); - } } } -void UpdateWorker::abortDownload() -{ - disconnect(downloadReply, &QNetworkReply::finished, this, &UpdateWorker::serveDownloadFinish); - disconnect(downloadReply, &QNetworkReply::downloadProgress, this, &UpdateWorker::process); - downloadReply->close(); - downloadReply->deleteLater(); - downloadFile.remove(); -} - void UpdateWorker::serveVersionCheckReply() { pending = false; @@ -168,51 +99,6 @@ void UpdateWorker::serveVersionCheckReply() emit checkComplete(versionReply, errStr); } -void UpdateWorker::serveDownloadFinish() -{ - downloadReply->close(); - downloadReply->deleteLater(); - if (downloadReply->error()) { - emit downloadError(downloadReply->errorString()); - } else { - emit downloadFinished(downloadFile.fileName()); - } -} - -void UpdateWorker::process(size_t bytesReceived, size_t bytesTotal) -{ - downloadFile.write(downloadReply->readAll()); - emit downloadProcess(bytesReceived, bytesTotal); -} - -QString UpdateWorker::getRepositeryExt() const -{ -# ifdef Q_OS_LINUX - return "AppImage"; -# elif defined(Q_OS_WIN64) || defined(Q_OS_WIN32) - return "zip"; -# elif defined(Q_OS_MACOS) - return "dmg"; -# endif -} - -QString UpdateWorker::getRepositoryFileName() const -{ - QString downloadFileName; -# ifdef Q_OS_LINUX - downloadFileName = "Cutter-v%1-x%2.Linux.AppImage"; -# elif defined(Q_OS_WIN64) || defined(Q_OS_WIN32) - downloadFileName = "Cutter-v%1-x%2.Windows.zip"; -# elif defined(Q_OS_MACOS) - downloadFileName = "Cutter-v%1-x%2.macOS.dmg"; -# endif - downloadFileName = - downloadFileName.arg(latestVersion.toString()) - .arg(QSysInfo::buildAbi().split('-').at(2).contains("64") ? "64" : "32"); - - return downloadFileName; -} - QVersionNumber UpdateWorker::currentVersionNumber() { return QVersionNumber(CUTTER_VERSION_MAJOR, CUTTER_VERSION_MINOR, CUTTER_VERSION_PATCH); diff --git a/src/common/UpdateWorker.h b/src/common/UpdateWorker.h index 61b8d038..46854f87 100644 --- a/src/common/UpdateWorker.h +++ b/src/common/UpdateWorker.h @@ -23,8 +23,7 @@ class QNetworkReply; /** * @class UpdateWorker - * @brief The UpdateWorker class is a class providing API to check for current Cutter version - * and download specific version of one. + * @brief The UpdateWorker class is a class providing API to check for current Cutter version. */ class UpdateWorker : public QObject @@ -47,23 +46,12 @@ public: void checkCurrentVersion(time_t timeoutMs); - /** - * @fn void UpdateWorker::download(QDir downloadPath, QString version) - * - * @brief Downloads provided @a version of Cutter into @a downloadDir. - * - * @sa downloadProcess(size_t bytesReceived, size_t bytesTotal) - */ - void download(QString filename, QString version); - /** * @fn void UpdateWorker::showUpdateDialog() * - * Shows dialog that allows user to either download latest version of Cutter from website - * or download it by clicking on a button. This dialog also has "Don't check for updates" - * button which disables on-start update checks if @a showDontCheckForUpdatesButton is true. - * - * @sa downloadProcess(size_t bytesReceived, size_t bytesTotal) + * Shows dialog that allows user to download latest version of Cutter from website. + * This dialog also has "Don't check for updates" button which disables on-start update + * checks if @a showDontCheckForUpdatesButton is true. */ void showUpdateDialog(bool showDontCheckForUpdatesButton); @@ -73,18 +61,6 @@ public: */ static QVersionNumber currentVersionNumber(); -public slots: - /** - * @fn void UpdateWorker::abortDownload() - * - * @brief Stops current process of downloading. - * - * @note UpdateWorker::downloadFinished(QString filename) is not send after this function. - * - * @sa download(QDir downloadDir, QString version) - */ - void abortDownload(); - signals: /** * @fn UpdateWorker::checkComplete(const QString& verson, const QString& errorMsg) @@ -95,46 +71,14 @@ signals: */ void checkComplete(const QVersionNumber &currVerson, const QString &errorMsg); - /** - * @fn UpdateWorker::downloadProcess(size_t bytesReceived, size_t bytesTotal) - * - * The signal is emitted each time when some amount of bytes was downloaded. - * May be used as indicator of download progress. - */ - void downloadProcess(size_t bytesReceived, size_t bytesTotal); - - /** - * @fn UpdateWorker::downloadFinished(QString filename) - * - * @brief The signal is emitted as soon as downloading completes. - */ - void downloadFinished(QString filename); - - /** - * @fn UpdateWorker::downloadError(QString errorStr) - * - * @brief The signal is emitted when error occures during download. - */ - void downloadError(QString errorStr); - private slots: void serveVersionCheckReply(); - void serveDownloadFinish(); - - void process(size_t bytesReceived, size_t bytesTotal); - -private: - QString getRepositeryExt() const; - QString getRepositoryFileName() const; - private: QNetworkAccessManager nm; QVersionNumber latestVersion; QTimer t; bool pending; - QFile downloadFile; - QNetworkReply *downloadReply; QNetworkReply *checkReply; };