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.
This commit is contained in:
Florian Märkl 2022-07-02 14:23:13 +02:00
parent bd49557cab
commit 2529196df0
2 changed files with 9 additions and 179 deletions

View File

@ -52,29 +52,6 @@ void UpdateWorker::checkCurrentVersion(time_t timeoutMs)
pending = true; 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) void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
{ {
QMessageBox mb; QMessageBox mb;
@ -82,69 +59,23 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton)
mb.setText(tr("There is an update available for Cutter.<br/>") + "<b>" + tr("Current version:") mb.setText(tr("There is an update available for Cutter.<br/>") + "<b>" + tr("Current version:")
+ "</b> " CUTTER_VERSION_FULL "<br/>" + "<b>" + tr("Latest version:") + "</b> " + "</b> " CUTTER_VERSION_FULL "<br/>" + "<b>" + tr("Latest version:") + "</b> "
+ latestVersion.toString() + "<br/><br/>" + latestVersion.toString() + "<br/><br/>"
+ tr("For update, please check the link:<br/>") + tr("To update, please check the link:<br/>")
+ QString("<a href=\"https://github.com/rizinorg/cutter/releases/tag/v%1\">" + QString("<a href=\"https://github.com/rizinorg/cutter/releases/tag/v%1\">"
"https://github.com/rizinorg/cutter/releases/tag/v%1</a><br/>") "https://github.com/rizinorg/cutter/releases/tag/v%1</a><br/>")
.arg(latestVersion.toString()) .arg(latestVersion.toString()));
+ tr("or click \"Download\" to download latest version of Cutter."));
if (showDontCheckForUpdatesButton) { if (showDontCheckForUpdatesButton) {
mb.setStandardButtons(QMessageBox::Save | QMessageBox::Reset | QMessageBox::Ok); mb.setStandardButtons(QMessageBox::Reset | QMessageBox::Ok);
mb.button(QMessageBox::Reset)->setText(tr("Don't check for updates")); mb.button(QMessageBox::Reset)->setText(tr("Don't check for updates automatically"));
} else { } else {
mb.setStandardButtons(QMessageBox::Save | QMessageBox::Ok); mb.setStandardButtons(QMessageBox::Ok);
} }
mb.button(QMessageBox::Save)->setText(tr("Download"));
mb.setDefaultButton(QMessageBox::Ok); mb.setDefaultButton(QMessageBox::Ok);
int ret = mb.exec(); int ret = mb.exec();
if (ret == QMessageBox::Reset) { if (ret == QMessageBox::Reset) {
Config()->setAutoUpdateEnabled(false); 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() void UpdateWorker::serveVersionCheckReply()
{ {
pending = false; pending = false;
@ -168,51 +99,6 @@ void UpdateWorker::serveVersionCheckReply()
emit checkComplete(versionReply, errStr); 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() QVersionNumber UpdateWorker::currentVersionNumber()
{ {
return QVersionNumber(CUTTER_VERSION_MAJOR, CUTTER_VERSION_MINOR, CUTTER_VERSION_PATCH); return QVersionNumber(CUTTER_VERSION_MAJOR, CUTTER_VERSION_MINOR, CUTTER_VERSION_PATCH);

View File

@ -23,8 +23,7 @@ class QNetworkReply;
/** /**
* @class UpdateWorker * @class UpdateWorker
* @brief The UpdateWorker class is a class providing API to check for current Cutter version * @brief The UpdateWorker class is a class providing API to check for current Cutter version.
* and download specific version of one.
*/ */
class UpdateWorker : public QObject class UpdateWorker : public QObject
@ -47,23 +46,12 @@ public:
void checkCurrentVersion(time_t timeoutMs); 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() * @fn void UpdateWorker::showUpdateDialog()
* *
* Shows dialog that allows user to either download latest version of Cutter from website * Shows dialog that allows user to download latest version of Cutter from website.
* or download it by clicking on a button. This dialog also has "Don't check for updates" * This dialog also has "Don't check for updates" button which disables on-start update
* button which disables on-start update checks if @a showDontCheckForUpdatesButton is true. * checks if @a showDontCheckForUpdatesButton is true.
*
* @sa downloadProcess(size_t bytesReceived, size_t bytesTotal)
*/ */
void showUpdateDialog(bool showDontCheckForUpdatesButton); void showUpdateDialog(bool showDontCheckForUpdatesButton);
@ -73,18 +61,6 @@ public:
*/ */
static QVersionNumber currentVersionNumber(); 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: signals:
/** /**
* @fn UpdateWorker::checkComplete(const QString& verson, const QString& errorMsg) * @fn UpdateWorker::checkComplete(const QString& verson, const QString& errorMsg)
@ -95,46 +71,14 @@ signals:
*/ */
void checkComplete(const QVersionNumber &currVerson, const QString &errorMsg); 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: private slots:
void serveVersionCheckReply(); void serveVersionCheckReply();
void serveDownloadFinish();
void process(size_t bytesReceived, size_t bytesTotal);
private:
QString getRepositeryExt() const;
QString getRepositoryFileName() const;
private: private:
QNetworkAccessManager nm; QNetworkAccessManager nm;
QVersionNumber latestVersion; QVersionNumber latestVersion;
QTimer t; QTimer t;
bool pending; bool pending;
QFile downloadFile;
QNetworkReply *downloadReply;
QNetworkReply *checkReply; QNetworkReply *checkReply;
}; };