author | alwin <alwin> | 2003-12-12 09:12:48 (UTC) |
---|---|---|
committer | alwin <alwin> | 2003-12-12 09:12:48 (UTC) |
commit | 77299749e119436aab7af82e065357fca0cead96 (patch) (side-by-side diff) | |
tree | 0f51b6faa069d88e0cb0c297b761eef0e5c50f3d /noncore | |
parent | f6ff7965fe62f42fcb0fb1cdb93585e0c6ed80fe (diff) | |
download | opie-77299749e119436aab7af82e065357fca0cead96.zip opie-77299749e119436aab7af82e065357fca0cead96.tar.gz opie-77299749e119436aab7af82e065357fca0cead96.tar.bz2 |
retrieving a body structure of a multipart mail mostly finished
the first occurence of a part of type "text/xxx" will be interpreted
as body text.
ToDo: fetch the parameters for a mime-part like encoding and so on.
-rw-r--r-- | noncore/net/mail/imapwrapper.cpp | 113 | ||||
-rw-r--r-- | noncore/net/mail/imapwrapper.h | 3 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.cpp | 113 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.h | 3 |
4 files changed, 196 insertions, 36 deletions
diff --git a/noncore/net/mail/imapwrapper.cpp b/noncore/net/mail/imapwrapper.cpp index 27f1410..fa967da 100644 --- a/noncore/net/mail/imapwrapper.cpp +++ b/noncore/net/mail/imapwrapper.cpp @@ -335,49 +335,49 @@ RecBody IMAPwrapper::fetchBody(const RecMail&mail) err = mailimap_examine( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox: %s",m_imap->imap_response); return body; } result = clist_new(); /* the range has to start at 1!!! not with 0!!!! */ set = mailimap_set_new_interval( mail.getNumber(),mail.getNumber() ); fetchAtt = mailimap_fetch_att_new_bodystructure(); fetchType = mailimap_fetch_type_new_fetch_att(fetchAtt); err = mailimap_fetch( m_imap, set, fetchType, &result ); mailimap_set_free( set ); mailimap_fetch_type_free( fetchType ); if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) { mailimap_msg_att * msg_att; msg_att = (mailimap_msg_att*)current->data; mailimap_msg_att_item*item = (mailimap_msg_att_item*)msg_att->att_list->first->data; body_desc = item->att_data.att_static->att_data.att_body; if (body_desc->bd_type==MAILIMAP_BODY_1PART) { searchBodyText(mail,body_desc->bd_data.bd_body_1part,body); } else if (body_desc->bd_type==MAILIMAP_BODY_MPART) { qDebug("Mulitpart mail"); - searchBodyText(mail,body_desc->bd_data.bd_body_mpart,body,0); + searchBodyText(mail,body_desc->bd_data.bd_body_mpart,body); } } else { qDebug("error fetching body: %s",m_imap->imap_response); } mailimap_fetch_list_free(result); return body; } /* this routine is just called when the mail has only ONE part. for filling the parts of a multi-part-message there are other routines 'cause we can not simply fetch the whole body. */ void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body) { if (!mailDescription) { return; } QString sub; switch (mailDescription->bd_type) { case MAILIMAP_BODY_TYPE_1PART_MSG: target_body.setType("text"); sub = mailDescription->bd_data.bd_type_text->bd_media_text; target_body.setSubtype(sub.lower()); fillPlainBody(mail,target_body); break; @@ -469,70 +469,157 @@ QStringList IMAPwrapper::address_list_to_stringlist(clist*list) from+=" "; named_from = true; } if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) { from+="<"; } if (current_address->ad_mailbox_name) { from+=QString(current_address->ad_mailbox_name); from+="@"; } if (current_address->ad_host_name) { from+=QString(current_address->ad_host_name); } if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) { from+=">"; } l.append(QString(from)); if (++count > 99) { break; } } return l; } -void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion) +QString IMAPwrapper::fetchPart(const RecMail&mail,QValueList<int>&path,bool internal_call) +{ + QString body(""); + const char*mb; + int err; + mailimap_fetch_type *fetchType; + mailimap_set *set; + clistcell*current,*cur; + + login(); + if (!m_imap) { + return body; + } + if (!internal_call) { + mb = mail.getMbox().latin1(); + /* select mailbox READONLY for operations */ + err = mailimap_examine( m_imap, (char*)mb); + if ( err != MAILIMAP_NO_ERROR ) { + qDebug("error selecting mailbox: %s",m_imap->imap_response); + return body; + } + } + set = mailimap_set_new_single(mail.getNumber()); + clist*id_list=clist_new(); + for (unsigned j=0; j < path.count();++j) { + uint32_t * p_id = (uint32_t *)malloc(sizeof(*p_id)); + *p_id = path[j]; + clist_append(id_list,p_id); + } + mailimap_section_part * section_part = mailimap_section_part_new(id_list); + mailimap_section_spec * section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL); + mailimap_section * section = mailimap_section_new(section_spec); + mailimap_fetch_att * fetch_att = mailimap_fetch_att_new_body_section(section); + + fetchType = mailimap_fetch_type_new_fetch_att(fetch_att); + + clist*result = clist_new(); + + err = mailimap_fetch( m_imap, set, fetchType, &result ); + mailimap_set_free( set ); + mailimap_fetch_type_free( fetchType ); + + if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) { + mailimap_msg_att * msg_att; + msg_att = (mailimap_msg_att*)current->data; + mailimap_msg_att_item*msg_att_item; + for(cur = clist_begin(msg_att->att_list) ; cur != NULL ; cur = clist_next(cur)) { + msg_att_item = (mailimap_msg_att_item*)clist_content(cur); + if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) { + if (msg_att_item->att_data.att_static->att_type == MAILIMAP_MSG_ATT_BODY_SECTION) { + char*text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part; + msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; + if (text) { + body = QString(text); + free(text); + } else { + body = ""; + } + } + } + } + + } else { + qDebug("error fetching text: %s",m_imap->imap_response); + } + mailimap_fetch_list_free(result); + return body; +} + +void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion,QValueList<int>recList) { /* current_recursion is for avoiding ugly mails which has a to deep body-structure */ - if (!mailDescription||current_recursion==2) { + if (!mailDescription||current_recursion==10) { return; } - qDebug("Mediatype: %s",mailDescription->bd_media_subtype); clistcell*current; mailimap_body*current_body; + unsigned int count = 0; for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) { + /* the point in the message */ + ++count; current_body = (mailimap_body*)current->data; if (current_body->bd_type==MAILIMAP_BODY_MPART) { - searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1); + QValueList<int>clist = recList; + clist.append(count); + searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1,clist); } else if (current_body->bd_type==MAILIMAP_BODY_1PART){ RecPart currentPart; fillSinglePart(currentPart,current_body->bd_data.bd_body_1part); - target_body.addPart(currentPart); + QValueList<int>clist = recList; + clist.append(count); + /* important: Check for is NULL 'cause a body can be empty! */ + if (currentPart.Type()=="text" && target_body.Bodytext().isNull() ) { + QString body_text = fetchPart(mail,clist,true); + target_body.setBodytext(body_text); + target_body.setType(currentPart.Type()); + target_body.setSubtype(currentPart.Subtype()); + } else { + QString id(""); + for (unsigned int j = 0; j < clist.count();++j) { + id+=(j>0?".":""); + id+=QString("%1").arg(clist[j]); + } + qDebug("ID= %s",id.latin1()); + currentPart.setIdentifier(id); + target_body.addPart(currentPart); + } } } - if (current_recursion==0) { - - } } void IMAPwrapper::fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description) { if (!Description) { return; } switch (Description->bd_type) { case MAILIMAP_BODY_TYPE_1PART_TEXT: target_part.setType("text"); fillSingleTextPart(target_part,Description->bd_data.bd_type_text); break; case MAILIMAP_BODY_TYPE_1PART_BASIC: fillSingleBasicPart(target_part,Description->bd_data.bd_type_basic); break; default: break; } } void IMAPwrapper::fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which) { if (!which) { return; @@ -568,38 +655,30 @@ void IMAPwrapper::fillSingleBasicPart(RecPart&target_part,mailimap_body_type_bas break; case MAILIMAP_MEDIA_BASIC_OTHER: default: if (which->bd_media_basic->med_basic_type) { type = which->bd_media_basic->med_basic_type; } else { type = ""; } break; } if (which->bd_media_basic->med_subtype) { sub = which->bd_media_basic->med_subtype; } else { sub = ""; } qDebug("Type = %s/%s",type.latin1(),sub.latin1()); target_part.setType(type.lower()); target_part.setSubtype(sub.lower()); fillBodyFields(target_part,which->bd_fields); } void IMAPwrapper::fillBodyFields(RecPart&target_part,mailimap_body_fields*which) { if (!which) return; - if (which->bd_id) { - qDebug("Part ID = %s",which->bd_id); - target_part.setIdentifier(which->bd_id); - } else { - qDebug("ID empty"); - target_part.setIdentifier(""); - } - clistcell*cur; mailimap_single_body_fld_param*param; for (cur = clist_begin(which->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) { param = (mailimap_single_body_fld_param*)cur->data; } } diff --git a/noncore/net/mail/imapwrapper.h b/noncore/net/mail/imapwrapper.h index f809edb..5ea45f3 100644 --- a/noncore/net/mail/imapwrapper.h +++ b/noncore/net/mail/imapwrapper.h @@ -4,49 +4,50 @@ #include <qlist.h> #include "mailwrapper.h" struct mailimap; struct mailimap_body_type_1part; struct mailimap_body_type_text; struct mailimap_body_type_basic; struct mailimap_body_type_mpart; struct mailimap_body_fields; struct mailimap_msg_att; class RecMail; class RecBody; class RecPart; class IMAPwrapper : public QObject { Q_OBJECT public: IMAPwrapper( IMAPaccount *a ); virtual ~IMAPwrapper(); QList<IMAPFolder>* listFolders(); void listMessages(const QString & mailbox,QList<RecMail>&target ); RecBody fetchBody(const RecMail&mail); + QString fetchPart(const RecMail&mail,QValueList<int>&path,bool internal_call=false); static void imap_progress( size_t current, size_t maximum ); protected: RecMail*parse_list_result(mailimap_msg_att*); void login(); void logout(); void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body); - void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion); + void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>()); void fillPlainBody(const RecMail&mail,RecBody&target_body); void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); /* just helpers */ static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); static QStringList address_list_to_stringlist(clist*list); private: IMAPaccount *account; mailimap *m_imap; }; #endif diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp index 27f1410..fa967da 100644 --- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp +++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp @@ -335,49 +335,49 @@ RecBody IMAPwrapper::fetchBody(const RecMail&mail) err = mailimap_examine( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox: %s",m_imap->imap_response); return body; } result = clist_new(); /* the range has to start at 1!!! not with 0!!!! */ set = mailimap_set_new_interval( mail.getNumber(),mail.getNumber() ); fetchAtt = mailimap_fetch_att_new_bodystructure(); fetchType = mailimap_fetch_type_new_fetch_att(fetchAtt); err = mailimap_fetch( m_imap, set, fetchType, &result ); mailimap_set_free( set ); mailimap_fetch_type_free( fetchType ); if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) { mailimap_msg_att * msg_att; msg_att = (mailimap_msg_att*)current->data; mailimap_msg_att_item*item = (mailimap_msg_att_item*)msg_att->att_list->first->data; body_desc = item->att_data.att_static->att_data.att_body; if (body_desc->bd_type==MAILIMAP_BODY_1PART) { searchBodyText(mail,body_desc->bd_data.bd_body_1part,body); } else if (body_desc->bd_type==MAILIMAP_BODY_MPART) { qDebug("Mulitpart mail"); - searchBodyText(mail,body_desc->bd_data.bd_body_mpart,body,0); + searchBodyText(mail,body_desc->bd_data.bd_body_mpart,body); } } else { qDebug("error fetching body: %s",m_imap->imap_response); } mailimap_fetch_list_free(result); return body; } /* this routine is just called when the mail has only ONE part. for filling the parts of a multi-part-message there are other routines 'cause we can not simply fetch the whole body. */ void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body) { if (!mailDescription) { return; } QString sub; switch (mailDescription->bd_type) { case MAILIMAP_BODY_TYPE_1PART_MSG: target_body.setType("text"); sub = mailDescription->bd_data.bd_type_text->bd_media_text; target_body.setSubtype(sub.lower()); fillPlainBody(mail,target_body); break; @@ -469,70 +469,157 @@ QStringList IMAPwrapper::address_list_to_stringlist(clist*list) from+=" "; named_from = true; } if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) { from+="<"; } if (current_address->ad_mailbox_name) { from+=QString(current_address->ad_mailbox_name); from+="@"; } if (current_address->ad_host_name) { from+=QString(current_address->ad_host_name); } if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) { from+=">"; } l.append(QString(from)); if (++count > 99) { break; } } return l; } -void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion) +QString IMAPwrapper::fetchPart(const RecMail&mail,QValueList<int>&path,bool internal_call) +{ + QString body(""); + const char*mb; + int err; + mailimap_fetch_type *fetchType; + mailimap_set *set; + clistcell*current,*cur; + + login(); + if (!m_imap) { + return body; + } + if (!internal_call) { + mb = mail.getMbox().latin1(); + /* select mailbox READONLY for operations */ + err = mailimap_examine( m_imap, (char*)mb); + if ( err != MAILIMAP_NO_ERROR ) { + qDebug("error selecting mailbox: %s",m_imap->imap_response); + return body; + } + } + set = mailimap_set_new_single(mail.getNumber()); + clist*id_list=clist_new(); + for (unsigned j=0; j < path.count();++j) { + uint32_t * p_id = (uint32_t *)malloc(sizeof(*p_id)); + *p_id = path[j]; + clist_append(id_list,p_id); + } + mailimap_section_part * section_part = mailimap_section_part_new(id_list); + mailimap_section_spec * section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL); + mailimap_section * section = mailimap_section_new(section_spec); + mailimap_fetch_att * fetch_att = mailimap_fetch_att_new_body_section(section); + + fetchType = mailimap_fetch_type_new_fetch_att(fetch_att); + + clist*result = clist_new(); + + err = mailimap_fetch( m_imap, set, fetchType, &result ); + mailimap_set_free( set ); + mailimap_fetch_type_free( fetchType ); + + if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) { + mailimap_msg_att * msg_att; + msg_att = (mailimap_msg_att*)current->data; + mailimap_msg_att_item*msg_att_item; + for(cur = clist_begin(msg_att->att_list) ; cur != NULL ; cur = clist_next(cur)) { + msg_att_item = (mailimap_msg_att_item*)clist_content(cur); + if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) { + if (msg_att_item->att_data.att_static->att_type == MAILIMAP_MSG_ATT_BODY_SECTION) { + char*text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part; + msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; + if (text) { + body = QString(text); + free(text); + } else { + body = ""; + } + } + } + } + + } else { + qDebug("error fetching text: %s",m_imap->imap_response); + } + mailimap_fetch_list_free(result); + return body; +} + +void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion,QValueList<int>recList) { /* current_recursion is for avoiding ugly mails which has a to deep body-structure */ - if (!mailDescription||current_recursion==2) { + if (!mailDescription||current_recursion==10) { return; } - qDebug("Mediatype: %s",mailDescription->bd_media_subtype); clistcell*current; mailimap_body*current_body; + unsigned int count = 0; for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) { + /* the point in the message */ + ++count; current_body = (mailimap_body*)current->data; if (current_body->bd_type==MAILIMAP_BODY_MPART) { - searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1); + QValueList<int>clist = recList; + clist.append(count); + searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1,clist); } else if (current_body->bd_type==MAILIMAP_BODY_1PART){ RecPart currentPart; fillSinglePart(currentPart,current_body->bd_data.bd_body_1part); - target_body.addPart(currentPart); + QValueList<int>clist = recList; + clist.append(count); + /* important: Check for is NULL 'cause a body can be empty! */ + if (currentPart.Type()=="text" && target_body.Bodytext().isNull() ) { + QString body_text = fetchPart(mail,clist,true); + target_body.setBodytext(body_text); + target_body.setType(currentPart.Type()); + target_body.setSubtype(currentPart.Subtype()); + } else { + QString id(""); + for (unsigned int j = 0; j < clist.count();++j) { + id+=(j>0?".":""); + id+=QString("%1").arg(clist[j]); + } + qDebug("ID= %s",id.latin1()); + currentPart.setIdentifier(id); + target_body.addPart(currentPart); + } } } - if (current_recursion==0) { - - } } void IMAPwrapper::fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description) { if (!Description) { return; } switch (Description->bd_type) { case MAILIMAP_BODY_TYPE_1PART_TEXT: target_part.setType("text"); fillSingleTextPart(target_part,Description->bd_data.bd_type_text); break; case MAILIMAP_BODY_TYPE_1PART_BASIC: fillSingleBasicPart(target_part,Description->bd_data.bd_type_basic); break; default: break; } } void IMAPwrapper::fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which) { if (!which) { return; @@ -568,38 +655,30 @@ void IMAPwrapper::fillSingleBasicPart(RecPart&target_part,mailimap_body_type_bas break; case MAILIMAP_MEDIA_BASIC_OTHER: default: if (which->bd_media_basic->med_basic_type) { type = which->bd_media_basic->med_basic_type; } else { type = ""; } break; } if (which->bd_media_basic->med_subtype) { sub = which->bd_media_basic->med_subtype; } else { sub = ""; } qDebug("Type = %s/%s",type.latin1(),sub.latin1()); target_part.setType(type.lower()); target_part.setSubtype(sub.lower()); fillBodyFields(target_part,which->bd_fields); } void IMAPwrapper::fillBodyFields(RecPart&target_part,mailimap_body_fields*which) { if (!which) return; - if (which->bd_id) { - qDebug("Part ID = %s",which->bd_id); - target_part.setIdentifier(which->bd_id); - } else { - qDebug("ID empty"); - target_part.setIdentifier(""); - } - clistcell*cur; mailimap_single_body_fld_param*param; for (cur = clist_begin(which->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) { param = (mailimap_single_body_fld_param*)cur->data; } } diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h index f809edb..5ea45f3 100644 --- a/noncore/net/mail/libmailwrapper/imapwrapper.h +++ b/noncore/net/mail/libmailwrapper/imapwrapper.h @@ -4,49 +4,50 @@ #include <qlist.h> #include "mailwrapper.h" struct mailimap; struct mailimap_body_type_1part; struct mailimap_body_type_text; struct mailimap_body_type_basic; struct mailimap_body_type_mpart; struct mailimap_body_fields; struct mailimap_msg_att; class RecMail; class RecBody; class RecPart; class IMAPwrapper : public QObject { Q_OBJECT public: IMAPwrapper( IMAPaccount *a ); virtual ~IMAPwrapper(); QList<IMAPFolder>* listFolders(); void listMessages(const QString & mailbox,QList<RecMail>&target ); RecBody fetchBody(const RecMail&mail); + QString fetchPart(const RecMail&mail,QValueList<int>&path,bool internal_call=false); static void imap_progress( size_t current, size_t maximum ); protected: RecMail*parse_list_result(mailimap_msg_att*); void login(); void logout(); void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body); - void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion); + void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>()); void fillPlainBody(const RecMail&mail,RecBody&target_body); void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); /* just helpers */ static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); static QStringList address_list_to_stringlist(clist*list); private: IMAPaccount *account; mailimap *m_imap; }; #endif |