[evolution-ews/gnome-2-28] Bug #654810 finditem API implementation
- From: Punit Jain <jpunit src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/gnome-2-28] Bug #654810 finditem API implementation
- Date: Wed, 14 Mar 2012 10:57:59 +0000 (UTC)
commit 4740ce99f9aa4bdca3fd10e7a86b07925971e079
Author: Punit Jain <jpunit novell com>
Date: Wed Mar 14 16:36:22 2012 +0530
Bug #654810 finditem API implementation
src/addressbook/Makefile.am | 4 +-
src/addressbook/e-book-backend-ews.c | 192 +++++++++++++++++++++++++---
src/server/e-ews-connection.c | 218 +++++++++++++++++++++++++++++++-
src/server/e-ews-connection.h | 52 ++++++++
src/server/e-ews-item.c | 69 +++++++----
src/utils/Makefile.am | 28 ++++-
src/utils/e-ews-query-to-restriction.c | 23 +++-
7 files changed, 533 insertions(+), 53 deletions(-)
---
diff --git a/src/addressbook/Makefile.am b/src/addressbook/Makefile.am
index 7264a9c..89e9230 100644
--- a/src/addressbook/Makefile.am
+++ b/src/addressbook/Makefile.am
@@ -38,11 +38,11 @@ libebookbackendews_la_LIBADD = \
$(top_builddir)/src/addressbook/lzx/liblzx.la \
$(LIBEBACKEND_LIBS) \
$(LIBEDATASERVER_LIBS) \
- $(LIBEDATABOOK_LIBS) \
+ $(LIBEDATABOOK_LIBS) \
$(LIBEBOOK_LIBS) \
$(DB_LIBS) \
$(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(SQLITE3_LIBS) \
+ $(SQLITE3_LIBS) \
$(SOUP_LIBS)
libebookbackendews_la_LDFLAGS = \
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index 340e7a7..45410c7 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -56,12 +56,15 @@
#include "e-ews-message.h"
#include "e-ews-connection.h"
#include "e-ews-item.h"
+#include <e-ews-query-to-restriction.h>
#define d(x) x
#define EDB_ERROR(_code) GNOME_Evolution_Addressbook_##_code
G_DEFINE_TYPE (EBookBackendEws, e_book_backend_ews, E_TYPE_BOOK_BACKEND)
+static gboolean ebews_fetch_items (EBookBackendEws *ebews, GSList *items, gboolean store_to_cache, GSList **vcards, GError **error);
+
typedef struct {
GCond *cond;
GMutex *mutex;
@@ -1158,18 +1161,18 @@ e_book_backend_ews_get_contact (EBookBackend *backend,
GCancellable *cancellable,
const gchar *id)
{
- EBookBackendEws *gwb;
+ EBookBackendEws *ebews;
- gwb = E_BOOK_BACKEND_EWS (backend);
+ ebews = E_BOOK_BACKEND_EWS (backend);
- switch (gwb->priv->mode) {
+ switch (ebews->priv->mode) {
case GNOME_Evolution_Addressbook_MODE_LOCAL :
e_data_book_respond_get_contact (book, opid, EDB_ERROR (ContactNotFound), "");
return;
case GNOME_Evolution_Addressbook_MODE_REMOTE :
- if (gwb->priv->cnc == NULL) {
+ if (ebews->priv->cnc == NULL) {
e_data_book_respond_get_contact (book, opid, EDB_ERROR (OtherError), NULL);
return;
}
@@ -1187,28 +1190,92 @@ e_book_backend_ews_get_contact_list (EBookBackend *backend,
GCancellable *cancellable,
const gchar *query )
{
- GList *vcard_list;
- EBookBackendEws *egwb;
+ GSList *vcard_list = NULL;
+ GSList *list, *l;
+ GError *error = NULL;
+ EBookBackendEws *ebews;
+ EBookBackendEwsPrivate *priv;
- egwb = E_BOOK_BACKEND_EWS (backend);
- vcard_list = NULL;
+ ebews = E_BOOK_BACKEND_EWS (backend);
+ priv = ebews->priv;
- switch (egwb->priv->mode) {
+ switch (priv->mode) {
case GNOME_Evolution_Addressbook_MODE_LOCAL :
- e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (Success), vcard_list);
- return;
+ if (e_book_backend_sqlitedb_get_is_populated (priv->ebsdb, priv->folder_id, NULL)) {
+ list = e_book_backend_sqlitedb_search (priv->ebsdb, priv->folder_id, query, NULL, NULL, NULL, &error);
+ l = list;
+ while (l) {
+ EbSdbSearchData *s_data = (EbSdbSearchData *) l->data;
+
+ vcard_list = g_slist_append (vcard_list, g_strdup (s_data->vcard));
+ e_book_backend_sqlitedb_search_data_free (s_data);
+ l = l->next;
+ }
+ e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (Success), (GList *) vcard_list);
+
+ g_slist_free (list);
+ g_slist_foreach (vcard_list, (GFunc) g_free, NULL);
+ g_slist_free (vcard_list);
+ return;
+ } else
+ e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (OfflineUnavailable), (GList *) vcard_list);
+ return;
case GNOME_Evolution_Addressbook_MODE_REMOTE:
- if (egwb->priv->cnc == NULL) {
+ if (priv->cnc == NULL) {
e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (AuthenticationRequired), NULL);
return;
}
- e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (Success), vcard_list);
+ if (e_book_backend_sqlitedb_get_is_populated (priv->ebsdb, priv->folder_id, NULL)) {
+ list = e_book_backend_sqlitedb_search (priv->ebsdb, priv->folder_id, query, NULL, NULL, NULL, &error);
+ l = list;
+ while (l) {
+ EbSdbSearchData *s_data = (EbSdbSearchData *) l->data;
+
+ vcard_list = g_slist_append (vcard_list, g_strdup (s_data->vcard));
+ e_book_backend_sqlitedb_search_data_free (s_data);
+ l = l->next;
+ }
+
+ e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (Success), (GList *) vcard_list);
+
+ g_slist_free (list);
+ g_slist_foreach (vcard_list, (GFunc) g_free, NULL);
+ g_slist_free (vcard_list);
+ return;
+
+ } else if (!priv->marked_for_offline) {
+ GSList *items=NULL;
+ EwsFolderId *fid=NULL;
+ gboolean includes_last_item;
+
+ fid = g_new0 (EwsFolderId, 1);
+ fid->id = g_strdup (priv->folder_id);
+ fid->is_distinguished_id = FALSE;
+
+ e_ews_connection_find_folder_items (priv->cnc, EWS_PRIORITY_MEDIUM,
+ fid, "IdOnly", NULL, NULL, query,
+ EWS_FOLDER_TYPE_CONTACTS,
+ &includes_last_item,
+ &items, (EwsConvertQueryCallback) (e_ews_query_to_restriction),
+ NULL, &error);
+
+ /*we have got Id for items lets fetch them using getitem operation*/
+ ebews_fetch_items (ebews, items, FALSE, &vcard_list, &error);
+ e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (Success), (GList *) vcard_list);
+
+ e_ews_folder_free_fid (fid);
+ g_slist_foreach (vcard_list, (GFunc) g_free, NULL);
+ g_slist_free (vcard_list);
+ return;
+ } else
+ e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (OtherError), (GList *) vcard_list);
return;
+
default :
break;
@@ -1724,6 +1791,38 @@ ebews_store_contact_items (EBookBackendEws *ebews, GSList *new_items, gboolean d
}
static void
+ebews_get_vcards_list (GSList *new_items, GSList **vcards)
+{
+ GSList *l;
+
+ for (l = new_items; l != NULL; l = g_slist_next (l)) {
+ EContact *contact;
+ gint i, element_type;
+ EEwsItem *item;
+ gchar *vcard_string=NULL;
+
+ item = (EEwsItem *) l->data;
+ contact = e_contact_new ();
+
+ for (i = 0; i < G_N_ELEMENTS (mappings); i++) {
+ element_type = mappings[i].element_type;
+ if (element_type == ELEMENT_TYPE_SIMPLE && !mappings [i].populate_contact_func) {
+ const char *val = mappings [i].get_simple_prop_func (item);
+ if (val != NULL)
+ e_contact_set (contact, mappings [i].field_id, val);
+ } else
+ mappings[i].populate_contact_func (contact, item);
+ }
+ vcard_string = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ *vcards = g_slist_append (*vcards, g_strdup(vcard_string));
+ g_free (vcard_string);
+ g_object_unref (item);
+ g_object_unref (contact);
+ }
+ g_slist_free (new_items);
+}
+
+static void
ews_mb_free (EwsMailbox *mb)
{
if (mb) {
@@ -1785,7 +1884,52 @@ ebews_store_distribution_list_items (EBookBackendEws *ebews, const EwsId *id, co
}
static void
-ebews_sync_items (EBookBackendEws *ebews, GSList *items, GError **error)
+ebews_vcards_append_dl (const EwsId *id, const gchar *d_name, GSList *members, GSList **vcards)
+{
+ GSList *l;
+ EContact *contact;
+ gchar *vcard_string=NULL;
+
+ contact = e_contact_new ();
+ e_contact_set (contact, E_CONTACT_UID, id->id);
+ e_contact_set (contact, E_CONTACT_REV, id->change_key);
+
+ e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE));
+ e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES, GINT_TO_POINTER (TRUE));
+ e_contact_set (contact, E_CONTACT_FULL_NAME, d_name);
+
+ for (l = members; l != NULL; l = g_slist_next (l)) {
+ EwsMailbox *mb = (EwsMailbox *) l->data;
+ EVCardAttribute *attr;
+
+ attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
+ if (mb->name) {
+ gint len = strlen (mb->name);
+ gchar *value;
+
+ if (mb->name [0] == '\"' && mb->name [len - 1] == '\"')
+ value = g_strdup_printf ("%s <%s>", mb->name, mb->email);
+ else
+ value = g_strdup_printf ("\"%s\" <%s>", mb->name, mb->email);
+
+ e_vcard_attribute_add_value (attr, value);
+ g_free (value);
+ } else
+ e_vcard_attribute_add_value (attr, mb->email);
+
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+ ews_mb_free (mb);
+ }
+ vcard_string = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ *vcards = g_slist_append (*vcards, g_strdup(vcard_string));
+ g_free (vcard_string);
+ g_slist_free (members);
+ g_object_unref (contact);
+}
+
+
+static gboolean
+ebews_fetch_items (EBookBackendEws *ebews, GSList *items, gboolean store_to_cache, GSList **vcards, GError **error)
{
EBookBackendEwsPrivate *priv;
EEwsConnection *cnc;
@@ -1822,8 +1966,12 @@ ebews_sync_items (EBookBackendEws *ebews, GSList *items, GError **error)
if (*error)
goto cleanup;
- if (new_items)
- ebews_store_contact_items (ebews, new_items, FALSE, error);
+ if (new_items) {
+ if (store_to_cache)
+ ebews_store_contact_items (ebews, new_items, FALSE, error);
+ else
+ ebews_get_vcards_list (new_items, vcards);
+ }
new_items = NULL;
/* Get the display names of the distribution lists */
@@ -1856,8 +2004,12 @@ ebews_sync_items (EBookBackendEws *ebews, GSList *items, GError **error)
e_ews_connection_expand_dl (cnc, EWS_PRIORITY_MEDIUM, mb, &members, &includes_last, NULL, error);
if (*error)
goto cleanup;
+
+ if (store_to_cache)
+ ebews_store_distribution_list_items (ebews, id, d_name, members, error);
+ else
+ ebews_vcards_append_dl (id, d_name, members, vcards);
- ebews_store_distribution_list_items (ebews, id, d_name, members, error);
g_free (mb);
if (*error)
@@ -1879,6 +2031,8 @@ cleanup:
g_slist_foreach (contact_item_ids, (GFunc) g_free, NULL);
g_slist_free (contact_item_ids);
}
+
+ return TRUE;
}
static gboolean
@@ -1919,7 +2073,7 @@ ebews_start_sync (gpointer data)
ebews_sync_deleted_items (ebews, items_deleted, &error);
if (items_created)
- ebews_sync_items (ebews, items_created, &error);
+ ebews_fetch_items (ebews, items_created, TRUE, NULL, &error);
if (error) {
if (items_updated) {
@@ -1931,7 +2085,7 @@ ebews_start_sync (gpointer data)
}
if (items_updated)
- ebews_sync_items (ebews, items_updated, &error);
+ ebews_fetch_items (ebews, items_updated, TRUE, NULL, &error);
if (error)
break;
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 67cda45..b4c49bb 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -97,6 +97,7 @@ struct _EwsAsyncData {
GSList *items_updated;
GSList *items_deleted;
+ gint total_items;
const gchar *directory;
GSList *items;
gchar *sync_state;
@@ -578,6 +579,38 @@ get_folder_response_cb (ESoapParameter *subparam, EwsNode *enode)
}
}
+static void
+find_folder_items_response_cb (ESoapParameter *subparam, EwsNode *enode)
+{
+ ESoapParameter *node, *subparam1;
+ EwsAsyncData *async_data;
+ gchar *last, *total;
+ gint total_items;
+ EEwsItem *item;
+ gboolean includes_last_item = FALSE;
+
+ node = e_soap_parameter_get_first_child_by_name (subparam, "RootFolder");
+ total = e_soap_parameter_get_property (node, "TotalItemsInView");
+ total_items = atoi (total);
+ g_free (total);
+ last = e_soap_parameter_get_property (node, "IncludesLastItemInRange");
+ if (!strcmp (last, "true"))
+ includes_last_item = TRUE;
+ g_free (last);
+
+ async_data = g_simple_async_result_get_op_res_gpointer (enode->simple);
+
+ node = e_soap_parameter_get_first_child_by_name (node, "Items");
+ for (subparam1 = e_soap_parameter_get_first_child (node);
+ subparam1; subparam1 = e_soap_parameter_get_next_child (subparam1)) {
+ item = e_ews_item_new_from_soap_parameter (subparam1);
+ if (!item) continue;
+ async_data->items = g_slist_append (async_data->items, item);
+ }
+ async_data->total_items = total_items;
+ async_data->includes_last_item = includes_last_item;
+}
+
/* Used for CreateItems and GetItems */
static void
get_items_response_cb (ESoapParameter *subparam, EwsNode *enode)
@@ -1938,6 +1971,47 @@ ews_append_additional_props_to_msg (ESoapMessage *msg, EwsAdditionalProps *add_p
e_soap_message_end_element (msg);
}
+static void
+ews_write_sort_order_to_msg (ESoapMessage *msg, EwsSortOrder *sort_order)
+{
+ if (!sort_order)
+ return;
+
+ e_soap_message_start_element (msg, "SortOrder", NULL, NULL);
+ e_soap_message_start_element (msg, "FieldOrder", NULL, NULL);
+ e_soap_message_add_attribute (msg, "Order", sort_order->order, NULL, NULL);
+
+ if (sort_order->uri_type == NORMAL_FIELD_URI)
+ e_ews_message_write_string_parameter_with_attribute (msg, "FieldURI", NULL, NULL, "FieldURI", (gchar *) sort_order->field_uri);
+ else if (sort_order->uri_type == INDEXED_FIELD_URI) {
+ EwsIndexedFieldURI *in_furi = (EwsIndexedFieldURI *) sort_order->field_uri;
+
+ e_soap_message_start_element (msg, "IndexedFieldURI", NULL, NULL);
+ e_soap_message_add_attribute (msg, "FieldURI", in_furi->field_uri, NULL, NULL);
+ e_soap_message_add_attribute (msg, "FieldIndex", in_furi->field_index, NULL, NULL);
+ e_soap_message_end_element (msg);
+ } else if (sort_order->uri_type == EXTENDED_FIELD_URI) {
+ EwsExtendedFieldURI *ex_furi = (EwsExtendedFieldURI *) sort_order->field_uri;
+
+ e_soap_message_start_element (msg, "ExtendedFieldURI", NULL, NULL);
+
+ if (ex_furi->distinguished_prop_set_id)
+ e_soap_message_add_attribute (msg, "DistinguishedPropertySetId", ex_furi->distinguished_prop_set_id, NULL, NULL);
+ if (ex_furi->prop_set_id)
+ e_soap_message_add_attribute (msg, "PropertySetId", ex_furi->prop_set_id, NULL, NULL);
+ if (ex_furi->prop_name)
+ e_soap_message_add_attribute (msg, "PropertyName", ex_furi->prop_name, NULL, NULL);
+ if (ex_furi->prop_id)
+ e_soap_message_add_attribute (msg, "PropertyId", ex_furi->prop_id, NULL, NULL);
+ if (ex_furi->prop_type)
+ e_soap_message_add_attribute (msg, "PropertyType", ex_furi->prop_type, NULL, NULL);
+
+ e_soap_message_end_element (msg);
+ }
+
+ e_soap_message_end_element (msg);
+ e_soap_message_end_element (msg);
+}
/**
* e_ews_connection_sync_folder_items_start
@@ -2114,6 +2188,148 @@ ews_append_folder_ids_to_msg (ESoapMessage *msg, const gchar *email, GSList *fol
}
}
+/**
+ * e_ews_connection_find_folder_items_start
+ * @cnc: The EWS Connection
+ * @pri: The priority associated with the request
+ * @fid: The folder id to which the items belong
+ * @default_props: Can take one of the values: IdOnly,Default or AllProperties
+ * @add_props: Specify any additional properties to be fetched
+ * @sort_order: Specific sorting order for items
+ * @query: evo query based on which items will be fetched
+ * @type: type of folder
+ * @convert_query_cb: a callback method to convert query to ews restiction
+ * @cb: Responses are parsed and returned to this callback
+ * @cancellable: a GCancellable to monitor cancelled operations
+ * @user_data: user data passed to callback
+ **/
+void
+e_ews_connection_find_folder_items_start (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *fid,
+ const gchar *default_props,
+ EwsAdditionalProps *add_props,
+ EwsSortOrder *sort_order,
+ const gchar *query,
+ EwsFolderType type,
+ EwsConvertQueryCallback convert_query_cb,
+ GAsyncReadyCallback cb,
+ GCancellable *cancellable,
+ gpointer user_data)
+{
+ ESoapMessage *msg;
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+
+ msg = e_ews_message_new_with_header (cnc->priv->uri, "FindItem", "Traversal", "Shallow", EWS_EXCHANGE_2007_SP1);
+ e_soap_message_start_element (msg, "ItemShape", "messages", NULL);
+ e_ews_message_write_string_parameter (msg, "BaseShape", NULL, default_props);
+
+ ews_append_additional_props_to_msg (msg, add_props);
+
+ e_soap_message_end_element (msg);
+
+ /*write restriction message based on query*/
+ if (convert_query_cb)
+ convert_query_cb (msg, query, type);
+
+ if (sort_order)
+ ews_write_sort_order_to_msg (msg, sort_order);
+
+ e_soap_message_start_element (msg, "ParentFolderIds", "messages", NULL);
+
+ if (fid->is_distinguished_id)
+ e_ews_message_write_string_parameter_with_attribute (msg, "DistinguishedFolderId", NULL, NULL, "Id", fid->id);
+ else
+ e_ews_message_write_string_parameter_with_attribute (msg, "FolderId", NULL, NULL, "Id", fid->id);
+
+ e_soap_message_end_element (msg);
+
+ /* Complete the footer and print the request */
+ e_ews_message_write_footer (msg);
+
+ simple = g_simple_async_result_new (G_OBJECT (cnc),
+ cb,
+ user_data,
+ e_ews_connection_find_folder_items_start);
+
+ async_data = g_new0 (EwsAsyncData, 1);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_data, (GDestroyNotify) async_data_free);
+
+ ews_connection_queue_request (cnc, msg, find_folder_items_response_cb, pri,
+ cancellable, simple, cb == ews_sync_reply_cb);
+}
+
+gboolean
+e_ews_connection_find_folder_items_finish (EEwsConnection *cnc,
+ GAsyncResult *result,
+ gboolean *includes_last_item,
+ GSList **items,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ EwsAsyncData *async_data;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (cnc), e_ews_connection_find_folder_items_start),
+ FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_data = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ *includes_last_item = async_data->includes_last_item;
+ *items = async_data->items;
+
+ return TRUE;
+}
+
+gboolean
+e_ews_connection_find_folder_items (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *fid,
+ const gchar *default_props,
+ EwsAdditionalProps *add_props,
+ EwsSortOrder *sort_order,
+ const gchar *query,
+ EwsFolderType type,
+ gboolean *includes_last_item,
+ GSList **items,
+ EwsConvertQueryCallback convert_query_cb,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EwsSyncData *sync_data;
+ gboolean result;
+
+ sync_data = g_new0 (EwsSyncData, 1);
+ sync_data->eflag = e_flag_new ();
+
+ e_ews_connection_find_folder_items_start (cnc, pri, fid, default_props,
+ add_props, sort_order, query,
+ type, convert_query_cb,
+ ews_sync_reply_cb, NULL,
+ (gpointer) sync_data);
+
+ e_flag_wait (sync_data->eflag);
+
+ result = e_ews_connection_find_folder_items_finish (cnc, sync_data->res,
+ includes_last_item,
+ items,
+ error);
+
+ e_flag_free (sync_data->eflag);
+ g_object_unref (sync_data->res);
+ g_free (sync_data);
+
+ return result;
+}
+
+
void
e_ews_connection_sync_folder_hierarchy_start (EEwsConnection *cnc,
gint pri,
@@ -3276,7 +3492,7 @@ e_ews_connection_move_folder (EEwsConnection *cnc,
}
-void
+void
e_ews_connection_get_folder_start (EEwsConnection *cnc,
gint pri,
const gchar *folder_shape,
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index a2eb33a..60e1465 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -138,6 +138,11 @@ typedef struct{
gboolean view_priv_items;
}EwsDelegateInfo;
+typedef enum {
+ NORMAL_FIELD_URI,
+ INDEXED_FIELD_URI,
+ EXTENDED_FIELD_URI
+} EwsFieldURIType;
typedef struct {
gchar *distinguished_prop_set_id;
@@ -159,6 +164,12 @@ typedef struct {
GSList *indexed_furis;
} EwsAdditionalProps;
+typedef struct {
+ gchar *order;
+ gint uri_type;
+ gpointer field_uri;
+} EwsSortOrder;
+
GType e_ews_connection_get_type (void);
EEwsConnection *e_ews_connection_new (const gchar *uri,
const gchar *username,
@@ -223,6 +234,47 @@ gboolean e_ews_connection_sync_folder_items
GCancellable *cancellable,
GError **error);
+typedef void (*EwsConvertQueryCallback) (ESoapMessage *msg,
+ const gchar *query,
+ EwsFolderType type);
+
+void e_ews_connection_find_folder_items_start
+ (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *fid,
+ const gchar *props,
+ EwsAdditionalProps *add_props,
+ EwsSortOrder *sort_order,
+ const gchar *query,
+ EwsFolderType type,
+ EwsConvertQueryCallback convert_query_cb,
+ GAsyncReadyCallback cb,
+ GCancellable *cancellable,
+ gpointer user_data);
+
+gboolean e_ews_connection_find_folder_items_finish
+ (EEwsConnection *cnc,
+ GAsyncResult *result,
+ gboolean *includes_last_item,
+ GSList **items,
+ GError **error);
+
+gboolean e_ews_connection_find_folder_items
+ (EEwsConnection *cnc,
+ gint pri,
+ EwsFolderId *fid,
+ const gchar *default_props,
+ EwsAdditionalProps *add_props,
+ EwsSortOrder *sort_order,
+ const gchar *query,
+ EwsFolderType type,
+ gboolean *includes_last_item,
+ GSList **items,
+ EwsConvertQueryCallback convert_query_cb,
+ GCancellable *cancellable,
+ GError **error);
+
+
/* Get folder items */
void e_ews_connection_get_items_start
(EEwsConnection *cnc,
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index 429e37b..508e549 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -862,56 +862,77 @@ static gboolean
e_ews_item_set_from_soap_parameter (EEwsItem *item, ESoapParameter *param)
{
EEwsItemPrivate *priv = item->priv;
- ESoapParameter *subparam, *node;
+ ESoapParameter *subparam, *node=NULL;
gboolean contact = FALSE, task = FALSE;
+ const gchar *name;
g_return_val_if_fail (param != NULL, FALSE);
- if ((node = e_soap_parameter_get_first_child_by_name (param, "AttachmentId"))) {
- priv->attachment_id = g_new0 (EwsId, 1);
- priv->attachment_id->id = e_soap_parameter_get_property (node, "Id");
- priv->attachment_id->change_key = e_soap_parameter_get_property (node, "ChangeKey");
- } else if ((node = e_soap_parameter_get_first_child_by_name (param, "ItemId"))) {
- /*Spesial case when we are facing <ReadFlagChange> during sync folders*/
- priv->item_id = g_new0 (EwsId, 1);
- priv->item_id->id = e_soap_parameter_get_property (node, "Id");
- priv->item_id->change_key = e_soap_parameter_get_property (node, "ChangeKey");
- return TRUE;
- } else if ((node = e_soap_parameter_get_first_child_by_name (param, "Message")))
+ name = e_soap_parameter_get_name (param);
+
+ /*We get two types of response for items from server like below from two apis
+ * Syncfolderitems and Finditem
+ * <m:Changes> <t:Items>
+ <t:Create> <t:Contact>
+ <t:Contact> <t:ItemId Id="AS4AUn=" ChangeKey="fsVU4==" />
+ <t:ItemId Id="AAA=" ChangeKey="NAgws"/> </t:Contact>
+ </t:Contact> <t:Contact>
+ </t:Create> <t:ItemId Id="AS4BS=" ChangeKey="fjidU4==" />
+ <t:Contact> </t:Contact>
+ <t:ItemId Id="ABB=" ChangeKey="GCDab"/> ...
+ </t:Contact> </t:Items>
+ </t:Create>
+ ...
+ </m:Changes>
+ So check param is the node we want to use, by comparing name or is it child of the param */
+
+ if (!g_ascii_strcasecmp (name, "Message") || (node = e_soap_parameter_get_first_child_by_name (param, "Message")))
priv->item_type = E_EWS_ITEM_TYPE_MESSAGE;
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "PostItem")))
+ else if (!g_ascii_strcasecmp (name, "PostItem") || (node = e_soap_parameter_get_first_child_by_name (param, "PostItem")))
priv->item_type = E_EWS_ITEM_TYPE_POST_ITEM;
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "CalendarItem")))
+ else if (!g_ascii_strcasecmp (name, "CalendarItem") || (node = e_soap_parameter_get_first_child_by_name (param, "CalendarItem")))
priv->item_type = E_EWS_ITEM_TYPE_CALENDAR_ITEM;
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "Contact"))) {
+ else if (!g_ascii_strcasecmp (name, "Contact") || (node = e_soap_parameter_get_first_child_by_name (param, "Contact"))) {
contact = TRUE;
priv->item_type = E_EWS_ITEM_TYPE_CONTACT;
priv->contact_fields = g_new0 (struct _EEwsContactFields, 1);
- } else if ((node = e_soap_parameter_get_first_child_by_name (param, "DistributionList")))
+ } else if (!g_ascii_strcasecmp (name, "DistributionList") || (node = e_soap_parameter_get_first_child_by_name (param, "DistributionList")))
priv->item_type = E_EWS_ITEM_TYPE_GROUP;
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "MeetingMessage")))
+ else if (!g_ascii_strcasecmp (name, "MeetingMessage") || (node = e_soap_parameter_get_first_child_by_name (param, "MeetingMessage")))
priv->item_type = E_EWS_ITEM_TYPE_MEETING_MESSAGE;
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "MeetingRequest")))
+ else if (!g_ascii_strcasecmp (name, "MeetingRequest") || (node = e_soap_parameter_get_first_child_by_name (param, "MeetingRequest")))
priv->item_type = E_EWS_ITEM_TYPE_MEETING_REQUEST;
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "MeetingResponse")))
+ else if (!g_ascii_strcasecmp (name, "MeetingResponse") || (node = e_soap_parameter_get_first_child_by_name (param, "MeetingResponse")))
priv->item_type = E_EWS_ITEM_TYPE_MEETING_RESPONSE;
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "MeetingCancellation")))
+ else if (!g_ascii_strcasecmp (name, "MeetingCancellation") || (node = e_soap_parameter_get_first_child_by_name (param, "MeetingCancellation")))
priv->item_type = E_EWS_ITEM_TYPE_MEETING_CANCELLATION;
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "Task"))) {
+ else if (!g_ascii_strcasecmp (name, "Task") || (node = e_soap_parameter_get_first_child_by_name (param, "Task"))) {
task = TRUE;
priv->item_type = E_EWS_ITEM_TYPE_TASK;
priv->task_fields = g_new0 (struct _EEwsTaskFields, 1);
priv->task_fields->has_due_date = FALSE;
priv->task_fields->has_start_date = FALSE;
priv->task_fields->has_complete_date = FALSE;
- }
- else if ((node = e_soap_parameter_get_first_child_by_name (param, "Item")))
+ } else if (!g_ascii_strcasecmp (name, "Item") || (node = e_soap_parameter_get_first_child_by_name (param, "Item")))
priv->item_type = E_EWS_ITEM_TYPE_GENERIC_ITEM;
- else {
+ else if ((node = e_soap_parameter_get_first_child_by_name (param, "AttachmentId"))) {
+ priv->attachment_id = g_new0 (EwsId, 1);
+ priv->attachment_id->id = e_soap_parameter_get_property (node, "Id");
+ priv->attachment_id->change_key = e_soap_parameter_get_property (node, "ChangeKey");
+ } else if ((node = e_soap_parameter_get_first_child_by_name (param, "ItemId"))) {
+ /*Spesial case when we are facing <ReadFlagChange> during sync folders*/
+ priv->item_id = g_new0 (EwsId, 1);
+ priv->item_id->id = e_soap_parameter_get_property (node, "Id");
+ priv->item_id->change_key = e_soap_parameter_get_property (node, "ChangeKey");
+ return TRUE;
+ } else {
g_warning ("Unable to find the Item type \n");
return FALSE;
}
+ if (!node)
+ node = param;
+
for (subparam = e_soap_parameter_get_first_child (node);
subparam != NULL;
subparam = e_soap_parameter_get_next_child (subparam)) {
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
index 947940a..a810ff1 100644
--- a/src/utils/Makefile.am
+++ b/src/utils/Makefile.am
@@ -10,7 +10,8 @@ libewsutils_la_CPPFLAGS = \
$(LIBEDATASERVER_CFLAGS) \
$(SQLITE3_CFLAGS) \
$(DEBUG_CFLAGS) \
- $(CAMEL_CFLAGS)
+ $(CAMEL_CFLAGS) \
+ $(LIBEDATACAL_CFLAGS)
libewsutils_la_SOURCES = \
ews-camel-compat.h \
@@ -20,14 +21,33 @@ libewsutils_la_SOURCES = \
e-sqlite3-vfs.c \
e-sqlite3-vfs.h \
ews-camel-common.c \
- ews-camel-common.h
+ ews-camel-common.h \
+ e-ews-query-to-restriction.c \
+ e-ews-query-to-restriction.h
libewsutils_la_LIBADD = \
$(top_builddir)/src/server/libeews-1.2.la \
- $(SQLITE3_LIBS) \
+ $(SQLITE3_LIBS) \
$(LIBEDATASERVER_LIBS) \
- $(CAMEL_LIBS)
+ $(CAMEL_LIBS) \
+ $(LIBEDATACAL_LIBS)
libewsutils_la_LDFLAGS = $(NO_UNDEFINED)
+noinst_PROGRAMS = ews-test-finditem-query
+
+TESTS = ews-test-finditem-query
+check_PROGRAMS = ews-test-finditem-query
+
+ews_test_finditem_query_CPPFLAGS = \
+ $(libewsutils_la_CPPFLAGS)
+
+ews_test_finditem_query_SOURCES = \
+ ews-test-finditem-query.c \
+ e-ews-query-to-restriction.c \
+ e-ews-query-to-restriction.h
+
+ews_test_finditem_query_LDADD = \
+ $(libewsutils_la_LIBADD)
+
-include $(top_srcdir)/git.mk
diff --git a/src/utils/e-ews-query-to-restriction.c b/src/utils/e-ews-query-to-restriction.c
index b7d3f06..4bb18cb 100644
--- a/src/utils/e-ews-query-to-restriction.c
+++ b/src/utils/e-ews-query-to-restriction.c
@@ -665,7 +665,7 @@ message_func_system_flag (ESExp *f,
WRITE_EXISTS_MESSAGE (msg, "item:HasAttachments")
} else if (!g_ascii_strcasecmp(name, "deleted") || !g_ascii_strcasecmp(name, "junk")) {
r = e_sexp_result_new (f, ESEXP_RES_BOOL);
- r->value.boolean = FALSE;
+ r->value.bool = FALSE;
return r;
}
}
@@ -717,6 +717,23 @@ message_func_current_date (ESExp *f,
return r;
}
+/* slightly modified version from master */
+static time_t
+ews_add_months (time_t t,
+ gint months)
+{
+ time_t res;
+
+ if (!months)
+ return t;
+
+ /* just for issues, to return something inaccurate, but sane */
+ res = t + (60 * 60 * 24 * 30 * months);
+
+ return res;
+}
+
+
static ESExpResult *
message_func_relative_months (ESExp *f,
gint argc,
@@ -728,11 +745,11 @@ message_func_relative_months (ESExp *f,
if (argc != 1 || argv[0]->type != ESEXP_RES_INT) {
r = e_sexp_result_new (f, ESEXP_RES_BOOL);
- r->value.boolean = FALSE;
+ r->value.bool = FALSE;
} else {
r = e_sexp_result_new (f, ESEXP_RES_INT);
- r->value.number = camel_folder_search_util_add_months (time (NULL), argv[0]->value.number);
+ r->value.number = ews_add_months (time (NULL), argv[0]->value.number);
}
return r;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]