File indexing completed on 2024-11-24 04:53:08

0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>
0002 
0003    This file is part of the Trojita Qt IMAP e-mail client,
0004    http://trojita.flaska.net/
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU General Public License as
0008    published by the Free Software Foundation; either version 2 of
0009    the License or (at your option) version 3 or any later version
0010    accepted by the membership of KDE e.V. (or its successor approved
0011    by the membership of KDE e.V.), which shall act as a proxy
0012    defined in Section 14 of version 3 of the license.
0013 
0014    This program is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017    GNU General Public License for more details.
0018 
0019    You should have received a copy of the GNU General Public License
0020    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #include "DiskPartCache.h"
0024 #include <QDebug>
0025 #include <QDir>
0026 
0027 namespace
0028 {
0029 /** @short Convert the QFile::FileError to a string representation */
0030 QString fileErrorToString(const QFile::FileError e)
0031 {
0032     switch (e) {
0033     case QFile::NoError:
0034         return QStringLiteral("QFile::NoError");
0035     case QFile::ReadError:
0036         return QStringLiteral("QFile::ReadError");
0037     case QFile::WriteError:
0038         return QStringLiteral("QFile::WriteError");
0039     case QFile::FatalError:
0040         return QStringLiteral("QFile::FatalError");
0041     case QFile::ResourceError:
0042         return QStringLiteral("QFile::ResourceError");
0043     case QFile::OpenError:
0044         return QStringLiteral("QFile::OpenError");
0045     case QFile::AbortError:
0046         return QStringLiteral("QFile::AbortError");
0047     case QFile::TimeOutError:
0048         return QStringLiteral("QFile::TimeOutError");
0049     case QFile::UnspecifiedError:
0050         return QStringLiteral("QFile::UnspecifiedError");
0051     case QFile::RemoveError:
0052         return QStringLiteral("QFile::RemoveError");
0053     case QFile::RenameError:
0054         return QStringLiteral("QFile::RenameError");
0055     case QFile::PositionError:
0056         return QStringLiteral("QFile::PositionError");
0057     case QFile::ResizeError:
0058         return QStringLiteral("QFile::ResizeError");
0059     case QFile::PermissionsError:
0060         return QStringLiteral("QFile::PermissionsError");
0061     case QFile::CopyError:
0062         return QStringLiteral("QFile::CopyError");
0063     }
0064     return QObject::tr("Unrecognized QFile error");
0065 }
0066 }
0067 
0068 namespace Imap
0069 {
0070 namespace Mailbox
0071 {
0072 
0073 DiskPartCache::DiskPartCache(const QString &cacheDir_)
0074     : cacheDir(cacheDir_)
0075 {
0076     if (!cacheDir.endsWith(QLatin1Char('/')))
0077         cacheDir.append(QLatin1Char('/'));
0078 }
0079 
0080 void DiskPartCache::clearAllMessages(const QString &mailbox)
0081 {
0082     QDir dir(dirForMailbox(mailbox));
0083     Q_FOREACH(const QString& fname, dir.entryList(QStringList() << QLatin1String("*.cache"))) {
0084         if (! dir.remove(fname)) {
0085             m_errorHandler(QObject::tr("Couldn't remove file %1 for mailbox %2").arg(fname, mailbox));
0086         }
0087     }
0088 }
0089 
0090 void DiskPartCache::clearMessage(const QString mailbox, const uint uid)
0091 {
0092     QDir dir(dirForMailbox(mailbox));
0093     Q_FOREACH(const QString& fname, dir.entryList(QStringList() << QString::fromUtf8("%1_*.cache").arg(QString::number(uid)))) {
0094         if (! dir.remove(fname)) {
0095             m_errorHandler(QObject::tr("Couldn't remove file %1 for message %2, mailbox %3").arg(fname, QString::number(uid), mailbox));
0096         }
0097     }
0098 }
0099 
0100 QByteArray DiskPartCache::messagePart(const QString &mailbox, const uint uid, const QByteArray &partId) const
0101 {
0102     QFile buf(fileForPart(mailbox, uid, partId));
0103     if (! buf.open(QIODevice::ReadOnly)) {
0104         return QByteArray();
0105     }
0106     return qUncompress(buf.readAll());
0107 }
0108 
0109 void DiskPartCache::setMsgPart(const QString &mailbox, const uint uid, const QByteArray &partId, const QByteArray &data)
0110 {
0111     QString myPath = dirForMailbox(mailbox);
0112     QDir dir(myPath);
0113     dir.mkpath(myPath);
0114     QString fileName(fileForPart(mailbox, uid, partId));
0115     QFile buf(fileName);
0116     if (! buf.open(QIODevice::WriteOnly)) {
0117         m_errorHandler(QObject::tr("Couldn't save the part %1 of message %2 (mailbox %3) into file %4: %5 (%6)").arg(
0118                            QString::fromUtf8(partId), QString::number(uid), mailbox, fileName, buf.errorString(),
0119                            fileErrorToString(buf.error())));
0120     }
0121     buf.write(qCompress(data));
0122 }
0123 
0124 void DiskPartCache::forgetMessagePart(const QString &mailbox, const uint uid, const QByteArray &partId)
0125 {
0126     QFile(fileForPart(mailbox, uid, partId)).remove();
0127 }
0128 
0129 QString DiskPartCache::dirForMailbox(const QString &mailbox) const
0130 {
0131     return cacheDir + QString::fromUtf8(mailbox.toUtf8().toBase64());
0132 }
0133 
0134 QString DiskPartCache::fileForPart(const QString &mailbox, const uint uid, const QByteArray &partId) const
0135 {
0136     return QStringLiteral("%1/%2_%3.cache").arg(dirForMailbox(mailbox), QString::number(uid), QString::fromUtf8(partId));
0137 }
0138 
0139 void DiskPartCache::setErrorHandler(const std::function<void(const QString &)> &handler)
0140 {
0141     m_errorHandler = handler;
0142 }
0143 
0144 }
0145 }
0146