File indexing completed on 2025-01-05 03:59:36
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2014 Abhinav Gangwar <abhgang@gmail.com> 0004 // 0005 0006 #include "RemoteIconLoader.h" 0007 0008 // Qt 0009 #include <QString> 0010 #include <QHash> 0011 #include <QUrl> 0012 #include <QImage> 0013 #include <QByteArray> 0014 #include <QFileInfo> 0015 #include <QCryptographicHash> 0016 0017 // Marble 0018 #include "HttpDownloadManager.h" 0019 #include "FileStoragePolicy.h" 0020 #include "MarbleDirs.h" 0021 #include "MarbleGlobal.h" 0022 0023 #include "digikam_debug.h" 0024 0025 namespace Marble 0026 { 0027 0028 class RemoteIconLoaderPrivate 0029 { 0030 public: 0031 RemoteIconLoaderPrivate() 0032 : m_storagePolicy(MarbleDirs::localPath() + QLatin1String("/cache/icons/")), 0033 m_downloadManager( &m_storagePolicy ) 0034 { 0035 } 0036 QHash<QUrl, QImage> m_iconCache; 0037 FileStoragePolicy m_storagePolicy; 0038 HttpDownloadManager m_downloadManager; 0039 0040 /** 0041 * Returns true if the icon for Url(=url) is available in cache 0042 */ 0043 bool isCached( const QUrl& url ) const; 0044 0045 /** 0046 * Returns icon for the url passes in argument 0047 */ 0048 QImage cachedIcon( const QUrl& url ) const; 0049 0050 /** 0051 * Returns true if icon is locally present on disk 0052 */ 0053 bool loadFromDiskCache( const QUrl& url ); 0054 0055 /** 0056 * Starts downloading icon if it isn't present cache and 0057 * could not be found locally on disk 0058 */ 0059 void initiateDownload( const QUrl& url ); 0060 0061 /** 0062 * Returns a name with which downloaded icon will be saved on disk 0063 */ 0064 static QString cacheFileName(const QUrl &url); 0065 }; 0066 0067 bool RemoteIconLoaderPrivate::isCached( const QUrl& url ) const 0068 { 0069 return m_iconCache.contains( url ); 0070 } 0071 0072 QImage RemoteIconLoaderPrivate::cachedIcon( const QUrl& url ) const 0073 { 0074 return m_iconCache.value( url ); 0075 } 0076 0077 bool RemoteIconLoaderPrivate::loadFromDiskCache( const QUrl& url ) 0078 { 0079 QString path = MarbleDirs::localPath() + QLatin1String("/cache/icons/") + cacheFileName(url); 0080 QImage icon = QFile::exists( path ) ? QImage( path ) : QImage(); 0081 if ( !icon.isNull() ) { 0082 m_iconCache.insert( url, icon ); 0083 return true; 0084 } 0085 return false; 0086 } 0087 0088 void RemoteIconLoaderPrivate::initiateDownload( const QUrl& url ) 0089 { 0090 DownloadUsage usage = DownloadBrowse; 0091 m_downloadManager.setDownloadEnabled(true); 0092 QString fileName = cacheFileName( url ); 0093 m_downloadManager.addJob(url, fileName, url.toString(), usage ); 0094 } 0095 0096 QString RemoteIconLoaderPrivate::cacheFileName(const QUrl &url) 0097 { 0098 const QString suffix = QFileInfo(url.path()).suffix(); 0099 const QByteArray hash = QCryptographicHash::hash( url.toEncoded(), QCryptographicHash::Md5 ).toHex(); 0100 const QString fileName = QString::fromLatin1(hash) + QLatin1Char('.') + suffix; 0101 return fileName; 0102 } 0103 0104 RemoteIconLoader::RemoteIconLoader( QObject *parent ) 0105 : QObject( parent ), 0106 d ( new RemoteIconLoaderPrivate() ) 0107 { 0108 connect( &d->m_downloadManager, SIGNAL(downloadComplete(QByteArray,QString)), this, 0109 SLOT(storeIcon(QByteArray,QString)) ); 0110 } 0111 0112 RemoteIconLoader::~RemoteIconLoader() 0113 { 0114 delete d; 0115 } 0116 0117 0118 QImage RemoteIconLoader::load( const QUrl& url ) 0119 { 0120 /* 0121 * If image has been downloaded previously then 0122 * return it from m_iconCache. All the downloaded 0123 * images in current running marble session are stored 0124 * in m_iconCache. 0125 */ 0126 if ( d->isCached( url ) ) { 0127 return d->cachedIcon( url ); 0128 } 0129 0130 /* 0131 * All the downloaded images are saved on disk 0132 * at location cache/icons/ ( relative location ). 0133 * If the rquested icon is present at this location then 0134 * return it. 0135 */ 0136 else if ( d->loadFromDiskCache( url ) ) { 0137 return d->cachedIcon( url ); 0138 } 0139 0140 // Otherwise initiate download 0141 else { 0142 d->initiateDownload( url ); 0143 } 0144 return QImage(); 0145 } 0146 0147 0148 void RemoteIconLoader::storeIcon( const QByteArray &data, const QString &fileName) 0149 { 0150 QImage icon = QImage::fromData( data ); 0151 d->m_iconCache.insert( QUrl(fileName), icon ); 0152 Q_EMIT iconReady(); 0153 } 0154 0155 } 0156 0157 #include "moc_RemoteIconLoader.cpp"