MailImporter

filtermailapp.cpp
1/*
2 filtermailapp.cpp - OS X Mail App import
3
4 SPDX-FileCopyrightText: 2004 Chris Howells <howells@kde.org>
5 Derived from code by:
6 SPDX-FileCopyrightText: 2003 Laurence Anderson <l.d.anderson@warwick.ac.uk>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10
11#include "filtermailapp.h"
12#include "mailimporter_debug.h"
13
14#include <KLocalizedString>
15
16#include <QFileDialog>
17#include <QTemporaryFile>
18
19using namespace MailImporter;
20
21class MailImporter::FilterMailAppPrivate
22{
23public:
24 QStringList mMboxFiles;
25};
26
27FilterMailApp::FilterMailApp()
28 : Filter(i18n("Import From OS X Mail"),
29 i18n("Chris Howells<br /><br />Filter accelerated by Danny Kukawka )"),
30 i18n("<p><b>OS X Mail Import Filter</b></p>"
31 "<p>This filter imports e-mails from the Mail client in Apple Mac OS X.</p>"))
32 , d(new MailImporter::FilterMailAppPrivate)
33{
34}
35
36FilterMailApp::~FilterMailApp() = default;
37
38void FilterMailApp::import()
39{
40 const QString directory = QFileDialog::getExistingDirectory(filterInfo()->parentWidget(), QString(), QDir::homePath());
41 importMails(directory);
42}
43
44void FilterMailApp::importMails(const QString &maildir)
45{
46 if (maildir.isEmpty()) {
47 filterInfo()->alert(i18n("No files selected."));
48 return;
49 }
50 setMailDir(maildir);
51 int currentFile = 1;
52 int overall_status = 0;
53 bool first_msg = true;
54
55 filterInfo()->setOverall(0);
56
57 // qCDebug(MAILIMPORTER_LOG) <<"starting by looking in directory" << directory;
58 traverseDirectory(mailDir());
59
60 QStringList::ConstIterator end(d->mMboxFiles.constEnd());
61 for (QStringList::ConstIterator filename = d->mMboxFiles.constBegin(); filename != end; ++filename, ++currentFile) {
62 if (filterInfo()->shouldTerminate()) {
63 break;
64 }
65 QFile mbox(*filename);
66 if (!mbox.open(QIODevice::ReadOnly)) {
67 filterInfo()->alert(i18n("Unable to open %1, skipping", *filename));
68 } else {
69 QFileInfo filenameInfo(*filename);
70 qCDebug(MAILIMPORTER_LOG) << "importing filename" << *filename;
71 QStringList name = (*filename).split(QLatin1Char('/'), Qt::SkipEmptyParts);
72 QString folderName(name[name.count() - 2]);
73
74 filterInfo()->setCurrent(0);
75 filterInfo()->addInfoLogEntry(i18n("Importing emails from %1...", *filename));
76 filterInfo()->setFrom(*filename);
77 filterInfo()->setTo(folderName);
78
79 QByteArray input(MAX_LINE, '\0');
80 long l = 0;
81
82 while (!mbox.atEnd()) {
84 tmp.open();
85 /* comment by Danny:
86 * Don't use QTextStream to read from mbox, better use QDataStream. QTextStream only
87 * support Unicode/Latin1/Locale. So you lost information from emails with
88 * charset!=Unicode/Latin1/Locale (e.g. KOI8-R) and Content-Transfer-Encoding != base64
89 * (e.g. 8Bit). It also not help to convert the QTextStream to Unicode. By this you
90 * get Unicode/UTF-email but KMail can't detect the correct charset.
91 */
92 QByteArray separate;
93
94 if (!first_msg) {
95 tmp.write(input.constData(), l);
96 }
97 l = mbox.readLine(input.data(), MAX_LINE); // read the first line, prevent "From "
98 tmp.write(input.constData(), l);
99
100 while (!mbox.atEnd() && (l = mbox.readLine(input.data(), MAX_LINE)) && ((separate = input.data()).left(5) != "From ")) {
101 tmp.write(input.constData(), l);
102 }
103 tmp.flush();
104 first_msg = false;
105
106 if (!importMessage(folderName, tmp.fileName(), filterInfo()->removeDupMessage())) {
107 filterInfo()->addErrorLogEntry(i18n("Could not import %1", tmp.fileName()));
108 }
109
110 int currentPercentage = (int)(((float)mbox.pos() / filenameInfo.size()) * 100);
111 filterInfo()->setCurrent(currentPercentage);
112 if (currentFile == 1) {
113 overall_status = (int)(currentPercentage * ((float)currentFile / d->mMboxFiles.count()));
114 } else {
115 overall_status =
116 (int)(((currentFile - 1) * (100.0 / (float)d->mMboxFiles.count())) + (currentPercentage * (1.0 / (float)d->mMboxFiles.count())));
117 }
118 filterInfo()->setOverall(overall_status);
119 if (filterInfo()->shouldTerminate()) {
120 break;
121 }
122 }
123
124 filterInfo()->addInfoLogEntry(i18n("Finished importing emails from %1", *filename));
125 if (countDuplicates() > 0) {
126 filterInfo()->addInfoLogEntry(i18np("1 duplicate message not imported to folder %2 in KMail",
127 "%1 duplicate messages not imported to folder %2 in KMail",
128 countDuplicates(),
129 folderName));
130 }
131 clearCountDuplicate();
132 mbox.close();
133 }
134 }
135 if (filterInfo()->shouldTerminate()) {
136 filterInfo()->addInfoLogEntry(i18n("Finished import, canceled by user."));
137 }
138}
139
140void FilterMailApp::traverseDirectory(const QString &dirName)
141{
142 QDir dir(dirName);
143 dir.setFilter(QDir::Dirs | QDir::Files);
144
145 const QFileInfoList fileinfolist = dir.entryInfoList();
146 for (const QFileInfo &fi : fileinfolist) {
147 const QString filename(fi.fileName());
148 if (filename == QLatin1Char('.') || filename == QLatin1StringView("..")) {
149 continue;
150 }
151 if (fi.isDir() && fi.isReadable()) {
152 traverseDirectory(fi.filePath());
153 } else {
154 if (!fi.isDir() && (filename == QLatin1StringView("mbox"))) {
155 qCDebug(MAILIMPORTER_LOG) << "adding the file" << fi.filePath();
156 d->mMboxFiles.append(fi.filePath());
157 }
158 }
159 }
160}
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 name(StandardShortcut id)
QString homePath()
bool flush()
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
qint64 write(const QByteArray &data)
typedef ConstIterator
qsizetype count() const const
bool isEmpty() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
SkipEmptyParts
virtual QString fileName() const const override
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.