File indexing completed on 2024-04-14 03:40:53

0001 /*
0002     SPDX-FileCopyrightText: 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>
0003 
0004     Adapted from https://wiki.qt.io/Download_Data_from_URL
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "filedownloader.h"
0010 
0011 #ifndef KSTARS_LITE
0012 #include "kstars.h"
0013 #endif
0014 
0015 #include "kstars_debug.h"
0016 
0017 #include <KLocalizedString>
0018 
0019 #include <QFile>
0020 #include <QProgressDialog>
0021 
0022 FileDownloader::FileDownloader(QObject *parent) : QObject(parent)
0023 {
0024     connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), this, SLOT(dataFinished(QNetworkReply*)));
0025 
0026     registerDataVerification([](const QByteArray &) { return true; });
0027     registerFileVerification([](const QString &) { return true;});
0028 }
0029 
0030 void FileDownloader::get(const QUrl &fileUrl)
0031 {
0032     QNetworkRequest request(fileUrl);
0033     m_DownloadedData.clear();
0034     isCancelled = false;
0035     m_Reply     = m_WebCtrl.get(request);
0036 
0037     connect(m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError()));
0038     connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));
0039     connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(setDownloadProgress(qint64,qint64)));
0040     connect(m_Reply, SIGNAL(readyRead()), this, SLOT(dataReady()));
0041 
0042     setDownloadProgress(0, 0);
0043 }
0044 
0045 void FileDownloader::post(const QUrl &fileUrl, QByteArray &data)
0046 {
0047     QNetworkRequest request(fileUrl);
0048     request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
0049     m_DownloadedData.clear();
0050     isCancelled = false;
0051     m_Reply     = m_WebCtrl.post(request, data);
0052 
0053     connect(m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError()));
0054     connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));
0055     connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(setDownloadProgress(qint64,qint64)));
0056     connect(m_Reply, SIGNAL(readyRead()), this, SLOT(dataReady()));
0057 
0058     setDownloadProgress(0, 0);
0059 }
0060 
0061 void FileDownloader::post(const QUrl &fileUrl, QHttpMultiPart *parts)
0062 {
0063     QNetworkRequest request(fileUrl);
0064     request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
0065     m_DownloadedData.clear();
0066     isCancelled = false;
0067     m_Reply     = m_WebCtrl.post(request, parts);
0068 
0069     connect(m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError()));
0070     connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));
0071     connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(setDownloadProgress(qint64,qint64)));
0072     connect(m_Reply, SIGNAL(readyRead()), this, SLOT(dataReady()));
0073 
0074     setDownloadProgress(0, 0);
0075 }
0076 
0077 void FileDownloader::dataReady()
0078 {
0079     if (m_downloadTemporaryFile.isOpen())
0080         m_downloadTemporaryFile.write(m_Reply->readAll());
0081     else
0082         m_DownloadedData += m_Reply->readAll();
0083 }
0084 
0085 void FileDownloader::dataFinished(QNetworkReply *pReply)
0086 {
0087     if (pReply->error() != QNetworkReply::NoError)
0088         return;
0089 
0090     dataReady();
0091 
0092     if (m_verifyData(m_DownloadedData) == false)
0093     {
0094         emit error(i18n("Data verification failed"));
0095         pReply->deleteLater();
0096         return;
0097     }
0098     else if (m_downloadTemporaryFile.isOpen())
0099     {
0100         m_downloadTemporaryFile.flush();
0101         m_downloadTemporaryFile.close();
0102 
0103         if (m_verifyFile(m_downloadTemporaryFile.fileName()) == false)
0104         {
0105             emit error(i18n("File verification failed"));
0106             pReply->deleteLater();
0107             return;
0108         }
0109         else
0110         {
0111             QFile::remove(m_DownloadedFileURL.toLocalFile());
0112             m_downloadTemporaryFile.copy(m_DownloadedFileURL.toLocalFile());
0113         }
0114     }
0115 
0116     if (isCancelled == false)
0117         emit downloaded();
0118 
0119     pReply->deleteLater();
0120 }
0121 
0122 void FileDownloader::slotError()
0123 {
0124     m_Reply->deleteLater();
0125 
0126 #ifndef KSTARS_LITE
0127     if (progressDialog != nullptr)
0128         progressDialog->hide();
0129 #endif
0130 
0131     if (isCancelled)
0132     {
0133         // Remove partially downloaded file, should we download to %tmp first?
0134         if (m_downloadTemporaryFile.isOpen())
0135         {
0136             m_downloadTemporaryFile.close();
0137             m_downloadTemporaryFile.remove();
0138         }
0139         emit canceled();
0140     }
0141     else
0142     {
0143         emit error(m_Reply->errorString());
0144     }
0145 }
0146 
0147 void FileDownloader::setProgressDialogEnabled(bool ShowProgressDialog, const QString &textTitle,
0148                                               const QString &textLabel)
0149 {
0150     m_ShowProgressDialog = ShowProgressDialog;
0151 
0152     if (title.isEmpty())
0153         title = i18n("Downloading");
0154     else
0155         title = textTitle;
0156 
0157     if (textLabel.isEmpty())
0158         label = i18n("Downloading Data...");
0159     else
0160         label = textLabel;
0161 }
0162 
0163 QUrl FileDownloader::getDownloadedFileURL() const
0164 {
0165     return m_DownloadedFileURL;
0166 }
0167 
0168 bool FileDownloader::setDownloadedFileURL(const QUrl &DownloadedFile)
0169 {
0170     m_DownloadedFileURL = DownloadedFile;
0171 
0172     if (m_DownloadedFileURL.isEmpty() == false)
0173     {
0174         bool rc= m_downloadTemporaryFile.open();
0175 
0176         if (rc == false)
0177             qCWarning(KSTARS) << m_downloadTemporaryFile.errorString();
0178         else
0179             qCDebug(KSTARS) << "Opened" << m_downloadTemporaryFile.fileName() << "to download data into" << DownloadedFile.toLocalFile();
0180 
0181         return rc;
0182     }
0183 
0184     return true;
0185 }
0186 
0187 void FileDownloader::setDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
0188 {
0189 #ifndef KSTARS_LITE
0190     if (m_ShowProgressDialog)
0191     {
0192         if (progressDialog == nullptr)
0193         {
0194             isCancelled    = false;
0195             progressDialog = new QProgressDialog(KStars::Instance());
0196             progressDialog->setWindowTitle(title);
0197             progressDialog->setLabelText(i18n("Awaiting response from server..."));
0198             connect(progressDialog, SIGNAL(canceled()), this, SIGNAL(canceled()));
0199             connect(progressDialog, &QProgressDialog::canceled, this, [&]() {
0200                 isCancelled = true;
0201                 m_Reply->abort();
0202                 progressDialog->close();
0203             });
0204             progressDialog->setMinimum(0);
0205             progressDialog->setMaximum(0);
0206             progressDialog->show();
0207             progressDialog->raise();
0208         }
0209 
0210         if (bytesReceived > 0)
0211         {
0212             progressDialog->setLabelText(label);
0213         }
0214 
0215         if (bytesTotal > 0)
0216         {
0217             progressDialog->setMaximum(bytesTotal);
0218             progressDialog->setValue(bytesReceived);
0219         }
0220         else
0221         {
0222             progressDialog->setMaximum(0);
0223         }
0224     }
0225 #else
0226     Q_UNUSED(bytesReceived);
0227     Q_UNUSED(bytesTotal);
0228 #endif
0229 }
0230 
0231 QByteArray FileDownloader::downloadedData() const
0232 {
0233     return m_DownloadedData;
0234 }