Skip to content

Commit

Permalink
QgsNetworkContentFetcherRegistry: a registry for temporary downloaded…
Browse files Browse the repository at this point in the history
… files
  • Loading branch information
3nids committed May 7, 2018
1 parent ba04dea commit 25108e5
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 0 deletions.
8 changes: 8 additions & 0 deletions python/core/qgsapplication.sip.in
Expand Up @@ -641,6 +641,14 @@ Returns the application's SVG cache, used for caching SVG images and handling pa
within SVG files.

.. versionadded:: 3.0
%End

static QgsNetworkContentFetcherRegistry *networkContentFetcherRegistry();
%Docstring
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement
within SVG files.

.. versionadded:: 3.2
%End

static QgsSymbolLayerRegistry *symbolLayerRegistry();
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -238,6 +238,7 @@ SET(QGIS_CORE_SRCS
qgsnetworkaccessmanager.cpp
qgsnetworkdiskcache.cpp
qgsnetworkcontentfetcher.cpp
qgsnetworkcontentfetcherregistry.cpp
qgsnetworkcontentfetchertask.cpp
qgsnetworkreplyparser.cpp
qgsobjectcustomproperties.cpp
Expand Down Expand Up @@ -625,6 +626,7 @@ SET(QGIS_CORE_MOC_HDRS
qgsnetworkaccessmanager.h
qgsnetworkdiskcache.h
qgsnetworkcontentfetcher.h
qgsnetworkcontentfetcherregistry.h
qgsnetworkcontentfetchertask.h
qgsnetworkreplyparser.h
qgsofflineediting.h
Expand Down
8 changes: 8 additions & 0 deletions src/core/qgsapplication.cpp
Expand Up @@ -22,6 +22,7 @@
#include "qgslogger.h"
#include "qgsproject.h"
#include "qgsnetworkaccessmanager.h"
#include "qgsnetworkcontentfetcherregistry.h"
#include "qgsproviderregistry.h"
#include "qgsexpression.h"
#include "qgsactionscoperegistry.h"
Expand Down Expand Up @@ -1664,6 +1665,11 @@ QgsSvgCache *QgsApplication::svgCache()
return members()->mSvgCache;
}

QgsNetworkContentFetcherRegistry *QgsApplication::networkContentFetcherRegistry()
{
return members()->mNetworkContentFertcherRegistry;
}

QgsSymbolLayerRegistry *QgsApplication::symbolLayerRegistry()
{
return members()->mSymbolLayerRegistry;
Expand Down Expand Up @@ -1743,6 +1749,7 @@ QgsApplication::ApplicationMembers::ApplicationMembers()
mAnnotationRegistry = new QgsAnnotationRegistry();
m3DRendererRegistry = new Qgs3DRendererRegistry();
mProjectStorageRegistry = new QgsProjectStorageRegistry();
mNetworkContentFertcherRegistry = new QgsNetworkContentFetcherRegistry();
}

QgsApplication::ApplicationMembers::~ApplicationMembers()
Expand All @@ -1766,6 +1773,7 @@ QgsApplication::ApplicationMembers::~ApplicationMembers()
delete mSvgCache;
delete mSymbolLayerRegistry;
delete mTaskManager;
delete mNetworkContentFertcherRegistry;
}

QgsApplication::ApplicationMembers *QgsApplication::members()
Expand Down
9 changes: 9 additions & 0 deletions src/core/qgsapplication.h
Expand Up @@ -46,6 +46,7 @@ class QgsUserProfileManager;
class QgsPageSizeRegistry;
class QgsLayoutItemRegistry;
class QgsAuthManager;
class QgsNetworkContentFetcherRegistry;

/**
* \ingroup core
Expand Down Expand Up @@ -586,6 +587,13 @@ class CORE_EXPORT QgsApplication : public QApplication
*/
static QgsSvgCache *svgCache();

/**
* Returns the application's SVG cache, used for caching SVG images and handling parameter replacement
* within SVG files.
* \since QGIS 3.2
*/
static QgsNetworkContentFetcherRegistry *networkContentFetcherRegistry();

