QGIS API Documentation  3.27.0-Master (aef1b1ec20)
qgssourcecache.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssourcecache.cpp
3  -----------------
4  begin : July 2020
5  copyright : (C) 2020 by Mathieu Pellerin
6  email : nirvn dot asia at gmail 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 "qgssourcecache.h"
19 
20 #include "qgis.h"
21 #include "qgslogger.h"
22 
23 #include <QFile>
24 #include <QBuffer>
25 #include <QTemporaryDir>
26 
28 
29 QgsSourceCacheEntry::QgsSourceCacheEntry( const QString &path )
31 {
32 }
33 
34 bool QgsSourceCacheEntry::isEqual( const QgsAbstractContentCacheEntry *other ) const
35 {
36  const QgsSourceCacheEntry *otherSource = dynamic_cast< const QgsSourceCacheEntry * >( other );
37  // cheapest checks first!
38  if ( !otherSource || otherSource->filePath != filePath )
39  return false;
40 
41  return true;
42 }
43 
44 int QgsSourceCacheEntry::dataSize() const
45 {
46  return filePath.size();
47 }
48 
49 void QgsSourceCacheEntry::dump() const
50 {
51  QgsDebugMsgLevel( QStringLiteral( "path: %1" ).arg( path ), 3 );
52 }
53 
55 
57  : QgsAbstractContentCache< QgsSourceCacheEntry >( parent, QObject::tr( "Source" ) )
58 {
59  temporaryDir.reset( new QTemporaryDir() );
60 
62 }
63 
64 QString QgsSourceCache::localFilePath( const QString &path, bool blocking )
65 {
66  const QString file = path.trimmed();
67  if ( file.isEmpty() )
68  return QString();
69 
70  const QMutexLocker locker( &mMutex );
71 
72  QgsSourceCacheEntry *currentEntry = findExistingEntry( new QgsSourceCacheEntry( file ) );
73 
74  //if current entry's temporary file is empty, create it
75  if ( currentEntry->filePath.isEmpty() )
76  {
77  bool isBroken;
78  const QString filePath = fetchSource( file, isBroken, blocking );
79  currentEntry->filePath = filePath;
80  }
81 
82  return currentEntry->filePath;
83 }
84 
85 QString QgsSourceCache::fetchSource( const QString &path, bool &isBroken, bool blocking ) const
86 {
87  QString filePath;
88 
89  if ( !path.startsWith( QLatin1String( "base64:" ) ) && QFile::exists( path ) )
90  {
91  filePath = path;
92  }
93  else
94  {
95  const QByteArray ba = getContent( path, QByteArray( "broken" ), QByteArray( "fetching" ), blocking );
96 
97  if ( ba == "broken" )
98  {
99  isBroken = true;
100  }
101  else
102  {
103  int id = 1;
104  filePath = temporaryDir->filePath( QString::number( id ) );
105  while ( QFile::exists( filePath ) )
106  filePath = temporaryDir->filePath( QString::number( ++id ) );
107 
108  QFile file( filePath );
109  file.open( QIODevice::WriteOnly );
110  file.write( ba );
111  file.close();
112  }
113  }
114 
115  return filePath;
116 }
void remoteContentFetched(const QString &url)
Emitted when the cache has finished retrieving content from a remote url.
Base class for entries in a QgsAbstractContentCache.
Abstract base class for file content caches, such as SVG or raster image caches.
QgsSourceCacheEntry * findExistingEntry(QgsSourceCacheEntry *entryTemplate)
Returns the existing entry from the cache which matches entryTemplate (deleting entryTemplate when do...
QByteArray getContent(const QString &path, const QByteArray &missingContent, const QByteArray &fetchingContent, bool blocking=false) const
Gets the file content corresponding to the given path.
QgsSourceCache(QObject *parent=nullptr)
Constructor for QgsSourceCache, with the specified parent object.
void remoteSourceFetched(const QString &url)
Emitted when the cache has finished retrieving a 3D model from a remote url.
QString localFilePath(const QString &path, bool blocking=false)
Returns a local file path reflecting the content of a specified source path.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39