[evolution-mapi] Bug #586353 - Implement message read-receipt and importance flags



commit 48d29512b7d164d00dc3834b0db73ab03b5eff8d
Author: Milan Crha <mcrha redhat com>
Date:   Wed Jan 25 18:55:36 2012 +0100

    Bug #586353 - Implement message read-receipt and importance flags

 src/camel/camel-mapi-folder-summary.h   |    2 +
 src/camel/camel-mapi-folder.c           |   46 ++++++++++++++++++-
 src/libexchangemapi/e-mapi-connection.c |    5 +-
 src/libexchangemapi/e-mapi-mail-utils.c |   73 ++++++++++++++++++++++++++++++-
 4 files changed, 120 insertions(+), 6 deletions(-)
---
diff --git a/src/camel/camel-mapi-folder-summary.h b/src/camel/camel-mapi-folder-summary.h
index 067d268..c530e8f 100644
--- a/src/camel/camel-mapi-folder-summary.h
+++ b/src/camel/camel-mapi-folder-summary.h
@@ -47,6 +47,8 @@
 
 G_BEGIN_DECLS
 
+#define CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT (CAMEL_MESSAGE_FOLDER_FLAGGED << 1)
+
 typedef struct _CamelMapiFolderSummary CamelMapiFolderSummary;
 typedef struct _CamelMapiFolderSummaryClass CamelMapiFolderSummaryClass;
 typedef struct _CamelMapiMessageInfo CamelMapiMessageInfo;
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index 80d00f4..9c9f042 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -308,6 +308,16 @@ gather_changed_objects_to_slist (EMapiConnection *conn,
 				if ((object_data->msg_flags & MSGFLAG_HASATTACH) != 0)
 					flags |= CAMEL_MESSAGE_ATTACHMENTS;
 
+				if ((minfo->info.flags & CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT) != 0) {
+					if ((object_data->msg_flags & MSGFLAG_RN_PENDING) == 0 &&
+					    !camel_message_info_user_flag (info, "receipt-handled")) {
+						camel_message_info_set_user_flag (info, "receipt-handled", TRUE);
+						minfo->info.dirty = TRUE;
+
+						camel_folder_summary_touch (gco->summary);
+					}
+				}
+
 				if ((minfo->info.flags & mask) != (flags & mask)) {
 					camel_message_info_set_flags (info, mask, flags);
 					minfo->server_flags = camel_message_info_flags (info);
@@ -386,6 +396,8 @@ gather_object_offline_cb (EMapiConnection *conn,
 		const mapi_id_t *pmid;
 		const uint32_t *pmsg_flags, *picon_index;
 		const struct FILETIME *last_modified;
+		const bool *pread_receipt;
+		const gchar *msg_class;
 		uint32_t msg_flags;
 		CamelMessageInfo *info;
 		gboolean is_new;
@@ -394,6 +406,11 @@ gather_object_offline_cb (EMapiConnection *conn,
 		pmsg_flags = e_mapi_util_find_array_propval (&object->properties, PR_MESSAGE_FLAGS);
 		last_modified = e_mapi_util_find_array_propval (&object->properties, PR_LAST_MODIFICATION_TIME);
 		picon_index = e_mapi_util_find_array_propval (&object->properties, PidTagIconIndex);
+		pread_receipt = e_mapi_util_find_array_propval (&object->properties, PidTagReadReceiptRequested);
+		msg_class = e_mapi_util_find_array_propval (&object->properties, PidTagMessageClass);
+
+		if (msg_class && g_str_has_prefix (msg_class, "REPORT.IPM.Note.IPNRN"))
+			pread_receipt = NULL;
 
 		if (!pmid) {
 			g_debug ("%s: Received message [%d/%d] without PR_MID", G_STRFUNC, obj_index, obj_total);
@@ -434,7 +451,7 @@ gather_object_offline_cb (EMapiConnection *conn,
 		info = camel_folder_summary_info_new_from_message (gos->folder->summary, msg, NULL);
 		if (info) {
 			CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
-			guint32 flags = 0, mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS | CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_FORWARDED;
+			guint32 flags = 0, mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS | CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_FORWARDED | CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT;
 
 			minfo->info.uid = camel_pstring_strdup (uid_str);
 
@@ -463,6 +480,12 @@ gather_object_offline_cb (EMapiConnection *conn,
 				minfo->server_flags = camel_message_info_flags (info);
 			}
 
+			if (pread_receipt)
+				flags |= CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT;
+
+			if (pread_receipt && (msg_flags & MSGFLAG_RN_PENDING) == 0)
+				camel_message_info_set_user_flag (info, "receipt-handled", TRUE);
+
 			minfo->info.dirty = TRUE;
 			camel_folder_summary_touch (gos->folder->summary);
 
@@ -511,6 +534,8 @@ gather_object_summary_cb (EMapiConnection *conn,
 	const uint32_t *pmsg_flags, *picon_index;
 	const struct FILETIME *last_modified;
 	const gchar *transport_headers;
+	const bool *pread_receipt;
+	const gchar *msg_class;
 	uint32_t msg_flags;
 	CamelMessageInfo *info;
 	gboolean is_new = FALSE;
@@ -524,6 +549,11 @@ gather_object_summary_cb (EMapiConnection *conn,
 	last_modified = e_mapi_util_find_array_propval (&object->properties, PR_LAST_MODIFICATION_TIME);
 	transport_headers = e_mapi_util_find_array_propval (&object->properties, PR_TRANSPORT_MESSAGE_HEADERS_UNICODE);
 	picon_index = e_mapi_util_find_array_propval (&object->properties, PidTagIconIndex);
+	pread_receipt = e_mapi_util_find_array_propval (&object->properties, PidTagReadReceiptRequested);
+	msg_class = e_mapi_util_find_array_propval (&object->properties, PidTagMessageClass);
+
+	if (msg_class && g_str_has_prefix (msg_class, "REPORT.IPM.Note.IPNRN"))
+		pread_receipt = NULL;
 
 	if (!pmid) {
 		g_debug ("%s: Received message [%d/%d] without PR_MID", G_STRFUNC, obj_index, obj_total);
@@ -668,7 +698,7 @@ gather_object_summary_cb (EMapiConnection *conn,
 
 	if (info) {
 		CamelMapiMessageInfo *minfo = (CamelMapiMessageInfo *) info;
-		guint32 flags = 0, mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS | CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_FORWARDED;
+		guint32 flags = 0, mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ATTACHMENTS | CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_FORWARDED | CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT;
 
 		if (last_modified) {
 			minfo->last_modified = e_mapi_util_filetime_to_time_t (last_modified);
@@ -691,6 +721,12 @@ gather_object_summary_cb (EMapiConnection *conn,
 				flags |= CAMEL_MESSAGE_FORWARDED;
 		}
 
+		if (pread_receipt)
+			flags |= CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT;
+
+		if (pread_receipt && (msg_flags & MSGFLAG_RN_PENDING) == 0)
+			camel_message_info_set_user_flag (info, "receipt-handled", TRUE);
+
 		if ((camel_message_info_flags (info) & mask) != flags) {
 			if (is_new)
 				minfo->info.flags = flags;
@@ -1536,7 +1572,7 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 	CamelService *service;
 	EMapiConnection *conn;
 	GPtrArray *known_uids;
-	GSList *read_items = NULL, *unread_items = NULL, *to_free = NULL, *junk_items = NULL, *deleted_items = NULL, *l;
+	GSList *read_items = NULL, *read_with_receipt = NULL, *unread_items = NULL, *to_free = NULL, *junk_items = NULL, *deleted_items = NULL, *l;
 	flags_diff_t diff, unset_flags;
 	const gchar *folder_id;
 	const gchar *full_name;
@@ -1614,6 +1650,8 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 
 			if (diff.bits & CAMEL_MESSAGE_SEEN) {
 				read_items = g_slist_prepend (read_items, mid);
+				if (flags & CAMEL_MAPI_MESSAGE_WITH_READ_RECEIPT)
+					read_with_receipt = g_slist_prepend (read_with_receipt, mid);
 				used = TRUE;
 			} else if (unset_flags.bits & CAMEL_MESSAGE_SEEN) {
 				unread_items = g_slist_prepend (unread_items, mid);
@@ -1646,6 +1684,8 @@ mapi_folder_synchronize_sync (CamelFolder *folder,
 
 	if (read_items && has_obj_folder) {
 		camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
+		if (read_with_receipt)
+			e_mapi_connection_set_flags (conn, &obj_folder, read_with_receipt, CLEAR_RN_PENDING, cancellable, NULL);
 		e_mapi_connection_set_flags (conn, &obj_folder, read_items, 0, cancellable, NULL);
 		camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK);
 	}
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index 033d93c..b302783 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -2835,14 +2835,15 @@ e_mapi_connection_transfer_summary (EMapiConnection *conn,
 				goto cleanup;
 			}
 
-			tags = set_SPropTagArray (mem_ctx, 7,
+			tags = set_SPropTagArray (mem_ctx, 8,
 				PR_FID,
 				PR_MID,
 				PR_MESSAGE_FLAGS,
 				PR_LAST_MODIFICATION_TIME,
 				PR_MESSAGE_CLASS,
 				PR_TRANSPORT_MESSAGE_HEADERS_UNICODE,
-				PidTagIconIndex);
+				PidTagIconIndex,
+				PidTagReadReceiptRequested);
 
 			ms = GetProps (&obj_message, MAPI_PROPS_SKIP_NAMEDID_CHECK | MAPI_UNICODE, tags, &lpProps, &prop_count);
 			if (ms == MAPI_E_SUCCESS) {
diff --git a/src/libexchangemapi/e-mapi-mail-utils.c b/src/libexchangemapi/e-mapi-mail-utils.c
index e42caa4..0d3d7a9 100644
--- a/src/libexchangemapi/e-mapi-mail-utils.c
+++ b/src/libexchangemapi/e-mapi-mail-utils.c
@@ -728,6 +728,8 @@ e_mapi_mail_utils_object_to_message (EMapiConnection *conn, /* const */ EMapiObj
 	} else {
 		CamelInternetAddress *to_addr, *cc_addr, *bcc_addr;
 		const struct FILETIME *msg_date;
+		const bool *read_receipt;
+		const uint32_t *priority;
 		gchar *name, *email;
 
 		to_addr = camel_internet_address_new ();
@@ -772,7 +774,7 @@ e_mapi_mail_utils_object_to_message (EMapiConnection *conn, /* const */ EMapiObj
 		if (email && *email) {
 			CamelInternetAddress *addr;
 
-			addr = camel_internet_address_new();
+			addr = camel_internet_address_new ();
 			camel_internet_address_add (addr, name, email);
 			camel_mime_message_set_from (msg, addr);
 		}
@@ -792,6 +794,42 @@ e_mapi_mail_utils_object_to_message (EMapiConnection *conn, /* const */ EMapiObj
 		str = e_mapi_util_find_array_propval (&object->properties, PidTagInReplyToId);
 		if (str)
 			camel_medium_add_header (CAMEL_MEDIUM (msg), "In-Reply-To", str);
+
+		priority = e_mapi_util_find_array_propval (&object->properties, PidTagImportance);
+		if (priority && *priority > 1)
+			camel_medium_add_header (CAMEL_MEDIUM (msg), "X-Priority", "1");
+
+		/* Read-Receipt handling */
+		read_receipt = e_mapi_util_find_array_propval (&object->properties, PidTagReadReceiptRequested);
+		if (read_receipt && *read_receipt) {
+			if (!camel_medium_get_header (CAMEL_MEDIUM (msg), "Disposition-Notification-To")) {
+				name = NULL;
+				email = NULL;
+
+				e_mapi_mail_utils_decode_email_address1 (conn, &object->properties,
+					PidTagReadReceiptName,
+					PidTagReadReceiptEmailAddress,
+					PidTagReadReceiptAddressType,
+					&name, &email);
+
+				if (email && *email) {
+					CamelInternetAddress *addr;
+					gchar *address;
+
+					addr = camel_internet_address_new ();
+					camel_internet_address_add (addr, name, email);
+					address = camel_address_encode (CAMEL_ADDRESS (addr));
+
+					camel_medium_add_header (CAMEL_MEDIUM (msg), "Disposition-Notification-To", address);
+
+					g_object_unref (addr);
+					g_free (address);
+				}
+
+				g_free (name);
+				g_free (email);
+			}
+		}
 	}
 
 	str = e_mapi_util_find_array_propval (&object->properties, PidNameContentClass);
@@ -1493,6 +1531,39 @@ e_mapi_mail_utils_message_to_object (struct _CamelMimeMessage *message,
 	if (str)
 		set_value (PidTagInternetMessageId, str);
 
+	str = camel_medium_get_header ((CamelMedium *) message, "X-Priority");
+	if (str && g_str_equal (str, "1")) {
+		ui32 = 2;
+		set_value (PidTagImportance, &ui32);
+	}
+
+	str = camel_medium_get_header ((CamelMedium *) message, "Disposition-Notification-To");
+	if (str) {
+		CamelInternetAddress *addr;
+
+		namep = NULL;
+		addressp = NULL;
+
+		addr = camel_internet_address_new ();
+		if (camel_address_decode (CAMEL_ADDRESS (addr), str) != -1 &&
+		    camel_internet_address_get (addr, 0, &namep, &addressp) &&
+		    addressp && *addressp) {
+			if (namep && *namep)
+				set_value (PidTagReadReceiptName, namep);
+
+			set_value (PidTagReadReceiptEmailAddress, addressp);
+			set_value (PidTagReadReceiptAddressType, "SMTP");
+
+			if ((create_flags & E_MAPI_CREATE_FLAG_SUBMIT) != 0) {
+				bl = true;
+
+				set_value (PidTagReadReceiptRequested, &bl);
+			}
+		}
+
+		g_object_unref (addr);
+	}
+
 	addresses = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO);
 	e_mapi_mail_add_recipients (object, addresses, olTo);
 



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