/**
* Returns the application's symbol layer registry, used for managing symbol layers.
* \since QGIS 3.0
Expand Down Expand Up @@ -802,6 +810,7 @@ class CORE_EXPORT QgsApplication : public QApplication
QgsColorSchemeRegistry *mColorSchemeRegistry = nullptr;
QgsFieldFormatterRegistry *mFieldFormatterRegistry = nullptr;
QgsGpsConnectionRegistry *mGpsConnectionRegistry = nullptr;
QgsNetworkContentFetcherRegistry *mNetworkContentFertcherRegistry = nullptr;
QgsMessageLog *mMessageLog = nullptr;
QgsPaintEffectRegistry *mPaintEffectRegistry = nullptr;
QgsPluginLayerRegistry *mPluginLayerRegistry = nullptr;
Expand Down
93 changes: 93 additions & 0 deletions src/core/qgsnetworkcontentfetcherregistry.cpp
@@ -0,0 +1,93 @@
/***************************************************************************
qgsnetworkcontentfetcherregistry.cpp
-------------------
begin : April, 2018
copyright : (C) 2018 by Denis Rouzaud
email : denis.rouzaud@gmail.com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsnetworkcontentfetcherregistry.h"

#include "qgsapplication.h"
#include "qgsnetworkcontentfetchertask.h"

QgsNetworkContentFetcherRegistry::QgsNetworkContentFetcherRegistry()
: QObject()
{
}

QgsNetworkContentFetcherRegistry::~QgsNetworkContentFetcherRegistry()
{
QMap<QUrl, FetchedContent>::const_iterator it = mFileRegistry.constBegin();
for ( ; it != mFileRegistry.constEnd(); ++it )
{
it.value().mFile->deleteLater();
}
}

const QgsNetworkContentFetcherTask *QgsNetworkContentFetcherRegistry::fetch( const QUrl &url, const bool reload )
{
if ( mFileRegistry.contains( url ) )
{
if ( !reload )
{
return mFileRegistry.value( url ).mFetchingTask;
}
else
{
FetchedContent content = mFileRegistry.take( url );
if ( content.mFetchingTask )
{
content.mFetchingTask->cancel();
}
if ( content.mFile )
{
content.mFile->deleteLater();
}
}
}

QgsNetworkContentFetcherTask *fetcher = new QgsNetworkContentFetcherTask( url );
QgsApplication::instance()->taskManager()->addTask( fetcher );
mFileRegistry.insert( url,
FetchedContent( nullptr,
QgsNetworkContentFetcherRegistry::Downloading ) );

QObject::connect( fetcher, &QgsNetworkContentFetcherTask::fetched, this, [ = ]()
{
QNetworkReply *reply = fetcher->reply();
FetchedContent content = mFileRegistry.take( url );
if ( reply->error() == QNetworkReply::NoError )
{
content.setFile( new QTemporaryFile( QStringLiteral( "XXXXXX" ) ) );
content.mFile->write( reply->readAll() );
content.setStatus( Finished );
}
else
{
content.setStatus( Failed );
content.setError( reply->error() );
}
mFileRegistry.insert( url, content );
} );


return fetcher;
}



QgsNetworkContentFetcherRegistry::FetchedContent QgsNetworkContentFetcherRegistry::file( const QUrl &url )
{
return mFileRegistry.value( url );
}
110 changes: 110 additions & 0 deletions src/core/qgsnetworkcontentfetcherregistry.h
@@ -0,0 +1,110 @@
/***************************************************************************
qgsnetworkcontentfetcherregistry.h
-------------------
begin : April, 2018
copyright : (C) 2018 by Denis Rouzaud
email : denis.rouzaud@gmail.com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSNETWORKCONTENTFETCHERREGISTRY_H
#define QGSNETWORKCONTENTFETCHERREGISTRY_H

#include <QObject>
#include <QMap>
#include <QNetworkReply>
#include <QTemporaryFile>

class QTemporaryFile;

class QgsNetworkContentFetcherTask;


/**
* \class QgsNetworkContentFetcherRegistry
* \ingroup core
* \brief Registry for temporary fetched files
*
* This provides a simple way of downloading and accessing
* remote files during QGIS application running.
*
* \see QgsNetworkContentFetcher
* \see QgsNetworkContentFetcherTask
*
* \since QGIS 3.2
*/
class QgsNetworkContentFetcherRegistry : public QObject
{
Q_OBJECT
public:
//! Status of fetched content
enum ContentStatus
{
UnknownUrl, //!< No download started for such URL
Downloading, //!< Currently downloading
Finished, //!< Download finished and successful
Failed //!< Download failed
};

/**
* FetchedContent contains a pointer to the file and the status of the download
*/
class FetchedContent
{
public:
//! Constructs a FetchedContent with pointer to the downloaded file and status of the download
explicit FetchedContent( QTemporaryFile *file = nullptr, ContentStatus status = UnknownUrl )
: mFile( file ), mStatus( status ) {}

//! Return a pointer to the local file, a null pointer if the file is not accessible yet.
const QFile *file() const {return mFile;}

//! Return the status of the download
ContentStatus status() const {return mStatus;}

//! Return the potential error of the download
QNetworkReply::NetworkError reply() const {return mError;}

private:
void setFile( QTemporaryFile *file ) {mFile = file;}
void setStatus( ContentStatus status ) {mStatus = status;}
void setError( QNetworkReply::NetworkError error ) {mError = error;}
QTemporaryFile *mFile;
QgsNetworkContentFetcherTask *mFetchingTask;
ContentStatus mStatus;
QNetworkReply::NetworkError mError = QNetworkReply::NoError;

// allow modification of task and file from main class
friend class QgsNetworkContentFetcherRegistry;
};

//! Create the registry for temporary downloaded files
explicit QgsNetworkContentFetcherRegistry();

~QgsNetworkContentFetcherRegistry();

/**
* @brief fetch
* @param url
* @param reload
* @return
*/
const QgsNetworkContentFetcherTask *fetch( const QUrl &url, const bool reload = false );

FetchedContent file( const QUrl &url );

private:
QMap<QUrl, FetchedContent> mFileRegistry;

};

#endif // QGSNETWORKCONTENTFETCHERREGISTRY_H

0 comments on commit 25108e5

Please sign in to comment.