Skip to content

Commit 2f44de0

Browse files
Gustrynyalldawson
authored andcommittedOct 23, 2017
[FEATURE] Download a file in Processing
1 parent 977ce42 commit 2f44de0

File tree

5 files changed

+198
-1
lines changed

5 files changed

+198
-1
lines changed
 

‎src/analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ SET(QGIS_ANALYSIS_SRCS
3737
processing/qgsalgorithmextractbyexpression.cpp
3838
processing/qgsalgorithmextractbyextent.cpp
3939
processing/qgsalgorithmextractbylocation.cpp
40+
processing/qgsalgorithmfiledownloader.cpp
4041
processing/qgsalgorithmfixgeometries.cpp
4142
processing/qgsalgorithmjoinbyattribute.cpp
4243
processing/qgsalgorithmjoinwithlines.cpp

‎src/analysis/processing/qgsalgorithmextractbyattribute.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ void QgsExtractByAttributeAlgorithm::initAlgorithm( const QVariantMap & )
6666

6767
QString QgsExtractByAttributeAlgorithm::shortHelpString() const
6868
{
69-
return QObject::tr( " This algorithm creates a new vector layer that only contains matching features from an input layer. "
69+
return QObject::tr( "This algorithm creates a new vector layer that only contains matching features from an input layer. "
7070
"The criteria for adding features to the resulting layer is defined based on the values "
7171
"of an attribute from the input layer." );
7272
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
18+
#include "qgsalgorithmfiledownloader.h"
19+
#include "qgsfiledownloader.h"
20+
#include <QEventLoop>
21+
#include <QFileInfo>
22+
#include <QTimer>
23+
#include <QUrl>
24+
25+
///@cond PRIVATE
26+
27+
QString QgsFileDownloaderAlgorithm::name() const
28+
{
29+
return QStringLiteral( "filedownloader" );
30+
}
31+
32+
QString QgsFileDownloaderAlgorithm::displayName() const
33+
{
34+
return tr( "File downloader" );
35+
}
36+
37+
QStringList QgsFileDownloaderAlgorithm::tags() const
38+
{
39+
return tr( "file,downloader,internet,url" ).split( ',' );
40+
}
41+
42+
QString QgsFileDownloaderAlgorithm::group() const
43+
{
44+
return tr( "File tool" );
45+
}
46+
47+
QString QgsFileDownloaderAlgorithm::shortHelpString() const
48+
{
49+
return tr( "This algorithm downloads a URL on the file system." );
50+
}
51+
52+
QgsFileDownloaderAlgorithm *QgsFileDownloaderAlgorithm::createInstance() const
53+
{
54+
return new QgsFileDownloaderAlgorithm();
55+
}
56+
57+
void QgsFileDownloaderAlgorithm::initAlgorithm( const QVariantMap & )
58+
{
59+
addParameter( new QgsProcessingParameterString( QStringLiteral( "URL" ), tr( "URL" ), QVariant(), false, false ) );
60+
addParameter( new QgsProcessingParameterFileDestination( QStringLiteral( "OUTPUT" ),
61+
tr( "File destination" ), QObject::tr( "*.*" ), QVariant(), true ) );
62+
addOutput( new QgsProcessingOutputFile( QStringLiteral( "OUTPUT" ), tr( "File destination" ) ) );
63+
}
64+
65+
QVariantMap QgsFileDownloaderAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
66+
{
67+
mFeedback = feedback;
68+
QString url = parameterAsString( parameters, QStringLiteral( "URL" ), context );
69+
QString outputFile = parameterAsFileOutput( parameters, QStringLiteral( "OUTPUT" ), context );
70+
71+
QEventLoop loop;
72+
QTimer timer;
73+
QgsFileDownloader *downloader = new QgsFileDownloader( QUrl( url ), outputFile, QString(), true );
74+
connect( mFeedback, &QgsFeedback::canceled, downloader, &QgsFileDownloader::cancelDownload );
75+
connect( downloader, &QgsFileDownloader::downloadError, this, &QgsFileDownloaderAlgorithm::reportErrors );
76+
connect( downloader, &QgsFileDownloader::downloadProgress, this, &QgsFileDownloaderAlgorithm::receiveProgressFromDownloader );
77+
connect( downloader, &QgsFileDownloader::downloadExited, &loop, &QEventLoop::quit );
78+
connect( &timer, &QTimer::timeout, this, &QgsFileDownloaderAlgorithm::sendProgressFeedback );
79+
downloader->startDownload();
80+
timer.start( 1000 );
81+
82+
loop.exec();
83+
84+
timer.stop();
85+
if ( ! QFileInfo( outputFile ).exists() )
86+
throw QgsProcessingException( tr( "Output file doesn't exist." ) );
87+
88+
QVariantMap outputs;
89+
outputs.insert( QStringLiteral( "OUTPUT" ), outputFile );
90+
return outputs;
91+
}
92+
93+
void QgsFileDownloaderAlgorithm::reportErrors( QStringList errors )
94+
{
95+
throw QgsProcessingException( errors.join( '\n' ) );
96+
}
97+
98+
void QgsFileDownloaderAlgorithm::sendProgressFeedback()
99+
{
100+
if ( ! mReceived.isEmpty() && ! mTotal.isEmpty() )
101+
mFeedback->pushInfo( tr( "%1 of %2 downloaded." ).arg( mReceived ).arg( mTotal ) );
102+
}
103+
104+
void QgsFileDownloaderAlgorithm::receiveProgressFromDownloader( qint64 bytesReceived, qint64 bytesTotal )
105+
{
106+
if ( bytesTotal != 0 )
107+
{
108+
if ( mTotal.isEmpty() )
109+
mTotal = humanSize( bytesTotal );
110+
111+
mReceived = humanSize( bytesReceived );
112+
mFeedback->setProgress( ( bytesReceived * 100 ) / bytesTotal );
113+
}
114+
}
115+
116+
QString QgsFileDownloaderAlgorithm::humanSize( qint64 &bytes )
117+
{
118+
QStringList list;
119+
list << "KB" << "MB" << "GB" << "TB";
120+
121+
QStringListIterator i( list );
122+
QString unit( "bytes" );
123+
124+
while ( bytes >= 1024.0 && i.hasNext() )
125+
{
126+
unit = i.next();
127+
bytes /= 1024.0;
128+
}
129+
return QString( "%1 %2" ).arg( QString::number( bytes ) ).arg( unit );
130+
}
131+
132+
///@endcond
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/***************************************************************************
2+
qgsalgorithmfiledownloader.h
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+
18+
#ifndef QGSALGORITHMFILEDOWNLOADER_H
19+
#define QGSALGORITHMFILEDOWNLOADER_H
20+
21+
#define SIP_NO_FILE
22+
23+
#include "qgis.h"
24+
#include "qgsprocessingalgorithm.h"
25+
26+
class QgsProcessingFeedback;
27+
28+
///@cond PRIVATE
29+
30+
/**
31+
* Native file downloader algorithm.
32+
*/
33+
class QgsFileDownloaderAlgorithm : public QgsProcessingAlgorithm, public QObject
34+
{
35+
public:
36+
QgsFileDownloaderAlgorithm() = default;
37+
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
38+
QString name() const override;
39+
QString displayName() const override;
40+
virtual QStringList tags() const override;
41+
QString group() const override;
42+
QString shortHelpString() const override;
43+
QgsFileDownloaderAlgorithm *createInstance() const override SIP_FACTORY;
44+
45+
protected:
46+
47+
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
48+
QgsProcessingContext &context, QgsProcessingFeedback * ) override;
49+
50+
private:
51+
QString mTotal;
52+
QString mReceived;
53+
QgsProcessingFeedback *mFeedback = nullptr;
54+
void reportErrors( QStringList errors );
55+
void receiveProgressFromDownloader( qint64 bytesReceived, qint64 bytesTotal );
56+
static QString humanSize( qint64 &bytes );
57+
void sendProgressFeedback();
58+
};
59+
60+
///@endcond PRIVATE
61+
62+
#endif // QGSALGORITHMFILEDOWNLOADER_H

‎src/analysis/processing/qgsnativealgorithms.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "qgsalgorithmextractbyexpression.h"
3333
#include "qgsalgorithmextractbyextent.h"
3434
#include "qgsalgorithmextractbylocation.h"
35+
#include "qgsalgorithmfiledownloader.h"
3536
#include "qgsalgorithmfixgeometries.h"
3637
#include "qgsalgorithmjoinbyattribute.h"
3738
#include "qgsalgorithmjoinwithlines.h"
@@ -92,6 +93,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
9293
addAlgorithm( new QgsCollectAlgorithm() );
9394
addAlgorithm( new QgsExtractByAttributeAlgorithm() );
9495
addAlgorithm( new QgsExtractByExpressionAlgorithm() );
96+
addAlgorithm( new QgsFileDownloaderAlgorithm() );
9597
addAlgorithm( new QgsMultipartToSinglepartAlgorithm() );
9698
addAlgorithm( new QgsSubdivideAlgorithm() );
9799
addAlgorithm( new QgsTransformAlgorithm() );

0 commit comments

Comments
 (0)
Please sign in to comment.