1
/***************************************************************************
2
filter_evolution_v2.cxx - Evolution 2.0.x mail import
5
copyright : (C) 2005 by Danny Kukawka <danny.kukawka@web.de>
6
(inspired and partly copied from filter_evolution)
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
18
#include "filter_evolution_v2.h"
21
#include <kfiledialog.h>
22
#include <ktemporaryfile.h>
24
using namespace MailImporter;
26
/** Default constructor. */
27
FilterEvolution_v2::FilterEvolution_v2() :
28
Filter(i18n("Import Evolution 2.x Local Mails and Folder Structure"),
30
i18n("<p><b>Evolution 2.x import filter</b></p>"
31
"<p>Select the base directory of your local Evolution mailfolder (usually ~/.evolution/mail/local/).</p>"
32
"<p><b>Note:</b> Never choose a Folder which <u>does not</u> contain mbox-files (for example "
33
"a maildir): if you do, you will get many new folders.</p>"
34
"<p>Since it is possible to recreate the folder structure, the folders "
35
"will be stored under: \"Evolution-Import\".</p>"))
40
FilterEvolution_v2::~FilterEvolution_v2()
45
QString FilterEvolution_v2::defaultPath()
47
return QDir::homePath() + QLatin1String( "/.evolution/mail/local" );
50
/** Recursive import of Evolution's mboxes. */
51
void FilterEvolution_v2::import()
53
setCountDuplicates(0);
55
* We ask the user to choose Evolution's root directory.
56
* This should be usually ~/.evolution/mail/local/
58
QString evolDir = defaultPath();
61
evolDir = QDir::homePath();
64
KFileDialog *kfd = new KFileDialog( evolDir, "", 0 );
65
kfd->setMode(KFile::Directory | KFile::LocalOnly);
67
const QString dir = kfd->selectedFile();
72
bool FilterEvolution_v2::excludeFiles(const QString& file)
74
if (( file.endsWith(QLatin1String(".db")) ||
75
file.endsWith(QLatin1String(".cmeta")) ||
76
file.endsWith(QLatin1String(".ev-summary")) ||
77
file.endsWith(QLatin1String(".ibex.index")) ||
78
file.endsWith(QLatin1String(".ibex.index.data")) )) {
84
void FilterEvolution_v2::importMails( const QString& maildir )
86
setMailDir( maildir );
87
if (mailDir().isEmpty()) {
88
filterInfo()->alert(i18n("No directory selected."));
92
* If the user only select homedir no import needed because
93
* there should be no files and we surely import wrong files.
95
else if ( mailDir() == QDir::homePath() || mailDir() == (QDir::homePath() + '/')) {
96
filterInfo()->addErrorLogEntry(i18n("No files found for import."));
98
filterInfo()->setOverall(0);
100
/** Recursive import of the MailArchives */
102
const QStringList rootSubDirs = dir.entryList(QStringList("[^\\.]*"), QDir::Dirs, QDir::Name); // Removal of . and ..
103
int currentDir = 1, numSubDirs = rootSubDirs.size();
104
QStringList::ConstIterator endFilename( rootSubDirs.constEnd() );
105
for(QStringList::ConstIterator filename = rootSubDirs.constBegin() ; filename != endFilename ; ++filename, ++currentDir) {
106
if (filterInfo()->shouldTerminate())
108
importDirContents(dir.filePath(*filename), *filename, *filename);
109
filterInfo()->setOverall((int) ((float) currentDir / numSubDirs * 100));
112
/** import last but not least all archives from the root-dir */
113
QDir importDir (mailDir());
114
const QStringList files = importDir.entryList(QStringList("[^\\.]*"), QDir::Files, QDir::Name);
115
endFilename = files.constEnd();
116
for ( QStringList::ConstIterator mailFile = files.constBegin(); mailFile != endFilename; ++mailFile) {
117
if (filterInfo()->shouldTerminate())
119
QString temp_mailfile = *mailFile;
120
if (!excludeFiles(temp_mailfile) )
122
filterInfo()->addInfoLogEntry( i18n("Start import file %1...", temp_mailfile ) );
123
importMBox(mailDir() + temp_mailfile , temp_mailfile, QString());
127
filterInfo()->addInfoLogEntry( i18n("Finished importing emails from %1", mailDir() ));
128
if(countDuplicates() > 0) {
129
filterInfo()->addInfoLogEntry( i18np("1 duplicate message not imported", "%1 duplicate messages not imported", countDuplicates()));
131
if (filterInfo()->shouldTerminate())
132
filterInfo()->addInfoLogEntry( i18n("Finished import, canceled by user."));
134
filterInfo()->setCurrent(100);
135
filterInfo()->setOverall(100);
139
* Import of a directory contents.
140
* @param info Information storage for the operation.
141
* @param dirName The name of the directory to import.
142
* @param KMailRootDir The directory's root directory in KMail's folder structure.
143
* @param KMailSubDir The directory's direct ancestor in KMail's folder structure.
145
void FilterEvolution_v2::importDirContents(const QString& dirName, const QString& KMailRootDir, const QString& KMailSubDir)
147
if (filterInfo()->shouldTerminate()) return;
149
/** Here Import all archives in the current dir */
152
QDir importDir (dirName);
153
const QStringList files = importDir.entryList(QStringList("[^\\.]*"), QDir::Files, QDir::Name);
154
QStringList::ConstIterator mailFileEnd( files.constEnd() );
155
for ( QStringList::ConstIterator mailFile = files.constBegin(); mailFile != mailFileEnd; ++mailFile) {
156
QString temp_mailfile = *mailFile;
157
if (!excludeFiles(temp_mailfile))
159
filterInfo()->addInfoLogEntry( i18n("Start import file %1...", temp_mailfile ) );
160
importMBox((dirName + '/' + temp_mailfile) , KMailRootDir, KMailSubDir);
164
/** If there are subfolders, we import them one by one */
165
QDir subfolders(dirName);
166
const QStringList subDirs = subfolders.entryList(QStringList("[^\\.]*"), QDir::Dirs, QDir::Name);
167
QStringList::ConstIterator end( subDirs.constEnd() );
168
for(QStringList::ConstIterator filename = subDirs.constBegin() ; filename != end; ++filename) {
170
if(!KMailSubDir.isNull()) {
171
kSubDir = KMailSubDir + '/' + *filename;
175
importDirContents( subfolders.filePath(*filename), KMailRootDir, kSubDir);
180
* Import of a MBox file.
181
* @param info Information storage for the operation.
182
* @param dirName The MBox's name.
183
* @param KMailRootDir The directory's root directory in KMail's folder structure.
184
* @param KMailSubDir The directory's equivalent in KMail's folder structure. *
186
void FilterEvolution_v2::importMBox(const QString& mboxName, const QString& rootDir, const QString& targetDir)
188
QFile mbox(mboxName);
189
bool first_msg = true;
190
if (!mbox.open(QIODevice::ReadOnly)) {
191
filterInfo()->alert(i18n("Unable to open %1, skipping", mboxName));
193
QFileInfo filenameInfo(mboxName);
195
filterInfo()->setCurrent(0);
196
if( mboxName.length() > 20 ) {
197
QString tmp_info = mboxName;
198
tmp_info = tmp_info.replace( mailDir(), "../" );
199
if (tmp_info.contains(".sbd"))
200
tmp_info.remove(".sbd");
201
filterInfo()->setFrom( tmp_info );
203
filterInfo()->setFrom(mboxName);
205
if(targetDir.contains(QLatin1String( ".sbd" ))) {
206
QString tmp_info = targetDir;
207
tmp_info.remove(QLatin1String( ".sbd" ));
208
filterInfo()->setTo(tmp_info);
210
filterInfo()->setTo(targetDir);
212
QByteArray input(MAX_LINE, '\0');
215
while (!mbox.atEnd()) {
218
/** @todo check if the file is really a mbox, maybe search for 'from' string at start */
220
* Don't use QTextStream to read from mbox, better use QDataStream. QTextStream only
221
* support Unicode/Latin1/Locale. So you lost information from emails with
222
* charset!=Unicode/Latin1/Locale (e.g. KOI8-R) and Content-Transfer-Encoding != base64
223
* (e.g. 8Bit). It also not help to convert the QTextStream to Unicode. By this you
224
* get Unicode/UTF-email but KMail can't detect the correct charset.
229
tmp.write( input, l );
230
l = mbox.readLine( input.data(),MAX_LINE); // read the first line, prevent "From "
231
tmp.write( input, l );
233
while ( ! mbox.atEnd() && (l = mbox.readLine(input.data(),MAX_LINE)) && ((separate = input.data()).left(5) != "From ")) {
234
tmp.write( input, l );
240
QString _targetDir = targetDir;
241
if(!targetDir.isNull()) {
242
if(_targetDir.contains(QLatin1String( ".sbd" )))
243
_targetDir.remove(QLatin1String( ".sbd" ));
244
destFolder += "Evolution-Import/" + _targetDir + '/' + filenameInfo.completeBaseName(); // mboxName;
246
destFolder = "Evolution-Import/" + rootDir;
247
if(destFolder.contains(QLatin1String( ".sbd" )))
248
destFolder.remove(QLatin1String( ".sbd" ));
252
if(filterInfo()->removeDupMessage())
253
addMessage( destFolder, tmp.fileName() );
255
addMessage_fastImport( destFolder, tmp.fileName() );
257
int currentPercentage = (int) (((float) mbox.pos() / filenameInfo.size()) * 100);
258
filterInfo()->setCurrent(currentPercentage);
259
if (filterInfo()->shouldTerminate())