From 15b11419ff37ada5d077d1ea8f91b5c171e0cbbf Mon Sep 17 00:00:00 2001 From: "J.D. Purcell" Date: Sat, 25 May 2024 12:27:01 -0400 Subject: [PATCH 1/4] Compile update check capability by default --- qView.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qView.pro b/qView.pro index fec7ccc2..617bed27 100644 --- a/qView.pro +++ b/qView.pro @@ -137,8 +137,8 @@ DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_NO_FOREACH # To disables both manual and automatic checking for updates either uncomment line below or -# add config flag while building from the commad line. -CONFIG += qv_disable_online_version_check +# add config flag while building from the command line. +#CONFIG += qv_disable_online_version_check qv_disable_online_version_check { DEFINES += QV_DISABLE_ONLINE_VERSION_CHECK From 61d5be5eae1279148ba46a93f009d3a5925a673b Mon Sep 17 00:00:00 2001 From: "J.D. Purcell" Date: Sat, 25 May 2024 12:38:07 -0400 Subject: [PATCH 2/4] Limit update check API request to latest version --- src/updatechecker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/updatechecker.cpp b/src/updatechecker.cpp index 733842fd..7f8d6e55 100644 --- a/src/updatechecker.cpp +++ b/src/updatechecker.cpp @@ -16,7 +16,7 @@ UpdateChecker::UpdateChecker(QObject *parent) : QObject(parent) void UpdateChecker::check() { - sendRequest(UPDATE_URL); + sendRequest(UPDATE_URL + "/latest"); } void UpdateChecker::sendRequest(const QUrl &url) @@ -49,7 +49,7 @@ void UpdateChecker::readReply(QNetworkReply *reply) return; } - QJsonObject object = json.array().first().toObject(); + QJsonObject object = json.object(); latestVersionNum = object.value("tag_name").toString("0.0").toDouble(); From 836526742907fb9c27d3a425d25f6c4d71892536 Mon Sep 17 00:00:00 2001 From: "J.D. Purcell" Date: Sat, 25 May 2024 12:39:28 -0400 Subject: [PATCH 3/4] Fix/improve changelog processing --- src/updatechecker.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/updatechecker.cpp b/src/updatechecker.cpp index 7f8d6e55..dfbcf5ec 100644 --- a/src/updatechecker.cpp +++ b/src/updatechecker.cpp @@ -53,9 +53,14 @@ void UpdateChecker::readReply(QNetworkReply *reply) latestVersionNum = object.value("tag_name").toString("0.0").toDouble(); - QStringList changelogList = object.value("body").toString().split("\n"); + static const QRegularExpression newLineRegEx("\r?\n"); + QStringList changelogList = object.value("body").toString().split(newLineRegEx); + // remove "changelog" heading changelogList.removeFirst(); - changelog = changelogList.join(""); + // remove additional newline if present + if (!changelogList.isEmpty() && changelogList.first().isEmpty()) + changelogList.removeFirst(); + changelog = changelogList.join("\n"); releaseDate = QDateTime::fromString(object.value("published_at").toString(), Qt::ISODate); releaseDate = releaseDate.toTimeSpec(Qt::LocalTime); @@ -71,7 +76,7 @@ void UpdateChecker::openDialog() auto *msgBox = new QMessageBox(); msgBox->setWindowTitle(tr("qView Update Available")); msgBox->setText(tr("qView %1 is available to download.").arg(QString::number(latestVersionNum, 'f', 1)) - + "\n\n" + releaseDate.toString(locale.dateFormat()) + "\n" + changelog); + + "\n\n" + releaseDate.toString(locale.dateFormat()) + "\n\n" + changelog); msgBox->setWindowModality(Qt::ApplicationModal); msgBox->setStandardButtons(QMessageBox::Close | QMessageBox::Reset); msgBox->button(QMessageBox::Reset)->setText(tr("&Disable Update Checking")); From 4a70c696b7b5349529a05f6e9c9584799bf15007 Mon Sep 17 00:00:00 2001 From: "J.D. Purcell" Date: Sat, 25 May 2024 12:42:33 -0400 Subject: [PATCH 4/4] Rate limit update checks at startup --- src/qvaboutdialog.cpp | 2 +- src/qvapplication.cpp | 6 +++--- src/qvapplication.h | 2 +- src/updatechecker.cpp | 22 +++++++++++++++++++++- src/updatechecker.h | 8 ++++++-- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/qvaboutdialog.cpp b/src/qvaboutdialog.cpp index 9bb26e93..609bad03 100644 --- a/src/qvaboutdialog.cpp +++ b/src/qvaboutdialog.cpp @@ -74,7 +74,7 @@ QVAboutDialog::QVAboutDialog(double givenLatestVersionNum, QWidget *parent) : #ifndef QV_DISABLE_ONLINE_VERSION_CHECK if (latestVersionNum < 0.0) { - qvApp->checkUpdates(); + qvApp->checkUpdates(false); latestVersionNum = 0.0; } #endif //QV_DISABLE_ONLINE_VERSION_CHECK diff --git a/src/qvapplication.cpp b/src/qvapplication.cpp index 58f1bec5..ba62ea3f 100644 --- a/src/qvapplication.cpp +++ b/src/qvapplication.cpp @@ -29,7 +29,7 @@ QVApplication::QVApplication(int &argc, char **argv) : QApplication(argc, argv) // Check for updates // TODO: move this to after first window show event if (getSettingsManager().getBoolean("updatenotifications")) { - checkUpdates(); + checkUpdates(true); } // Setup macOS dock menu @@ -196,10 +196,10 @@ MainWindow *QVApplication::getMainWindow(bool shouldBeEmpty) return window; } -void QVApplication::checkUpdates() +void QVApplication::checkUpdates(bool isStartupCheck) { #ifndef QV_DISABLE_ONLINE_VERSION_CHECK - updateChecker.check(); + updateChecker.check(isStartupCheck); #endif // QV_DISABLE_ONLINE_VERSION_CHECK } diff --git a/src/qvapplication.h b/src/qvapplication.h index 7d71c303..55b9bd74 100644 --- a/src/qvapplication.h +++ b/src/qvapplication.h @@ -41,7 +41,7 @@ class QVApplication : public QApplication MainWindow *getMainWindow(bool shouldBeEmpty); - void checkUpdates(); + void checkUpdates(bool isStartupCheck); void checkedUpdates(); diff --git a/src/updatechecker.cpp b/src/updatechecker.cpp index dfbcf5ec..baf1288b 100644 --- a/src/updatechecker.cpp +++ b/src/updatechecker.cpp @@ -14,8 +14,15 @@ UpdateChecker::UpdateChecker(QObject *parent) : QObject(parent) connect(&netAccessManager, &QNetworkAccessManager::finished, this, &UpdateChecker::readReply); } -void UpdateChecker::check() +void UpdateChecker::check(bool isStartupCheck) { + if (isStartupCheck) + { + QDateTime lastCheckTime = getLastCheckTime(); + if (lastCheckTime.isValid() && QDateTime::currentDateTimeUtc() < lastCheckTime.addSecs(STARTUP_CHECK_INTERVAL_HOURS * 3600)) + return; + } + sendRequest(UPDATE_URL + "/latest"); } @@ -65,9 +72,22 @@ void UpdateChecker::readReply(QNetworkReply *reply) releaseDate = QDateTime::fromString(object.value("published_at").toString(), Qt::ISODate); releaseDate = releaseDate.toTimeSpec(Qt::LocalTime); + setLastCheckTime(QDateTime::currentDateTimeUtc()); + emit checkedUpdates(); } +QDateTime UpdateChecker::getLastCheckTime() const +{ + qint64 secsSinceEpoch = QSettings().value("lastupdatecheck").toLongLong(); + return secsSinceEpoch == 0 ? QDateTime() : QDateTime::fromSecsSinceEpoch(secsSinceEpoch, Qt::UTC); +} + +void UpdateChecker::setLastCheckTime(QDateTime value) +{ + QSettings().setValue("lastupdatecheck", value.toSecsSinceEpoch()); +} + void UpdateChecker::openDialog() { QLocale locale; diff --git a/src/updatechecker.h b/src/updatechecker.h index efefd9ae..987833f2 100644 --- a/src/updatechecker.h +++ b/src/updatechecker.h @@ -9,7 +9,7 @@ class UpdateChecker : public QObject public: explicit UpdateChecker(QObject *parent = nullptr); - void check(); + void check(bool isStartupCheck); void openDialog(); @@ -23,11 +23,15 @@ class UpdateChecker : public QObject void readReply(QNetworkReply *reply); - bool showSystemNotification(); + QDateTime getLastCheckTime() const; + + void setLastCheckTime(QDateTime value); private: const QString UPDATE_URL = "https://api.github.com/repos/jurplel/qview/releases"; const QString DOWNLOAD_URL = "https://interversehq.com/qview/download/"; + // If update checking is enabled, this rate limits the auto-check that happens at startup + const int STARTUP_CHECK_INTERVAL_HOURS = 4; double latestVersionNum;