8#include <QJsonDocument>
10#include <QNetworkReply>
11#include <QNetworkRequest>
14#include <QVersionNumber>
19static constexpr auto k_releaseDataUrl =
"https://gibis-unifesp.github.io/wiRedPanda/latest-release.json";
27#elif defined(Q_OS_MACOS)
29#elif defined(Q_OS_LINUX)
38 if (platform ==
"Linux") {
39 if (arch ==
"x86_64") {
40 return QStringLiteral(
"linuxX64");
42 if (arch ==
"arm64") {
43 return QStringLiteral(
"linuxArm64");
47 if (platform ==
"Windows") {
48 if (arch ==
"x86_64") {
49 return QStringLiteral(
"windowsX64");
51 if (arch ==
"arm64") {
52 return QStringLiteral(
"windowsArm64");
56 if (platform ==
"macOS") {
58 return QStringLiteral(
"macosUniversal");
63bool shouldOfferUpdate(
const QString &tagName,
const QVersionNumber ¤tVersion,
const QString &skippedVersion)
65 const QVersionNumber latest = QVersionNumber::fromString(tagName).normalized();
66 if (latest.isNull() || latest <= currentVersion) {
71 return latest.toString() != skippedVersion;
76 return url.isValid() && url.scheme() == QLatin1String(
"https") && url.host() == QLatin1String(
"github.com");
87 connect(&m_network, &QNetworkAccessManager::sslErrors,
this, [](QNetworkReply *reply,
const QList<QSslError> &errors) {
88 qWarning() <<
"UpdateChecker: SSL errors, aborting reply:" << errors;
102 const QString today = QDate::currentDate().toString(Qt::ISODate);
108 request.setHeader(QNetworkRequest::UserAgentHeader,
"wiRedPanda/" APP_VERSION);
109 request.setAttribute(QNetworkRequest::RedirectPolicyAttribute,
110 QNetworkRequest::NoLessSafeRedirectPolicy);
111 request.setTransferTimeout(10000);
113 QNetworkReply *reply = m_network.get(request);
117 reply->setReadBufferSize(1024 * 1024 + 1);
118 connect(reply, &QNetworkReply::downloadProgress,
this, [reply](qint64 received, qint64) {
119 if (received > 1024 * 1024) {
123 connect(reply, &QNetworkReply::finished,
this, [
this, reply] { onReplyFinished(reply); });
126void UpdateChecker::onReplyFinished(QNetworkReply *reply)
128 reply->deleteLater();
132 if (reply->error() != QNetworkReply::NoError) {
136 const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
137 if (doc.isNull() || !doc.isObject()) {
147 const QString version = doc.object().value(
"version").toString();
151 const QVersionNumber latest = QVersionNumber::fromString(version).normalized();
154 const QString arch = QSysInfo::buildCpuArchitecture();
156 QUrl downloadUrl = key.isEmpty() ? QUrl{} : QUrl(doc.object().value(key).toString());
158 const QUrl releaseUrl = QUrl(QStringLiteral(
"https://github.com/GIBIS-UNIFESP/wiRedPanda/releases/tag/%1").arg(latest.toString()));
160 qWarning() <<
"UpdateChecker: release URL has unexpected scheme/host, ignoring update notification:" << releaseUrl;
164 qWarning() <<
"UpdateChecker: download URL has unexpected scheme/host, falling back to release page:" << downloadUrl;
Typed wrappers around QSettings for all application preferences.
bool isSafeGitHubUrl(const QUrl &url)
True when url is safe to download from or hand to the OS's URL handler.
static constexpr auto k_releaseDataUrl
QString releaseAssetKey(const QString &platform, const QString &arch)
The key in latest-release.json holding the download URL for the given platform ("Windows"/"macOS"/"Li...
bool shouldOfferUpdate(const QString &tagName, const QVersionNumber ¤tVersion, const QString &skippedVersion)
True when the release tagged tagName should be offered to a user running currentVersion who may have ...
static QString currentPlatform()
Checks the wiRedPanda site's published release data for newer versions.
bool isSafeGitHubUrl(const QUrl &url)
True when url is safe to download from or hand to the OS's URL handler.
QString releaseAssetKey(const QString &platform, const QString &arch)
The key in latest-release.json holding the download URL for the given platform ("Windows"/"macOS"/"Li...
bool shouldOfferUpdate(const QString &tagName, const QVersionNumber ¤tVersion, const QString &skippedVersion)
True when the release tagged tagName should be offered to a user running currentVersion who may have ...
File-format version constants and application version accessor.
static QString updateCheckLastDate()
static bool updateChecksDisabled()
Global opt-out of update checks (for offline/managed installs); default false (enabled).
static QString updateCheckSkippedVersion()
static void setUpdateCheckLastDate(const QString &date)
UpdateChecker(QObject *parent=nullptr)
void updateAvailable(const QString &latestVersion, const QUrl &downloadUrl, const QUrl &releaseUrl)
Emitted when a newer release is available and has not been suppressed.
void checkForUpdates()
Initiates an asynchronous version check.
const QVersionNumber current