Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

genericwrapper.cpp

Go to the documentation of this file.
00001 #include "genericwrapper.h"
00002 #include <libetpan/libetpan.h>
00003 #include "mailtypes.h"
00004 #include "mailstatics.h"
00005 
00006 #include <opie2/odebug.h>
00007 #include <qdatetime.h>
00008 
00009 using namespace Opie::Core;
00010 Genericwrapper::Genericwrapper()
00011     : AbstractMail(),MailStatics()
00012 {
00013     bodyCache.clear();
00014     m_storage = 0;
00015     m_folder = 0;
00016 }
00017 
00018 Genericwrapper::~Genericwrapper()
00019 {
00020     if (m_folder) {
00021         mailfolder_free(m_folder);
00022     }
00023     if (m_storage) {
00024         mailstorage_free(m_storage);
00025     }
00026     cleanMimeCache();
00027 }
00028 
00029 void Genericwrapper::fillSingleBody(RecPartP&target,mailmessage*,mailmime*mime)
00030 {
00031     if (!mime) {
00032         return;
00033     }
00034     mailmime_field*field = 0;
00035     mailmime_single_fields fields;
00036     memset(&fields, 0, sizeof(struct mailmime_single_fields));
00037     if (mime->mm_mime_fields != NULL) {
00038         mailmime_single_fields_init(&fields, mime->mm_mime_fields,
00039             mime->mm_content_type);
00040     }
00041 
00042     mailmime_content*type = fields.fld_content;
00043     clistcell*current;
00044     if (!type) {
00045         target->setType("text");
00046         target->setSubtype("plain");
00047     } else {
00048         target->setSubtype(type->ct_subtype);
00049         switch(type->ct_type->tp_data.tp_discrete_type->dt_type) {
00050         case MAILMIME_DISCRETE_TYPE_TEXT:
00051             target->setType("text");
00052             break;
00053         case MAILMIME_DISCRETE_TYPE_IMAGE:
00054             target->setType("image");
00055             break;
00056         case MAILMIME_DISCRETE_TYPE_AUDIO:
00057             target->setType("audio");
00058             break;
00059         case MAILMIME_DISCRETE_TYPE_VIDEO:
00060             target->setType("video");
00061             break;
00062         case MAILMIME_DISCRETE_TYPE_APPLICATION:
00063             target->setType("application");
00064             break;
00065         case MAILMIME_DISCRETE_TYPE_EXTENSION:
00066         default:
00067             if (type->ct_type->tp_data.tp_discrete_type->dt_extension) {
00068                 target->setType(type->ct_type->tp_data.tp_discrete_type->dt_extension);
00069             }
00070             break;
00071         }
00072         if (type->ct_parameters) {
00073             fillParameters(target,type->ct_parameters);
00074         }
00075     }
00076     if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) {
00077         for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) {
00078             field = (mailmime_field*)current->data;
00079             switch(field->fld_type) {
00080             case MAILMIME_FIELD_TRANSFER_ENCODING:
00081                 target->setEncoding(getencoding(field->fld_data.fld_encoding));
00082                 break;
00083             case MAILMIME_FIELD_ID:
00084                 target->setIdentifier(field->fld_data.fld_id);
00085                 break;
00086             case MAILMIME_FIELD_DESCRIPTION:
00087                 target->setDescription(field->fld_data.fld_description);
00088                 break;
00089             default:
00090                 break;
00091             }
00092         }
00093     }
00094 }
00095 
00096 void Genericwrapper::fillParameters(RecPartP&target,clist*parameters)
00097 {
00098     if (!parameters) {return;}
00099     clistcell*current=0;
00100     mailmime_parameter*param;
00101     for (current=clist_begin(parameters);current!=0;current=clist_next(current)) {
00102         param = (mailmime_parameter*)current->data;
00103         if (param) {
00104             target->addParameter(QString(param->pa_name).lower(),QString(param->pa_value));
00105         }
00106     }
00107 }
00108 
00109 QString Genericwrapper::getencoding(mailmime_mechanism*aEnc)
00110 {
00111     QString enc="7bit";
00112     if (!aEnc) return enc;
00113     switch(aEnc->enc_type) {
00114     case MAILMIME_MECHANISM_7BIT:
00115         enc = "7bit";
00116         break;
00117     case MAILMIME_MECHANISM_8BIT:
00118         enc = "8bit";
00119         break;
00120     case MAILMIME_MECHANISM_BINARY:
00121         enc = "binary";
00122         break;
00123     case MAILMIME_MECHANISM_QUOTED_PRINTABLE:
00124         enc = "quoted-printable";
00125         break;
00126     case MAILMIME_MECHANISM_BASE64:
00127         enc = "base64";
00128         break;
00129     case MAILMIME_MECHANISM_TOKEN:
00130     default:
00131         if (aEnc->enc_token) {
00132             enc = QString(aEnc->enc_token);
00133         }
00134         break;
00135     }
00136     return enc;
00137 }
00138 
00139 void Genericwrapper::traverseBody(RecBodyP&target,mailmessage*message,mailmime*mime,QValueList<int>recList,unsigned int current_rec,int current_count)
00140 {
00141     if (current_rec >= 10) {
00142         odebug << "too deep recursion!" << oendl;
00143     }
00144     if (!message || !mime) {
00145         return;
00146     }
00147     int r;
00148     char*data = 0;
00149     size_t len;
00150     clistiter * cur = 0;
00151     RecPartP part = new RecPart();
00152 
00153     switch (mime->mm_type) {
00154     case MAILMIME_SINGLE:
00155     {
00156         QValueList<int>countlist = recList;
00157         countlist.append(current_count);
00158         r = mailmessage_fetch_section(message,mime,&data,&len);
00159         part->setSize(len);
00160         part->setPositionlist(countlist);
00161         fillSingleBody(part,message,mime);
00162         if (part->Identifier().isEmpty()) {
00163             part->setIdentifier(gen_attachment_id());
00164         }
00165 
00166         if (part->Type()=="text" && target->Bodytext().isNull()) {
00167             encodedString*rs = new encodedString();
00168             rs->setContent(data,len);
00169             encodedString*res = decode_String(rs,part->Encoding());
00170             if (countlist.count()>2) {
00171                 bodyCache[part->Identifier()]=rs;
00172                 target->addPart(part);
00173             } else {
00174                 delete rs;
00175             }
00176             QString b;
00177             b = QString(res->Content());
00178             delete res;
00179             target->setBodytext(b);
00180             target->setDescription(part);
00181         } else {
00182             bodyCache[part->Identifier()]=new encodedString(data,len);
00183             target->addPart(part);
00184         }
00185     }
00186     break;
00187     case MAILMIME_MULTIPLE:
00188     {
00189         unsigned int ccount = 1;
00190         mailmime*cbody=0;
00191         QValueList<int>countlist = recList;
00192         for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) {
00193             cbody = (mailmime*)clist_content(cur);
00194             if (cbody->mm_type==MAILMIME_MULTIPLE) {
00195                 RecPartP targetPart = new RecPart();
00196                 targetPart->setType("multipart");
00197                 countlist.append(current_count);
00198                 targetPart->setPositionlist(countlist);
00199                 target->addPart(targetPart);
00200             }
00201             traverseBody(target,message, cbody,countlist,current_rec+1,ccount);
00202             if (cbody->mm_type==MAILMIME_MULTIPLE) {
00203                 countlist = recList;
00204             }
00205             ++ccount;
00206         }
00207     }
00208     break;
00209     case MAILMIME_MESSAGE:
00210     {
00211         QValueList<int>countlist = recList;
00212         countlist.append(current_count);
00213         /* the own header is always at recursion 0 - we don't need that */
00214         if (current_rec > 0) {
00215             part->setPositionlist(countlist);
00216             r = mailmessage_fetch_section(message,mime,&data,&len);
00217             part->setSize(len);
00218             part->setPositionlist(countlist);
00219             part->setIdentifier(gen_attachment_id());
00220             part->setType("message");
00221             part->setSubtype("rfc822");
00222             bodyCache[part->Identifier()]=new encodedString(data,len);
00223             target->addPart(part);
00224         }
00225         if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
00226             traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,countlist,current_rec+1);
00227         }
00228     }
00229     break;
00230     }
00231 }
00232 
00233 RecBodyP Genericwrapper::parseMail( mailmessage * msg )
00234 {
00235     int err = MAILIMF_NO_ERROR;
00236     mailmime_single_fields fields;
00237     /* is bound to msg and will be freed there */
00238     mailmime * mime=0;
00239     RecBodyP body = new RecBody();
00240     memset(&fields, 0, sizeof(struct mailmime_single_fields));
00241     err = mailmessage_get_bodystructure(msg,&mime);
00242     QValueList<int>recList;
00243     traverseBody(body,msg,mime,recList);
00244     return body;
00245 }
00246 
00247 QString Genericwrapper::parseAddressList( mailimf_address_list *list )
00248 {
00249     QString result( "" );
00250 
00251     bool first = true;
00252     if (list == 0) return result;
00253     for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) {
00254         mailimf_address *addr = (mailimf_address *) current->data;
00255 
00256         if ( !first ) {
00257             result.append( "," );
00258         } else {
00259             first = false;
00260         }
00261 
00262         switch ( addr->ad_type ) {
00263             case MAILIMF_ADDRESS_MAILBOX:
00264                 result.append( parseMailbox( addr->ad_data.ad_mailbox ) );
00265                 break;
00266             case MAILIMF_ADDRESS_GROUP:
00267                 result.append( parseGroup( addr->ad_data.ad_group ) );
00268                 break;
00269             default:
00270                 odebug << "Generic: unkown mailimf address type" << oendl;
00271                 break;
00272         }
00273     }
00274 
00275     return result;
00276 }
00277 
00278 QString Genericwrapper::parseGroup( mailimf_group *group )
00279 {
00280     QString result( "" );
00281 
00282     result.append( group->grp_display_name );
00283     result.append( ": " );
00284 
00285     if ( group->grp_mb_list != NULL ) {
00286         result.append( parseMailboxList( group->grp_mb_list ) );
00287     }
00288 
00289     result.append( ";" );
00290 
00291     return result;
00292 }
00293 
00294 QString Genericwrapper::parseMailbox( mailimf_mailbox *box )
00295 {
00296     QString result( "" );
00297 
00298     if ( box->mb_display_name == NULL ) {
00299         result.append( box->mb_addr_spec );
00300     } else {
00301         result.append( convert_String(box->mb_display_name).latin1() );
00302         result.append( " <" );
00303         result.append( box->mb_addr_spec );
00304         result.append( ">" );
00305     }
00306 
00307     return result;
00308 }
00309 
00310 QString Genericwrapper::parseMailboxList( mailimf_mailbox_list *list )
00311 {
00312     QString result( "" );
00313 
00314     bool first = true;
00315     for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) {
00316         mailimf_mailbox *box = (mailimf_mailbox *) current->data;
00317 
00318         if ( !first ) {
00319             result.append( "," );
00320         } else {
00321             first = false;
00322         }
00323 
00324         result.append( parseMailbox( box ) );
00325     }
00326 
00327     return result;
00328 }
00329 
00330 encodedString* Genericwrapper::fetchDecodedPart(const RecMailP&,const RecPartP&part)
00331 {
00332     QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part->Identifier());
00333     if (it==bodyCache.end()) return new encodedString();
00334     encodedString*t = decode_String(it.data(),part->Encoding());
00335     return t;
00336 }
00337 
00338 encodedString* Genericwrapper::fetchRawPart(const RecMailP&,const RecPartP&part)
00339 {
00340     QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part->Identifier());
00341     if (it==bodyCache.end()) return new encodedString();
00342     encodedString*t = it.data();
00343     return t;
00344 }
00345 
00346 QString Genericwrapper::fetchTextPart(const RecMailP&mail,const RecPartP&part)
00347 {
00348     encodedString*t = fetchDecodedPart(mail,part);
00349     QString text=t->Content();
00350     delete t;
00351     return text;
00352 }
00353 
00354 void Genericwrapper::cleanMimeCache()
00355 {
00356     QMap<QString,encodedString*>::Iterator it = bodyCache.begin();
00357     for (;it!=bodyCache.end();++it) {
00358         encodedString*t = it.data();
00359         //it.setValue(0);
00360         if (t) delete t;
00361     }
00362     bodyCache.clear();
00363     odebug << "Genericwrapper: cache cleaned" << oendl;
00364 }
00365 
00366 QStringList Genericwrapper::parseInreplies(mailimf_in_reply_to * in_replies)
00367 {
00368     QStringList res;
00369     if (!in_replies || !in_replies->mid_list) return res;
00370     clistiter * current = 0;
00371     for ( current = clist_begin( in_replies->mid_list ); current != NULL; current = current->next ) {
00372         QString h((char*)current->data);
00373         while (h.length()>0 && h[0]=='<') {
00374             h.remove(0,1);
00375         }
00376         while (h.length()>0 && h[h.length()-1]=='>') {
00377             h.remove(h.length()-1,1);
00378         }
00379         if (h.length()>0) {
00380             res.append(h);
00381         }
00382     }
00383     return res;
00384 }
00385 
00386 void Genericwrapper::parseList(QValueList<Opie::Core::OSmartPointer<RecMail> > &target,mailsession*session,const QString&mailbox,bool mbox_as_to)
00387 {
00388     int r,toffset;
00389     mailmessage_list * env_list = 0;
00390     r = mailsession_get_messages_list(session,&env_list);
00391     if (r != MAIL_NO_ERROR) {
00392         odebug << "Error message list" << oendl;
00393         return;
00394     }
00395     r = mailsession_get_envelopes_list(session, env_list);
00396     if (r != MAIL_NO_ERROR) {
00397         odebug << "Error filling message list" << oendl;
00398         if (env_list) {
00399             mailmessage_list_free(env_list);
00400         }
00401         return;
00402     }
00403     mailimf_references * refs = 0;
00404     mailimf_in_reply_to * in_replies = 0;
00405     uint32_t i = 0;
00406     for(; i < carray_count(env_list->msg_tab) ; ++i) {
00407         mailmessage * msg;
00408         QBitArray mFlags(7);
00409         msg = (mailmessage*)carray_get(env_list->msg_tab, i);
00410         if (msg->msg_fields == NULL) {
00411             //odebug << "could not fetch envelope of message " << i << "" << oendl;
00412             continue;
00413         }
00414         RecMailP mail = new RecMail();
00415         mail->setWrapper(this);
00416         mail_flags * flag_result = 0;
00417         r = mailmessage_get_flags(msg,&flag_result);
00418         if (r == MAIL_ERROR_NOT_IMPLEMENTED) {
00419             mFlags.setBit(FLAG_SEEN);
00420         }
00421         mailimf_single_fields single_fields;
00422         mailimf_single_fields_init(&single_fields, msg->msg_fields);
00423         mail->setMsgsize(msg->msg_size);
00424         mail->setFlags(mFlags);
00425         mail->setMbox(mailbox);
00426         mail->setNumber(msg->msg_index);
00427         if (single_fields.fld_subject)
00428             mail->setSubject( convert_String(single_fields.fld_subject->sbj_value));
00429         if (single_fields.fld_from)
00430             mail->setFrom(parseMailboxList(single_fields.fld_from->frm_mb_list));
00431         if (!mbox_as_to) {
00432             if (single_fields.fld_to)
00433                 mail->setTo( parseAddressList( single_fields.fld_to->to_addr_list ) );
00434         } else {
00435             mail->setTo(mailbox);
00436         }
00437         if (single_fields.fld_cc)
00438             mail->setCC( parseAddressList( single_fields.fld_cc->cc_addr_list ) );
00439         if (single_fields.fld_bcc)
00440             mail->setBcc( parseAddressList( single_fields.fld_bcc->bcc_addr_list ) );
00441         if (single_fields.fld_orig_date) {
00442             QDateTime d = parseDateTime( single_fields.fld_orig_date->dt_date_time,toffset);
00443             mail->setDate( d,toffset );
00444         }
00445         if (single_fields.fld_message_id && single_fields.fld_message_id->mid_value) {
00446             mail->setMsgid(QString(single_fields.fld_message_id->mid_value));
00447         }
00448         if (single_fields.fld_reply_to) {
00449             QStringList t = parseAddressList(single_fields.fld_reply_to->rt_addr_list);
00450             if (t.count()>0) {
00451                 mail->setReplyto(t[0]);
00452             }
00453         }
00454 #if 0
00455         refs = single_fields.fld_references;
00456         if (refs && refs->mid_list && clist_count(refs->mid_list)) {
00457             char * text = (char*)refs->mid_list->first->data;
00458             mail->setReplyto(QString(text));
00459         }
00460 #endif
00461         if (single_fields.fld_in_reply_to && single_fields.fld_in_reply_to->mid_list &&
00462                 clist_count(single_fields.fld_in_reply_to->mid_list)) {
00463             mail->setInreply(parseInreplies(single_fields.fld_in_reply_to));
00464         }
00465         target.append(mail);
00466     }
00467     if (env_list) {
00468         mailmessage_list_free(env_list);
00469     }
00470 }

Generated on Sat Nov 5 16:17:37 2005 for OPIE by  doxygen 1.4.2