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.hxx"
26 FilterMBox::FilterMBox() :
27 Filter( i18n("Import mbox Files (UNIX, Evolution)"),
28 "Laurence Anderson <p>( Filter accelerated by Danny Kukawka )</p>",
29 i18n("<p><b>mbox import filter</b></p>"
30 "<p>This filter will import mbox files into KMail. Use this filter "
31 "if you want to import mails from Ximian Evolution or other mailers "
32 "that use this traditional UNIX format.</p>"
33 "<p><b>Note:</b> Emails will be imported into folders named after the "
34 "file they came from, prefixed with MBOX-</p>" ))
37 FilterMBox::~FilterMBox()
41 void FilterMBox::import(FilterInfo
*info
)
44 int overall_status
= 0;
45 bool first_msg
= true;
47 const QStringList filenames
= KFileDialog::getOpenFileNames( QDir::homePath(), "*|" + i18n("mbox Files (*)"), info
->parent() );
50 for ( QStringList::ConstIterator filename
= filenames
.constBegin(); filename
!= filenames
.constEnd(); ++filename
, ++currentFile
) {
51 QFile
mbox( *filename
);
52 if (! mbox
.open( QIODevice::ReadOnly
) ) {
53 info
->alert( i18n("Unable to open %1, skipping", *filename
) );
55 QFileInfo
filenameInfo( *filename
);
56 QString
folderName( "MBOX-" + filenameInfo
.completeBaseName() );
59 info
->addLog( i18n("Importing emails from %1...", *filename
) );
61 info
->setFrom( *filename
);
62 info
->setTo( folderName
);
64 QByteArray
input(MAX_LINE
,'\0');
67 while ( ! mbox
.atEnd() ) {
72 * Don't use QTextStream to read from mbox, better use QDataStream. QTextStream only
73 * support Unicode/Latin1/Locale. So you lost information from emails with
74 * charset!=Unicode/Latin1/Locale (e.g. KOI8-R) and Content-Transfer-Encoding != base64
75 * (e.g. 8Bit). It also not help to convert the QTextStream to Unicode. By this you
76 * get Unicode/UTF-email but KMail can't detect the correct charset.
79 QString x_status_flag
= "";
81 /* check if the first line start with "From " (and not "From: ") and discard the line
82 * in this case because some IMAP servers (e.g. Cyrus) don't accept this header line */
83 if(!first_msg
&& ((separate
= input
.data()).left(5) != "From "))
84 tmp
.write( input
, l
);
86 l
= mbox
.readLine( input
.data(),MAX_LINE
); // read the first line, prevent "From "
88 if ((separate
= input
.data()).left(5) != "From ")
89 tmp
.write( input
, l
);
91 while ( ! mbox
.atEnd() && (l
= mbox
.readLine(input
.data(),MAX_LINE
)) && ((separate
= input
.data()).left(5) != "From ")) {
92 tmp
.write( input
, l
);
94 if ((separate
= input
.data()).left(10) == "X-Status: ") {
95 x_status_flag
= separate
;
96 x_status_flag
.remove("X-Status: ");
97 x_status_flag
= x_status_flag
.trimmed();
98 // qDebug("x_status_flag: %s", x_status_flag.toLatin1() );
101 // workaround to fix hang if a corrupted mbox contains some
102 // binary data, for more see bug #106796
103 if (mbox
.pos() == filepos
)
104 mbox
.seek(mbox
.size());
106 filepos
= mbox
.pos();
111 /* comment by Danny Kukawka:
112 * addMessage() == old function, need more time and check for duplicates
113 * addMessage_fastImport == new function, faster and no check for duplicates
115 if ( tmp
.size() > 0 ) {
116 if(info
->removeDupMsg
)
117 addMessage( info
, folderName
, tmp
.fileName(), x_status_flag
);
119 addMessage_fastImport( info
, folderName
, tmp
.fileName(), x_status_flag
);
122 kWarning() << "Message size is 0 bytes, not importing it.";
124 int currentPercentage
= (int) ( ( (float) mbox
.pos() / filenameInfo
.size() ) * 100 );
125 info
->setCurrent( currentPercentage
);
126 if (currentFile
== 1)
127 overall_status
= (int)( currentPercentage
*((float)currentFile
/filenames
.count()));
129 overall_status
= (int)(((currentFile
-1)*(100.0/(float)filenames
.count()))+(currentPercentage
*(1.0/(float)filenames
.count())));
130 info
->setOverall( overall_status
);
132 if ( info
->shouldTerminate() ) break;
135 info
->addLog( i18n("Finished importing emails from %1", *filename
));
136 if (count_duplicates
> 0) {
137 info
->addLog( i18np("1 duplicate message not imported to folder %2 in KMail",
138 "%1 duplicate messages not imported to folder %2 in KMail",
139 count_duplicates
, folderName
));
141 if (info
->shouldTerminate()) info
->addLog( i18n("Finished import, canceled by user."));
142 count_duplicates
= 0;
143 // don't forget to close the file !!!