Add support of multiple update urls
This commit is contained in:
parent
d931015d6b
commit
576d9d5662
@ -28,10 +28,11 @@ const auto updatesUrl =
|
||||
#endif
|
||||
const auto resultHideWaitUs = 300'000;
|
||||
} // namespace
|
||||
using Loader = update::Loader;
|
||||
|
||||
Manager::Manager()
|
||||
: settings_(std::make_unique<Settings>())
|
||||
, updater_(std::make_unique<update::Loader>(QUrl(updatesUrl)))
|
||||
, updater_(std::make_unique<Loader>(Loader::Urls{{updatesUrl}}))
|
||||
, updateAutoChecker_(std::make_unique<update::AutoChecker>(*updater_))
|
||||
, models_(std::make_unique<CommonModels>())
|
||||
{
|
||||
|
@ -92,22 +92,26 @@ QStringList toList(const QJsonValue &value)
|
||||
|
||||
} // namespace
|
||||
|
||||
Loader::Loader(const QUrl &updateUrl, QObject *parent)
|
||||
Loader::Loader(const update::Loader::Urls &updateUrls, QObject *parent)
|
||||
: QObject(parent)
|
||||
, network_(new QNetworkAccessManager(this))
|
||||
, model_(new Model(this))
|
||||
, updateUrl_(updateUrl)
|
||||
, updateUrls_(updateUrls)
|
||||
, downloadPath_(
|
||||
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
|
||||
"/updates")
|
||||
{
|
||||
std::random_device device;
|
||||
std::mt19937 generator(device());
|
||||
std::shuffle(updateUrls_.begin(), updateUrls_.end(), generator);
|
||||
|
||||
connect(network_, &QNetworkAccessManager::finished, //
|
||||
this, &Loader::handleReply);
|
||||
}
|
||||
|
||||
void Loader::handleReply(QNetworkReply *reply)
|
||||
{
|
||||
if (reply->url() == updateUrl_) {
|
||||
if (updateUrls_.contains(reply->url())) {
|
||||
handleUpdateReply(reply);
|
||||
} else {
|
||||
handleComponentReply(reply);
|
||||
@ -116,7 +120,28 @@ void Loader::handleReply(QNetworkReply *reply)
|
||||
|
||||
void Loader::checkForUpdates()
|
||||
{
|
||||
auto reply = network_->get(QNetworkRequest(updateUrl_));
|
||||
startDownloadUpdates({});
|
||||
}
|
||||
|
||||
void Loader::startDownloadUpdates(const QUrl &previous)
|
||||
{
|
||||
SOFT_ASSERT(!updateUrls_.isEmpty(), return );
|
||||
|
||||
QUrl url;
|
||||
if (previous.isEmpty())
|
||||
url = updateUrls_.first();
|
||||
else {
|
||||
const auto index = updateUrls_.indexOf(previous);
|
||||
SOFT_ASSERT(index != -1, return );
|
||||
if (index == updateUrls_.size() - 1)
|
||||
return;
|
||||
url = updateUrls_[index + 1];
|
||||
}
|
||||
|
||||
if (url.isEmpty())
|
||||
return;
|
||||
|
||||
auto reply = network_->get(QNetworkRequest(url));
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
handleUpdateReply(reply);
|
||||
}
|
||||
@ -127,13 +152,28 @@ void Loader::handleUpdateReply(QNetworkReply *reply)
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
emit error(toError(*reply));
|
||||
startDownloadUpdates(reply->url());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto replyData = reply->readAll();
|
||||
if (replyData.isEmpty()) {
|
||||
emit error(
|
||||
tr("Received empty updates info from %1").arg(reply->url().toString()));
|
||||
startDownloadUpdates(reply->url());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SOFT_ASSERT(model_, return );
|
||||
model_->parse(replyData);
|
||||
const auto parseError = model_->parse(replyData);
|
||||
if (!parseError.isEmpty()) {
|
||||
emit error(tr("Failed to parse updates from %1 (%2)")
|
||||
.arg(reply->url().toString(), parseError));
|
||||
startDownloadUpdates(reply->url());
|
||||
return;
|
||||
}
|
||||
|
||||
if (model_->hasUpdates())
|
||||
emit updatesAvailable();
|
||||
}
|
||||
@ -324,20 +364,20 @@ void Model::initView(QTreeView *view)
|
||||
});
|
||||
}
|
||||
|
||||
void Model::parse(const QByteArray &data)
|
||||
QString Model::parse(const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
const auto doc = QJsonDocument::fromJson(data, &error);
|
||||
if (doc.isNull()) {
|
||||
LERROR() << error.errorString();
|
||||
return;
|
||||
return tr("Failed to parse: %1 at %2")
|
||||
.arg(error.errorString())
|
||||
.arg(error.offset);
|
||||
}
|
||||
|
||||
const auto json = doc.object();
|
||||
const auto version = json[versionKey].toInt();
|
||||
if (version != 1) {
|
||||
LERROR() << "Wrong updates.json version" << version;
|
||||
return;
|
||||
return tr("Wrong updates version %1").arg(version);
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
@ -347,6 +387,11 @@ void Model::parse(const QByteArray &data)
|
||||
updateState(*root_);
|
||||
|
||||
endResetModel();
|
||||
|
||||
if (!root_) {
|
||||
return tr("No data parsed");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<Model::Component> Model::parse(const QJsonObject &json) const
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
|
||||
void initView(QTreeView* view);
|
||||
|
||||
void parse(const QByteArray& data);
|
||||
QString parse(const QByteArray& data);
|
||||
void setExpansions(const std::map<QString, QString>& expansions);
|
||||
UserActions userActions() const;
|
||||
void updateStates();
|
||||
@ -130,7 +130,8 @@ class Loader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Loader(const QUrl& updateUrl, QObject* parent = nullptr);
|
||||
using Urls = QVector<QUrl>;
|
||||
explicit Loader(const Urls& updateUrls, QObject* parent = nullptr);
|
||||
|
||||
void checkForUpdates();
|
||||
void applyUserActions();
|
||||
@ -150,10 +151,11 @@ private:
|
||||
void commitUpdate();
|
||||
void updateProgress(qint64 bytesSent, qint64 bytesTotal);
|
||||
bool startDownload(File& file);
|
||||
void startDownloadUpdates(const QUrl& previous);
|
||||
|
||||
QNetworkAccessManager* network_;
|
||||
Model* model_;
|
||||
QUrl updateUrl_;
|
||||
Urls updateUrls_;
|
||||
QString downloadPath_;
|
||||
std::map<QNetworkReply*, File*> downloads_;
|
||||
UserActions currentActions_;
|
||||
|
Loading…
Reference in New Issue
Block a user