1 /***************************************************************************
2 filter_mbox.cxx - mbox mail import
5 copyright : (C) 2003 by Laurence Anderson
6 email : l.d.anderson@warwick.ac.uk
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 ***************************************************************************/
19 #include <kfiledialog.h>
20 #include <ktemporaryfile.h>
23 #include "filter_mbox.h"
25 using namespace MailImporter
;
27 FilterMBox::FilterMBox() :
28 Filter( i18n("Import mbox Files (UNIX, Evolution)"),
29 "Laurence Anderson <p>( Filter accelerated by Danny Kukawka )</p>",
30 i18n("<p><b>mbox import filter</b></p>"
31 "<p>This filter will import mbox files into KMail. Use this filter "
32 "if you want to import mails from Ximian Evolution or other mailers "
33 "that use this traditional UNIX format.</p>"
34 "<p><b>Note:</b> Emails will be imported into folders named after the "
35 "file they came from, prefixed with MBOX-</p>" ))
39 FilterMBox::~FilterMBox()
43 void FilterMBox::import()
45 const QStringList filenames
= KFileDialog::getOpenFileNames( QDir::homePath(), "*|" + i18n("mbox Files (*)"), filterInfo()->parent() );
46 if ( filenames
.isEmpty() )
48 filterInfo()->alert(i18n("No files selected."));
51 importMails(filenames
);
54 void FilterMBox::importMails(const QStringList
&filenames
)
57 int overall_status
= 0;
58 bool first_msg
= true;
61 filterInfo()->setOverall(0);
63 QStringList::ConstIterator
end( filenames
.constEnd() );
64 for ( QStringList::ConstIterator filename
= filenames
.constBegin(); filename
!= end
; ++filename
, ++currentFile
) {
65 QFile
mbox( *filename
);
66 if (! mbox
.open( QIODevice::ReadOnly
) ) {
67 filterInfo()->alert( i18n("Unable to open %1, skipping", *filename
) );
69 QFileInfo
filenameInfo( *filename
);
70 QString
folderName( "MBOX-" + filenameInfo
.completeBaseName() );
72 filterInfo()->setCurrent(0);
73 filterInfo()->addInfoLogEntry( i18n("Importing emails from %1...", *filename
) );
75 filterInfo()->setFrom( *filename
);
76 filterInfo()->setTo( folderName
);
78 QByteArray
input(MAX_LINE
,'\0');
81 while ( ! mbox
.atEnd() ) {
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.
94 /* check if the first line start with "From " (and not "From: ") and discard the line
95 * in this case because some IMAP servers (e.g. Cyrus) don't accept this header line */
96 if(!first_msg
&&((separate
= input
.data()).left(5) != "From " ))
97 tmp
.write( input
, l
);
99 l
= mbox
.readLine( input
.data(),MAX_LINE
); // read the first line, prevent "From "
101 if ((separate
= input
.data()).left(5) != "From " )
102 tmp
.write( input
, l
);
104 while ( ! mbox
.atEnd() && (l
= mbox
.readLine(input
.data(),MAX_LINE
)) &&((separate
= input
.data()).left(5) != "From ")) {
105 tmp
.write( input
, l
);
107 // workaround to fix hang if a corrupted mbox contains some
108 // binary data, for more see bug #106796
109 if (mbox
.pos() == filepos
)
110 mbox
.seek(mbox
.size());
112 filepos
= mbox
.pos();
117 /* comment by Danny Kukawka:
118 * addMessage() == old function, need more time and check for duplicates
119 * addMessage_fastImport == new function, faster and no check for duplicates
121 if ( tmp
.size() > 0 ) {
122 if(filterInfo()->removeDupMessage())
123 addMessage( folderName
, tmp
.fileName() );
125 addMessage_fastImport( folderName
, tmp
.fileName() );
128 kWarning() << "Message size is 0 bytes, not importing it.";
130 int currentPercentage
= (int) ( ( (float) mbox
.pos() / filenameInfo
.size() ) * 100 );
131 filterInfo()->setCurrent( currentPercentage
);
132 if (currentFile
== 1)
133 overall_status
= (int)( currentPercentage
*((float)currentFile
/filenames
.count()));
135 overall_status
= (int)(((currentFile
-1)*(100.0/(float)filenames
.count()))+(currentPercentage
*(1.0/(float)filenames
.count())));
136 filterInfo()->setOverall( overall_status
);
138 if ( filterInfo()->shouldTerminate() ) break;
141 filterInfo()->addInfoLogEntry( i18n("Finished importing emails from %1", *filename
));
142 if (countDuplicates() > 0) {
143 filterInfo()->addInfoLogEntry( i18np("1 duplicate message not imported to folder %2 in KMail",
144 "%1 duplicate messages not imported to folder %2 in KMail",
145 countDuplicates(), folderName
));
147 if (filterInfo()->shouldTerminate())
148 filterInfo()->addInfoLogEntry( i18n("Finished import, canceled by user."));
150 setCountDuplicates(0);
151 // don't forget to close the file !!!