[evolution-mapi] Added support for message threading (conversation threading).
- From: Johnny Jacob <jjohnny src gnome org>
- To: svn-commits-list gnome org
- Subject: [evolution-mapi] Added support for message threading (conversation threading).
- Date: Fri, 19 Jun 2009 01:58:02 -0400 (EDT)
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]