10#include "filtersylpheed.h"
12#include "mailimporter_debug.h"
13#include <KLocalizedString>
14#include <QDomDocument>
18using namespace MailImporter;
20class MailImporter::FilterSylpheedPrivate
23 int mImportDirDone = 0;
28 : Filter(
i18n(
"Import Sylpheed Maildirs and Folder Structure"),
29 QStringLiteral(
"Danny Kukawka"),
30 i18n(
"<p><b>Sylpheed import filter</b></p>"
31 "<p>Select the base directory of the Sylpheed mailfolder you want to import "
32 "(usually: ~/Mail ).</p>"
33 "<p>Since it is possible to recreate the folder structure, the folders "
34 "will be stored under: \"Sylpheed-Import\" in your local folder.</p>"
35 "<p>This filter also recreates the status of message, e.g. new or forwarded.</p>"))
36 , d(new MailImporter::FilterSylpheedPrivate)
43QString FilterSylpheed::isMailerFound()
45 QDir directory(FilterSylpheed::defaultSettingsPath());
46 if (directory.exists()) {
47 return i18nc(
"name of sylpheed application",
"Sylpheed");
52QString FilterSylpheed::defaultSettingsPath()
57QString FilterSylpheed::localMailDirPath()
59 QFile folderListFile(FilterSylpheed::defaultSettingsPath() + QLatin1StringView(
"/folderlist.xml"));
60 if (folderListFile.exists()) {
63 qCWarning(MAILIMPORTER_LOG) <<
"Impossible to open " << folderListFile.fileName();
65 const QDomDocument::ParseResult parseResult = doc.
setContent(&folderListFile);
67 qCDebug(MAILIMPORTER_LOG) <<
"Unable to load document.Parse error in line " << parseResult.errorLine <<
", col " << parseResult.errorColumn <<
": "
68 << qPrintable(parseResult.errorMessage);
78 if (e.tagName() == QLatin1StringView(
"folder")) {
79 if (e.hasAttribute(QStringLiteral(
"type"))) {
80 if (e.attribute(QStringLiteral(
"type")) == QLatin1StringView(
"mh")) {
81 return e.attribute(QStringLiteral(
"path"));
93 QString homeDir = localMailDirPath();
104void FilterSylpheed::processDirectory(
const QString &path)
110 if (filterInfo()->shouldTerminate()) {
113 importDirContents(dir.filePath(*filename));
114 filterInfo()->setOverall((d->mTotalDir > 0) ? (
int)((
float)d->mImportDirDone / d->mTotalDir * 100) : 0);
122 filterInfo()->alert(
i18n(
"No directory selected."));
131 filterInfo()->addErrorLogEntry(
i18n(
"No files found for import."));
133 filterInfo()->setOverall(0);
135 d->mImportDirDone = 0;
140 d->mTotalDir = Filter::countDirectory(dir,
false);
141 processDirectory(mailDir());
143 filterInfo()->addInfoLogEntry(
i18n(
"Finished importing emails from %1", mailDir()));
144 if (countDuplicates() > 0) {
145 filterInfo()->addInfoLogEntry(
i18np(
"1 duplicate message not imported",
"%1 duplicate messages not imported", countDuplicates()));
148 if (filterInfo()->shouldTerminate()) {
149 filterInfo()->addInfoLogEntry(
i18n(
"Finished import, canceled by user."));
151 clearCountDuplicate();
152 filterInfo()->setCurrent(100);
153 filterInfo()->setOverall(100);
161void FilterSylpheed::importDirContents(
const QString &dirName)
163 if (filterInfo()->shouldTerminate()) {
168 importFiles(dirName);
171 processDirectory(dirName);
174bool FilterSylpheed::excludeFile(
const QString &file)
176 if (file.
endsWith(QLatin1StringView(
".sylpheed_cache")) || file.
endsWith(QLatin1StringView(
".sylpheed_mark"))
177 || file.
endsWith(QLatin1StringView(
".mh_sequences"))) {
183QString FilterSylpheed::defaultInstallFolder()
const
185 return i18nc(
"define folder name where we will import sylpheed mails",
"Sylpheed-Import") + QLatin1Char(
'/');
188QString FilterSylpheed::markFile()
const
190 return QStringLiteral(
".sylpheed_mark");
198void FilterSylpheed::importFiles(
const QString &dirName)
202 bool generatedPath =
false;
204 QHash<QString, unsigned long> msgflags;
206 QDir importDir(dirName);
207 const QString defaultInstallPath = defaultInstallFolder();
209 const QStringList files = importDir.entryList(QStringList(QStringLiteral(
"[^\\.]*")),
QDir::Files,
QDir::Name);
211 int numFiles = files.
size();
213 readMarkFile(
dir.filePath(markFile()), msgflags);
217 if (filterInfo()->shouldTerminate()) {
220 QString _mfile = *mailFile;
221 if (!excludeFile(_mfile)) {
222 if (!generatedPath) {
223 _path = defaultInstallPath;
224 QString _tmp =
dir.filePath(*mailFile);
227 QString _info = _path;
228 filterInfo()->addInfoLogEntry(
i18n(
"Import folder %1...", _info.
remove(0, 15)));
230 filterInfo()->setFrom(_info);
231 filterInfo()->setTo(_path);
232 generatedPath =
true;
235 MailImporter::MessageStatus
status;
236 if (msgflags[_mfile]) {
237 status = msgFlagsToString((msgflags[_mfile]));
241 if (!importMessage(_path,
dir.filePath(*mailFile), filterInfo()->removeDupMessage(),
status)) {
242 filterInfo()->addErrorLogEntry(
i18n(
"Could not import %1", *mailFile));
244 filterInfo()->setCurrent((
int)((
float)currentFile / numFiles * 100));
249void FilterSylpheed::readMarkFile(
const QString &path, QHash<QString, unsigned long> &dict)
272 QDataStream stream(&file);
274 if (Q_BYTE_ORDER == Q_LITTLE_ENDIAN) {
282 if (in > (quint32)0xffff) {
286 while (!stream.atEnd()) {
287 if (filterInfo()->shouldTerminate()) {
299MailImporter::MessageStatus FilterSylpheed::msgFlagsToString(
unsigned long flags)
301 MailImporter::MessageStatus
status;
306 if ((flags & 3UL) == 0UL) {
316 status.setForwarded(
true);
~FilterSylpheed() override
Destructor.
virtual void importMails(const QString &maildir)
void import() override
Recursive import of Sylpheed maildir.
FilterSylpheed()
Default constructor.
Q_SCRIPTABLE CaptureState status()
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
KIOCORE_EXPORT QString dir(const QString &fileClass)
const QList< QKeySequence > & end()
QDomElement documentElement() const const
ParseResult setContent(QAnyStringView text, ParseOptions options)
QDomElement firstChildElement(const QString &tagName, const QString &namespaceURI) const const
bool isNull() const const
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
iterator insert(const Key &key, const T &value)
const_iterator constBegin() const const
const_iterator constEnd() const const
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)
QString & setNum(double n, char format, int precision)