MailImporter

filterkmail_maildir.cpp
1/*
2 filterkmail_maildir.cpp - Kmail maildir mail import
3
4 SPDX-FileCopyrightText: 2005 Danny Kukawka <danny.kukawka@web.de>
5 SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9
10#include "filterkmail_maildir.h"
11
12#include <KLocalizedString>
13#include <QFileDialog>
14
15using namespace MailImporter;
16
17class MailImporter::FilterKMail_maildirPrivate
18{
19public:
20 int mImportDirDone = 0;
21 int mTotalDir = 0;
22};
23
24/** Default constructor. */
26 : Filter(i18n("Import KMail Maildirs and Folder Structure"),
27 QStringLiteral("Danny Kukawka"),
28 i18n("<p><b>KMail import filter</b></p>"
29 "<p>Select the base directory of the KMail mailfolder you want to import.</p>"
30 "<p><b>Note:</b> Never select your current local KMail maildir (usually "
31 "~/Mail or ~/.kde/share/apps/kmail/mail ): in this case, ImportWizard may become stuck "
32 "in a continuous loop. </p>"
33 "<p>This filter does not import KMail mailfolders with mbox files.</p>"
34 "<p>Since it is possible to recreate the folder structure, the folders "
35 "will be stored under: \"KMail-Import\" in your local folder.</p>"))
36 , d(new MailImporter::FilterKMail_maildirPrivate)
37{
38}
39
40/** Destructor. */
42
43/** Recursive import of KMail maildir. */
45{
46 clearCountDuplicate();
47 const QString homeDir = QDir::homePath();
48 const QString maildir = QFileDialog::getExistingDirectory(nullptr, QString(), homeDir);
49 if (!maildir.isEmpty()) {
50 importMails(maildir);
51 }
52}
53
54void FilterKMail_maildir::processDirectory(const QString &path)
55{
56 QDir dir(path);
57 const QStringList rootSubDirs = dir.entryList(QStringList(QStringLiteral("*")), QDir::Dirs | QDir::Hidden, QDir::Name);
58 QStringList::ConstIterator end = rootSubDirs.constEnd();
59 for (QStringList::ConstIterator filename = rootSubDirs.constBegin(); filename != end; ++filename) {
60 if (filterInfo()->shouldTerminate()) {
61 break;
62 }
63 if (!(*filename == QLatin1Char('.') || *filename == QLatin1StringView(".."))) {
64 filterInfo()->setCurrent(0);
65 importDirContents(dir.filePath(*filename));
66 filterInfo()->setOverall((d->mTotalDir > 0) ? (int)((float)d->mImportDirDone / d->mTotalDir * 100) : 0);
67 filterInfo()->setCurrent(100);
68 ++d->mImportDirDone;
69 }
70 }
71}
72
74{
75 if (maildir.isEmpty()) {
76 filterInfo()->alert(i18n("No directory selected."));
77 return;
78 }
79 setMailDir(maildir);
80 /**
81 * If the user only select homedir no import needed because
82 * there should be no files and we surely import wrong files.
83 */
84 if (mailDir() == QDir::homePath() || mailDir() == (QDir::homePath() + QLatin1Char('/'))) {
85 filterInfo()->addErrorLogEntry(i18n("No files found for import."));
86 } else {
87 filterInfo()->setOverall(0);
88 d->mImportDirDone = 0;
89
90 /** Recursive import of the MailArchives */
91 QDir dir(mailDir());
92 d->mTotalDir = Filter::countDirectory(dir, true /*search hidden directory*/);
93 processDirectory(mailDir());
94
95 filterInfo()->addInfoLogEntry(i18n("Finished importing emails from %1", mailDir()));
96 if (countDuplicates() > 0) {
97 filterInfo()->addInfoLogEntry(i18np("1 duplicate message not imported", "%1 duplicate messages not imported", countDuplicates()));
98 }
99 }
100 if (filterInfo()->shouldTerminate()) {
101 filterInfo()->addInfoLogEntry(i18n("Finished import, canceled by user."));
102 }
103 filterInfo()->setCurrent(100);
104 filterInfo()->setOverall(100);
105}
106
107/**
108 * Import of a directory contents.
109 * @param info Information storage for the operation.
110 * @param dirName The name of the directory to import.
111 */
112void FilterKMail_maildir::importDirContents(const QString &dirName)
113{
114 /** Here Import all archives in the current dir */
115 importFiles(dirName);
116
117 /** If there are subfolders, we import them one by one */
118
119 processDirectory(dirName);
120}
121
122/**
123 * Import the files within a Folder.
124 * @param info Information storage for the operation.
125 * @param dirName The name of the directory to import.
126 */
127void FilterKMail_maildir::importFiles(const QString &dirName)
128{
129 QDir dir(dirName);
130 QString _path;
131 bool generatedPath = false;
132
133 QDir importDir(dirName);
134 const QStringList files = importDir.entryList(QStringList(QStringLiteral("[^\\.]*")), QDir::Files, QDir::Name);
135 int currentFile = 1;
136 int numFiles = files.size();
137 QStringList::ConstIterator filesEnd(files.constEnd());
138
139 for (QStringList::ConstIterator mailFile = files.constBegin(); mailFile != filesEnd; ++mailFile, ++currentFile) {
140 if (filterInfo()->shouldTerminate()) {
141 return;
142 }
143
144 QString temp_mailfile = *mailFile;
145 if (!(temp_mailfile.endsWith(QLatin1StringView(".index")) || temp_mailfile.endsWith(QLatin1StringView(".index.ids"))
146 || temp_mailfile.endsWith(QLatin1StringView(".index.sorted")) || temp_mailfile.endsWith(QLatin1StringView(".uidcache")))) {
147 if (!generatedPath) {
148 _path = QStringLiteral("KMail-Import");
149 QString _tmp = dir.filePath(*mailFile);
150 _tmp.remove(mailDir(), Qt::CaseSensitive);
151 const QStringList subFList = _tmp.split(QLatin1Char('/'), Qt::SkipEmptyParts);
153 for (QStringList::ConstIterator it = subFList.constBegin(); it != end; ++it) {
154 QString _cat = *it;
155 if (!(_cat == *mailFile)) {
156 if (_cat.startsWith(QLatin1Char('.')) && _cat.endsWith(QLatin1StringView(".directory"))) {
157 _cat.remove(0, 1);
158 _cat.remove((_cat.length() - 10), 10);
159 } else if (_cat.startsWith(QLatin1Char('.'))) {
160 _cat.remove(0, 1);
161 }
162 _path += QLatin1Char('/') + _cat;
163 }
164 }
165 if (_path.endsWith(QLatin1StringView("cur"))) {
166 _path.remove(_path.length() - 4, 4);
167 }
168 QString _info = _path;
169 filterInfo()->addInfoLogEntry(i18n("Import folder %1...", _info.remove(0, 12)));
170 filterInfo()->setFrom(_info);
171 filterInfo()->setTo(_path);
172 generatedPath = true;
173 }
174
175 if (!importMessage(_path, dir.filePath(*mailFile), filterInfo()->removeDupMessage())) {
176 filterInfo()->addErrorLogEntry(i18n("Could not import %1, duplicated message", *mailFile));
177 }
178 filterInfo()->setCurrent((int)((float)currentFile / numFiles * 100));
179 }
180 }
181}
~FilterKMail_maildir() override
Destructor.
void importMails(const QString &maildir)
void import() override
Recursive import of KMail maildir.
The Filter class.
Definition filters.h:29
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
KIOCORE_EXPORT QString dir(const QString &fileClass)
const QList< QKeySequence > & end()
QString homePath()
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
typedef ConstIterator
const_iterator constBegin() const const
const_iterator constEnd() const const
iterator end()
qsizetype size() const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype length() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
CaseSensitive
SkipEmptyParts
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:39 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.