* lib: correctly handle embedded text parts
This commit is contained in:
@ -521,6 +521,8 @@ mu_msg_mime_part_to_string (GMimePart *part, gboolean *err)
|
|||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
stream = NULL;
|
stream = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (err, NULL);
|
||||||
|
|
||||||
*err = TRUE; /* guilty until proven innocent */
|
*err = TRUE; /* guilty until proven innocent */
|
||||||
g_return_val_if_fail (GMIME_IS_PART(part), NULL);
|
g_return_val_if_fail (GMIME_IS_PART(part), NULL);
|
||||||
|
|
||||||
|
|||||||
@ -35,8 +35,8 @@
|
|||||||
#endif /*BUILD_CRYPTO*/
|
#endif /*BUILD_CRYPTO*/
|
||||||
|
|
||||||
static gboolean handle_children (MuMsg *msg, GMimeObject *mobj, MuMsgOptions opts,
|
static gboolean handle_children (MuMsg *msg, GMimeObject *mobj, MuMsgOptions opts,
|
||||||
unsigned index, MuMsgPartForeachFunc func, gpointer user_data);
|
unsigned index, MuMsgPartForeachFunc func,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
struct _DoData {
|
struct _DoData {
|
||||||
GMimeObject *mime_obj;
|
GMimeObject *mime_obj;
|
||||||
@ -137,7 +137,7 @@ accumulate_text (MuMsg *msg, MuMsgPart *part, GString **gstrp)
|
|||||||
if (!g_mime_content_type_is_type (ctype, "text", "plain"))
|
if (!g_mime_content_type_is_type (ctype, "text", "plain"))
|
||||||
return; /* not plain text */
|
return; /* not plain text */
|
||||||
txt = mu_msg_mime_part_to_string
|
txt = mu_msg_mime_part_to_string
|
||||||
((GMimePart*)part, &err);
|
((GMimePart*)part->data, &err);
|
||||||
if (txt)
|
if (txt)
|
||||||
g_string_append (*gstrp, txt);
|
g_string_append (*gstrp, txt);
|
||||||
g_free (txt);
|
g_free (txt);
|
||||||
@ -153,6 +153,8 @@ mu_msg_part_get_text (MuMsg *msg, MuMsgPart *self, MuMsgOptions opts,
|
|||||||
|
|
||||||
g_return_val_if_fail (msg, NULL);
|
g_return_val_if_fail (msg, NULL);
|
||||||
g_return_val_if_fail (self && self->data, NULL);
|
g_return_val_if_fail (self && self->data, NULL);
|
||||||
|
g_return_val_if_fail (err, NULL);
|
||||||
|
|
||||||
mobj = (GMimeObject*)self->data;
|
mobj = (GMimeObject*)self->data;
|
||||||
|
|
||||||
if (GMIME_IS_PART (mobj) &&
|
if (GMIME_IS_PART (mobj) &&
|
||||||
@ -363,8 +365,13 @@ handle_encrypted_part (MuMsg *msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
looks_like_body (GMimeObject *parent, MuMsgPart *msgpart)
|
looks_like_body (MuMsg *msg, GMimeObject *parent, MuMsgPart *msgpart)
|
||||||
{
|
{
|
||||||
|
/* if we've already seen a body for this one, don't consider
|
||||||
|
* more */
|
||||||
|
if (msg->_file->_body_seen)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (parent &&
|
if (parent &&
|
||||||
!GMIME_IS_MESSAGE_PART(parent) &&
|
!GMIME_IS_MESSAGE_PART(parent) &&
|
||||||
!GMIME_IS_MULTIPART(parent))
|
!GMIME_IS_MULTIPART(parent))
|
||||||
@ -399,8 +406,11 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
|
|||||||
msgpart.part_type |= get_disposition ((GMimeObject*)part);
|
msgpart.part_type |= get_disposition ((GMimeObject*)part);
|
||||||
|
|
||||||
/* a top-level non-attachment text part is probably a body */
|
/* a top-level non-attachment text part is probably a body */
|
||||||
if (looks_like_body (parent, &msgpart))
|
if (looks_like_body (msg, parent, &msgpart)) {
|
||||||
msgpart.part_type |= MU_MSG_PART_TYPE_BODY;
|
msgpart.part_type |= MU_MSG_PART_TYPE_BODY;
|
||||||
|
/* remember that we (probably) saw the body */
|
||||||
|
msg->_file->_body_seen = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
msgpart.data = (gpointer)part;
|
msgpart.data = (gpointer)part;
|
||||||
msgpart.index = index;
|
msgpart.index = index;
|
||||||
@ -434,12 +444,11 @@ handle_message_part (MuMsg *msg, GMimeMessagePart *mmsg, GMimeObject *parent,
|
|||||||
func (msg, &msgpart, user_data);
|
func (msg, &msgpart, user_data);
|
||||||
|
|
||||||
if (opts & MU_MSG_OPTION_RECURSE_RFC822) {
|
if (opts & MU_MSG_OPTION_RECURSE_RFC822) {
|
||||||
GMimeMessage *mime_msg;
|
GMimeObject *mobj;
|
||||||
mime_msg = g_mime_message_part_get_message (mmsg);
|
mobj = g_mime_message_get_mime_part
|
||||||
|
(g_mime_message_part_get_message (mmsg));
|
||||||
return handle_children
|
return handle_children
|
||||||
(msg,
|
(msg, mobj, opts, index, func, user_data);
|
||||||
(GMimeObject*)mime_msg,
|
|
||||||
opts, index, func, user_data);
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,10 @@ struct _MuMsgFile {
|
|||||||
char _path [PATH_MAX + 1];
|
char _path [PATH_MAX + 1];
|
||||||
char _maildir [PATH_MAX + 1];
|
char _maildir [PATH_MAX + 1];
|
||||||
|
|
||||||
|
/* when we iterate over the parts, remember whether
|
||||||
|
* the body has been seen already */
|
||||||
|
gboolean _body_seen;
|
||||||
|
|
||||||
/* list where we push allocated strings so we can
|
/* list where we push allocated strings so we can
|
||||||
* free them when the struct gets destroyed
|
* free them when the struct gets destroyed
|
||||||
*/
|
*/
|
||||||
@ -69,7 +73,7 @@ struct _MuMsg {
|
|||||||
* convert a GMimePart to a string
|
* convert a GMimePart to a string
|
||||||
*
|
*
|
||||||
* @param part a GMimePart
|
* @param part a GMimePart
|
||||||
* @param err will receive TRUE if there was an error, FALSE otherwise
|
* @param err will receive TRUE if there was an error, FALSE otherwise. Must NOT be NULL.
|
||||||
*
|
*
|
||||||
* @return utf8 string for this MIME part, to be freed by caller
|
* @return utf8 string for this MIME part, to be freed by caller
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -390,6 +390,8 @@ maybe_index_text_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
|||||||
char *txt, *norm;
|
char *txt, *norm;
|
||||||
Xapian::TermGenerator termgen;
|
Xapian::TermGenerator termgen;
|
||||||
|
|
||||||
|
/* we handle the body text elsewhere; this is about other text
|
||||||
|
* parts */
|
||||||
if (part->part_type & MU_MSG_PART_TYPE_BODY)
|
if (part->part_type & MU_MSG_PART_TYPE_BODY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -458,7 +460,7 @@ add_terms_values_attach (Xapian::Document& doc, MuMsg *msg,
|
|||||||
MuMsgFieldId mfid, GStringChunk *strchunk)
|
MuMsgFieldId mfid, GStringChunk *strchunk)
|
||||||
{
|
{
|
||||||
PartData pdata (doc, mfid, strchunk);
|
PartData pdata (doc, mfid, strchunk);
|
||||||
mu_msg_part_foreach (msg, MU_MSG_OPTION_NONE,
|
mu_msg_part_foreach (msg, MU_MSG_OPTION_RECURSE_RFC822,
|
||||||
(MuMsgPartForeachFunc)each_part, &pdata);
|
(MuMsgPartForeachFunc)each_part, &pdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,7 +690,7 @@ mu_store_add_msg (MuStore *store, MuMsg *msg, GError **err)
|
|||||||
|
|
||||||
doc.add_term (term);
|
doc.add_term (term);
|
||||||
|
|
||||||
MU_WRITE_LOG ("adding: %s", term.c_str());
|
// MU_WRITE_LOG ("adding: %s", term.c_str());
|
||||||
|
|
||||||
/* note, this will replace any other messages for this path */
|
/* note, this will replace any other messages for this path */
|
||||||
id = store->db_writable()->replace_document (term, doc);
|
id = store->db_writable()->replace_document (term, doc);
|
||||||
|
|||||||
Reference in New Issue
Block a user