Kstars

filedownloader.cpp
1 /*
2  SPDX-FileCopyrightText: 2016 Jasem Mutlaq <[email protected]>
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 
22 FileDownloader::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 
30 void 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 
45 void 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 
61 void 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 
77 void 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 
85 void 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 
122 void 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 
147 void 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 
163 QUrl FileDownloader::getDownloadedFileURL() const
164 {
165  return m_DownloadedFileURL;
166 }
167 
168 bool 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 
187 void 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
226  Q_UNUSED(bytesReceived);
227  Q_UNUSED(bytesTotal);
228 #endif
229 }
230 
231 QByteArray FileDownloader::downloadedData() const
232 {
233  return m_DownloadedData;
234 }
bool remove()
QNetworkReply::NetworkError error() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static KStars * Instance()
Definition: kstars.h:125
void deleteLater()
QString i18n(const char *text, const TYPE &arg...)
bool isEmpty() const const
QString toLocalFile() const const
QString errorString() const const
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QString label(StandardShortcut id)
void finished(int result)
virtual QVariant get(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Aug 15 2022 04:04:01 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.