QGIS API Documentation  3.24.2-Tisler (13c1a02865)
qgswebdavexternalstorage.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgswebdavexternalstorage.cpp
3  --------------------------------------
4  Date : March 2021
5  Copyright : (C) 2021 by Julien Cabieces
6  Email : julien dot cabieces at oslandia dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
21 #include "qgsapplication.h"
22 #include "qgsfeedback.h"
23 
24 #include <QFile>
25 #include <QPointer>
26 #include <QFileInfo>
27 
29 
30 QgsWebDAVExternalStorageStoreTask::QgsWebDAVExternalStorageStoreTask( const QUrl &url, const QString &filePath, const QString &authCfg )
31  : QgsTask( tr( "Storing %1" ).arg( QFileInfo( filePath ).baseName() ) )
32  , mUrl( url )
33  , mFilePath( filePath )
34  , mAuthCfg( authCfg )
35  , mFeedback( new QgsFeedback( this ) )
36 {
37 }
38 
39 bool QgsWebDAVExternalStorageStoreTask::run()
40 {
42  request.setAuthCfg( mAuthCfg );
43 
44  QNetworkRequest req( mUrl );
45  QgsSetRequestInitiatorClass( req, QStringLiteral( "QgsWebDAVExternalStorageStoreTask" ) );
46 
47  QFile *f = new QFile( mFilePath );
48  f->open( QIODevice::ReadOnly );
49 
50  connect( &request, &QgsBlockingNetworkRequest::uploadProgress, this, [ = ]( qint64 bytesReceived, qint64 bytesTotal )
51  {
52  if ( !isCanceled() && bytesTotal > 0 )
53  {
54  const int progress = ( bytesReceived * 100 ) / bytesTotal;
55  setProgress( progress );
56  }
57  } );
58 
59  QgsBlockingNetworkRequest::ErrorCode err = request.put( req, f, mFeedback.get() );
60 
62  {
63  mErrorString = request.errorMessage();
64  }
65 
66  return !isCanceled() && err == QgsBlockingNetworkRequest::NoError;
67 }
68 
69 void QgsWebDAVExternalStorageStoreTask::cancel()
70 {
71  mFeedback->cancel();
73 }
74 
75 QString QgsWebDAVExternalStorageStoreTask::errorString() const
76 {
77  return mErrorString;
78 }
79 
80 QgsWebDAVExternalStorageStoredContent::QgsWebDAVExternalStorageStoredContent( const QString &filePath, const QString &url, const QString &authcfg )
81 {
82  QString storageUrl = url;
83  if ( storageUrl.endsWith( "/" ) )
84  storageUrl.append( QFileInfo( filePath ).fileName() );
85 
86  mUploadTask = new QgsWebDAVExternalStorageStoreTask( storageUrl, filePath, authcfg );
87 
88  connect( mUploadTask, &QgsTask::taskCompleted, this, [ = ]
89  {
90  mUrl = storageUrl;
92  emit stored();
93  } );
94 
95  connect( mUploadTask, &QgsTask::taskTerminated, this, [ = ]
96  {
97  reportError( mUploadTask->errorString() );
98  } );
99 
100  connect( mUploadTask, &QgsTask::progressChanged, this, [ = ]( double progress )
101  {
102  emit progressChanged( progress );
103  } );
104 }
105 
106 void QgsWebDAVExternalStorageStoredContent::store()
107 {
109  QgsApplication::taskManager()->addTask( mUploadTask );
110 }
111 
112 
113 void QgsWebDAVExternalStorageStoredContent::cancel()
114 {
115  if ( !mUploadTask )
116  return;
117 
118  disconnect( mUploadTask, &QgsTask::taskTerminated, this, nullptr );
119  connect( mUploadTask, &QgsTask::taskTerminated, this, [ = ]
120  {
122  emit canceled();
123  } );
124 
125  mUploadTask->cancel();
126 }
127 
128 QString QgsWebDAVExternalStorageStoredContent::url() const
129 {
130  return mUrl;
131 }
132 
133 
134 QgsWebDAVExternalStorageFetchedContent::QgsWebDAVExternalStorageFetchedContent( QgsFetchedContent *fetchedContent )
135  : mFetchedContent( fetchedContent )
136 {
137  connect( mFetchedContent, &QgsFetchedContent::fetched, this, &QgsWebDAVExternalStorageFetchedContent::onFetched );
138  connect( mFetchedContent, &QgsFetchedContent::errorOccurred, this, [ = ]( QNetworkReply::NetworkError code, const QString & errorMsg )
139  {
140  Q_UNUSED( code );
141  reportError( errorMsg );
142  } );
143 }
144 
145 void QgsWebDAVExternalStorageFetchedContent::fetch()
146 {
147  if ( !mFetchedContent )
148  return;
149 
151  mFetchedContent->download();
152 
153  // could be already fetched/cached
154  if ( mFetchedContent->status() == QgsFetchedContent::Finished )
155  {
157  emit fetched();
158  }
159 }
160 
161 QString QgsWebDAVExternalStorageFetchedContent::filePath() const
162 {
163  return mFetchedContent ? mFetchedContent->filePath() : QString();
164 }
165 
166 void QgsWebDAVExternalStorageFetchedContent::onFetched()
167 {
168  if ( !mFetchedContent )
169  return;
170 
171  if ( mFetchedContent->status() == QgsFetchedContent::Finished )
172  {
174  emit fetched();
175  }
176 }
177 
178 void QgsWebDAVExternalStorageFetchedContent::cancel()
179 {
180  mFetchedContent->cancel();
181 }
182 
183 QString QgsWebDAVExternalStorage::type() const
184 {
185  return QStringLiteral( "WebDAV" );
186 };
187 
188 QString QgsWebDAVExternalStorage::displayName() const
189 {
190  return QObject::tr( "WebDAV Storage" );
191 };
192 
193 QgsExternalStorageStoredContent *QgsWebDAVExternalStorage::doStore( const QString &filePath, const QString &url, const QString &authcfg ) const
194 {
195  return new QgsWebDAVExternalStorageStoredContent( filePath, url, authcfg );
196 };
197 
198 QgsExternalStorageFetchedContent *QgsWebDAVExternalStorage::doFetch( const QString &url, const QString &authConfig ) const
199 {
200  QgsFetchedContent *fetchedContent = QgsApplication::networkContentFetcherRegistry()->fetch( url, Qgis::ActionStart::Deferred, authConfig );
201 
202  return new QgsWebDAVExternalStorageFetchedContent( fetchedContent );
203 }
204 
@ Canceled
Content fetching/storing has been canceled.
@ Running
Content fetching/storing is in progress.
@ Finished
Content fetching/storing is finished and successful.
static QgsNetworkContentFetcherRegistry * networkContentFetcherRegistry()
Returns the application's network content registry used for fetching temporary files during QGIS sess...
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
ErrorCode put(QNetworkRequest &request, QIODevice *data, QgsFeedback *feedback=nullptr)
Performs a "put" operation on the specified request, using the given data.
void setAuthCfg(const QString &authCfg)
Sets the authentication config id which should be used during the request.
QString errorMessage() const
Returns the error message string, after a get() or post() request has been made.
void uploadProgress(qint64, qint64)
Emitted when when data are sent during a request.
@ NoError
No error was encountered.
Class for QgsExternalStorage fetched content.
Class for QgsExternalStorage stored content.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
FetchedContent holds useful information about a network content being fetched.
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...
@ Finished
Download finished and successful.
void fetched()
Emitted when the file is fetched and accessible.
QgsFetchedContent * fetch(const QString &url, Qgis::ActionStart fetchingMode=Qgis::ActionStart::Deferred, const QString &authConfig=QString())
Initialize a download for the given URL.
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
Abstract base class for long running background tasks.
void taskCompleted()
Will be emitted by task to indicate its successful completion.
void progressChanged(double progress)
Will be emitted by task when its progress changes.
virtual void cancel()
Notifies the task that it should terminate.
void taskTerminated()
Will be emitted by task if it has terminated for any reason other then completion (e....
#define QgsSetRequestInitiatorClass(request, _class)