File indexing completed on 2025-01-05 03:59:36

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
0004 //
0005 
0006 
0007 // Own
0008 #include "FileStoragePolicy.h"
0009 
0010 // Qt
0011 #include <QDir>
0012 #include <QDirIterator>
0013 #include <QFile>
0014 #include <QFileInfo>
0015 
0016 // Marble
0017 #include "MarbleGlobal.h"
0018 #include "MarbleDirs.h"
0019 
0020 #include "digikam_debug.h"
0021 
0022 using namespace Marble;
0023 
0024 FileStoragePolicy::FileStoragePolicy( const QString &dataDirectory, QObject *parent )
0025     : StoragePolicy( parent ),
0026       m_dataDirectory( dataDirectory )
0027 {
0028     if ( m_dataDirectory.isEmpty() )
0029         m_dataDirectory = MarbleDirs::localPath() + QLatin1String("/cache/");
0030 
0031     if ( !QDir( m_dataDirectory ).exists() )
0032         QDir::root().mkpath( m_dataDirectory );
0033 }
0034 
0035 FileStoragePolicy::~FileStoragePolicy()
0036 {
0037 }
0038 
0039 bool FileStoragePolicy::fileExists( const QString &fileName ) const
0040 {
0041     const QString fullName = m_dataDirectory + QLatin1Char('/') + fileName;
0042     return QFile::exists( fullName );
0043 }
0044 
0045 bool FileStoragePolicy::updateFile( const QString &fileName, const QByteArray &data )
0046 {
0047     QFileInfo const dirInfo( fileName );
0048     QString const fullName = dirInfo.isAbsolute() ? fileName : m_dataDirectory + QLatin1Char('/') + fileName;
0049 
0050     // Create directory if it doesn't exist yet...
0051     QFileInfo info( fullName );
0052 
0053     const QDir localFileDir = info.dir();
0054     const QString localFileDirPath = localFileDir.absolutePath();
0055 
0056     if ( !QDir( localFileDirPath ).exists() )
0057         QDir::root().mkpath( localFileDirPath );
0058 
0059     // ... and save the file content
0060     QFile file( fullName );
0061     if ( !file.open( QIODevice::WriteOnly ) ) {
0062         m_errorMsg = fullName + QLatin1String(": ") + file.errorString();
0063         qCCritical(DIGIKAM_MARBLE_LOG) << "file.open" << m_errorMsg;
0064         return false;
0065     }
0066 
0067     quint64 oldSize = file.size();
0068 
0069     if ( !file.write( data ) ) {
0070         m_errorMsg = fullName + QLatin1String(": ") + file.errorString();
0071         qCCritical(DIGIKAM_MARBLE_LOG) << "file.write" << m_errorMsg;
0072         Q_EMIT sizeChanged( file.size() - oldSize );
0073         return false;
0074     }
0075 
0076     Q_EMIT sizeChanged( file.size() - oldSize );
0077     file.close();
0078 
0079     return true;
0080 }
0081 
0082 void FileStoragePolicy::clearCache()
0083 {
0084     qCDebug(DIGIKAM_MARBLE_LOG) << Q_FUNC_INFO;
0085     if ( m_dataDirectory.isEmpty()
0086     || !(m_dataDirectory.endsWith(QLatin1String( "data" ))   // on Windows
0087     ||   m_dataDirectory.endsWith(QLatin1String( "marble" )) // on all other OSes
0088     ))
0089     {
0090         qCDebug(DIGIKAM_MARBLE_LOG) << "Data Directory:" << m_dataDirectory;
0091         qCDebug(DIGIKAM_MARBLE_LOG) << "Error: Refusing to erase files under unknown conditions for safety reasons!";
0092         return;
0093     }
0094 
0095     const QString cachedMapsDirectory = m_dataDirectory + QLatin1String("/maps");
0096 
0097     QDirIterator it( cachedMapsDirectory, QDir::NoDotAndDotDot | QDir::Dirs );
0098     qCDebug(DIGIKAM_MARBLE_LOG) << cachedMapsDirectory;
0099     while (it.hasNext()) {
0100         it.next();
0101         QString planetDirectory = it.filePath();
0102         QDirIterator itPlanet( planetDirectory, QDir::NoDotAndDotDot | QDir::Dirs );
0103         while (itPlanet.hasNext()) {
0104             itPlanet.next();
0105             QString themeDirectory = itPlanet.filePath();
0106             QDirIterator itTheme( themeDirectory, QDir::NoDotAndDotDot | QDir::Dirs );
0107             while (itTheme.hasNext()) {
0108                 itTheme.next();
0109                 QString tileDirectory = itTheme.filePath();
0110 
0111                 if ( itTheme.fileName().toInt() <= maxBaseTileLevel ) {
0112                     continue;
0113                 }
0114 
0115                 QDirIterator itTile( tileDirectory, QDir::Files | QDir::NoSymLinks, QDirIterator::Subdirectories );
0116                 while (itTile.hasNext()) {
0117                     itTile.next();
0118                     QString filePath = itTile.filePath();
0119                     QString lowerCase = filePath.toLower();
0120 
0121                     // We try to be very careful and just delete images
0122                     // FIXME, when vectortiling I suppose also vector tiles will have
0123                     // to be deleted
0124                     if ( lowerCase.endsWith( QLatin1String( ".jpg" ) )
0125                       || lowerCase.endsWith( QLatin1String( ".png" ) )
0126                       || lowerCase.endsWith( QLatin1String( ".gif" ) )
0127                       || lowerCase.endsWith( QLatin1String( ".svg" ) )
0128                       || lowerCase.endsWith( QLatin1String( ".o5m" ) )
0129                     )
0130                     {
0131                         // We cannot Q_EMIT clear, because we don't make a full clear
0132                         QFile file( filePath );
0133                         Q_EMIT sizeChanged( -file.size() );
0134                         file.remove();
0135                     }
0136                 }
0137             }
0138         }
0139     }
0140 }
0141 
0142 QString FileStoragePolicy::lastErrorMessage() const
0143 {
0144     return m_errorMsg;
0145 }
0146 
0147 #include "moc_FileStoragePolicy.cpp"