|
| 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 ¶meters, 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 |
0 commit comments