[evolution-mapi] Added support for message threading (conversation threading).



commit 6e99b5985e3659ad5ddafa1ed22f33de6164c80b
Author: Johnny Jacob <jjohnny novell com>
Date:   Fri Jun 19 10:19:22 2009 +0530

    Added support for message threading (conversation threading).

 src/camel/ChangeLog           |    8 +++
 src/camel/camel-mapi-folder.c |  125 +++++++++++++++++++++++++++++++++++++++--
 src/camel/camel-mapi-folder.h |    3 +
 3 files changed, 130 insertions(+), 6 deletions(-)
---
diff --git a/src/camel/ChangeLog b/src/camel/ChangeLog
index 31ec3f1..73facd5 100644
--- a/src/camel/ChangeLog
+++ b/src/camel/ChangeLog
@@ -1,3 +1,11 @@
+2009-06-19  Johnny Jacob  <jjohnny novell com>
+
+	* camel-mapi-folder.c (mapi_set_message_id): Added. Sets the message id (mime message id).
+	(mapi_set_message_references): Added. Sets message references for message threading.
+	(mapi_update_cache): Add message threading information in message info.
+	(fetch_item_cb, fetch_items_cb): Collect message reference headers
+	(mapi_folder_item_to_msg): Write message references to mime message.
+
 2009-06-10  Johnny Jacob  <jjohnny novell com>
 
 	** Fix for BGO 583490 â?? evolution-mapi not removing listing of message not on server
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index b09a55e..d285c7e 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -259,6 +259,15 @@ fetch_items_cb (FetchItemsCallbackData *item_data, gpointer data)
 		case PR_MESSAGE_SIZE:
 			item->header.size = *(glong *)prop_data;
 			break;
+		case PR_INTERNET_MESSAGE_ID:
+			item->header.message_id = g_strdup (prop_data);
+			break;
+		case PR_INTERNET_REFERENCES:
+			item->header.references = g_strdup (prop_data);
+			break;
+		case PR_IN_REPLY_TO_ID:
+			item->header.in_reply_to = g_strdup (prop_data);
+			break;
 		case PR_MESSAGE_DELIVERY_TIME:
 			delivery_date = (struct FILETIME *) prop_data;
 			break;
@@ -322,6 +331,80 @@ fetch_items_cb (FetchItemsCallbackData *item_data, gpointer data)
 }
 
 static void
