Commit 21b9ae14 authored by Laurent Montel's avatar Laurent Montel 😁
Browse files

Fix Bug 275008 - kmail should support importing gzip'd mail archives

FIXED-IN: 4.12
BUG: 275008
parent b440b178
......@@ -19,6 +19,7 @@
#include <kfiledialog.h>
#include <ktemporaryfile.h>
#include <kdebug.h>
#include <KFilterDev>
#include "filter_mailmangzip.h"
......@@ -56,97 +57,100 @@ void FilterMailmanGzip::importMails(const QStringList &filenames)
filterInfo()->setOverall(0);
QStringList::ConstIterator end( filenames.constEnd() );
for ( QStringList::ConstIterator filename = filenames.constBegin(); filename != end; ++filename, ++currentFile) {
QFile mbox( *filename );
if (! mbox.open( QIODevice::ReadOnly ) ) {
filterInfo()->alert( i18n("Unable to open %1, skipping", *filename ) );
} else {
QFileInfo filenameInfo( *filename );
QString folderName( "MBOX-" + filenameInfo.completeBaseName() );
filterInfo()->setCurrent(0);
filterInfo()->addInfoLogEntry( i18n("Importing emails from %1...", *filename ) );
filterInfo()->setFrom( *filename );
filterInfo()->setTo( folderName );
QByteArray input(MAX_LINE,'\0');
long l = 0;
while ( ! mbox.atEnd() ) {
KTemporaryFile tmp;
tmp.open();
qint64 filepos = 0;
/* comment by Danny:
QIODevice *device = KFilterDev::deviceForFile(*filename, QLatin1String( "application/x-gzip" ), false);
if (!device) {
kDebug() << "Could not create KFilterDev";
filterInfo()->alert( i18n( "Unable to open archive file '%1', skipping", *filename ) );
continue;
}
device->open(QIODevice::ReadOnly);
QFileInfo filenameInfo( *filename );
QString folderName( "MBOX-" + filenameInfo.completeBaseName() );
filterInfo()->setCurrent(0);
filterInfo()->addInfoLogEntry( i18n("Importing emails from %1...", *filename ) );
filterInfo()->setFrom( *filename );
filterInfo()->setTo( folderName );
QByteArray input(MAX_LINE,'\0');
long l = 0;
while ( ! device->atEnd() ) {
KTemporaryFile tmp;
tmp.open();
qint64 filepos = 0;
/* comment by Danny:
* Don't use QTextStream to read from mbox, better use QDataStream. QTextStream only
* support Unicode/Latin1/Locale. So you lost information from emails with
* charset!=Unicode/Latin1/Locale (e.g. KOI8-R) and Content-Transfer-Encoding != base64
* (e.g. 8Bit). It also not help to convert the QTextStream to Unicode. By this you
* get Unicode/UTF-email but KMail can't detect the correct charset.
*/
QByteArray separate;
QByteArray separate;
/* check if the first line start with "From " (and not "From: ") and discard the line
/* check if the first line start with "From " (and not "From: ") and discard the line
* in this case because some IMAP servers (e.g. Cyrus) don't accept this header line */
if(!first_msg &&((separate = input.data()).left(5) != "From " ))
tmp.write( input, l );
if(!first_msg &&((separate = input.data()).left(5) != "From " ))
tmp.write( input, l );
l = mbox.readLine( input.data(),MAX_LINE); // read the first line, prevent "From "
l = device->readLine( input.data(),MAX_LINE); // read the first line, prevent "From "
if ((separate = input.data()).left(5) != "From " )
tmp.write( input, l );
if ((separate = input.data()).left(5) != "From " )
tmp.write( input, l );
while ( ! mbox.atEnd() && (l = mbox.readLine(input.data(),MAX_LINE)) &&((separate = input.data()).left(5) != "From ")) {
tmp.write( input, l );
while ( ! device->atEnd() && (l = device->readLine(input.data(),MAX_LINE)) &&((separate = input.data()).left(5) != "From ")) {
tmp.write( input, l );
// workaround to fix hang if a corrupted mbox contains some
// binary data, for more see bug #106796
if (mbox.pos() == filepos)
mbox.seek(mbox.size());
else
filepos = mbox.pos();
}
tmp.flush();
first_msg = false;
// workaround to fix hang if a corrupted mbox contains some
// binary data, for more see bug #106796
if (device->pos() == filepos)
device->seek(device->size());
else
filepos = device->pos();
}
tmp.flush();
first_msg = false;
/* comment by Danny Kukawka:
/* comment by Danny Kukawka:
* addMessage() == old function, need more time and check for duplicates
* addMessage_fastImport == new function, faster and no check for duplicates
*/
if ( tmp.size() > 0 ) {
if(filterInfo()->removeDupMessage())
addMessage( folderName, tmp.fileName() );
else
addMessage_fastImport( folderName, tmp.fileName() );
}
else
kWarning() << "Message size is 0 bytes, not importing it.";
int currentPercentage = (int) ( ( (float) mbox.pos() / filenameInfo.size() ) * 100 );
filterInfo()->setCurrent( currentPercentage );
if (currentFile == 1)
overall_status = (int)( currentPercentage*((float)currentFile/filenames.count()));
if ( tmp.size() > 0 ) {
if(filterInfo()->removeDupMessage())
addMessage( folderName, tmp.fileName() );
else
overall_status = (int)(((currentFile-1)*(100.0/(float)filenames.count()))+(currentPercentage*(1.0/(float)filenames.count())));
filterInfo()->setOverall( overall_status );
if ( filterInfo()->shouldTerminate() ) break;
addMessage_fastImport( folderName, tmp.fileName() );
}
else
kWarning() << "Message size is 0 bytes, not importing it.";
int currentPercentage = (int) ( ( (float) device->pos() / filenameInfo.size() ) * 100 );
filterInfo()->setCurrent( currentPercentage );
if (currentFile == 1)
overall_status = (int)( currentPercentage*((float)currentFile/filenames.count()));
else
overall_status = (int)(((currentFile-1)*(100.0/(float)filenames.count()))+(currentPercentage*(1.0/(float)filenames.count())));
filterInfo()->setOverall( overall_status );
if ( filterInfo()->shouldTerminate() ) break;
}
filterInfo()->addInfoLogEntry( i18n("Finished importing emails from %1", *filename ));
if (countDuplicates() > 0) {
filterInfo()->addInfoLogEntry( i18np("1 duplicate message not imported to folder %2 in KMail",
"%1 duplicate messages not imported to folder %2 in KMail",
countDuplicates(), folderName));
}
if (filterInfo()->shouldTerminate())
filterInfo()->addInfoLogEntry( i18n("Finished import, canceled by user."));
setCountDuplicates(0);
// don't forget to close the file !!!
mbox.close();
filterInfo()->addInfoLogEntry( i18n("Finished importing emails from %1", *filename ));
if (countDuplicates() > 0) {
filterInfo()->addInfoLogEntry( i18np("1 duplicate message not imported to folder %2 in KMail",
"%1 duplicate messages not imported to folder %2 in KMail",
countDuplicates(), folderName));
}
if (filterInfo()->shouldTerminate())
filterInfo()->addInfoLogEntry( i18n("Finished import, canceled by user."));
setCountDuplicates(0);
// don't forget to close the file !!!
device->close();
delete device;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment