File indexing completed on 2024-05-19 04:29:18

0001 /*
0002  *  SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  *
0006  */
0007 #include "KisRemoteFileFetcher.h"
0008 
0009 #include <QApplication>
0010 #include <QDebug>
0011 #include <QMessageBox>
0012 #include <QNetworkAccessManager>
0013 #include <QNetworkReply>
0014 #include <QNetworkRequest>
0015 #include <QProgressDialog>
0016 
0017 #include <klocalizedstring.h>
0018 
0019 KisRemoteFileFetcher::KisRemoteFileFetcher(QObject *parent)
0020     : QObject(parent)
0021     , m_request(nullptr)
0022     , m_reply(nullptr)
0023 {
0024 }
0025 
0026 KisRemoteFileFetcher::~KisRemoteFileFetcher()
0027 {
0028     delete m_request;
0029     delete m_reply;
0030 }
0031 
0032 bool KisRemoteFileFetcher::fetchFile(const QUrl &remote, QIODevice *io)
0033 {
0034     Q_ASSERT(!remote.isLocalFile());
0035 
0036     if (remote.scheme() != "data") {
0037         QMessageBox msgBox;
0038         msgBox.setWindowTitle(i18nc("@title:window", "Krita"));
0039         msgBox.setIcon(QMessageBox::Question);
0040         msgBox.setText(i18nc("Fetching remote image",
0041                              "Do you want to download the image from %1?\nClick \"Show Details\" to view the full link "
0042                              "to the image.")
0043                            .arg(remote.host()));
0044         msgBox.setDetailedText(remote.toDisplayString());
0045         msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
0046         msgBox.setDefaultButton(QMessageBox::No);
0047         const int res = msgBox.exec();
0048 
0049         if (res != QMessageBox::Yes) {
0050             return false;
0051         }
0052     }
0053 
0054     QNetworkAccessManager manager(this);
0055     m_request = new QNetworkRequest(remote);
0056     m_request->setRawHeader("User-Agent", QString("Krita-%1").arg(qApp->applicationVersion()).toUtf8());
0057     m_reply = manager.get(*m_request);
0058 
0059     QLocale loc;
0060 
0061     QProgressDialog progress;
0062     progress.setWindowTitle(i18nc("@title:window", "Krita"));
0063     progress.setLabelText(i18nc("Fetching remote image", "Downloading image from %1...").arg(remote.host()));
0064     progress.setMinimum(0);
0065     progress.setMaximum(0);
0066     progress.setWindowModality(Qt::ApplicationModal);
0067     progress.setWindowFlag(Qt::CustomizeWindowHint, true);
0068     progress.setWindowFlag(Qt::WindowCloseButtonHint, false);
0069     connect(m_reply, &QNetworkReply::finished, &progress, &QProgressDialog::accept);
0070     connect(m_reply,
0071             qOverload<QNetworkReply::NetworkError>(&QNetworkReply::error),
0072             &progress,
0073             &QProgressDialog::cancel);
0074     connect(m_reply, &QNetworkReply::downloadProgress, &progress, [&](const int ist, const int max) {
0075         progress.setMaximum(max);
0076         progress.setValue(ist);
0077         progress.setLabelText(i18nc("Fetching remote image", "Downloading image from %1... (%2 / %3)")
0078                                   .arg(remote.host())
0079                                   .arg(loc.formattedDataSize(ist))
0080                                   .arg(loc.formattedDataSize(max)));
0081     });
0082 
0083     connect(&progress, &QProgressDialog::canceled, m_reply, &QNetworkReply::abort);
0084 
0085     progress.exec();
0086 
0087     // avoid double free on manager destruction
0088     m_reply->setParent(nullptr);
0089 
0090     if (m_reply->error() != QNetworkReply::NoError) {
0091         QMessageBox msgBox;
0092         msgBox.setWindowTitle(i18nc("@title:window", "Krita"));
0093         msgBox.setIcon(QMessageBox::Critical);
0094         msgBox.setText(i18nc("Fetching remote image", "Could not download %1.").arg(remote.toDisplayString()));
0095         msgBox.setDetailedText(m_reply->errorString());
0096         msgBox.setDefaultButton(QMessageBox::Ok);
0097         msgBox.exec();
0098         return false;
0099     }
0100 
0101     if (!io->isOpen()) {
0102         io->open(QIODevice::WriteOnly);
0103     }
0104     io->write(m_reply->readAll());
0105     io->close();
0106 
0107     return true;
0108 }
0109 
0110 QByteArray KisRemoteFileFetcher::fetchFile(const QUrl &remote)
0111 {
0112     QByteArray ba;
0113     QEventLoop loop;
0114 
0115     QNetworkAccessManager manager(nullptr);
0116     connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
0117 
0118     QNetworkRequest *request = new QNetworkRequest(remote);
0119     request->setRawHeader("User-Agent", QString("Krita-%1").arg(qApp->applicationVersion()).toUtf8());
0120 
0121     QNetworkReply *reply = manager.get(*request);
0122 
0123     loop.exec();
0124 
0125     if (reply->error() != QNetworkReply::NoError) {
0126         ba = reply->readAll();
0127     }
0128 
0129     reply->setParent(nullptr);
0130 
0131     return ba;
0132 
0133 }
0134 
0135 void KisRemoteFileFetcher::error(QNetworkReply::NetworkError error)
0136 {
0137     Q_UNUSED(error);
0138 
0139     qDebug() << "error" << m_reply->errorString();
0140 }