launcher/network-downloader.cpp

64 lines
2.2 KiB
C++

#include "network-downloader.h"
bool downloadFromUrl(const QString &url, const QString &installPath, std::function<void(QString, unsigned int, unsigned int)> logCallback = nullptr) {
if (url == "") {
if (logCallback) logCallback("Empty download URL", 0, 0);
return false;
}
if (QFile::exists(installPath)) {
if (logCallback) logCallback("File already exists: " + installPath, 0, 0);
return true;
}
if (logCallback) logCallback("Downloading from url...", 0, 0);
QNetworkAccessManager manager;
QNetworkRequest request((QUrl(url)));
QEventLoop loop;
QNetworkReply *reply = manager.get(request);
QObject::connect(reply, &QNetworkReply::downloadProgress, [&](qint64 received, qint64 total){
if (logCallback) logCallback(QString("Download progress: %1/%2 bytes").arg(received).arg(total), received, total);
});
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (!statusCode.isValid()) {
if (logCallback) logCallback("Download failed: Invalid Status code", 0, 0);
reply->deleteLater();
return false;
}
if (reply->error() != QNetworkReply::NoError) {
if (logCallback) logCallback("Download failed: " + reply->errorString(), 0, 0);
reply->deleteLater();
return false;
}
if (statusCode.toInt() == 302 || statusCode.toInt() == 301) {
QVariant redir = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (!redir.isValid()) {
if (logCallback) logCallback("Download failed: Invalid redirect", 0, 0);
reply->deleteLater();
return false;
}
QUrl newUrl = redir.toUrl();
return downloadFromUrl(newUrl.toString(), installPath, logCallback);
}
QFile file(installPath);
if (file.open(QIODevice::WriteOnly)) {
file.write(reply->readAll());
file.close();
if (logCallback) logCallback("Download complete: " + installPath, 0, 0);
} else {
if (logCallback) logCallback("Cannot write file: " + installPath, 0, 0);
}
reply->deleteLater();
return true;
}