QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsnetworkcontentfetcherregistry.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsnetworkcontentfetcherregistry.cpp
3  -------------------
4  begin : April, 2018
5  copyright : (C) 2018 by Denis Rouzaud
6  email : [email protected]
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 
20 
21 #include "qgsapplication.h"
22 
24 {
25  QMap<QString, QgsFetchedContent *>::const_iterator it = mFileRegistry.constBegin();
26  for ( ; it != mFileRegistry.constEnd(); ++it )
27  {
28  delete it.value();
29  }
30  mFileRegistry.clear();
31 }
32 
33 const QgsFetchedContent *QgsNetworkContentFetcherRegistry::fetch( const QString &url, const FetchingMode fetchingMode )
34 {
35 
36  if ( mFileRegistry.contains( url ) )
37  {
38  return mFileRegistry.value( url );
39  }
40 
42 
43  mFileRegistry.insert( url, content );
44 
45  if ( fetchingMode == DownloadImmediately )
46  content->download();
47 
48 
49  return content;
50 }
51 
52 QFile *QgsNetworkContentFetcherRegistry::localFile( const QString &filePathOrUrl )
53 {
54  QFile *file = nullptr;
55  QString path = filePathOrUrl;
56 
57  if ( !QUrl::fromUserInput( filePathOrUrl ).isLocalFile() )
58  {
59  if ( mFileRegistry.contains( path ) )
60  {
61  const QgsFetchedContent *content = mFileRegistry.value( path );
62  if ( content && content->status() == QgsFetchedContent::Finished && content->file() )
63  {
64  file = content->file();
65  }
66  else
67  {
68  // if the file is not downloaded yet or has failed, return nullptr
69  }
70  }
71  else
72  {
73  // if registry doesn't contain the URL, return nullptr
74  }
75  }
76  else
77  {
78  file = new QFile( filePathOrUrl );
79  }
80  return file;
81 }
82 
83 QString QgsNetworkContentFetcherRegistry::localPath( const QString &filePathOrUrl )
84 {
85  QString path = filePathOrUrl;
86 
87  if ( !QUrl::fromUserInput( filePathOrUrl ).isLocalFile() )
88  {
89  if ( mFileRegistry.contains( path ) )
90  {
91  const QgsFetchedContent *content = mFileRegistry.value( path );
92  if ( content->status() == QgsFetchedContent::Finished && !content->filePath().isEmpty() )
93  {
94  path = content->filePath();
95  }
96  else
97  {
98  // if the file is not downloaded yet or has failed, return empty string
99  path = QString();
100  }
101  }
102  else
103  {
104  // if registry doesn't contain the URL, keep path unchanged
105  }
106  }
107  return path;
108 }
109 
110 
111 
112 
113 void QgsFetchedContent::download( bool redownload )
114 {
115 
116  if ( redownload && status() == QgsFetchedContent::Downloading )
117  {
118  {
119  if ( mFetchingTask )
120  disconnect( mFetchingTask, &QgsNetworkContentFetcherTask::taskCompleted, this, &QgsFetchedContent::taskCompleted );
121  }
122  cancel();
123  }
124  if ( redownload ||
127  {
128  mFetchingTask = new QgsNetworkContentFetcherTask( mUrl );
129  // use taskCompleted which is main thread rather than fetched signal in worker thread
130  connect( mFetchingTask, &QgsNetworkContentFetcherTask::taskCompleted, this, &QgsFetchedContent::taskCompleted );
131  QgsApplication::instance()->taskManager()->addTask( mFetchingTask );
133  }
134 
135 }
136 
138 {
139  if ( mFetchingTask && mFetchingTask->canCancel() )
140  {
141  mFetchingTask->cancel();
142  }
143  if ( mFile )
144  {
145  mFile->deleteLater();
146  mFilePath = QString();
147  }
148 }
149 
150 
151 void QgsFetchedContent::taskCompleted()
152 {
153  if ( !mFetchingTask || !mFetchingTask->reply() )
154  {
155  // if no reply, it has been canceled
156  mStatus = QgsFetchedContent::Failed;
157  mError = QNetworkReply::OperationCanceledError;
158  mFilePath = QString();
159  }
160  else
161  {
162  QNetworkReply *reply = mFetchingTask->reply();
163  if ( reply->error() == QNetworkReply::NoError )
164  {
165  QTemporaryFile *tf = new QTemporaryFile( QStringLiteral( "XXXXXX" ) );
166  mFile = tf;
167  tf->open();
168  mFile->write( reply->readAll() );
169  // Qt docs notes that on some system if fileName is not called before close, file might get deleted
170  mFilePath = tf->fileName();
171  tf->close();
172  mStatus = QgsFetchedContent::Finished;
173  }
174  else
175  {
176  mStatus = QgsFetchedContent::Failed;
177  mError = reply->error();
178  mFilePath = QString();
179  }
180  }
181 
182  emit fetched();
183 }
QgsFetchedContent::file
QFile * file() const
Returns a pointer to the local file, or nullptr if the file is not accessible yet.
Definition: qgsnetworkcontentfetcherregistry.h:70
QgsNetworkContentFetcherTask::reply
QNetworkReply * reply()
Returns the network reply.
Definition: qgsnetworkcontentfetchertask.cpp:72
QgsNetworkContentFetcherRegistry::~QgsNetworkContentFetcherRegistry
~QgsNetworkContentFetcherRegistry() override
Definition: qgsnetworkcontentfetcherregistry.cpp:23
QgsNetworkContentFetcherTask
Handles HTTP network content fetching in a background task.
Definition: qgsnetworkcontentfetchertask.h:48
QgsNetworkContentFetcherRegistry::DownloadImmediately
@ DownloadImmediately
The download will start immediately, not need to run QgsFecthedContent::download()
Definition: qgsnetworkcontentfetcherregistry.h:131
QgsApplication::instance
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
Definition: qgsapplication.cpp:411
QgsNetworkContentFetcherTask::cancel
void cancel() override
Notifies the task that it should terminate.
Definition: qgsnetworkcontentfetchertask.cpp:64
QgsTaskManager::addTask
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
Definition: qgstaskmanager.cpp:416
QgsTask::taskCompleted
void taskCompleted()
Will be emitted by task to indicate its successful completion.
qgsapplication.h
qgsnetworkcontentfetcherregistry.h
QgsFetchedContent::Failed
@ Failed
Download failed.
Definition: qgsnetworkcontentfetcherregistry.h:50
QgsFetchedContent::Downloading
@ Downloading
Currently downloading.
Definition: qgsnetworkcontentfetcherregistry.h:48
QgsNetworkContentFetcherRegistry::localPath
QString localPath(const QString &filePathOrUrl)
Returns the path to a local file or to a temporary file previously fetched by the registry.
Definition: qgsnetworkcontentfetcherregistry.cpp:83
QgsNetworkContentFetcherRegistry::fetch
const QgsFetchedContent * fetch(const QString &url, FetchingMode fetchingMode=DownloadLater)
Initialize a download for the given URL.
Definition: qgsnetworkcontentfetcherregistry.cpp:33
QgsNetworkContentFetcherRegistry::FetchingMode
FetchingMode
Enum to determine when the download should start.
Definition: qgsnetworkcontentfetcherregistry.h:129
QgsTask::canCancel
bool canCancel() const
Returns true if the task can be canceled.
Definition: qgstaskmanager.h:102
QgsFetchedContent::NotStarted
@ NotStarted
No download started for such URL.
Definition: qgsnetworkcontentfetcherregistry.h:47
QgsFetchedContent::cancel
void cancel()
Cancel the download operation.
Definition: qgsnetworkcontentfetcherregistry.cpp:137
QgsApplication::taskManager
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
Definition: qgsapplication.cpp:2133
QgsFetchedContent::status
ContentStatus status() const
Returns the status of the download.
Definition: qgsnetworkcontentfetcherregistry.h:77
QgsFetchedContent
FetchedContent holds useful information about a network content being fetched.
Definition: qgsnetworkcontentfetcherregistry.h:41
QgsNetworkContentFetcherRegistry::localFile
QFile * localFile(const QString &filePathOrUrl)
Returns a QFile from a local file or to a temporary file previously fetched by the registry.
Definition: qgsnetworkcontentfetcherregistry.cpp:52
QgsFetchedContent::Finished
@ Finished
Download finished and successful.
Definition: qgsnetworkcontentfetcherregistry.h:49
QgsFetchedContent::download
void download(bool redownload=false)
Start the download.
Definition: qgsnetworkcontentfetcherregistry.cpp:113
QgsFetchedContent::fetched
void fetched()
Emitted when the file is fetched and accessible.
QgsFetchedContent::filePath
const QString filePath() const
Returns the path to the local file, an empty string if the file is not accessible yet.
Definition: qgsnetworkcontentfetcherregistry.h:74