7#include "filterkmailarchive.h"
9#include <KLocalizedString>
14#include "mailimporter_debug.h"
15#include <QApplication>
17#include <QSharedPointer>
19#include <QMimeDatabase>
22using namespace MailImporter;
24class MailImporter::FilterKMailArchivePrivate
30FilterKMailArchive::FilterKMailArchive()
32 QStringLiteral(
"Klar\xE4lvdalens Datakonsult AB"),
33 i18n(
"<p><b>KMail Archive File Import Filter</b></p>"
34 "<p>This filter will import archives files previously exported by KMail.</p>"
35 "<p>Archive files contain a complete folder subtree compressed into a single file.</p>"))
36 , d(new MailImporter::FilterKMailArchivePrivate)
40FilterKMailArchive::~FilterKMailArchive() =
default;
48 const QString end = QStringLiteral(
".directory");
49 const int expectedIndex = dirName.
length() -
end.length();
54 returnName = returnName.
right(returnName.
length() - 1);
60 if (filterInfo()->shouldTerminate()) {
64 qApp->processEvents();
65 return filterImporter()->importMessage(file, folderPath, d->mTotalFiles, d->mFilesDone);
68bool FilterKMailArchive::importFolder(
const KArchiveDirectory *folder,
const QString &folderPath)
70 qCDebug(MAILIMPORTER_LOG) <<
"Importing folder" << folder->
name();
71 filterInfo()->addInfoLogEntry(
i18n(
"Importing folder '%1'...", folderPath));
72 filterInfo()->setTo(filterImporter()->topLevelFolder() + folderPath);
73 const KArchiveDirectory *
const messageDir =
dynamic_cast<const KArchiveDirectory *
>(folder->
entry(QStringLiteral(
"cur")));
78 const QStringList lstEntries = messageDir->
entries();
79 for (
const QString &entryName : lstEntries) {
80 filterInfo()->setCurrent(cur * 100 / total);
81 filterInfo()->setOverall(d->mTotalFiles == 0 ? 0 : (d->mFilesDone * 100 / d->mTotalFiles));
82 const KArchiveEntry *
const entry = messageDir->
entry(entryName);
85 const int oldCount = d->mFilesDone;
86 if (!importMessage(
static_cast<const KArchiveFile *
>(entry), folderPath)) {
91 if (oldCount != d->mFilesDone) {
97 filterInfo()->addErrorLogEntry(
i18n(
"Unexpected subfolder %1 in folder %2.", entryName, folder->
name()));
101 filterInfo()->addErrorLogEntry(
i18n(
"No subfolder named 'cur' in folder %1.", folder->
name()));
106bool FilterKMailArchive::importDirectory(
const KArchiveDirectory *directory,
const QString &folderPath)
108 qCDebug(MAILIMPORTER_LOG) <<
"Importing directory" << directory->
name();
109 const QStringList lstEntries = directory->
entries();
110 for (
const QString &entryName : lstEntries) {
111 const KArchiveEntry *
const entry = directory->
entry(entryName);
114 const auto dir =
static_cast<const KArchiveDirectory *
>(entry);
117 if (!importFolder(dir, folderPath + QLatin1Char(
'/') +
dir->name())) {
123 const QString folderName = folderNameForDirectoryName(entry->
name());
125 filterInfo()->addErrorLogEntry(
i18n(
"Unexpected subdirectory named '%1'.", entry->
name()));
127 if (!importDirectory(dir, folderPath + QLatin1Char(
'/') + folderName)) {
138int FilterKMailArchive::countFiles(
const KArchiveDirectory *directory)
const
141 const QStringList lstEntries = directory->
entries();
142 for (
const QString &entryName : lstEntries) {
143 const KArchiveEntry *
const entry = directory->
entry(entryName);
147 count += countFiles(
static_cast<const KArchiveDirectory *
>(entry));
153void FilterKMailArchive::import()
156 i18n(
"Select KMail Archive File to Import"),
158 QStringLiteral(
"%1 (*.tar *.tar.gz *.tar.bz2 *.zip)").arg(
i18n(
"KMail Archive Files ")));
160 filterInfo()->alert(
i18n(
"Please select an archive file that should be imported."));
163 importMails(archiveFile);
166void FilterKMailArchive::importMails(
const QString &archiveFile)
169 filterInfo()->alert(
i18n(
"No archive selected."));
172 filterInfo()->setFrom(archiveFile);
176 using KArchivePtr = QSharedPointer<KArchive>;
179 archive = KArchivePtr(
new KTar(archiveFile));
181 archive = KArchivePtr(
new KZip(archiveFile));
183 filterInfo()->alert(
i18n(
"The file '%1' does not appear to be a valid archive.", archiveFile));
188 filterInfo()->alert(
i18n(
"Unable to open archive file '%1'", archiveFile));
192 filterInfo()->setOverall(0);
193 filterInfo()->addInfoLogEntry(
i18n(
"Counting files in archive..."));
194 d->mTotalFiles = countFiles(archive->directory());
196 if (importDirectory(archive->directory(), QString())) {
197 filterInfo()->setOverall(100);
198 filterInfo()->setCurrent(100);
199 filterInfo()->addInfoLogEntry(
i18n(
"Importing the archive file '%1' into the folder '%2' succeeded.", archiveFile, filterImporter()->topLevelFolder()));
200 filterInfo()->addInfoLogEntry(
i18np(
"1 message was imported.",
"%1 messages were imported.", d->mFilesDone));
202 filterInfo()->addInfoLogEntry(
i18n(
"Importing the archive failed."));
QStringList entries() const
const KArchiveEntry * entry(const QString &name) const
virtual bool isDirectory() const
virtual bool isFile() const
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
KCALUTILS_EXPORT QString mimeType()
KIOCORE_EXPORT QString dir(const QString &fileClass)
const QList< QKeySequence > & end()
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
qsizetype count() const const
QMimeType mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString right(qsizetype n) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString toLower() const const