first version

This commit is contained in:
tooomm 2026-07-07 22:30:20 +02:00
parent 6c960fdf31
commit 315879fe6b
2 changed files with 76 additions and 61 deletions

View file

@ -2,6 +2,7 @@
#include "version_string.h" #include "version_string.h"
#include <optional>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
@ -44,54 +45,84 @@ void ReleaseChannel::checkForUpdates()
} }
// Different release channel checking functions for different operating systems // Different release channel checking functions for different operating systems
bool ReleaseChannel::downloadMatchesCurrentOS(const QString &fileName) std::optional<int> ReleaseChannel::getTargetVersionForCurrentOS(const QString &fileName)
{ {
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
static QRegularExpression version_regex("macOS(\\d+)"); const bool isIntel = [] {
auto match = version_regex.match(fileName);
if (!match.hasMatch()) {
return false;
}
auto getSystemVersion = [] {
// QSysInfo does not go through translation layers
// We need to use sysctl to reliably detect the underlying architecture
char arch[255]; char arch[255];
size_t len = sizeof(arch); size_t len = sizeof(arch);
if (sysctlbyname("machdep.cpu.brand_string", arch, &len, nullptr, 0) == 0) { if (sysctlbyname("machdep.cpu.brand_string", arch, &len, nullptr, 0) == 0) {
// Intel mac is only supported on macOS 13 versions return QString::fromUtf8(arch).contains("Intel");
if (QString::fromUtf8(arch).contains("Intel")) {
return 13;
}
} }
return false;
return QSysInfo::productVersion().split(".")[0].toInt(); }();
}; const int systemVersion = QSysInfo::productVersion().split(".")[0].toInt();
if (isIntel) {
// older(smaller) releases are compatible with a newer or the same system version static QRegularExpression regex(R"(macOS(\d+)_Intel)");
int sys_maj = getSystemVersion(); auto match = regex.match(fileName);
int rel_maj = match.captured(1).toInt(); if (!match.hasMatch()) {
return rel_maj == sys_maj; return std::nullopt;
}
int version = match.captured(1).toInt();
if (version <= systemVersion) {
return version;
}
return std::nullopt;
}
static QRegularExpression regex(R"(macOS(\d+)(?!_Intel))");
auto match = regex.match(fileName);
if (!match.hasMatch()) {
return std::nullopt;
}
int version = match.captured(1).toInt();
if (version <= systemVersion) {
return version;
}
return std::nullopt;
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
#if Q_PROCESSOR_WORDSIZE == 4 #if Q_PROCESSOR_WORDSIZE == 8
return fileName.contains("32bit"); const int systemVersion = QSysInfo::productVersion().split(".")[0].toInt();
#elif Q_PROCESSOR_WORDSIZE == 8 static QRegularExpression regex(R"(Windows(\d+))");
const QString &version = QSysInfo::productVersion(); auto match = regex.match(fileName);
if (version.startsWith("7") || version.startsWith("8")) { if (!match.hasMatch()) {
return fileName.contains("Win7"); return std::nullopt;
} else {
return fileName.contains("Win10");
} }
int version = match.captured(1).toInt();
if (version <= systemVersion) {
return version;
}
#endif
return std::nullopt;
#else #else
Q_UNUSED(fileName); Q_UNUSED(fileName);
return false; return std::nullopt;
#endif #endif
}
#else // If the OS doesn't fit one of the above #defines, then it will never match QString ReleaseChannel::findBestDownloadUrl(const QVariantList &assets)
Q_UNUSED(fileName); {
return false; QString bestUrl;
#endif int bestVersion = -1;
for (const auto &rawAsset : assets) {
QVariantMap asset = rawAsset.toMap();
QString name = asset["name"].toString();
QString url = asset["browser_download_url"].toString();
auto version = getTargetVersionForCurrentOS(name);
if (!version) {
continue;
}
if (*version > bestVersion) {
bestVersion = *version;
bestUrl = url;
}
}
if (!bestUrl.isEmpty()) {
qCInfo(ReleaseChannelLog)
<< "Selected compatible asset version=" << bestVersion
<< "url=" << bestUrl;
}
return bestUrl;
} }
QString StableReleaseChannel::getManualDownloadUrl() const QString StableReleaseChannel::getManualDownloadUrl() const
@ -138,16 +169,9 @@ void StableReleaseChannel::releaseListFinished()
lastRelease->setPublishDate(resultMap["published_at"].toDate()); lastRelease->setPublishDate(resultMap["published_at"].toDate());
if (resultMap.contains("assets")) { if (resultMap.contains("assets")) {
auto rawAssets = resultMap["assets"].toList(); auto url = findBestDownloadUrl(resultMap["assets"].toList());
for (const auto &rawAsset : rawAssets) { if (!url.isEmpty()) {
QVariantMap asset = rawAsset.toMap(); lastRelease->setDownloadUrl(url);
QString name = asset["name"].toString();
QString url = asset["browser_download_url"].toString();
if (downloadMatchesCurrentOS(name)) {
lastRelease->setDownloadUrl(url);
break;
}
} }
} }
@ -289,21 +313,10 @@ void BetaReleaseChannel::fileListFinished()
bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0); bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
bool compatibleVersion = false; bool compatibleVersion = false;
QStringList resultUrlList{}; QString downloadUrl = findBestDownloadUrl(resultList);
for (QVariant file : resultList) { if (!downloadUrl.isEmpty()) {
QVariantMap map = file.toMap(); compatibleVersion = true;
resultUrlList << map["browser_download_url"].toString(); lastRelease->setDownloadUrl(downloadUrl);
}
resultUrlList.sort();
// iterate in reverse so the first item is the latest os version
for (auto url = resultUrlList.rbegin(); url < resultUrlList.rend(); ++url) {
if (downloadMatchesCurrentOS(*url)) {
compatibleVersion = true;
lastRelease->setDownloadUrl(*url);
qCInfo(ReleaseChannelLog) << "Found compatible version url=" << *url;
break;
}
} }
emit finishedCheck(needToUpdate, compatibleVersion, lastRelease); emit finishedCheck(needToUpdate, compatibleVersion, lastRelease);

View file

@ -7,6 +7,7 @@
#ifndef RELEASECHANNEL_H #ifndef RELEASECHANNEL_H
#define RELEASECHANNEL_H #define RELEASECHANNEL_H
#include <optional>
#include <QDate> #include <QDate>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QObject> #include <QObject>
@ -96,7 +97,8 @@ protected:
Release *lastRelease; Release *lastRelease;
protected: protected:
static bool downloadMatchesCurrentOS(const QString &fileName); std::optional<int> getTargetVersionForCurrentOS(const QString &fileName);
QString findBestDownloadUrl(const QVariantList &assets);
[[nodiscard]] virtual QString getReleaseChannelUrl() const = 0; [[nodiscard]] virtual QString getReleaseChannelUrl() const = 0;
public: public: