Skip to content

Commit 219ec72

Browse files
committed
05-27 18:56
1 parent 835ff73 commit 219ec72

14 files changed

+380
-169
lines changed

MicroMailClient.pro.user

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE QtCreatorProject>
3-
<!-- Written by QtCreator 3.6.1, 2016-05-26T14:23:41. -->
3+
<!-- Written by QtCreator 3.6.1, 2016-05-27T18:55:56. -->
44
<qtcreator>
55
<data>
66
<variable>EnvironmentId</variable>

Model/IMAPClient.h

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ class IMAPClient : public ReceiveMailClient
7070

7171
qDebug() << "In select Folder, folder = "<< folder << ", mailList.size = " << _mailList.size () << "uids.size = " << uids.size ()<< "\n";
7272

73+
for(int i=0; i<_mailList.size (); i++){
74+
for(int j=0; j<i; j++){
75+
if( _mailList.at (i).uid == _mailList.at(j).uid )
76+
qDebug() << QString::fromUtf8( _mailList.at (i).subject.c_str()) << " and " << QString::fromUtf8 (_mailList.at (j).subject.c_str()) << " has the same uid, subject = " << QString::fromUtf8 (_mailList.at (i).subject.c_str()) << "\n";
77+
}
78+
}
79+
7380
_curListIndex = 0;
7481

7582
return uids.size ();
@@ -78,27 +85,40 @@ class IMAPClient : public ReceiveMailClient
7885

7986
int getMailBodies(QList<MAILBODY_PTR> & result, int count ) override{
8087

81-
std::string msg;
88+
std::string partsPaths;
8289

8390
int counter = 0;
8491

85-
qDebug() << "listIndex = " <<_curListIndex << ", mailList.size=" << _mailList.size () << "\n";
86-
8792
for( ; _curListIndex < _mailList.size (); _curListIndex++, counter++) {
8893

8994
if( counter >= count )
9095
break;
9196

92-
auto info = _mailList.at (_curListIndex);
97+
auto info = _mailList.at ( _mailList.size () - _curListIndex - 1);
9398

94-
_session->loadMessage (_selectedFolder.toStdString (), info, msg);
99+
// if ( info.uid != "1577" )
100+
// continue;
101+
102+
_session->loadMessage (_selectedFolder.toStdString (), info);
95103

96104
MAILBODY_PTR newmail = MAILBODY_PTR::create(QString::fromUtf8 (info.subject.c_str ()));
97105

98-
newmail->setContent (QString::fromUtf8 (msg.c_str ()));
99-
newmail->setSender (QString::fromUtf8 (info.from.c_str()));
106+
newmail->setContent (QString::fromUtf8 (info.text.c_str ()));
107+
108+
newmail->setHTMLContent (QString::fromUtf8 (info.htmlText.c_str ()));
109+
110+
// qDebug() << QString::fromUtf8 ( info.uid.c_str() ) << " content: " << newmail->getHTMLContent ()<< "\n";
111+
112+
std::string sender = info.from.find_last_of('<') != std::string::npos ?
113+
info.from.substr(info.from.find_last_of('<')+1, info.from.find_last_of('>') - info.from.find_last_of('<')-1) :
114+
info.from ;
115+
116+
newmail->setSender (QString::fromUtf8 (sender.c_str()));
117+
100118
newmail->addRecipient (QString::fromUtf8 (info.to.c_str()));
119+
101120
newmail->setDateTime (QString::fromUtf8 (info.date.c_str()));
121+
102122
newmail->setIsread (false);
103123

104124
result.push_back (newmail);
@@ -130,6 +150,8 @@ class IMAPClient : public ReceiveMailClient
130150

131151
Poco::Net::IMAPClientSession::MessageInfoVec _mailList;
132152

153+
// QMap<QString, Poco::Net::IMAPClientSession::MessageInfoVec> _mailList;
154+
133155
SESSION_PTR _session;
134156

135157
};

Model/IMAPClientSession.cpp

Lines changed: 115 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@
1010
#include "Poco/TextConverter.h"
1111
#include "Poco/Net/MessageHeader.h"
1212

13+
#include <Windows.h>
14+
1315
#include <iostream>
16+
#include <codecvt>
1417
#include <sstream>
1518
#include <algorithm>
1619
#include <iterator>
1720
#include <string>
1821
#include <vector>
22+
#include <fstream>
1923

2024
using Poco::NumberFormatter;
2125
using Poco::DateTimeFormatter;
@@ -32,6 +36,43 @@ namespace Poco {
3236

3337
//POCO_IMPLEMENT_EXCEPTION(IMAPException, NetException, "IMAP Exception")
3438

39+
// GB2312转UTF8
40+
std::string GB2312ToUTF8(const char* lpszGb32Text)
41+
{
42+
int nUnicodeBufLen = MultiByteToWideChar(CP_ACP, 0, lpszGb32Text, -1, 0, 0);
43+
if (nUnicodeBufLen == 0)
44+
return "";
45+
46+
WCHAR* pUnicodeBuf = new WCHAR[nUnicodeBufLen];
47+
if (pUnicodeBuf == 0)
48+
return "";
49+
50+
MultiByteToWideChar(CP_ACP, 0, lpszGb32Text, -1, pUnicodeBuf, nUnicodeBufLen);
51+
52+
int nUtf8BufLen = WideCharToMultiByte(CP_UTF8, 0, pUnicodeBuf, -1, 0, 0, NULL, NULL);
53+
if (nUtf8BufLen == 0)
54+
{
55+
delete[] pUnicodeBuf;
56+
return "";
57+
}
58+
59+
char* pUft8Buf = new char[nUtf8BufLen];
60+
if (pUft8Buf == 0)
61+
{
62+
delete[] pUnicodeBuf;
63+
return "";
64+
}
65+
66+
WideCharToMultiByte(CP_UTF8, 0, pUnicodeBuf, -1, pUft8Buf, nUtf8BufLen, NULL, NULL);
67+
68+
std::string strUtf8 = pUft8Buf;
69+
70+
delete[] pUnicodeBuf;
71+
delete[] pUft8Buf;
72+
73+
return strUtf8;
74+
}
75+
3576
template <class S=std::string>
3677
S trimchar(const S& str, const char ch)
3778
{
@@ -317,35 +358,41 @@ namespace Poco {
317358
if (!sendCommand("DELETE \"" + folder + "\" *", response, data)) throw NetException("Can't delete folder", response);
318359
}
319360

320-
void IMAPClientSession::loadMessage (const std::string & folder, const MessageInfo & info, std::string & message) {
361+
void IMAPClientSession::loadMessage (const std::string & folder, MessageInfo & info) {
321362
std::string response, tmpdata;
322363
std::vector<std::string> data, data1;
323-
message.clear ( );
324364

325365
if ( !sendCommand ("SELECT \"" + folder + "\"", response, data) ) throw NetException ("Can't select from folder", response);
326366

327-
loadText (info.uid, info.parts, "", message);
367+
loadText (info.uid, info.parts, "", "HTML" , info.htmlText);
368+
loadText (info.uid, info.parts, "", "PLAIN" , info.text);
328369

329370
// sendCommand ("CLOSE", response, data1);
330371

331-
if ( data.size ( ) <= 2 ) return;
372+
// if ( data.size ( ) <= 2 ) return;
373+
374+
// for ( int i = 1; i < data.size ( ) - 2; i++ ) {
375+
// if( data[i].length() > 0 && data[i][0] != '*' ){
376+
// message += data[i];
377+
// message += "\r\n";
378+
// }
379+
// }
332380

333-
for ( int i = 1; i < data.size ( ) - 2; i++ ) {
334-
if( data[i].length() > 0 && data[i][0] != '*' ){
335-
message += data[i];
336-
message += "\r\n";
337-
}
338-
}
339381
}
340382

341-
void IMAPClientSession::loadText (const std::string & uid, const PartInfo & info, const std::string & index, std::string & text) {
383+
void IMAPClientSession::loadText (const std::string & uid, const PartInfo & info, const std::string & index, const std::string & _type, std::string & text) {
384+
342385
auto & attrs = info.attributes;
343386

387+
std::string type = _type;
388+
389+
std::transform(type.begin (), type.end (), type.begin (), ::toupper );
390+
344391
std::string response;
345392
std::vector<std::string> result;
346393
std::stringstream ss;
347394

348-
if ( std::find (attrs.begin ( ), attrs.end ( ), "TEXT") != info.attributes.end ( ) ) { // 如果是正文类型
395+
if ( std::find (attrs.begin ( ), attrs.end ( ), type) != info.attributes.end ( ) ) { // 如果是正文类型
349396

350397
if ( !sendCommand ("UID FETCH " + uid + " BODY.PEEK[" + ( index.length() == 0 ? "1" : index ) + "]", response, result) )
351398
throw NetException ("Cannot Load Mail Text", response);
@@ -371,29 +418,54 @@ namespace Poco {
371418
}
372419

373420
} else {
374-
std::cout << "UNKNONW CONTENT TRANSFER TYPE: " ;
421+
std::cout << "Unknown Content Transfer Type: " ;
375422
for(auto s : attrs){
376423
std::cout << s << ";";
377424
}
378-
std::cout << std::endl;
425+
// std::cout << "Content: " << ss.str ()<< std::endl;
379426
text += ss.str ( );
380427
//throw NetException ("UNKNOWN CONTENT TRANSFER TYPE");
381428
}
382429

383-
} else if( std::find (attrs.begin ( ), attrs.end ( ), "APPLICATION") != attrs.end()) { // 附件类型, 只记录index和文件名(需要用decoder解码), 不需要读内容
384-
385430
}
386431

387432
for ( int i = 0; i < info.childs.size ( ); i++ ) {
388-
loadText (uid, info.childs.at(i), index + "." + std::to_string(i+1), text);
433+
std::string nextindex = index.length () == 0 ? std::to_string(i+1) : index + "." + std::to_string(i+1);
434+
loadText (uid, info.childs.at(i), nextindex, type, text);
389435
}
390436

391-
text += "\n";
437+
// text += "\n";
392438

393439
return;
394440

395441
}
396442

443+
void IMAPClientSession::loadParts (const std::string & uid, const PartInfo & info, const std::string & index, const std::string & _type, std::vector<std::string> & paths){
444+
445+
auto & attrs = info.attributes;
446+
447+
std::string type = _type;
448+
449+
std::transform(type.begin (), type.end (), type.begin (), ::toupper );
450+
451+
std::string response;
452+
std::vector<std::string> result;
453+
454+
if ( std::find (attrs.begin ( ), attrs.end ( ), type) != info.attributes.end ( ) ) {
455+
456+
paths.push_back (index);
457+
458+
}
459+
460+
for ( int i = 0; i < info.childs.size ( ); i++ ) {
461+
std::string nextindex = index.length () == 0 ? std::to_string(i+1) : index + "." + std::to_string(i+1);
462+
loadParts(uid, info.childs.at(i), nextindex, type, paths);
463+
}
464+
465+
466+
}
467+
468+
397469
void IMAPClientSession::getMessages(const std::string& folder, std::vector<std::string>& uids, MessageInfoVec& messages)
398470
{
399471
std::string response, response1;
@@ -481,7 +553,7 @@ namespace Poco {
481553
m.from = IMAPClientSession::decoder(trim (tokens4[1]));
482554
//m.from = MessageHeader::decodeWord(trim(tokens4[1]));
483555
else if ( cmd == "TO" )
484-
m.from = IMAPClientSession::decoder (trim (tokens4[1]));
556+
m.to = IMAPClientSession::decoder (trim (tokens4[1]));
485557
//m.to = MessageHeader::decodeWord(trim(tokens4[1]));
486558
}
487559
messages.push_back(m);
@@ -541,30 +613,41 @@ namespace Poco {
541613

542614
if ( encoding[0] == 'B' ) { // Base64编码
543615
Base64Decoder decode (iss);
544-
while ( !decode.eof ( ) && (c = decode.get()) ) {
616+
while ( ( c = decode.get ( ) ) != -1 ) {
545617
tmp += c;
546618
}
547619
} else if ( encoding[0] == 'Q' ) { // Quote-Printable编码
548620
QuotedPrintableDecoder qpd (iss);
549-
while ( !qpd.eof ( ) && ( c = qpd.get ( ) ) ) {
550-
text += c;
621+
while ( ( c = qpd.get ( ) ) != -1 ) {
622+
tmp += c;
551623
}
552624

553625
} else { // 编码未知, 直接返回原字符串
554626
outs = ins;
555627
return;
556628
}
557629

558-
// 转换字符集
630+
// 标题转换字符集
559631
if ( charset != charset_to ) {
560-
try {
561-
TextEncoding & enc = TextEncoding::byName (charset);
562-
TextEncoding & dec = TextEncoding::byName (charset_to);
563-
TextConverter converter (enc, dec);
564-
converter.convert (tmp, outs);
565-
} catch ( ... ) { // 无法转换的未知字符集(包括GB2312)
566-
std::cout << "Unknown charset " << charset << std::endl;
567-
outs = tmp;
632+
std::transform(charset.begin (), charset.end (), charset.begin (), ::toupper);
633+
if( charset == "GB2312" ){
634+
std::cout << "charset == gb2312" << std::endl;
635+
try{
636+
outs = GB2312ToUTF8 (tmp.c_str ());
637+
}catch( std::exception & e ){
638+
std::cout << e.what () << std::endl;
639+
}
640+
}else{
641+
try {
642+
TextEncoding & enc = TextEncoding::byName (charset);
643+
TextEncoding & dec = TextEncoding::byName (charset_to);
644+
TextConverter converter (enc, dec);
645+
converter.convert (tmp, outs);
646+
} catch ( ... ) { // 无法转换的未知字符集(包括GB2312)
647+
std::cout << "Unknown charset " << charset << std::endl;
648+
std::cout << "Content: " << tmp << std::endl;
649+
outs = tmp;
650+
}
568651
}
569652
} else { // 不需要转换字符集
570653
outs = tmp;
@@ -581,7 +664,7 @@ namespace Poco {
581664
break;
582665
}
583666
if ( start > 0 ) {
584-
outs = text.substr (0, start);
667+
outs += text.substr (0, start);
585668
}
586669

587670
text = text.substr (start+2); // 从=?之后开始查找其余信息

Model/IMAPClientSession.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ namespace Poco {
5757
std::string flags;
5858
PartInfo parts;
5959

60-
60+
std::string htmlText;
6161
std::string text;
6262

6363
bool seen;
@@ -94,8 +94,9 @@ namespace Poco {
9494
virtual void copyMessage (const std::string& uid, const std::string& from_folder, const std::string& to_folder);
9595
virtual void moveMessage (const std::string& uid, const std::string& from_folder, const std::string& to_folder);
9696
virtual void deleteMessage (const std::string& uid, const std::string& folder, bool expunge = true);
97-
virtual void loadMessage (const std::string & folder, const MessageInfo & info, std::string & message);
98-
virtual void loadText (const std::string & uid, const PartInfo & info, const std::string & index, std::string & text);
97+
virtual void loadMessage (const std::string & folder, MessageInfo & info);
98+
virtual void loadText (const std::string & uid, const PartInfo & info, const std::string & index, const std::string & type, std::string & text);
99+
virtual void loadParts (const std::string & uid, const PartInfo & info, const std::string & index, const std::string & type, std::vector<std::string> & paths);
99100

100101
virtual void createFolder (const std::string& folder);
101102
virtual void deleteFolder (const std::string& folder);

Model/MailBody.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ class MailBody : public QObject {
5252
return _content;
5353
}
5454

55+
QString getHTMLContent(){
56+
return _htmlContent;
57+
}
58+
59+
void setHTMLContent (QString c){
60+
_htmlContent = c;
61+
}
62+
5563
void setContent(QString c){
5664
_content = c;
5765
}
@@ -99,6 +107,8 @@ class MailBody : public QObject {
99107

100108
QString _content;
101109

110+
QString _htmlContent;
111+
102112
QString _sender;
103113

104114
QString _datetime;

Model/MailClient.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class MailClient{
2222

2323
virtual int getTimeout() = 0;
2424

25-
virtual void setTimeout(int) = 0;
25+
virtual void setTimeout(int) = 0;
2626

2727
// virtual ~MailClient() = 0;
2828

0 commit comments

Comments
 (0)