File indexing completed on 2024-04-14 05:34:45
0001 /* This file is part of inqludeclient 0002 * Copyright 2014 David Faure <faure@kde.org> 0003 * 0004 * This library is free software; you can redistribute it and/or modify 0005 * it under the terms of the GNU Lesser General Public License as published by 0006 * the Free Software Foundation; either version 2 of the License or ( at 0007 * your option ) version 3 or, at the discretion of KDE e.V. ( which shall 0008 * act as a proxy as in section 14 of the GPLv3 ), any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "downloadhandler.h" 0022 0023 #include <QCoreApplication> 0024 #include <QUrl> 0025 #include <QFile> 0026 #include <QTextStream> 0027 #include <QJsonArray> 0028 #include <QJsonDocument> 0029 #include <QJsonObject> 0030 #include <QNetworkAccessManager> 0031 #include <QNetworkRequest> 0032 #include <QNetworkReply> 0033 0034 DownloadHandler::DownloadHandler(QTextStream &errorStream, const QString &library) 0035 : m_errorStream(errorStream), m_library(library), m_reply(Q_NULLPTR), m_destFile(Q_NULLPTR) 0036 { 0037 } 0038 0039 DownloadHandler::~DownloadHandler() 0040 { 0041 m_errorStream.flush(); 0042 delete m_destFile; 0043 delete m_reply; 0044 } 0045 0046 void DownloadHandler::download(const QJsonDocument &doc) 0047 { 0048 const QJsonArray libs = doc.array(); 0049 for (int i = 0; i < libs.count(); ++i) { 0050 const QJsonObject details = libs.at(i).toObject(); 0051 const QString name = details.value("name").toString(); 0052 if (name == m_library) { 0053 const QJsonObject packages = details.value("packages").toObject(); 0054 const QString source = packages.value("source").toString(); 0055 if (source.isEmpty()) { 0056 m_errorStream << "Library " << m_library << " has no source package\n"; 0057 const QJsonObject urls = details.value("urls").toObject(); 0058 const QString vcs = urls.value("vcs").toString(); 0059 if (!vcs.isEmpty()) { 0060 m_errorStream << "Suggestion: see " << vcs << " for access to the sources\n"; 0061 } 0062 handlingCompleted(); 0063 } else { 0064 const QUrl sourceUrl(source); 0065 m_errorStream << "Downloading " << sourceUrl.toDisplayString() << "...\n"; 0066 startDownload(sourceUrl); 0067 } 0068 return; 0069 } 0070 } 0071 m_errorStream << "Library " << m_library << " not found\n"; 0072 handlingCompleted(); 0073 } 0074 0075 void DownloadHandler::startDownload(const QUrl &sourceUrl) 0076 { 0077 m_destFile = new QFile(sourceUrl.fileName()); 0078 if (!m_destFile->open(QIODevice::WriteOnly)) { 0079 m_errorStream << "Cannot write to " << m_destFile->fileName() << "\n"; 0080 handlingCompleted(); 0081 return; 0082 } 0083 m_qnam = new QNetworkAccessManager(this); 0084 QNetworkRequest request(sourceUrl); 0085 m_reply = m_qnam->get(request); 0086 connect(m_reply, &QNetworkReply::readyRead, this, &DownloadHandler::slotReadyRead); 0087 connect(m_qnam, &QNetworkAccessManager::finished, this, &DownloadHandler::slotFinished); 0088 } 0089 0090 void DownloadHandler::slotReadyRead() 0091 { 0092 if (m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).isNull()) { 0093 m_destFile->write(m_reply->readAll()); 0094 } 0095 } 0096 0097 void DownloadHandler::slotFinished(QNetworkReply* reply) 0098 { 0099 if (reply->error() != QNetworkReply::NoError) { 0100 m_errorStream << reply->errorString() << '\n'; 0101 } 0102 0103 // Handle redirections 0104 const QUrl possibleRedirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); 0105 if (!possibleRedirectUrl.isEmpty() && possibleRedirectUrl != m_urlRedirect) { 0106 m_urlRedirect = reply->url().resolved(possibleRedirectUrl); 0107 if (m_urlRedirect.scheme().startsWith("http")) { 0108 m_errorStream << "Redirected to " << m_urlRedirect.toDisplayString() << "...\n"; 0109 reply->deleteLater(); 0110 m_reply = m_qnam->get(QNetworkRequest(m_urlRedirect)); 0111 connect(m_reply, &QNetworkReply::readyRead, this, &DownloadHandler::slotReadyRead); 0112 return; 0113 } else { 0114 m_errorStream << "Redirection to" << m_urlRedirect.toDisplayString() << "forbidden.\n"; 0115 } 0116 } 0117 m_urlRedirect.clear(); 0118 m_destFile->close(); 0119 handlingCompleted(); 0120 }