QGIS API Documentation 4.1.0-Master (3b8ef1f72a3)
Loading...
Searching...
No Matches
qgsfileuploader.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsfileuploader.cpp
3 --------------------------------------
4 Date : August 2025
5 Copyright : (C) 2025 by Valentin Buira
6 Email : valentin dot buira at gmail 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
16#include "qgsfileuploader.h"
17
18#include "qgsapplication.h"
19#include "qgsauthmanager.h"
21#include "qgslogger.h"
23
24#include <QFileInfo>
25#include <QHttpMultiPart>
26#include <QNetworkAccessManager>
27#include <QNetworkReply>
28#include <QNetworkRequest>
29#include <QString>
30#include <qmimedatabase.h>
31
32#include "moc_qgsfileuploader.cpp"
33
34using namespace Qt::StringLiterals;
35
36QgsFileUploader::QgsFileUploader( const QString &uploadFileName, const QUrl &url, const QString &formName, const QString &authcfg, bool delayStart )
37 : mUrl( url )
38 , mFormName( formName )
39 , mUploadCanceled( false )
40{
41 if ( !uploadFileName.isEmpty() )
42 mFile.setFileName( uploadFileName );
43 mAuthCfg = authcfg;
44 if ( !delayStart )
46}
47
48
51
53{
54 QNetworkRequest request( mUrl );
55 QgsSetRequestInitiatorClass( request, u"QgsFileUploader"_s );
56 if ( !mAuthCfg.isEmpty() )
57 {
59 }
60
61
62 auto multiPart = std::make_unique<QHttpMultiPart>( QHttpMultiPart::FormDataType );
63
64 QHttpPart filePart;
65 auto file = std::make_unique<QFile>( mFile.fileName() );
66 QFileInfo fi = QFileInfo( file->fileName() );
67
68 QMimeDatabase db;
69 QMimeType mimeType = db.mimeTypeForFile( file->fileName() );
70
71 filePart.setHeader( QNetworkRequest::ContentTypeHeader, mimeType.name() );
72 filePart.setHeader( QNetworkRequest::ContentDispositionHeader, u"form-data; %1filename=\"%2\""_s.arg( ( mFormName.isEmpty() ) ? QString( "" ) : u"name=\"%1\"; "_s.arg( mFormName ), fi.fileName() ) );
73 if ( !file->open( QIODevice::ReadOnly ) )
74 {
75 error( tr( "Error reading file %1" ).arg( mFile.fileName() ) );
76 onFinished();
77 return;
78 }
79 filePart.setBodyDevice( file.get() );
80 file.release()->setParent( multiPart.get() );
81
82 multiPart->append( filePart );
83
84
86
87 if ( !mAuthCfg.isEmpty() )
88 {
89 networkRequest->setAuthCfg( mAuthCfg );
90 }
91
92
93 connect( networkRequest, &QgsBlockingNetworkRequest::uploadProgress, this, &QgsFileUploader::onUploadProgress );
94 connect( this, &QgsFileUploader::uploadCanceled, networkRequest, &QgsBlockingNetworkRequest::abort );
95
96
97 const QgsBlockingNetworkRequest::ErrorCode errorCode = networkRequest->post( request, multiPart.get(), false );
98
99 if ( errorCode == QgsBlockingNetworkRequest::NoError )
100 {
101 // upload successful, nothing to do it's all good
102 }
103 else if ( errorCode == QgsBlockingNetworkRequest::TimeoutError )
104 {
105 error( tr( "Network request %1 timed out" ).arg( networkRequest->errorMessage() ) );
106 }
107 else if ( errorCode == QgsBlockingNetworkRequest::NetworkError )
108 {
109 error( tr( "Upload failed, Server returned: %1" ).arg( networkRequest->errorMessage() ) );
110 }
111 else // All other errors
112 {
113 error( tr( "Upload failed: %1" ).arg( networkRequest->errorMessage() ) );
114 }
115 onFinished();
116
117 networkRequest->deleteLater();
118}
119
121{
122 mUploadCanceled = true;
123 emit uploadCanceled();
124 onFinished();
125}
126
127
128void QgsFileUploader::error( const QStringList &errorMessages )
129{
130 for ( const QString &error : errorMessages )
131 mErrors << error;
132
133 emit uploadError( mErrors );
134}
135
136void QgsFileUploader::error( const QString &errorMessage )
137{
138 error( QStringList() << errorMessage );
139}
140
141
142void QgsFileUploader::onFinished()
143{
144 // when canceled
145 if ( !mErrors.isEmpty() || mUploadCanceled )
146 {
147 if ( mFile.isOpen() )
148 mFile.close();
149 }
150 else
151 {
152 // download finished normally
153 if ( mFile.isOpen() )
154 {
155 mFile.flush();
156 mFile.close();
157 }
158
159 else
160 {
161 emit uploadCompleted( mUrl );
162 }
163 }
164 this->deleteLater();
165}
166
167
168void QgsFileUploader::onUploadProgress( qint64 bytesSent, qint64 bytesTotal )
169{
170 if ( mUploadCanceled )
171 {
172 return;
173 }
174 emit uploadProgress( bytesSent, bytesTotal );
175}
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkRequest with an authentication config.
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
void uploadProgress(qint64 bytesReceived, qint64 bytesTotal)
Emitted when when data are sent during a request.
void abort()
Aborts the network request immediately.
ErrorCode post(QNetworkRequest &request, QIODevice *data, bool forceRefresh=false, QgsFeedback *feedback=nullptr)
Performs a "post" 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(), post(), head() or put() request has been made.
@ NetworkError
A network error occurred.
@ NoError
No error was encountered.
@ TimeoutError
Timeout was reached before a reply was received.
void startUpload()
Called to start the upload.
void cancelUpload()
Call to abort the upload and delete this object after the cancellation has been processed.
void uploadError(QStringList errorMessages)
Emitted when an error makes the upload fail.
void uploadCompleted(const QUrl &url)
Emitted when the upload has completed successfully.
void uploadCanceled()
Emitted when the upload was canceled by the user.
QgsFileUploader(const QString &uploadFileName, const QUrl &url, const QString &formName=QString(), const QString &authcfg=QString(), bool delayStart=true)
QgsFileUploader.
~QgsFileUploader() override
void uploadProgress(qint64 bytesSent, qint64 bytesTotal)
Emitted when data are ready to be processed.
#define QgsSetRequestInitiatorClass(request, _class)