Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Unmaintained
KDE Pim
Commits
21b9ae14
Commit
21b9ae14
authored
Sep 16, 2013
by
Laurent Montel
😁
Browse files
Fix Bug 275008 - kmail should support importing gzip'd mail archives
FIXED-IN: 4.12 BUG: 275008
parent
b440b178
Changes
1
Hide whitespace changes
Inline
Side-by-side
mailimporter/filter_mailmangzip.cpp
View file @
21b9ae14
...
...
@@ -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
;
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment