[Evolution-hackers] [PATCH] evolution-ews: implement Exchange categories as evolution labels (read only)



This patch is a proof of concept for adding evolution labels to an
exchange back end.  The outlook categories perform roughly the same
function, and evolution even mirrors their colour scheme.

This patch allows evolution to fill in the labels from the EWS
Category element.  That means that any colour you add to a message via
the categories in outlook (or the outlook web server) automatically
appears in evolution.

The next phase will be to allow evolution to modify the categories.

Signed-off-by: James Bottomley <James Bottomley parallels com>

diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index cd5ac7c..af0753a 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -59,7 +59,7 @@ which needs to be better organized via functions */
 
 #define MAX_ATTACHMENT_SIZE 1*1024*1024   /*In bytes*/
 
-#define SUMMARY_ITEM_FLAGS "item:ResponseObjects item:Sensitivity item:Importance"
+#define SUMMARY_ITEM_FLAGS "item:ResponseObjects item:Sensitivity item:Importance item:Categories"
 #define ITEM_PROPS "item:Subject item:DateTimeReceived item:DateTimeSent item:DateTimeCreated item:Size " \
 		   "item:HasAttachments item:InReplyTo"
 #define SUMMARY_ITEM_PROPS ITEM_PROPS " " SUMMARY_ITEM_FLAGS
@@ -1301,7 +1301,7 @@ camel_ews_folder_init (CamelEwsFolder *ews_folder)
 
 	folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_DELETED |
 		CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN |
-		CAMEL_MESSAGE_FORWARDED;
+		CAMEL_MESSAGE_FORWARDED | CAMEL_MESSAGE_USER;
 
 	folder->folder_flags = CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY | CAMEL_FOLDER_HAS_SEARCH_CAPABILITY;
 
diff --git a/src/camel/camel-ews-utils.c b/src/camel/camel-ews-utils.c
index d983130..83057ac 100644
--- a/src/camel/camel-ews-utils.c
+++ b/src/camel/camel-ews-utils.c
@@ -651,6 +651,58 @@ camel_ews_utils_sync_deleted_items (CamelEwsFolder *ews_folder, GSList *items_de
 	g_slist_free (items_deleted);
 }
 
+static const gchar*
+ews_utils_rename_label(const gchar *cat)
+{
+	gint i;
+
+	/* this is a mapping from Exchange/Outlook categories to
+	 * evolution labels based on the standard colours */
+	const gchar *labels[] = {
+		"Red Category", "$Labelimportant",
+		"Orange Category", "$Labelwork",
+		"Green Category", "$Labelpersonal",
+		"Blue Category", "$Labeltodo",
+		"Purple Category", "$Labellater",
+		NULL, NULL
+	};
+
+	if (!cat || !*cat)
+		return "";
+
+	for (i = 0; labels[i]; i += 2) {
+		if (!g_ascii_strcasecmp (cat, labels[i]))
+			return labels[i + 1];
+	}
+	return cat;
+}
+
+static void
+ews_utils_merge_server_user_flags (EEwsItem *item, CamelEwsMessageInfo *mi)
+{
+	GSList *list = NULL;
+	const GSList *p;
+	const CamelFlag *flag;
+
+	/* transfer camel flags to a list */
+	for (flag = camel_message_info_user_flags (&mi->info); flag;
+	     flag = flag->next)
+		list = g_slist_append(list, (gchar *)flag->name);
+
+	/* we're transferring from server only, so just dump them */
+	for (p = list; p; p = p->next) {
+		camel_flag_set(&mi->info.user_flags, p->data, 0);
+	}
+	//g_slist_foreach(list, (GFunc)g_free, NULL);
+	g_slist_free(list);
+
+	/* now transfer over all the categories */
+	for (p = e_ews_item_get_categories (item); p; p = p->next) {
+		camel_flag_set(&mi->info.user_flags,
+			       ews_utils_rename_label(p->data), 1);
+	}
+}
+
 static gint
 ews_utils_get_server_flags (EEwsItem *item)
 {
@@ -833,8 +885,9 @@ camel_ews_utils_sync_updated_items (CamelEwsFolder *ews_folder, GSList *items_up
 			gint server_flags;
 
 			server_flags = ews_utils_get_server_flags (item);
+			ews_utils_merge_server_user_flags (item, mi);
 			if (camel_ews_update_message_info_flags (folder->summary, (CamelMessageInfo *)mi,
-						server_flags, NULL))
+								 server_flags, NULL))
 				camel_folder_change_info_change_uid (ci, mi->info.uid);
 
 			mi->change_key = g_strdup (id->change_key);
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index fd42ea9..9787958 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -169,6 +169,12 @@ struct _EEwsItemPrivate {
 
 	EwsId *associated_calendar_item_id;
 
+	/* the evolution labels are implemented as exchange
+	 * Categories.  These appear in the message headers as
+	 * Keywords: and are set and extracted from the EWS server as
+	 * <Categories> which is a string array valued XML element */
+	GSList *categories;
+
 	struct _EEwsContactFields *contact_fields;
 };
 
@@ -470,6 +476,29 @@ static void parse_extended_property (EEwsItemPrivate *priv, ESoapParameter *para
 	}
 }
 
+static void parse_categories (EEwsItemPrivate *priv, ESoapParameter *param)
+{
+	gchar *value;
+	ESoapParameter *subparam;
+
+	/* release all the old data (if any) */
+	if (priv->categories) {
+		g_slist_foreach (priv->categories, (GFunc) g_free, NULL);
+		g_slist_free (priv->categories);
+		priv->categories = NULL;
+	}
+
+	/* categories are an array of <string> */
+	for (subparam = e_soap_parameter_get_first_child(param);
+	     subparam != NULL;
+	     subparam = e_soap_parameter_get_next_child(subparam)) {
+		value = e_soap_parameter_get_string_value (subparam);
+
+		priv->categories = g_slist_append(priv->categories, value);
+	}
+
+}
+
 static EwsImportance
 parse_importance (ESoapParameter *param)
 {
@@ -734,6 +763,8 @@ e_ews_item_set_from_soap_parameter (EEwsItem *item, ESoapParameter *param)
 			g_free (value);
 		} else if (!g_ascii_strcasecmp (name, "Size")) {
 			priv->size = e_soap_parameter_get_int_value (subparam);
+		} else if (!g_ascii_strcasecmp (name, "Categories")) {
+			parse_categories (priv, subparam);
 		} else if (!g_ascii_strcasecmp (name, "Importance")) {
 			priv->importance = parse_importance (subparam);
 		} else if (!g_ascii_strcasecmp (name, "InReplyTo")) {
@@ -1026,6 +1057,14 @@ e_ews_item_get_from		(EEwsItem *item)
 	return (const EwsMailbox *) item->priv->from;
 }
 
+const GSList *
+e_ews_item_get_categories	(EEwsItem *item)
+{
+	g_return_val_if_fail (E_IS_EWS_ITEM (item), NULL);
+
+	return item->priv->categories;
+}
+
 EwsImportance
 e_ews_item_get_importance	(EEwsItem *item)
 {
diff --git a/src/server/e-ews-item.h b/src/server/e-ews-item.h
index f4982bd..f143ae1 100644
--- a/src/server/e-ews-item.h
+++ b/src/server/e-ews-item.h
@@ -141,6 +141,8 @@ const EwsMailbox *
 		e_ews_item_get_from		(EEwsItem *item);
 EwsImportance
 		e_ews_item_get_importance	(EEwsItem *item);
+const GSList *
+		e_ews_item_get_categories	(EEwsItem *item);
 EwsMailbox *
 		e_ews_item_mailbox_from_soap_param
 						(ESoapParameter *param);




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