[evolution-ews/wip/mcrha/office365: 15/50] Implement e_o365_connection_get_folders_delta_sync()




commit 7ed1c0c0dc5150f82dadb41fa1e060242fba0a4a
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]