mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-02 23:35:40 +08:00
#42 Enable reading update info from GitHub Packages REST API
This commit is contained in:
@@ -149,6 +149,18 @@ namespace BlackConfig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString& CBuildConfig::gitHubRepoUrl()
|
||||||
|
{
|
||||||
|
static const QString url = "https://github.com/swift-project/pilotclient/";
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& CBuildConfig::gitHubRepoApiUrl()
|
||||||
|
{
|
||||||
|
static const QString url = "https://api.github.com/repos/swift-project/pilotclient/";
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
const QString &CBuildConfig::buildDateAndTime()
|
const QString &CBuildConfig::buildDateAndTime()
|
||||||
{
|
{
|
||||||
// http://en.cppreference.com/w/cpp/preprocessor/replace#Predefined_macros
|
// http://en.cppreference.com/w/cpp/preprocessor/replace#Predefined_macros
|
||||||
|
|||||||
@@ -118,6 +118,12 @@ namespace BlackConfig
|
|||||||
//! Vatsim client key
|
//! Vatsim client key
|
||||||
static const QString &vatsimPrivateKey(); // defined in buildconfig_gen.cpp.in
|
static const QString &vatsimPrivateKey(); // defined in buildconfig_gen.cpp.in
|
||||||
|
|
||||||
|
//! GitHub repository URL
|
||||||
|
static const QString &gitHubRepoUrl();
|
||||||
|
|
||||||
|
//! GitHub Packages REST API URL
|
||||||
|
static const QString &gitHubRepoApiUrl();
|
||||||
|
|
||||||
//! Returns SHA-1 of git HEAD at build time
|
//! Returns SHA-1 of git HEAD at build time
|
||||||
static const QString &gitHeadSha1();
|
static const QString &gitHeadSha1();
|
||||||
|
|
||||||
|
|||||||
@@ -159,11 +159,15 @@ namespace BlackCore
|
|||||||
m_setupReader.reset(new CSetupReader(this));
|
m_setupReader.reset(new CSetupReader(this));
|
||||||
connect(m_setupReader.data(), &CSetupReader::setupHandlingCompleted, this, &CApplication::onSetupHandlingCompleted, Qt::QueuedConnection);
|
connect(m_setupReader.data(), &CSetupReader::setupHandlingCompleted, this, &CApplication::onSetupHandlingCompleted, Qt::QueuedConnection);
|
||||||
connect(m_setupReader.data(), &CSetupReader::setupHandlingCompleted, this, &CApplication::setupHandlingCompleted, Qt::QueuedConnection); // hand thru
|
connect(m_setupReader.data(), &CSetupReader::setupHandlingCompleted, this, &CApplication::setupHandlingCompleted, Qt::QueuedConnection); // hand thru
|
||||||
connect(m_setupReader.data(), &CSetupReader::updateInfoAvailable, this, &CApplication::updateInfoAvailable, Qt::QueuedConnection);
|
|
||||||
connect(m_setupReader.data(), &CSetupReader::successfullyReadSharedUrl, m_networkWatchDog, &CNetworkWatchdog::setWorkingSharedUrl, Qt::QueuedConnection);
|
connect(m_setupReader.data(), &CSetupReader::successfullyReadSharedUrl, m_networkWatchDog, &CNetworkWatchdog::setWorkingSharedUrl, Qt::QueuedConnection);
|
||||||
|
|
||||||
this->addParserOptions(m_setupReader->getCmdLineOptions()); // add options from reader
|
this->addParserOptions(m_setupReader->getCmdLineOptions()); // add options from reader
|
||||||
|
|
||||||
|
// check for updates
|
||||||
|
m_gitHubPackagesReader.reset(new CGitHubPackagesReader(this));
|
||||||
|
connect(m_gitHubPackagesReader.data(), &CGitHubPackagesReader::updateInfoAvailable, this, &CApplication::updateInfoAvailable, Qt::QueuedConnection);
|
||||||
|
reloadUpdateInfo();
|
||||||
|
|
||||||
// startup done
|
// startup done
|
||||||
connect(this, &CApplication::startUpCompleted, this, &CApplication::onStartUpCompleted, Qt::QueuedConnection);
|
connect(this, &CApplication::startUpCompleted, this, &CApplication::onStartUpCompleted, Qt::QueuedConnection);
|
||||||
connect(this, &CApplication::coreFacadeStarted, this, &CApplication::onCoreFacadeStarted, Qt::QueuedConnection);
|
connect(this, &CApplication::coreFacadeStarted, this, &CApplication::onCoreFacadeStarted, Qt::QueuedConnection);
|
||||||
@@ -336,9 +340,15 @@ namespace BlackCore
|
|||||||
CUpdateInfo CApplication::getUpdateInfo() const
|
CUpdateInfo CApplication::getUpdateInfo() const
|
||||||
{
|
{
|
||||||
if (m_shutdown) { return CUpdateInfo(); }
|
if (m_shutdown) { return CUpdateInfo(); }
|
||||||
const CSetupReader *r = m_setupReader.data();
|
if (!m_gitHubPackagesReader) { return CUpdateInfo(); }
|
||||||
if (!r) { return CUpdateInfo(); }
|
return m_gitHubPackagesReader->getUpdateInfo();
|
||||||
return r->getUpdateInfo();
|
}
|
||||||
|
|
||||||
|
void CApplication::reloadUpdateInfo()
|
||||||
|
{
|
||||||
|
if (m_shutdown) { return; }
|
||||||
|
if (!m_gitHubPackagesReader) { return; }
|
||||||
|
m_gitHubPackagesReader->readUpdateInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
CDistribution CApplication::getOwnDistribution() const
|
CDistribution CApplication::getOwnDistribution() const
|
||||||
@@ -1099,6 +1109,11 @@ namespace BlackCore
|
|||||||
m_webDataServices.reset();
|
m_webDataServices.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_gitHubPackagesReader)
|
||||||
|
{
|
||||||
|
m_gitHubPackagesReader.reset();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_setupReader)
|
if (m_setupReader)
|
||||||
{
|
{
|
||||||
m_setupReader->gracefulShutdown();
|
m_setupReader->gracefulShutdown();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "blackcore/corefacadeconfig.h"
|
#include "blackcore/corefacadeconfig.h"
|
||||||
#include "blackcore/db/databasereaderconfig.h"
|
#include "blackcore/db/databasereaderconfig.h"
|
||||||
#include "blackcore/data/globalsetup.h"
|
#include "blackcore/data/globalsetup.h"
|
||||||
|
#include "blackcore/githubpackagesreader.h"
|
||||||
#include "blackcore/application/applicationsettings.h"
|
#include "blackcore/application/applicationsettings.h"
|
||||||
#include "blackcore/inputmanager.h"
|
#include "blackcore/inputmanager.h"
|
||||||
#include "blackcore/webreaderflags.h"
|
#include "blackcore/webreaderflags.h"
|
||||||
@@ -166,9 +167,11 @@ namespace BlackCore
|
|||||||
Data::CGlobalSetup getGlobalSetup() const;
|
Data::CGlobalSetup getGlobalSetup() const;
|
||||||
|
|
||||||
//! Update info
|
//! Update info
|
||||||
//! \threadsafe
|
|
||||||
BlackMisc::Db::CUpdateInfo getUpdateInfo() const;
|
BlackMisc::Db::CUpdateInfo getUpdateInfo() const;
|
||||||
|
|
||||||
|
//! Reload update info
|
||||||
|
void reloadUpdateInfo();
|
||||||
|
|
||||||
//! Own distribution
|
//! Own distribution
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
BlackMisc::Db::CDistribution getOwnDistribution() const;
|
BlackMisc::Db::CDistribution getOwnDistribution() const;
|
||||||
@@ -714,6 +717,7 @@ namespace BlackCore
|
|||||||
BlackMisc::CApplicationInfo m_applicationInfo; //!< Application if specified
|
BlackMisc::CApplicationInfo m_applicationInfo; //!< Application if specified
|
||||||
QScopedPointer<CCoreFacade> m_coreFacade; //!< core facade if any
|
QScopedPointer<CCoreFacade> m_coreFacade; //!< core facade if any
|
||||||
QScopedPointer<CSetupReader> m_setupReader; //!< setup reader
|
QScopedPointer<CSetupReader> m_setupReader; //!< setup reader
|
||||||
|
QScopedPointer<CGitHubPackagesReader> m_gitHubPackagesReader; //!< github packages reader
|
||||||
QScopedPointer<CWebDataServices> m_webDataServices; //!< web data services
|
QScopedPointer<CWebDataServices> m_webDataServices; //!< web data services
|
||||||
QScopedPointer<BlackMisc::CFileLogger> m_fileLogger; //!< file logger
|
QScopedPointer<BlackMisc::CFileLogger> m_fileLogger; //!< file logger
|
||||||
QPointer<CCookieManager> m_cookieManager; //!< single cookie manager for our access manager
|
QPointer<CCookieManager> m_cookieManager; //!< single cookie manager for our access manager
|
||||||
|
|||||||
52
src/blackcore/githubpackagesreader.cpp
Normal file
52
src/blackcore/githubpackagesreader.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* Copyright (C) 2020
|
||||||
|
* swift project community / contributors
|
||||||
|
*
|
||||||
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||||
|
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
|
||||||
|
* or distributed except according to the terms contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
#include "githubpackagesreader.h"
|
||||||
|
#include "blackcore/application.h"
|
||||||
|
#include "blackconfig/buildconfig.h"
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
using namespace BlackMisc::Db;
|
||||||
|
using namespace BlackConfig;
|
||||||
|
|
||||||
|
namespace BlackCore
|
||||||
|
{
|
||||||
|
CGitHubPackagesReader::CGitHubPackagesReader(QObject *parent) : QObject(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CGitHubPackagesReader::readUpdateInfo()
|
||||||
|
{
|
||||||
|
// https://docs.github.com/en/rest/reference/repos#releases
|
||||||
|
|
||||||
|
const QNetworkRequest request(QUrl(CBuildConfig::gitHubRepoApiUrl() % u"releases"));
|
||||||
|
auto reply = sApp->getNetworkAccessManager()->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [this, reply]
|
||||||
|
{
|
||||||
|
if (reply->error() == QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
const auto updateInfo = CUpdateInfo::fromGitHubReleasesJson(reply->readAll());
|
||||||
|
if (!updateInfo.isEmpty())
|
||||||
|
{
|
||||||
|
m_updateInfo.set(updateInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reply->deleteLater();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CUpdateInfo CGitHubPackagesReader::getUpdateInfo() const
|
||||||
|
{
|
||||||
|
return m_updateInfo.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/blackcore/githubpackagesreader.h
Normal file
45
src/blackcore/githubpackagesreader.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* Copyright (C) 2020
|
||||||
|
* swift project community / contributors
|
||||||
|
*
|
||||||
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||||
|
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
|
||||||
|
* or distributed except according to the terms contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
#ifndef BLACKCORE_GITHUBPACKAGESREADER_H
|
||||||
|
#define BLACKCORE_GITHUBPACKAGESREADER_H
|
||||||
|
|
||||||
|
#include "blackmisc/db/updateinfo.h"
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace BlackCore
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
* Read available updates from GitHub Packages REST API.
|
||||||
|
*/
|
||||||
|
class CGitHubPackagesReader : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Constructor.
|
||||||
|
CGitHubPackagesReader(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
//! Read updates from GitHub Packages.
|
||||||
|
void readUpdateInfo();
|
||||||
|
|
||||||
|
//! Get updates cached from previous read.
|
||||||
|
BlackMisc::Db::CUpdateInfo getUpdateInfo() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
//! Updates have been received from GitHub Packages.
|
||||||
|
void updateInfoAvailable(bool available);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BlackMisc::CData<BlackMisc::Db::TUpdateInfo> m_updateInfo { this };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -86,8 +86,7 @@ namespace BlackGui
|
|||||||
void CUpdateInfoComponent::requestLoadOfSetup()
|
void CUpdateInfoComponent::requestLoadOfSetup()
|
||||||
{
|
{
|
||||||
if (!sGui || sGui->isShuttingDown()) { return; }
|
if (!sGui || sGui->isShuttingDown()) { return; }
|
||||||
const CStatusMessageList msgs(sGui->requestReloadOfSetupAndVersion());
|
sGui->reloadUpdateInfo();
|
||||||
CLogMessage::preformatted(msgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUpdateInfoComponent::changedUpdateInfo()
|
void CUpdateInfoComponent::changedUpdateInfo()
|
||||||
|
|||||||
@@ -7,8 +7,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "updateinfo.h"
|
#include "updateinfo.h"
|
||||||
|
#include "blackmisc/stringutils.h"
|
||||||
#include "blackconfig/buildconfig.h"
|
#include "blackconfig/buildconfig.h"
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
using namespace BlackConfig;
|
using namespace BlackConfig;
|
||||||
|
|
||||||
@@ -148,5 +152,56 @@ namespace BlackMisc
|
|||||||
if (jsonString.isEmpty()) { return CUpdateInfo(); }
|
if (jsonString.isEmpty()) { return CUpdateInfo(); }
|
||||||
return CUpdateInfo::fromDatabaseJson(Json::jsonObjectFromString(jsonString));
|
return CUpdateInfo::fromDatabaseJson(Json::jsonObjectFromString(jsonString));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CUpdateInfo CUpdateInfo::fromGitHubReleasesJson(const QByteArray &jsonData)
|
||||||
|
{
|
||||||
|
// https://docs.github.com/en/rest/reference/repos#releases
|
||||||
|
|
||||||
|
const QString url = CBuildConfig::gitHubRepoUrl() + QStringLiteral("releases/download");
|
||||||
|
CDistribution alphaDistribution("ALPHA", 5, false);
|
||||||
|
CDistribution betaDistribution("BETA", 10, false);
|
||||||
|
alphaDistribution.addDownloadUrl(url);
|
||||||
|
betaDistribution.addDownloadUrl(url);
|
||||||
|
|
||||||
|
CUpdateInfo result;
|
||||||
|
result.m_distributions = { alphaDistribution, betaDistribution };
|
||||||
|
|
||||||
|
for (const QJsonValue &release : QJsonDocument::fromJson(jsonData).array())
|
||||||
|
{
|
||||||
|
QString version = release[QLatin1String("tag_name")].toString();
|
||||||
|
if (version.isEmpty() || version[0] != 'v') { continue; }
|
||||||
|
version.remove(0, 1);
|
||||||
|
if (containsChar(version, [](QChar c) { return c != '.' && !is09(c); })) { continue; }
|
||||||
|
|
||||||
|
bool existing = !release[QLatin1String("draft")].toBool();
|
||||||
|
bool alpha = release[QLatin1String("prerelease")].toBool();
|
||||||
|
|
||||||
|
for (const QJsonValue &asset : release[QLatin1String("assets")].toArray())
|
||||||
|
{
|
||||||
|
QString name = asset[QLatin1String("name")].toString();
|
||||||
|
QString filename = QStringLiteral("v%1/%2").arg(version, name);
|
||||||
|
int size = asset[QLatin1String("size")].toInt();
|
||||||
|
|
||||||
|
CArtifact::ArtifactType type = CArtifact::UnknownArtifact;
|
||||||
|
if (name.startsWith(QStringLiteral("swiftinstaller"))) { type = CArtifact::PilotClientInstaller; }
|
||||||
|
else if (name.startsWith(QStringLiteral("swiftsymbols"))) { type = CArtifact::Symbols; }
|
||||||
|
else if (name.startsWith(QStringLiteral("xswiftbus"))) { type = CArtifact::XSwiftBus; }
|
||||||
|
|
||||||
|
CPlatform platform;
|
||||||
|
if (name.contains(QStringLiteral("windows-32"))) { platform = CPlatform::win32Platform(); }
|
||||||
|
else if (name.contains(QStringLiteral("windows-64"))) { platform = CPlatform::win64Platform(); }
|
||||||
|
else if (name.contains(QStringLiteral("linux-64"))) { platform = CPlatform::linuxPlatform(); }
|
||||||
|
else if (name.contains(QStringLiteral("macos-64"))) { platform = CPlatform::macOSPlatform(); }
|
||||||
|
else if (name.contains(QStringLiteral("allos"))) { platform = CPlatform::allOs(); }
|
||||||
|
|
||||||
|
CArtifact artifact(filename, version, {}, type, size, existing, platform);
|
||||||
|
artifact.setDistributions({ alpha ? alphaDistribution : betaDistribution });
|
||||||
|
|
||||||
|
if (type == CArtifact::PilotClientInstaller) { result.m_artifactsPilotClient.push_back(artifact); }
|
||||||
|
else if (type == CArtifact::XSwiftBus) { result.m_artifactsXSwiftBus.push_back(artifact); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
} // ns
|
} // ns
|
||||||
} // ns
|
} // ns
|
||||||
|
|||||||
@@ -97,6 +97,9 @@ namespace BlackMisc
|
|||||||
//! Object from database JSOn format
|
//! Object from database JSOn format
|
||||||
static CUpdateInfo fromDatabaseJson(const QString &jsonString);
|
static CUpdateInfo fromDatabaseJson(const QString &jsonString);
|
||||||
|
|
||||||
|
//! Object from GitHub Releases REST API JSON format
|
||||||
|
static CUpdateInfo fromGitHubReleasesJson(const QByteArray &jsonData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CArtifactList m_artifactsPilotClient; //!< artifacts pilot client
|
CArtifactList m_artifactsPilotClient; //!< artifacts pilot client
|
||||||
CArtifactList m_artifactsXSwiftBus; //!< artifacts XSwiftBus
|
CArtifactList m_artifactsXSwiftBus; //!< artifacts XSwiftBus
|
||||||
|
|||||||
Reference in New Issue
Block a user