QGIS API Documentation  3.24.2-Tisler (13c1a02865)
qgsnetworkcontentfetchertask.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsnetworkcontentfetchertask.cpp
3  -------------------
4  begin : March 2018
5  copyright : (C) 2018 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
21 #include <QEventLoop>
22 
23 QgsNetworkContentFetcherTask::QgsNetworkContentFetcherTask( const QUrl &url, const QString &authcfg, QgsTask::Flags flags )
24  : QgsNetworkContentFetcherTask( QNetworkRequest( url ), authcfg, flags )
25 {
26 }
27 
28 QgsNetworkContentFetcherTask::QgsNetworkContentFetcherTask( const QNetworkRequest &request, const QString &authcfg, QgsTask::Flags flags )
29  : QgsTask( tr( "Fetching %1" ).arg( request.url().toString() ), flags )
30  , mRequest( request )
31  , mAuthcfg( authcfg )
32 {
33 }
34 
36 {
37  if ( mFetcher )
38  mFetcher->deleteLater();
39 }
40 
42 {
43  mFetcher = new QgsNetworkContentFetcher();
44  QEventLoop loop;
45 
46  // We need to set the event loop (and not 'this') as receiver for all signal to ensure execution
47  // in the same thread and in the same order of emission. Indeed 'this' and 'loop' lives in
48  // different thread because they have been created in different thread.
49 
50  connect( mFetcher, &QgsNetworkContentFetcher::finished, &loop, &QEventLoop::quit );
51  connect( mFetcher, &QgsNetworkContentFetcher::downloadProgress, &loop, [ = ]( qint64 bytesReceived, qint64 bytesTotal )
52  {
53  if ( !isCanceled() && bytesTotal > 0 )
54  {
55  const int progress = ( bytesReceived * 100 ) / bytesTotal;
56  // don't emit 100% progress reports until completely fetched - otherwise we get
57  // intermediate 100% reports from redirects
58  if ( progress < 100 )
60  }
61  } );
62 
63 
64  bool hasErrorOccurred = false;
65  connect( mFetcher, &QgsNetworkContentFetcher::errorOccurred, &loop, [ &hasErrorOccurred, this ]( QNetworkReply::NetworkError code, const QString & errorMsg )
66  {
67  hasErrorOccurred = true;
68  emit errorOccurred( code, errorMsg );
69  } );
70 
71  mFetcher->fetchContent( mRequest, mAuthcfg );
72  loop.exec();
73  if ( !isCanceled() )
74  setProgress( 100 );
75  emit fetched();
76 
77  return !isCanceled() && !hasErrorOccurred;
78 }
79 
81 {
82  if ( mFetcher )
83  mFetcher->cancel();
84 
86 }
87 
89 {
90  return mFetcher ? mFetcher->reply() : nullptr;
91 }
92 
94 {
95  return mFetcher ? mFetcher->contentAsString() : QString();
96 }
Handles HTTP network content fetching in a background task.
bool run() override
Performs the task's operation.
QString contentAsString() const
Returns the fetched content as a string.
void fetched()
Emitted when the network content has been fetched, regardless of whether the fetch was successful or ...
QNetworkReply * reply()
Returns the network reply.
QgsNetworkContentFetcherTask(const QUrl &url, const QString &authcfg=QString(), QgsTask::Flags flags=QgsTask::CanCancel)
Constructor for a QgsNetworkContentFetcherTask which fetches the specified url.
void cancel() override
Notifies the task that it should terminate.
void errorOccurred(QNetworkReply::NetworkError code, const QString &errorMsg)
Emitted when an error with code error occurred while processing the request errorMsg is a textual des...
HTTP network content fetcher.
void finished()
Emitted when content has loaded.
void errorOccurred(QNetworkReply::NetworkError code, const QString &errorMsg)
Emitted when an error with code error occurred while processing the request errorMsg is a textual des...
void cancel()
Cancels any ongoing request.
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
Emitted when data is received.
QNetworkReply * reply()
Returns a reference to the network reply.
QString contentAsString() const
Returns the fetched content as a string.
void fetchContent(const QUrl &url, const QString &authcfg=QString())
Fetches content from a remote URL and handles redirects.
Abstract base class for long running background tasks.
double progress() const
Returns the task's progress (between 0.0 and 100.0)
virtual void cancel()
Notifies the task that it should terminate.
bool isCanceled() const
Will return true if task should terminate ASAP.
void setProgress(double progress)
Sets the task's current progress.