Skip to content
Permalink
Browse files

Add QgsSourceCache

  • Loading branch information
nirvn committed Jul 18, 2020
1 parent 25179ae commit 80627eb74099a59220104ccf1c34c5172f231c13
@@ -695,6 +695,13 @@ Returns the application's image cache, used for caching resampled versions of ra
.. seealso:: :py:func:`svgCache`

.. versionadded:: 3.6
%End

static QgsSourceCache *sourceCache();
%Docstring
Returns the application's source cache, used for caching embedded and remote source strings as local files

.. versionadded:: 3.16
%End

static QgsNetworkContentFetcherRegistry *networkContentFetcherRegistry() /KeepReference/;
@@ -0,0 +1,56 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgssourcecache.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsSourceCache : QgsAbstractContentCacheBase
{
%Docstring
A cache for source strings that returns a local file path containing the source content.

QgsSourceCache is not usually directly created, but rather accessed through
:py:func:`QgsApplication.sourceCache()`.

.. versionadded:: 3.16
%End

%TypeHeaderCode
#include "qgssourcecache.h"
%End
public:

QgsSourceCache( QObject *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsSourceCache, with the specified ``parent`` object.
%End

QString localFilePath( const QString &path, bool blocking = false );
%Docstring
Returns a local file path reflecting the content of a specified source ``path``

``path`` may be a local file, remote (HTTP) url, or a base 64 encoded string (with a "base64:" prefix).
%End

signals:

void remoteSourceFetched( const QString &url );
%Docstring
Emitted when the cache has finished retrieving a 3D model from a remote ``url``.
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgssourcecache.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -194,6 +194,7 @@
%Include auto_generated/qgssimplifymethod.sip
%Include auto_generated/qgssnappingconfig.sip
%Include auto_generated/qgssnappingutils.sip
%Include auto_generated/qgssourcecache.sip
%Include auto_generated/qgsspatialindex.sip
%Include auto_generated/qgsspatialindexkdbush.sip
%Include auto_generated/qgsspatialindexkdbushdata.sip
@@ -409,6 +409,7 @@ SET(QGIS_CORE_SRCS
qgssqliteexpressioncompiler.cpp
qgssqlstatement.cpp
qgssqliteutils.cpp
qgssourcecache.cpp
qgsspatialiteutils.cpp
qgsstatisticalsummary.cpp
qgsstoredexpressionmanager.cpp
@@ -966,6 +967,7 @@ SET(QGIS_CORE_HDRS
qgsspatialindexkdbush.h
qgsspatialindexkdbushdata.h
qgsspatialindexutils.h
qgssourcecache.h
qgsspatialiteutils.h
qgssqlexpressioncompiler.h
qgssqliteutils.h
@@ -35,6 +35,7 @@
#include "qgsscalebarrendererregistry.h"
#include "qgssvgcache.h"
#include "qgsimagecache.h"
#include "qgssourcecache.h"
#include "qgscolorschemeregistry.h"
#include "qgspainteffectregistry.h"
#include "qgsprojectstorageregistry.h"
@@ -2139,6 +2140,11 @@ QgsImageCache *QgsApplication::imageCache()
return members()->mImageCache;
}

QgsSourceCache *QgsApplication::sourceCache()
{
return members()->mSourceCache;
}

QgsNetworkContentFetcherRegistry *QgsApplication::networkContentFetcherRegistry()
{
return members()->mNetworkContentFetcherRegistry;
@@ -2287,6 +2293,11 @@ QgsApplication::ApplicationMembers::ApplicationMembers()
mImageCache = new QgsImageCache();
profiler->end();
}
{
profiler->start( tr( "Setup source cache" ) );
mSourceCache = new QgsSourceCache();
profiler->end();
}
{
profiler->start( tr( "Setup color scheme registry" ) );
mColorSchemeRegistry = new QgsColorSchemeRegistry();
@@ -36,6 +36,7 @@ class QgsLocalizedDataPathRegistry;
class QgsRendererRegistry;
class QgsSvgCache;
class QgsImageCache;
class QgsSourceCache;
class QgsSymbolLayerRegistry;
class QgsRasterRendererRegistry;
class QgsGpsConnectionRegistry;
@@ -643,6 +644,13 @@ class CORE_EXPORT QgsApplication : public QApplication
*/
static QgsImageCache *imageCache();

/**
* Returns the application's source cache, used for caching embedded and remote source strings as local files
*
* \since QGIS 3.16
*/
static QgsSourceCache *sourceCache();

/**
* Returns the application's network content registry used for fetching temporary files during QGIS session
* \since QGIS 3.2
@@ -942,6 +950,7 @@ class CORE_EXPORT QgsApplication : public QApplication
QgsRendererRegistry *mRendererRegistry = nullptr;
QgsSvgCache *mSvgCache = nullptr;
QgsImageCache *mImageCache = nullptr;
QgsSourceCache *mSourceCache = nullptr;
QgsSymbolLayerRegistry *mSymbolLayerRegistry = nullptr;
QgsCalloutRegistry *mCalloutRegistry = nullptr;
QgsTaskManager *mTaskManager = nullptr;
@@ -0,0 +1,116 @@
/***************************************************************************
qgssourcecache.cpp
-----------------
begin : July 2020
copyright : (C) 2020 by Mathieu Pellerin
email : nirvn dot asia at gmail dot 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 "qgssourcecache.h"

#include "qgis.h"
#include "qgslogger.h"

#include <QFile>
#include <QBuffer>
#include <QTemporaryDir>

///@cond PRIVATE

QgsSourceCacheEntry::QgsSourceCacheEntry( const QString &path )
: QgsAbstractContentCacheEntry( path )
{
}

bool QgsSourceCacheEntry::isEqual( const QgsAbstractContentCacheEntry *other ) const
{
const QgsSourceCacheEntry *otherSource = dynamic_cast< const QgsSourceCacheEntry * >( other );
// cheapest checks first!
if ( !otherSource || otherSource->filePath != filePath )
return false;

return true;
}

int QgsSourceCacheEntry::dataSize() const
{
return filePath.size();
}

void QgsSourceCacheEntry::dump() const
{
QgsDebugMsgLevel( QStringLiteral( "path: %1" ).arg( path ), 3 );
}

///@endcond

QgsSourceCache::QgsSourceCache( QObject *parent )
: QgsAbstractContentCache< QgsSourceCacheEntry >( parent, QObject::tr( "Source" ) )
{
temporaryDir.reset( new QTemporaryDir() );

connect( this, &QgsAbstractContentCacheBase::remoteContentFetched, this, &QgsSourceCache::remoteSourceFetched );
}

QString QgsSourceCache::localFilePath( const QString &path, bool blocking )
{
const QString file = path.trimmed();
if ( file.isEmpty() )
return QString();

QMutexLocker locker( &mMutex );

QgsSourceCacheEntry *currentEntry = findExistingEntry( new QgsSourceCacheEntry( file ) );

//if current entry's temporary file is empty, create it
if ( currentEntry->filePath.isEmpty() )
{
bool isBroken;
QString filePath = fetchSource( file, isBroken, blocking );
currentEntry->filePath = filePath;
}

return currentEntry->filePath;
}

QString QgsSourceCache::fetchSource( const QString &path, bool &isBroken, bool blocking ) const
{
QString filePath;

if ( !path.startsWith( QStringLiteral( "base64:" ) ) && QFile::exists( path ) )
{
filePath = path;
}
else
{
QByteArray ba = getContent( path, QByteArray( "broken" ), QByteArray( "fetching" ), blocking );

if ( ba == "broken" )
{
isBroken = true;
}
else
{
int id = 1;
filePath = temporaryDir->filePath( QString::number( id ) );
while ( QFile::exists( filePath ) )
filePath = temporaryDir->filePath( QString::number( ++id ) );

QFile file( filePath );
file.open( QIODevice::WriteOnly );
file.write( ba );
file.close();
}
}

return filePath;
}
@@ -0,0 +1,103 @@
/***************************************************************************
qgssourcecache.h
---------------
begin : July 2020
copyright : (C) 2020 by Mathieu Pellerin
email : nirvn dot asia at gmail dot 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 QGSSOURCECACHE_H
#define QGSSOURCECACHE_H

#include "qgsabstractcontentcache.h"
#include "qgis_sip.h"
#include "qgis_core.h"

#ifndef SIP_RUN

///@cond PRIVATE

/**
* \ingroup core
* \class QgsSourceCacheEntry
* An entry for a QgsSourceCache, representing a given source's file path
* \since QGIS 3.16
*/
class CORE_EXPORT QgsSourceCacheEntry : public QgsAbstractContentCacheEntry
{
public:

/**
* Constructor for QgsSourceCacheEntry, corresponding to the specified \a path.
*/
QgsSourceCacheEntry( const QString &path ) ;

//! The local file path of the source string
QString filePath;

int dataSize() const override;
void dump() const override;
bool isEqual( const QgsAbstractContentCacheEntry *other ) const override;

};

///@endcond
#endif

/**
* \class QgsSourceCache
* \ingroup core
* A cache for source strings that returns a local file path containing the source content.
*
* QgsSourceCache is not usually directly created, but rather accessed through
* QgsApplication::sourceCache().
*
* \since QGIS 3.16
*/
#ifdef SIP_RUN
class CORE_EXPORT QgsSourceCache : public QgsAbstractContentCacheBase // for sip we skip to the base class and avoid the template difficulty
{
#else
class CORE_EXPORT QgsSourceCache : public QgsAbstractContentCache< QgsSourceCacheEntry >
{
#endif
Q_OBJECT

public:

/**
* Constructor for QgsSourceCache, with the specified \a parent object.
*/
QgsSourceCache( QObject *parent SIP_TRANSFERTHIS = nullptr );

/**
* Returns a local file path reflecting the content of a specified source \a path
*
* \a path may be a local file, remote (HTTP) url, or a base 64 encoded string (with a "base64:" prefix).
*/
QString localFilePath( const QString &path, bool blocking = false );

signals:

/**
* Emitted when the cache has finished retrieving a 3D model from a remote \a url.
*/
void remoteSourceFetched( const QString &url );

private:

QString fetchSource( const QString &path, bool &isBroken, bool blocking = false ) const;

std::unique_ptr< QTemporaryDir > temporaryDir;
};

#endif // QGSSOURCECACHE_H

0 comments on commit 80627eb

Please sign in to comment.
You can’t perform that action at this time.