[evolution-ews/wip/mcrha/office365] Implement e_o365_connection_get_folders_delta_sync()
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/mcrha/office365] Implement e_o365_connection_get_folders_delta_sync()
- Date: Tue, 9 Jun 2020 16:36:25 +0000 (UTC)
commit 672c4532752eb0037410468bea05474f4bdec825
Author: Milan Crha <mcrha redhat com>
Date: Tue Jun 9 18:39:59 2020 +0200
Implement e_o365_connection_get_folders_delta_sync()
src/Office365/common/e-o365-connection.c | 106 ++++++++++++++++++---
src/Office365/common/e-o365-connection.h | 10 ++
src/Office365/common/e-o365-json-utils.c | 8 ++
src/Office365/common/e-o365-json-utils.h | 2 +
.../evolution/e-mail-config-o365-backend.c | 30 ++++--
5 files changed, 136 insertions(+), 20 deletions(-)
---
diff --git a/src/Office365/common/e-o365-connection.c b/src/Office365/common/e-o365-connection.c
index adda8909..2da65b34 100644
--- a/src/Office365/common/e-o365-connection.c
+++ b/src/Office365/common/e-o365-connection.c
@@ -17,6 +17,7 @@
#include "evolution-ews-config.h"
+#include <string.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <json-glib/json-glib.h>
@@ -1162,22 +1163,28 @@ e_o365_construct_uri (EO365Connection *cnc,
return g_string_free (uri, FALSE);
}
+typedef struct _EO365ResponseData {
+ GSList **out_items; /* JsonObject * */
+ gchar **out_delta_link; /* set only if available and not NULL */
+} EO365ResponseData;
+
static gboolean
-e_o365_list_folders_response_cb (EO365Connection *cnc,
- SoupMessage *message,
- GInputStream *input_stream,
- JsonNode *node,
- gpointer user_data,
- gchar **out_next_link,
- GCancellable *cancellable,
- GError **error)
+e_o365_read_valued_response_cb (EO365Connection *cnc,
+ SoupMessage *message,
+ GInputStream *input_stream,
+ JsonNode *node,
+ gpointer user_data,
+ gchar **out_next_link,
+ GCancellable *cancellable,
+ GError **error)
{
+ EO365ResponseData *response_data = user_data;
JsonObject *object;
JsonArray *value;
- GSList **out_folders = user_data;
+ const gchar *delta_link;
guint ii, len;
- g_return_val_if_fail (out_folders != NULL, FALSE);
+ g_return_val_if_fail (response_data != NULL, FALSE);
g_return_val_if_fail (out_next_link != NULL, FALSE);
g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node), FALSE);
@@ -1186,6 +1193,11 @@ e_o365_list_folders_response_cb (EO365Connection *cnc,
*out_next_link = g_strdup (e_o365_json_get_string_member (object, "@odata.nextLink", NULL));
+ delta_link = e_o365_json_get_string_member (object, "@odata.deltaLink", NULL);
+
+ if (delta_link && response_data->out_delta_link)
+ *response_data->out_delta_link = g_strdup (delta_link);
+
value = e_o365_json_get_array_member (object, "value");
g_return_val_if_fail (value != NULL, FALSE);
@@ -1200,7 +1212,7 @@ e_o365_list_folders_response_cb (EO365Connection *cnc,
JsonObject *elem_object = json_node_get_object (elem);
if (elem_object)
- *out_folders = g_slist_prepend (*out_folders, json_object_ref (elem_object));
+ *response_data->out_items = g_slist_prepend (*response_data->out_items,
json_object_ref (elem_object));
}
}
@@ -1216,6 +1228,7 @@ e_o365_connection_list_folders_sync (EO365Connection *cnc,
GCancellable *cancellable,
GError **error)
{
+ EO365ResponseData rd;
SoupMessage *message;
gchar *uri;
gboolean success;
@@ -1240,7 +1253,76 @@ e_o365_connection_list_folders_sync (EO365Connection *cnc,
g_free (uri);
- success = o365_connection_send_request_sync (cnc, message, e_o365_list_folders_response_cb,
out_folders, cancellable, error);
+ memset (&rd, 0, sizeof (EO365ResponseData));
+
+ rd.out_items = out_folders;
+
+ success = o365_connection_send_request_sync (cnc, message, e_o365_read_valued_response_cb, &rd,
cancellable, error);
+
+ g_clear_object (&message);
+
+ return success;
+}
+
+gboolean
+e_o365_connection_get_folders_delta_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the
account user */
+ const gchar *select, /* fields to select, nullable */
+ const gchar *delta_link, /* previous delta link */
+ guint max_page_size, /* 0 for default by the server */
+ gchar **out_delta_link,
+ GSList **out_folders, /* JsonObject * - the returned mailFolder
objects */
+ GCancellable *cancellable,
+ GError **error)
+{
+ EO365ResponseData rd;
+ SoupMessage *message = NULL;
+ gboolean success;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (out_delta_link != NULL, FALSE);
+ g_return_val_if_fail (out_folders != NULL, FALSE);
+
+ if (delta_link)
+ message = soup_message_new (SOUP_METHOD_GET, delta_link);
+
+ if (!message) {
+ gchar *uri;
+
+ uri = e_o365_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "mailFolders",
+ "delta",
+ "$select", select,
+ NULL);
+
+ message = soup_message_new (SOUP_METHOD_GET, uri);
+
+ if (!message) {
+ g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: ā%sā"),
uri);
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+ }
+
+ if (max_page_size > 0) {
+ gchar *prefer_value;
+
+ prefer_value = g_strdup_printf ("odata.maxpagesize=%u", max_page_size);
+
+ soup_message_headers_append (message->request_headers, "Prefer", prefer_value);
+
+ g_free (prefer_value);
+ }
+
+ memset (&rd, 0, sizeof (EO365ResponseData));
+
+ rd.out_items = out_folders;
+ rd.out_delta_link = out_delta_link;
+
+ success = o365_connection_send_request_sync (cnc, message, e_o365_read_valued_response_cb, &rd,
cancellable, error);
g_clear_object (&message);
diff --git a/src/Office365/common/e-o365-connection.h b/src/Office365/common/e-o365-connection.h
index f16145d9..566d3c01 100644
--- a/src/Office365/common/e-o365-connection.h
+++ b/src/Office365/common/e-o365-connection.h
@@ -101,6 +101,16 @@ gboolean e_o365_connection_list_folders_sync
GSList **out_folders, /* JsonObject * - the returned
mailFolder objects */
GCancellable *cancellable,
GError **error);
+gboolean e_o365_connection_get_folders_delta_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const gchar *select, /* fields to select, nullable */
+ const gchar *delta_link, /* previous delta link */
+ guint max_page_size, /* 0 for default by the server */
+ gchar **out_delta_link,
+ GSList **out_folders, /* JsonObject * - the returned
mailFolder objects */
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
diff --git a/src/Office365/common/e-o365-json-utils.c b/src/Office365/common/e-o365-json-utils.c
index 0a02b15f..4cd74854 100644
--- a/src/Office365/common/e-o365-json-utils.c
+++ b/src/Office365/common/e-o365-json-utils.c
@@ -159,6 +159,14 @@ e_o365_json_get_string_member (JsonObject *object,
return json_node_get_string (node);
}
+/* https://docs.microsoft.com/en-us/graph/delta-query-overview */
+
+gboolean
+e_o365_delta_is_removed_object (JsonObject *object)
+{
+ return json_object_has_member (object, "@removed");
+}
+
/* https://docs.microsoft.com/en-us/graph/api/resources/mailfolder?view=graph-rest-1.0 */
const gchar *
diff --git a/src/Office365/common/e-o365-json-utils.h b/src/Office365/common/e-o365-json-utils.h
index 5cc2e886..f1ed0300 100644
--- a/src/Office365/common/e-o365-json-utils.h
+++ b/src/Office365/common/e-o365-json-utils.h
@@ -42,6 +42,8 @@ const gchar * e_o365_json_get_string_member (JsonObject *object,
const gchar *member_name,
const gchar *default_value);
+gboolean e_o365_delta_is_removed_object (JsonObject *object);
+
const gchar * e_o365_mail_folder_get_display_name (JsonObject *object);
const gchar * e_o365_mail_folder_get_id (JsonObject *object);
const gchar * e_o365_mail_folder_get_parent_folder_id (JsonObject *object);
diff --git a/src/Office365/evolution/e-mail-config-o365-backend.c
b/src/Office365/evolution/e-mail-config-o365-backend.c
index e677fd8c..18394184 100644
--- a/src/Office365/evolution/e-mail-config-o365-backend.c
+++ b/src/Office365/evolution/e-mail-config-o365-backend.c
@@ -91,6 +91,9 @@ test_clicked_cb (GtkButton *button,
ESource *source;
EO365Connection *cnc;
GSList *folders = NULL, *link;
+ gboolean success;
+ static gchar *delta_link = NULL;
+ gchar *new_delta_link = NULL;
GError *error = NULL;
settings = e_mail_config_service_backend_get_settings (backend);
@@ -99,7 +102,15 @@ test_clicked_cb (GtkButton *button,
cnc = e_o365_connection_new (source, CAMEL_O365_SETTINGS (settings));
g_return_if_fail (cnc != NULL);
- if (!e_o365_connection_list_folders_sync (cnc, NULL, NULL, NULL, &folders, NULL, &error)) {
+ //success = e_o365_connection_list_folders_sync (cnc, NULL, NULL, NULL, &folders, NULL, &error);
+ success = e_o365_connection_get_folders_delta_sync (cnc, NULL, NULL, delta_link, 0, &new_delta_link,
&folders, NULL, &error);
+
+ if (success) {
+ g_free (delta_link);
+ delta_link = new_delta_link;
+ }
+
+ if (!success) {
printf ("%s: failed with error: %s\n", __FUNCTION__, error ? error->message : "none");
} else {
if (error) {
@@ -111,13 +122,16 @@ test_clicked_cb (GtkButton *button,
for (link = folders; link; link = g_slist_next (link)) {
JsonObject *folder = link->data;
- printf (" %p: '%s' childCount:%d total:%d unread:%d id:'%s' parent:'%s'\n", folder,
- e_o365_mail_folder_get_display_name (folder),
- e_o365_mail_folder_get_child_folder_count (folder),
- e_o365_mail_folder_get_total_item_count (folder),
- e_o365_mail_folder_get_unread_item_count (folder),
- e_o365_mail_folder_get_id (folder),
- e_o365_mail_folder_get_parent_folder_id (folder));
+ if (e_o365_delta_is_removed_object (folder))
+ printf (" %p: removed folder id:'%s'\n", folder, e_o365_mail_folder_get_id
(folder));
+ else
+ printf (" %p: '%s' childCount:%d total:%d unread:%d id:'%s' parent:'%s'\n",
folder,
+ e_o365_mail_folder_get_display_name (folder),
+ e_o365_mail_folder_get_child_folder_count (folder),
+ e_o365_mail_folder_get_total_item_count (folder),
+ e_o365_mail_folder_get_unread_item_count (folder),
+ e_o365_mail_folder_get_id (folder),
+ e_o365_mail_folder_get_parent_folder_id (folder));
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]