File indexing completed on 2024-04-28 15:15:40

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