+mapi_set_message_id (CamelMapiMessageInfo *mapi_mi, const gchar *message_id)
+{
+	gchar *msgid;
+	guint8 *digest;
+	gsize length;
+	CamelMessageInfoBase *mi = &mapi_mi->info;
+
+	msgid = camel_header_msgid_decode (message_id);
+	if (msgid) {
+		GChecksum *checksum;
+
+		length = g_checksum_type_get_length (G_CHECKSUM_MD5);
+		digest = g_alloca (length);
+
+		checksum = g_checksum_new (G_CHECKSUM_MD5);
+		g_checksum_update (checksum, (guchar *) msgid, -1);
+		g_checksum_get_digest (checksum, digest, &length);
+		g_checksum_free (checksum);
+
+		memcpy(mi->message_id.id.hash, digest, sizeof(mi->message_id.id.hash));
+		g_free(msgid);
+	}
+
+}
+
+static void
+mapi_set_message_references (CamelMapiMessageInfo *mapi_mi, const gchar *references, const gchar *in_reply_to)
+{
+	struct _camel_header_references *refs, *irt, *scan;
+	guint8 *digest;
+	gint count;
+	gsize length;
+	CamelMessageInfoBase *mi = &mapi_mi->info;
+
+	refs = camel_header_references_decode (references);
+	irt = camel_header_references_inreplyto_decode (in_reply_to);
+	if (refs || irt) {
+		if (irt) {
+			/* The References field is populated from the "References" and/or "In-Reply-To"
+			   headers. If both headers exist, take the first thing in the In-Reply-To header
+			   that looks like a Message-ID, and append it to the References header. */
+
+			if (refs)
+				irt->next = refs;
+
+			refs = irt;
+		}
+
+		count = camel_header_references_list_size(&refs);
+		mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * sizeof(mi->references->references[0])));
+
+		length = g_checksum_type_get_length (G_CHECKSUM_MD5);
+		digest = g_alloca (length);
+
+		count = 0;
+		scan = refs;
+		while (scan) {
+			GChecksum *checksum;
+
+			checksum = g_checksum_new (G_CHECKSUM_MD5);
+			g_checksum_update (checksum, (guchar *) scan->id, -1);
+			g_checksum_get_digest (checksum, digest, &length);
+			g_checksum_free (checksum);
+
+			memcpy(mi->references->references[count].id.hash, digest, sizeof(mi->message_id.id.hash));
+			count++;
+			scan = scan->next;
+		}
+		mi->references->size = count;
+		camel_header_references_list_clear(&refs);
+	}
+}
+
+static void
 mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **changeinfo,
 		   CamelException *ex, gboolean uid_flag) 
 {
@@ -396,6 +479,12 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
 			mi->info.date_sent = mi->info.date_received = item->header.recieved_time;
 			mi->info.size = (guint32) item->header.size;
 
+			/*Threading related properties*/
+			mapi_set_message_id (mi, item->header.message_id);
+			if (item->header.references || item->header.in_reply_to)
+				mapi_set_message_references (mi, item->header.references, item->header.in_reply_to);
+
+			/*Recipients*/
  			for (l = item->recipients; l; l=l->next) {
  				gchar *formatted_id = NULL;
 				const char *name, *display_name;
@@ -814,6 +903,9 @@ mapi_refresh_folder(CamelFolder *folder, CamelException *ex)
 		PR_SENT_REPRESENTING_EMAIL_ADDRESS,
 		PR_SENT_REPRESENTING_ADDRTYPE,
 		PR_LAST_MODIFICATION_TIME,
+		PR_INTERNET_MESSAGE_ID,
+		PR_INTERNET_REFERENCES,
+		PR_IN_REPLY_TO_ID,
 		PR_DISPLAY_TO,
 		PR_DISPLAY_CC,
 		PR_DISPLAY_BCC
@@ -957,6 +1049,11 @@ static const uint32_t camel_GetPropsList[] = {
 	PR_CONVERSATION_TOPIC, 
 	PR_CONVERSATION_TOPIC_UNICODE, 
 
+	/*Properties used for message threading.*/
+	PR_INTERNET_MESSAGE_ID,
+	PR_INTERNET_REFERENCES,
+	PR_IN_REPLY_TO_ID,
+
 	PR_BODY, 
 	PR_BODY_UNICODE, 
 	PR_HTML,
@@ -1142,6 +1239,15 @@ fetch_item_cb (FetchItemsCallbackData *item_data, gpointer data)
 		case PR_MESSAGE_SIZE:
 			item->header.size = *(glong *)prop_data;
 			break;
+		case PR_INTERNET_MESSAGE_ID:
+			item->header.message_id = g_strdup (prop_data);
+			break;
+		case PR_INTERNET_REFERENCES:
+			item->header.references = g_strdup (prop_data);
+			break;
+		case PR_IN_REPLY_TO_ID:
+			item->header.in_reply_to = g_strdup (prop_data);
+			break;
 		case PR_MESSAGE_CLASS:
 		case PR_MESSAGE_CLASS_UNICODE:
 			msg_class = (const char *) prop_data;
@@ -1339,8 +1445,8 @@ mapi_populate_msg_body_from_item (CamelMultipart *multipart, MapiItem *item, Exc
 
 static CamelMimeMessage *
 mapi_folder_item_to_msg( CamelFolder *folder,
-		MapiItem *item,
-		CamelException *ex )
+			 MapiItem *item,
+			 CamelException *ex )
 {
 	CamelMimeMessage *msg = NULL;
 	CamelMultipart *multipart = NULL;
@@ -1350,12 +1456,9 @@ mapi_folder_item_to_msg( CamelFolder *folder,
 	/* char *body = NULL; */
 	ExchangeMAPIStream *body = NULL;
 	GSList *body_part_list = NULL;
-	const char *uid = NULL;
 
 	attach_list = item->attachments;
-
 	msg = camel_mime_message_new ();
-
 	multipart = camel_multipart_new ();
 
 	/*FIXME : Using set of default. Fix it during mimewriter*/
@@ -1366,7 +1469,7 @@ mapi_folder_item_to_msg( CamelFolder *folder,
 
 	camel_multipart_set_boundary (multipart, NULL);
 
-	camel_mime_message_set_message_id (msg, uid);
+	/* Handle Multipart */
 	body_part_list = item->msg.body_parts;
 	while (body_part_list){
 	       body = body_part_list->data;
@@ -1374,11 +1477,21 @@ mapi_folder_item_to_msg( CamelFolder *folder,
 	       body_part_list = g_slist_next (body_part_list);
 	}
 
+	/* Threading */
+	if (item->header.message_id)
+		camel_medium_add_header (CAMEL_MEDIUM (msg), "Message-Id", item->header.message_id);
+
+	if (item->header.references)
+		camel_medium_add_header (CAMEL_MEDIUM (msg), "References", item->header.references);
+
+	if (item->header.in_reply_to)
+		camel_medium_add_header (CAMEL_MEDIUM (msg), "In-Reply-To", item->header.in_reply_to);
 
 	/*Set recipient details*/
 	mapi_msg_set_recipient_list (msg, item);
 	mapi_populate_details_from_item (folder, msg, item);
 
+	/** Attachment Handling*/
 	if (attach_list) {
 		GSList *al = attach_list;
 		for (al = attach_list; al != NULL; al = al->next) {
diff --git a/src/camel/camel-mapi-folder.h b/src/camel/camel-mapi-folder.h
index 0fc6fa4..71b50cf 100644
--- a/src/camel/camel-mapi-folder.h
+++ b/src/camel/camel-mapi-folder.h
@@ -65,6 +65,9 @@ typedef struct {
 	gchar *from_email;
 	gchar *from_type;
 
+	gchar *references;
+	gchar *message_id;
+	gchar *in_reply_to;
 	/*TODO : Obsolete this. Moved to recipient list*/
 	gchar *to;
 	gchar *cc;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]