Skip to content

Commit

Permalink
Fetch all URLs from a single URL
Browse files Browse the repository at this point in the history
  • Loading branch information
illwieckz committed Jan 19, 2021
1 parent cb1d60c commit ef4580b
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 83 deletions.
24 changes: 15 additions & 9 deletions News.qml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ Item {
bottomMargin: 10
}

function fetchFallbackNews() {
console.log("fetching fallback posts json");
fetchNews(downloader.newsFallbackUrl);
}

function fetchNews(jsonUrl) {
var news = new XMLHttpRequest();

Expand All @@ -55,11 +60,8 @@ Item {
}

if (newsObj === null) {
var fallbackJsonUrl = 'qrc:/resources/disconnected_posts.json';

if (jsonUrl !== fallbackJsonUrl) {
console.log("fetching fallback posts json");
fetchNews(fallbackJsonUrl);
if (jsonUrl !== downloader.newsFallbackUrl) {
fetchFallbackNews();
return;
}
}
Expand Down Expand Up @@ -98,6 +100,14 @@ Item {
news.send();
}

Connections {
target: splashController

onNewsUrlFetched: {
fetchNews(newsUrl);
}
}

SwipeView {
id: swipe

Expand All @@ -109,10 +119,6 @@ Item {
left: leftButton.right
right: rightButton.left
}

Component.onCompleted: {
fetchNews('https://unvanquished.net/api/get_recent_posts/');
}
}

PageIndicator {
Expand Down
94 changes: 76 additions & 18 deletions currentversionfetcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
*/

#include "currentversionfetcher.h"
#include "system.h"

#include <QDebug>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

CurrentVersionFetcher::CurrentVersionFetcher(QObject* parent) : QObject(parent), manager_(new QNetworkAccessManager(this))
{
Expand All @@ -35,35 +37,91 @@ void CurrentVersionFetcher::fetchCurrentVersion(QString url)
manager_->get(request);
}

void ComponentVersionFetcher(QJsonObject jsonObject, QString componentSlug, QString componentSystem, QString *componentVersion, QString *componentUrl)
{
QString componentMirror;
QString componentPath;

QJsonObject componentObject = jsonObject[componentSlug].toObject();
if (componentObject.isEmpty()) {
qDebug() << "ComponentVersionFetcher: undefined “" << componentSlug << "” key";
} else {
QJsonValue version = componentObject.value("version");
if (version == QJsonValue::Undefined) {
qDebug() << "ComponentVersionFetcher: undefined “version” value for" << componentSlug;
} else {
*componentVersion = version.toString();
}

QJsonArray mirrorsArray = componentObject["mirrors"].toArray();
if (!mirrorsArray.count()) {
qDebug() << "ComponentVersionFetcher: undefined “mirrors” key for " << componentSlug;
} else {
componentMirror = mirrorsArray.first().toString();
}

QJsonObject parcelsObject = componentObject["parcels"].toObject();
if (parcelsObject.isEmpty()) {
qDebug() << "ComponentVersionFetcher: undefined “parcels” key for" << componentSlug;
} else {
QJsonObject systemObject = parcelsObject[componentSystem].toObject();
if (systemObject.isEmpty()) {
qDebug() << "ComponentVersionFetcher: undefined “" << componentSystem << "” key for " << componentSlug;
} else {
QJsonValue path = systemObject.value("path");
if (path == QJsonValue::Undefined) {
qDebug() << "ComponentVersionFetcher: undefined “path” value for" << componentSlug;
} else {
componentPath = path.toString();
}
}
}

*componentUrl = componentMirror + "/" + componentPath;
if (*componentUrl == "/") {
*componentUrl = "";
}

qDebug() << "ComponentVersionFetcher: fetched component =" << componentSlug;
qDebug() << "ComponentVersionFetcher: fetched system =" << componentSystem;
qDebug() << "ComponentVersionFetcher: fetched version =" << *componentVersion;
qDebug() << "ComponentVersionFetcher: fetched mirror =" << componentMirror;
qDebug() << "ComponentVersionFetcher: fetched path =" << componentPath;
qDebug() << "ComponentVersionFetcher: fetched url =" << *componentUrl;
}
}

void CurrentVersionFetcher::reply(QNetworkReply* reply)
{
QString game;
QString updater;
QString updaterVersion;
QString updaterUrl;
QString gameVersion;
QString gameUrl;
QString newsVersion;
QString newsUrl;

if (reply->error() != QNetworkReply::NoError) {
qDebug() << "CurrentVersionFetcher: network error";
emit onCurrentVersions(updater, game);
emit onCurrentVersions(updaterVersion, updaterUrl, gameVersion, gameUrl, newsUrl);
return;
}

QJsonParseError error;
QJsonDocument json = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qDebug() << "CurrentVersionFetcher: JSON parsing error";
emit onCurrentVersions(updater, game);
emit onCurrentVersions(updaterVersion, updaterUrl, gameVersion, gameUrl, newsUrl);
return;
}
QJsonValue value = json.object().value("updater");
if (value != QJsonValue::Undefined) {
updater = value.toString();
} else {
qDebug() << "CurrentVersionFetcher: undefined “updater” value";
}
value = json.object().value("unvanquished");
if (value != QJsonValue::Undefined) {
game = value.toString();
} else {
qDebug() << "CurrentVersionFetcher: undefined “unvanquished” value";
}
qDebug() << "CurrentVersionFetcher: fetched versions: updater =" << updater << "game =" << game;
emit onCurrentVersions(updater, game);

QJsonObject jsonObject = json.object();

ComponentVersionFetcher(jsonObject, "updater", Sys::updaterSystem(), &updaterVersion, &updaterUrl);

ComponentVersionFetcher(jsonObject, "game", "all-all", &gameVersion, &gameUrl);

ComponentVersionFetcher(jsonObject, "news", "all-all", &newsVersion, &newsUrl);

emit onCurrentVersions(updaterVersion, updaterUrl, gameVersion, gameUrl, newsUrl);
}

2 changes: 1 addition & 1 deletion currentversionfetcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class CurrentVersionFetcher : public QObject
void fetchCurrentVersion(QString url);

signals:
void onCurrentVersions(QString updater, QString game);
void onCurrentVersions(QString updaterVersion, QString updaterUrl, QString gameVersion, QString gameUrl, QString newsUrl);

private slots:
void reply(QNetworkReply* reply);
Expand Down
4 changes: 2 additions & 2 deletions deployment.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Network resources used by the updater
- News REST endpoint which returns links to Wordpress articles on unvanquished.net. The featured image in each news article must be a type which is supported by the updater (see issue #51). Currently PNG and JPEG are known to work.
- versions.json file on unvanquished.net, used to determine whether update is needed
- current.json file on unvanquished.net, used to determine whether update is needed
- Github releases. These are targeted by download links on unvanquished.net and by the updater's self-update process.
- Torrent URL used to download the latest game version

Expand Down Expand Up @@ -35,4 +35,4 @@
```
2. Upload `UnvUpdaterWin.zip` and `UnvanquishedUpdater.exe` from `build-docker/release-win/`.

4. Bump the updater version on unvanquished.net to the new tag, so that it is reflected in versions.json and the download links.
4. Bump the updater version on unvanquished.net to the new tag, so that it is reflected in current.json and the download links.
2 changes: 1 addition & 1 deletion gamelauncher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ GameLauncher::GameLauncher(const QString& connectUrl, const Settings& settings)
// Does our version of daemon have -connect-trusted?
static bool haveConnectTrusted(const QString& gameVersion)
{
// Updater version up to v0.2.0 may set "unknown" as game version if versions.json request fails
// Updater version up to v0.2.0 may set "unknown" as game version if current.json request fails
if (gameVersion == "unknown")
return false;
// Hacky string comparison, assume we won't go down to 0.9 or up to 0.100 :)
Expand Down
10 changes: 5 additions & 5 deletions linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ QString archiveName()
return "linux-amd64.zip";
}

QString updaterSystem()
{
return "linux-amd64";
}

void migrateHomePath()
{
QString legacyHomePath = QDir::homePath() + "/.unvanquished";
Expand Down Expand Up @@ -247,11 +252,6 @@ bool updateUpdater(const QString& updaterArchive, const QString& connectUrl)
return false;
}

QString updaterArchiveName()
{
return "UnvUpdaterLinux.zip";
}

std::string getCertStore()
{
// From Go: https://golang.org/src/crypto/x509/root_linux.go
Expand Down
17 changes: 12 additions & 5 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ struct CommandLineOptions {
QString ariaLogFilename;
int splashMilliseconds = 3000;
RelaunchCommand relaunchCommand = RelaunchCommand::NONE;
QString updateUpdaterVersion;
QString updateUpdaterUrl;
QString connectUrl;
};

Expand Down Expand Up @@ -121,13 +121,16 @@ CommandLineOptions getCommandLineOptions(const QApplication& app) {
splashMsOption.setValueName("duration in milliseconds");
QCommandLineOption internalCommandOption("internalcommand");
internalCommandOption.setValueName("command");
QCommandLineOption updaterUrl("updaterurl");
updaterUrl.setValueName("url");
QCommandLineParser optionParser;
optionParser.addHelpOption();
optionParser.addVersionOption();
optionParser.addOption(logFileNameOption);
optionParser.addOption(ariaLogFilenameOption);
optionParser.addOption(splashMsOption);
optionParser.addOption(internalCommandOption);
optionParser.addOption(updaterUrl);
optionParser.addPositionalArgument("URL", "address of Unvanquished server to connect to", "[URL]");
optionParser.process(app);
CommandLineOptions options;
Expand All @@ -144,9 +147,13 @@ CommandLineOptions getCommandLineOptions(const QApplication& app) {
options.relaunchCommand = RelaunchCommand::PLAY_NOW;
} else if (command == "updategame") {
options.relaunchCommand = RelaunchCommand::UPDATE_GAME;
} else if (command.startsWith("updateupdater:")) {
} else if (command.startsWith("updateupdater")) {
options.relaunchCommand = RelaunchCommand::UPDATE_UPDATER;
options.updateUpdaterVersion = command.section(':', 1);
if (optionParser.isSet(updaterUrl)) {
options.updateUpdaterUrl = optionParser.value(updaterUrl);
} else {
options.updateUpdaterUrl = "";
}
} else {
argParseError("Invalid --internalcommand option: " + command);
}
Expand Down Expand Up @@ -208,9 +215,9 @@ int main(int argc, char *argv[])
}

SplashController splashController(
options.relaunchCommand, options.updateUpdaterVersion, options.connectUrl, settings);
options.relaunchCommand, options.updateUpdaterUrl, options.connectUrl, settings);
splashController.checkForUpdate();
QmlDownloader downloader(options.ariaLogFilename, options.connectUrl, settings);
QmlDownloader downloader(options.ariaLogFilename, options.connectUrl, splashController, settings);
QQmlApplicationEngine engine;
engine.addImportPath(QLatin1String("qrc:/"));
engine.addImageProvider(QLatin1String("fluidicons"), new IconsImageProvider());
Expand Down
10 changes: 5 additions & 5 deletions osx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ QString archiveName()
return "macos-amd64.zip";
}

QString updaterSystem()
{
return "macos-amd64";
}

QString defaultInstallPath()
{
return QDir::homePath() + "/Games/Unvanquished";
Expand Down Expand Up @@ -163,11 +168,6 @@ bool updateUpdater(const QString& updaterArchive, const QString&)
return true;
}

QString updaterArchiveName()
{
return "UnvUpdaterOSX.zip";
}

std::string getCertStore()
{
return ""; // Not used on OSX.
Expand Down
18 changes: 12 additions & 6 deletions qmldownloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
#include "qmldownloader.h"
#include "system.h"

static const QString UPDATER_BASE_URL("https://github.com/Unvanquished/updater/releases/download");

QmlDownloader::QmlDownloader(QString ariaLogFilename, QString connectUrl, Settings& settings) :
QmlDownloader::QmlDownloader(QString ariaLogFilename, QString connectUrl, SplashController& splashController, Settings& settings) :
ariaLogFilename_(ariaLogFilename),
connectUrl_(connectUrl),
splashController_(splashController),
settings_(settings),
downloadSpeed_(0),
uploadSpeed_(0),
Expand All @@ -42,6 +42,10 @@ QmlDownloader::~QmlDownloader()
stopAria();
}

QString QmlDownloader::newsFallbackUrl() const {
return "qrc:/resources/disconnected_posts.json";
}

int QmlDownloader::downloadSpeed() const {
return downloadSpeed_;
}
Expand Down Expand Up @@ -155,6 +159,9 @@ void QmlDownloader::startUpdate(const QString& selectedInstallPath)
emit fatalMessage("Install dir not writable. Please select another");
return;
}

QString gameUrl = splashController_.gameUrl();
qDebug() << "Using torrent file:" << gameUrl;
// Persist the install path only now that download has been initiated and we know the path is good
emit statusMessage("Installing to " + dir.canonicalPath());
if (settings_.installPath() != selectedInstallPath) {
Expand All @@ -166,7 +173,7 @@ void QmlDownloader::startUpdate(const QString& selectedInstallPath)
setState(DOWNLOADING);
worker_ = new DownloadWorker(ariaLogFilename_);
worker_->setDownloadDirectory(dir.canonicalPath().toStdString());
worker_->addTorrent("https://cdn.unvanquished.net/current.torrent");
worker_->addTorrent(gameUrl.toStdString());
worker_->moveToThread(&thread_);
connect(&thread_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
connect(worker_, SIGNAL(onDownloadEvent(int)), this, SLOT(onDownloadEvent(int)));
Expand Down Expand Up @@ -201,14 +208,13 @@ void QmlDownloader::stopAria()
}
}

void QmlDownloader::startUpdaterUpdate(QString version)
void QmlDownloader::startUpdaterUpdate(QString updaterUrl)
{
QString url = UPDATER_BASE_URL + "/" + version + "/" + Sys::updaterArchiveName();
temp_dir_.reset(new QTemporaryDir());
worker_ = new DownloadWorker(ariaLogFilename_);
worker_->setDownloadDirectory(QDir(temp_dir_->path()).canonicalPath().toStdString());
worker_->setConnectUrl(connectUrl_);
worker_->addUpdaterUri(url.toStdString());
worker_->addUpdaterUri(updaterUrl.toStdString());
worker_->moveToThread(&thread_);
connect(&thread_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
connect(worker_, SIGNAL(onDownloadEvent(int)), this, SLOT(onDownloadEvent(int)));
Expand Down
Loading

0 comments on commit ef4580b

Please sign in to comment.