Kstars

filedownloader.cpp
1/*
2 SPDX-FileCopyrightText: 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 Adapted from https://wiki.qt.io/Download_Data_from_URL
5
6 SPDX-License-Identifier: GPL-2.0-or-later
7*/
8
9#include "filedownloader.h"
10
11#ifndef KSTARS_LITE
12#include "kstars.h"
13#endif
14
15#include "kstars_debug.h"
16
17#include <KLocalizedString>
18
19#include <QFile>
20#include <QProgressDialog>
21
22FileDownloader::FileDownloader(QObject *parent) : QObject(parent)
23{
24 connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), this, SLOT(dataFinished(QNetworkReply*)));
25
26 registerDataVerification([](const QByteArray &) { return true; });
27 registerFileVerification([](const QString &) { return true;});
28}
29
30void FileDownloader::get(const QUrl &fileUrl)
31{
32 QNetworkRequest request(fileUrl);
33 m_DownloadedData.clear();
34 isCancelled = false;
35 m_Reply = m_WebCtrl.get(request);
36
37 connect(m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError()));
38 connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));
39 connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(setDownloadProgress(qint64,qint64)));
40 connect(m_Reply, SIGNAL(readyRead()), this, SLOT(dataReady()));
41
42 setDownloadProgress(0, 0);
43}
44
45void FileDownloader::post(const QUrl &fileUrl, QByteArray &data)
46{
47 QNetworkRequest request(fileUrl);
48 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
49 m_DownloadedData.clear();
50 isCancelled = false;
51 m_Reply = m_WebCtrl.post(request, data);
52
53 connect(m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError()));
54 connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));
55 connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(setDownloadProgress(qint64,qint64)));
56 connect(m_Reply, SIGNAL(readyRead()), this, SLOT(dataReady()));
57
58 setDownloadProgress(0, 0);
59}
60
61void FileDownloader::post(const QUrl &fileUrl, QHttpMultiPart *parts)
62{
63 QNetworkRequest request(fileUrl);
64 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
65 m_DownloadedData.clear();
66 isCancelled = false;
67 m_Reply = m_WebCtrl.post(request, parts);
68
69 connect(m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError()));
70 connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));
71 connect(m_Reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(setDownloadProgress(qint64,qint64)));
72 connect(m_Reply, SIGNAL(readyRead()), this, SLOT(dataReady()));
73
74 setDownloadProgress(0, 0);
75}
76
77void FileDownloader::dataReady()
78{
79 if (m_downloadTemporaryFile.isOpen())
80 m_downloadTemporaryFile.write(m_Reply->readAll());
81 else
82 m_DownloadedData += m_Reply->readAll();
83}
84
85void FileDownloader::dataFinished(QNetworkReply *pReply)
86{
87 if (pReply->error() != QNetworkReply::NoError)
88 return;
89
90 dataReady();
91
92 if (m_verifyData(m_DownloadedData) == false)
93 {
94 emit error(i18n("Data verification failed"));
95 pReply->deleteLater();
96 return;
97 }
98 else if (m_downloadTemporaryFile.isOpen())
99 {
100 m_downloadTemporaryFile.flush();
101 m_downloadTemporaryFile.close();
102
103 if (m_verifyFile(m_downloadTemporaryFile.fileName()) == false)
104 {
105 emit error(i18n("File verification failed"));
106 pReply->deleteLater();
107 return;
108 }
109 else
110 {
111 QFile::remove(m_DownloadedFileURL.toLocalFile());
112 m_downloadTemporaryFile.copy(m_DownloadedFileURL.toLocalFile());
113 }
114 }
115
116 if (isCancelled == false)
117 emit downloaded();
118
119 pReply->deleteLater();
120}
121
122void FileDownloader::slotError()
123{
124 m_Reply->deleteLater();
125
126#ifndef KSTARS_LITE
127 if (progressDialog != nullptr)
128 progressDialog->hide();
129#endif
130
131 if (isCancelled)
132 {
133 // Remove partially downloaded file, should we download to %tmp first?
134 if (m_downloadTemporaryFile.isOpen())
135 {
136 m_downloadTemporaryFile.close();
137 m_downloadTemporaryFile.remove();
138 }
139 emit canceled();
140 }
141 else
142 {
143 emit error(m_Reply->errorString());
144 }
145}
146
147void FileDownloader::setProgressDialogEnabled(bool ShowProgressDialog, const QString &textTitle,
148 const QString &textLabel)
149{
150 m_ShowProgressDialog = ShowProgressDialog;
151
152 if (title.isEmpty())
153 title = i18n("Downloading");
154 else
155 title = textTitle;
156
157 if (textLabel.isEmpty())
158 label = i18n("Downloading Data...");
159 else
160 label = textLabel;
161}
162
163QUrl FileDownloader::getDownloadedFileURL() const
164{
165 return m_DownloadedFileURL;
166}
167
168bool FileDownloader::setDownloadedFileURL(const QUrl &DownloadedFile)
169{
170 m_DownloadedFileURL = DownloadedFile;
171
172 if (m_DownloadedFileURL.isEmpty() == false)
173 {
174 bool rc= m_downloadTemporaryFile.open();
175
176 if (rc == false)
177 qCWarning(KSTARS) << m_downloadTemporaryFile.errorString();
178 else
179 qCDebug(KSTARS) << "Opened" << m_downloadTemporaryFile.fileName() << "to download data into" << DownloadedFile.toLocalFile();
180
181 return rc;
182 }
183
184 return true;
185}
186
187void FileDownloader::setDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
188{
189#ifndef KSTARS_LITE
190 if (m_ShowProgressDialog)
191 {
192 if (progressDialog == nullptr)
193 {
194 isCancelled = false;
195 progressDialog = new QProgressDialog(KStars::Instance());
196 progressDialog->setWindowTitle(title);
197 progressDialog->setLabelText(i18n("Awaiting response from server..."));
198 connect(progressDialog, SIGNAL(canceled()), this, SIGNAL(canceled()));
199 connect(progressDialog, &QProgressDialog::canceled, this, [&]() {
200 isCancelled = true;
201 m_Reply->abort();
202 progressDialog->close();
203 });
204 progressDialog->setMinimum(0);
205 progressDialog->setMaximum(0);
206 progressDialog->show();
207 progressDialog->raise();
208 }
209
210 if (bytesReceived > 0)
211 {
212 progressDialog->setLabelText(label);
213 }
214
215 if (bytesTotal > 0)
216 {
217 progressDialog->setMaximum(bytesTotal);
218 progressDialog->setValue(bytesReceived);
219 }
220 else
221 {
222 progressDialog->setMaximum(0);
223 }
224 }
225#else
227 Q_UNUSED(bytesTotal);
228#endif
229}
230
231QByteArray FileDownloader::downloadedData() const
232{
233 return m_DownloadedData;
234}
static KStars * Instance()
Definition kstars.h:123
QString i18n(const char *text, const TYPE &arg...)
void clear()
bool copy(const QString &fileName, const QString &newName)
bool remove()
virtual void close() override
bool flush()
QString errorString() const const
bool isOpen() const const
QByteArray readAll()
qint64 write(const QByteArray &data)
QNetworkReply * get(const QNetworkRequest &request)
QNetworkReply * post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
virtual void abort()=0
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
void setLabelText(const QString &text)
void setMaximum(int maximum)
void setMinimum(int minimum)
void setValue(int progress)
bool isEmpty() const const
virtual QString fileName() const const override
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool isEmpty() const const
QString toLocalFile() const const
bool close()
void hide()
void raise()
void show()
void setWindowTitle(const QString &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 24 2024 11:49:20 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.