QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsalgorithmfiledownloader.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmfiledownloader.cpp
3  ---------------------
4  begin : October 2017
5  copyright : (C) 2017 by Etienne Trimaille
6  email : etienne at kartoza dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsfiledownloader.h"
20 #include "qgsfileutils.h"
21 #include <QEventLoop>
22 #include <QFileInfo>
23 #include <QTimer>
24 #include <QUrl>
25 
27 
28 QString QgsFileDownloaderAlgorithm::name() const
29 {
30  return QStringLiteral( "filedownloader" );
31 }
32 
33 QString QgsFileDownloaderAlgorithm::displayName() const
34 {
35  return tr( "Download file" );
36 }
37 
38 QStringList QgsFileDownloaderAlgorithm::tags() const
39 {
40  return tr( "file,downloader,internet,url,fetch,get,https" ).split( ',' );
41 }
42 
43 QString QgsFileDownloaderAlgorithm::group() const
44 {
45  return tr( "File tools" );
46 }
47 
48 QString QgsFileDownloaderAlgorithm::groupId() const
49 {
50  return QStringLiteral( "filetools" );
51 }
52 
53 QString QgsFileDownloaderAlgorithm::shortHelpString() const
54 {
55  return tr( "This algorithm downloads a URL on the file system." );
56 }
57 
58 QgsFileDownloaderAlgorithm *QgsFileDownloaderAlgorithm::createInstance() const
59 {
60  return new QgsFileDownloaderAlgorithm();
61 }
62 
63 void QgsFileDownloaderAlgorithm::initAlgorithm( const QVariantMap & )
64 {
65  addParameter( new QgsProcessingParameterString( QStringLiteral( "URL" ), tr( "URL" ), QVariant(), false, false ) );
66  addParameter( new QgsProcessingParameterFileDestination( QStringLiteral( "OUTPUT" ),
67  tr( "File destination" ), QObject::tr( "All files (*.*)" ), QVariant(), true ) );
68 }
69 
70 QVariantMap QgsFileDownloaderAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
71 {
72  mFeedback = feedback;
73  QString url = parameterAsString( parameters, QStringLiteral( "URL" ), context );
74  if ( url.isEmpty() )
75  throw QgsProcessingException( tr( "No URL specified" ) );
76  QString outputFile = parameterAsFileOutput( parameters, QStringLiteral( "OUTPUT" ), context );
77 
78  QEventLoop loop;
79  QTimer timer;
80  QgsFileDownloader *downloader = new QgsFileDownloader( QUrl( url ), outputFile, QString(), true );
81  connect( mFeedback, &QgsFeedback::canceled, downloader, &QgsFileDownloader::cancelDownload );
82  connect( downloader, &QgsFileDownloader::downloadError, this, &QgsFileDownloaderAlgorithm::reportErrors );
83  connect( downloader, &QgsFileDownloader::downloadProgress, this, &QgsFileDownloaderAlgorithm::receiveProgressFromDownloader );
84  connect( downloader, &QgsFileDownloader::downloadExited, &loop, &QEventLoop::quit );
85  connect( &timer, &QTimer::timeout, this, &QgsFileDownloaderAlgorithm::sendProgressFeedback );
86  downloader->startDownload();
87  timer.start( 1000 );
88 
89  loop.exec();
90 
91  timer.stop();
92  bool exists = QFileInfo::exists( outputFile );
93  if ( !feedback->isCanceled() && !exists )
94  throw QgsProcessingException( tr( "Output file doesn't exist." ) );
95 
96  QVariantMap outputs;
97  outputs.insert( QStringLiteral( "OUTPUT" ), exists ? outputFile : QString() );
98  return outputs;
99 }
100 
101 void QgsFileDownloaderAlgorithm::reportErrors( const QStringList &errors )
102 {
103  throw QgsProcessingException( errors.join( '\n' ) );
104 }
105 
106 void QgsFileDownloaderAlgorithm::sendProgressFeedback()
107 {
108  if ( !mReceived.isEmpty() && mLastReport != mReceived )
109  {
110  mLastReport = mReceived;
111  if ( mTotal.isEmpty() )
112  mFeedback->pushInfo( tr( "%1 downloaded." ).arg( mReceived ) );
113  else
114  mFeedback->pushInfo( tr( "%1 of %2 downloaded." ).arg( mReceived, mTotal ) );
115  }
116 }
117 
118 void QgsFileDownloaderAlgorithm::receiveProgressFromDownloader( qint64 bytesReceived, qint64 bytesTotal )
119 {
120  mReceived = QgsFileUtils::representFileSize( bytesReceived );
121  if ( bytesTotal > 0 )
122  {
123  if ( mTotal.isEmpty() )
124  mTotal = QgsFileUtils::representFileSize( bytesTotal );
125 
126  mFeedback->setProgress( ( bytesReceived * 100 ) / bytesTotal );
127  }
128 }
129 
QgsFileDownloader
Definition: qgsfiledownloader.h:43
QgsFileDownloader::startDownload
void startDownload()
Called to start the download.
Definition: qgsfiledownloader.cpp:49
QgsFileDownloader::downloadExited
void downloadExited()
Emitted always when the downloader exits.
QgsProcessingFeedback
Definition: qgsprocessingfeedback.h:37
QgsFeedback::canceled
void canceled()
Internal routines can connect to this signal if they use event loop.
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
QgsProcessingParameterFileDestination
Definition: qgsprocessingparameters.h:3005
QgsProcessingParameterString
Definition: qgsprocessingparameters.h:2202
QgsFileDownloader::downloadProgress
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
Emitted when data are ready to be processed.
qgsalgorithmfiledownloader.h
qgsfileutils.h
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:66
QgsFileDownloader::downloadError
void downloadError(QStringList errorMessages)
Emitted when an error makes the download fail.
QgsFileUtils::representFileSize
static QString representFileSize(qint64 bytes)
Returns the human size from bytes.
Definition: qgsfileutils.cpp:24
QgsFileDownloader::cancelDownload
void cancelDownload()
Call to abort the download and delete this object after the cancellation has been processed.
Definition: qgsfiledownloader.cpp:84
qgsfiledownloader.h
QgsProcessingException
Definition: qgsexception.h:82