[evolution-ews/wip/mcrha/office365] Implement rename and delete of mail folders
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/mcrha/office365] Implement rename and delete of mail folders
- Date: Thu, 25 Jun 2020 14:02:46 +0000 (UTC)
commit d4931e8faf6067fdaed9f6c0b711d8ec0bdb5a95
Author: Milan Crha <mcrha redhat com>
Date: Thu Jun 25 16:02:11 2020 +0200
Implement rename and delete of mail folders
src/Office365/camel/camel-o365-store-summary.c | 8 +-
src/Office365/camel/camel-o365-store.c | 339 ++++++++++++++++++++-
src/Office365/common/e-o365-connection.c | 216 ++++++++++++-
src/Office365/common/e-o365-connection.h | 23 ++
src/Office365/common/e-o365-json-utils.h | 14 +-
.../evolution/e-mail-config-o365-backend.c | 63 ----
6 files changed, 564 insertions(+), 99 deletions(-)
---
diff --git a/src/Office365/camel/camel-o365-store-summary.c b/src/Office365/camel/camel-o365-store-summary.c
index 619f01ac..246331f0 100644
--- a/src/Office365/camel/camel-o365-store-summary.c
+++ b/src/Office365/camel/camel-o365-store-summary.c
@@ -840,7 +840,7 @@ camel_o365_store_summary_set_folder_display_name (CamelO365StoreSummary *store_s
rpd.prefix_len = strlen (old_full_name);
rpd.removed = NULL;
- g_hash_table_foreach_remove (store_summary->priv->id_full_name_hash,
o365_remove_prefixed_cb, &rpd);
+ g_hash_table_foreach_steal (store_summary->priv->id_full_name_hash,
o365_remove_prefixed_cb, &rpd);
new_full_name = o365_store_summary_build_new_full_name (old_full_name,
display_name);
diff = strlen (new_full_name) - rpd.prefix_len;
@@ -1162,10 +1162,10 @@ o365_store_summary_gather_folder_infos (gpointer key,
g_return_if_fail (gid != NULL);
if (!gid->prefix_len || (g_str_has_prefix (full_name, gid->prefix) &&
- full_name[gid->prefix_len] == '/')) {
+ (full_name[gid->prefix_len] == '/' || !full_name[gid->prefix_len]))) {
const gchar *without_prefix = full_name + gid->prefix_len + (gid->prefix_len > 0 ? 1 : 0);
- if (gid->recursive || !strchr (without_prefix, '/')) {
+ if (gid->recursive || !*without_prefix) {
CamelFolderInfo *info;
info = camel_o365_store_summary_build_folder_info_for_id (gid->store_summary, id);
@@ -1201,7 +1201,7 @@ camel_o365_store_summary_build_folder_info (CamelO365StoreSummary *store_summary
g_hash_table_foreach (store_summary->priv->id_full_name_hash, o365_store_summary_gather_folder_infos,
&gid);
- info = camel_folder_info_build (gid.folder_infos, NULL, '/', TRUE);
+ info = camel_folder_info_build (gid.folder_infos, top, '/', TRUE);
UNLOCK (store_summary);
diff --git a/src/Office365/camel/camel-o365-store.c b/src/Office365/camel/camel-o365-store.c
index adf925f8..a648b2fe 100644
--- a/src/Office365/camel/camel-o365-store.c
+++ b/src/Office365/camel/camel-o365-store.c
@@ -404,8 +404,8 @@ o365_store_get_folder_sync (CamelStore *store,
}
static void
-o365_store_save_summary_locked (CamelO365StoreSummary *summary,
- const gchar *where)
+o365_store_save_summary (CamelO365StoreSummary *summary,
+ const gchar *where)
{
GError *error = NULL;
@@ -502,13 +502,336 @@ o365_store_create_folder_sync (CamelStore *store,
json_object_unref (mail_folder);
- LOCK (o365_store);
- o365_store_save_summary_locked (o365_store->priv->summary, G_STRFUNC);
- UNLOCK (o365_store);
+ o365_store_save_summary (o365_store->priv->summary, G_STRFUNC);
return fi;
}
+static void
+o365_store_notify_created_recursive (CamelStore *store,
+ CamelFolderInfo *folder_info)
+{
+ while (folder_info) {
+ camel_store_folder_created (store, folder_info);
+ camel_subscribable_folder_subscribed (CAMEL_SUBSCRIBABLE (store), folder_info);
+
+ if (folder_info->child)
+ o365_store_notify_created_recursive (store, folder_info->child);
+
+ folder_info = folder_info->next;
+ }
+}
+
+static gboolean
+o365_store_move_mail_folder (CamelO365Store *o365_store,
+ EO365Connection *cnc,
+ const gchar *folder_id,
+ const gchar *des_folder_id,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EO365MailFolder *moved_mail_folder = NULL;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE (o365_store), FALSE);
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (folder_id != NULL, FALSE);
+ g_return_val_if_fail (des_folder_id != NULL, FALSE);
+ g_return_val_if_fail (g_strcmp0 (folder_id, des_folder_id) != 0, FALSE);
+
+ success = e_o365_connection_copy_move_mail_folder_sync (cnc, NULL, folder_id, des_folder_id, FALSE,
&moved_mail_folder, cancellable, error);
+
+ if (success && moved_mail_folder) {
+ CamelFolderInfo *fi;
+ gchar *new_full_name;
+
+ fi = camel_o365_store_summary_build_folder_info_for_id (o365_store->priv->summary, folder_id);
+
+ camel_o365_store_summary_set_folder_parent_id (o365_store->priv->summary, folder_id,
e_o365_mail_folder_get_parent_folder_id (moved_mail_folder));
+ camel_o365_store_summary_rebuild_hashes (o365_store->priv->summary);
+
+ camel_subscribable_folder_unsubscribed (CAMEL_SUBSCRIBABLE (o365_store), fi);
+ camel_store_folder_deleted (CAMEL_STORE (o365_store), fi);
+
+ camel_folder_info_free (fi);
+
+ new_full_name = camel_o365_store_summary_dup_folder_full_name (o365_store->priv->summary,
folder_id);
+ g_warn_if_fail (new_full_name != NULL);
+
+ fi = camel_o365_store_summary_build_folder_info (o365_store->priv->summary, new_full_name,
TRUE);
+
+ o365_store_notify_created_recursive (CAMEL_STORE (o365_store), fi);
+
+ json_object_unref (moved_mail_folder);
+ camel_folder_info_free (fi);
+ g_free (new_full_name);
+ }
+
+ return success;
+}
+
+static void
+o365_store_delete_folders_from_summary_recursive (CamelO365Store *o365_store,
+ CamelFolderInfo *fi,
+ gboolean send_signals)
+{
+ CamelStore *store = send_signals ? CAMEL_STORE (o365_store) : NULL;
+ CamelSubscribable *subscribable = send_signals ? CAMEL_SUBSCRIBABLE (o365_store) : NULL;
+
+ while (fi) {
+ gchar *folder_id;
+
+ if (fi->child)
+ o365_store_delete_folders_from_summary_recursive (o365_store, fi->child,
send_signals);
+
+ folder_id = camel_o365_store_summary_dup_folder_id_for_full_name (o365_store->priv->summary,
fi->full_name);
+ if (folder_id) {
+ camel_o365_store_summary_remove_folder (o365_store->priv->summary, folder_id);
+ g_free (folder_id);
+ }
+
+ if (send_signals) {
+ camel_subscribable_folder_unsubscribed (subscribable, fi);
+ camel_store_folder_deleted (store, fi);
+ }
+
+ fi = fi->next;
+ }
+}
+
+static gboolean
+o365_store_delete_folder_sync (CamelStore *store,
+ const gchar *folder_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelO365Store *o365_store;
+ CamelFolderInfo *folder_info;
+ EO365Connection *cnc = NULL;
+ gchar *folder_id;
+ gchar *trash_folder_id;
+ gchar *trash_full_name;
+ gboolean success;
+ gboolean is_under_trash_folder, claim_unsubscribe = TRUE;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE (store), FALSE);
+
+ o365_store = CAMEL_O365_STORE (store);
+
+ folder_info = camel_store_get_folder_info_sync (store, folder_name,
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
+ cancellable, &local_error);
+
+ if (!folder_info) {
+ if (local_error)
+ g_propagate_error (error, local_error);
+
+ return FALSE;
+ }
+
+ folder_id = camel_o365_store_summary_dup_folder_id_for_full_name (o365_store->priv->summary,
folder_name);
+
+ if (!folder_id) {
+ camel_folder_info_free (folder_info);
+
+ g_set_error_literal (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Folder does not exist"));
+
+ return FALSE;
+ }
+
+ trash_folder_id = camel_o365_store_summary_dup_folder_id_for_type (o365_store->priv->summary,
CAMEL_FOLDER_TYPE_TRASH);
+ trash_full_name = camel_o365_store_summary_dup_folder_full_name (o365_store->priv->summary,
trash_folder_id);
+
+ if (!trash_full_name) {
+ camel_folder_info_free (folder_info);
+ g_free (trash_folder_id);
+ g_free (folder_id);
+
+ g_set_error_literal (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Cannot find “Deleted Items”
folder"));
+
+ return FALSE;
+ }
+
+ is_under_trash_folder = g_str_has_prefix (folder_name, trash_full_name);
+
+ if (is_under_trash_folder) {
+ gint len = strlen (trash_full_name);
+
+ is_under_trash_folder = len > 0 && (trash_full_name[len - 1] == '/' || folder_name[len] ==
'/');
+ }
+
+ g_free (trash_full_name);
+
+ if (!camel_o365_store_ensure_connected (o365_store, &cnc, cancellable, error)) {
+ camel_folder_info_free (folder_info);
+ g_free (trash_folder_id);
+ g_free (folder_id);
+
+ return FALSE;
+ }
+
+ if (camel_o365_store_summary_get_folder_is_foreign (o365_store->priv->summary, folder_id) ||
+ camel_o365_store_summary_get_folder_is_public (o365_store->priv->summary, folder_id)) {
+ /* do not delete foreign or public folders,
+ * only remove them from the local cache */
+ success = TRUE;
+ } else if (is_under_trash_folder) {
+ success = e_o365_connection_delete_mail_folder_sync (cnc, NULL, folder_id, cancellable,
&local_error);
+ } else {
+ success = o365_store_move_mail_folder (o365_store, cnc, folder_id, "deleteditems",
cancellable, &local_error);
+ claim_unsubscribe = FALSE;
+ }
+
+ g_clear_object (&cnc);
+
+ if (!success) {
+ camel_folder_info_free (folder_info);
+ g_free (trash_folder_id);
+ g_free (folder_id);
+
+ camel_o365_store_maybe_disconnect (o365_store, local_error);
+ g_propagate_error (error, local_error);
+
+ return FALSE;
+ }
+
+ if (is_under_trash_folder)
+ o365_store_delete_folders_from_summary_recursive (o365_store, folder_info, FALSE);
+
+ if (claim_unsubscribe) {
+ camel_subscribable_folder_unsubscribed (CAMEL_SUBSCRIBABLE (o365_store), folder_info);
+ camel_store_folder_deleted (store, folder_info);
+ }
+
+ camel_folder_info_free (folder_info);
+
+ o365_store_save_summary (o365_store->priv->summary, G_STRFUNC);
+
+ g_free (trash_folder_id);
+ g_free (folder_id);
+
+ return TRUE;
+}
+
+static gboolean
+o365_store_rename_folder_sync (CamelStore *store,
+ const gchar *old_name,
+ const gchar *new_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelO365Store *o365_store;
+ EO365Connection *cnc;
+ const gchar *old_slash, *new_slash;
+ gint parent_len;
+ gchar *folder_id;
+ gboolean success = TRUE;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE (store), FALSE);
+
+ if (!g_strcmp0 (old_name, new_name))
+ return TRUE;
+
+ o365_store = CAMEL_O365_STORE (store);
+ folder_id = camel_o365_store_summary_dup_folder_id_for_full_name (o365_store->priv->summary,
old_name);
+
+ if (!folder_id) {
+ g_set_error (error, CAMEL_STORE_ERROR, CAMEL_STORE_ERROR_NO_FOLDER,
+ _("Folder “%s” does not exist"), old_name);
+
+ return FALSE;
+ }
+
+ if (!camel_o365_store_ensure_connected (o365_store, &cnc, cancellable, error)) {
+ g_free (folder_id);
+ return FALSE;
+ }
+
+ old_slash = g_strrstr (old_name, "/");
+ new_slash = g_strrstr (new_name, "/");
+
+ if (old_slash)
+ old_slash++;
+ else
+ old_slash = old_name;
+
+ if (new_slash)
+ new_slash++;
+ else
+ new_slash = new_name;
+
+ parent_len = old_slash - old_name;
+
+ /* First move the folder, if needed */
+ if (new_slash - new_name != parent_len ||
+ strncmp (old_name, new_name, parent_len)) {
+ gchar *new_parent_id;
+
+ if (new_slash - new_name > 0) {
+ gchar *new_parent;
+
+ new_parent = g_strndup (new_name, new_slash - new_name - 1);
+ new_parent_id = camel_o365_store_summary_dup_folder_id_for_full_name
(o365_store->priv->summary, new_parent);
+
+ if (!new_parent_id) {
+ g_set_error (error, CAMEL_STORE_ERROR, CAMEL_STORE_ERROR_NO_FOLDER,
+ _("Folder “%s” does not exist"), new_parent);
+
+ g_free (new_parent);
+ g_free (folder_id);
+
+ return FALSE;
+ }
+
+ g_free (new_parent);
+ } else {
+ new_parent_id = NULL;
+ }
+
+ success = o365_store_move_mail_folder (o365_store, cnc, folder_id, new_parent_id ?
new_parent_id : "msgfolderroot", cancellable, &local_error);
+
+ g_free (new_parent_id);
+ }
+
+ /* Then rename the folder, if needed */
+ if (success && g_strcmp0 (old_slash, new_slash) != 0) {
+ EO365MailFolder *mail_folder = NULL;
+
+ success = e_o365_connection_rename_mail_folder_sync (cnc, NULL, folder_id, new_slash,
&mail_folder, cancellable, &local_error);
+
+ if (mail_folder) {
+ camel_o365_store_summary_set_folder_display_name (o365_store->priv->summary,
folder_id,
+ e_o365_mail_folder_get_display_name (mail_folder), TRUE);
+
+ json_object_unref (mail_folder);
+ }
+ }
+
+ if (success) {
+ CamelFolderInfo *fi;
+
+ fi = camel_o365_store_summary_build_folder_info_for_id (o365_store->priv->summary, folder_id);
+
+ if (fi) {
+ camel_store_folder_renamed (store, old_name, fi);
+ camel_folder_info_free (fi);
+ }
+ }
+
+ o365_store_save_summary (o365_store->priv->summary, G_STRFUNC);
+
+ if (!success && local_error) {
+ camel_o365_store_maybe_disconnect (o365_store, local_error);
+ g_propagate_error (error, local_error);
+ }
+
+ g_free (folder_id);
+
+ return success;
+}
+
typedef struct _FolderRenamedData {
gchar *id;
gchar *old_name;
@@ -667,7 +990,7 @@ o365_get_folder_info_sync (CamelStore *store,
LOCK (o365_store);
camel_o365_store_summary_set_delta_link (o365_store->priv->summary,
new_delta_link);
- o365_store_save_summary_locked (o365_store->priv->summary, G_STRFUNC);
+ o365_store_save_summary (o365_store->priv->summary, G_STRFUNC);
fdd.added_ids = g_slist_reverse (fdd.added_ids);
fdd.renamed_data = g_slist_reverse (fdd.renamed_data);
@@ -1015,7 +1338,7 @@ o365_store_dispose (GObject *object)
LOCK (o365_store);
if (o365_store->priv->summary) {
- o365_store_save_summary_locked (o365_store->priv->summary, G_STRFUNC);
+ o365_store_save_summary (o365_store->priv->summary, G_STRFUNC);
g_clear_object (&o365_store->priv->summary);
}
@@ -1078,10 +1401,8 @@ camel_o365_store_class_init (CamelO365StoreClass *class)
store_class = CAMEL_STORE_CLASS (class);
store_class->get_folder_sync = o365_store_get_folder_sync;
store_class->create_folder_sync = o365_store_create_folder_sync;
-#if 0
store_class->delete_folder_sync = o365_store_delete_folder_sync;
store_class->rename_folder_sync = o365_store_rename_folder_sync;
-#endif
store_class->get_folder_info_sync = o365_get_folder_info_sync;
store_class->initial_setup_sync = o365_store_initial_setup_sync;
store_class->get_trash_folder_sync = o365_store_get_trash_folder_sync;
diff --git a/src/Office365/common/e-o365-connection.c b/src/Office365/common/e-o365-connection.c
index 6df4ba51..31cd7791 100644
--- a/src/Office365/common/e-o365-connection.c
+++ b/src/Office365/common/e-o365-connection.c
@@ -1335,6 +1335,29 @@ o365_connection_send_request_sync (EO365Connection *cnc,
return success;
}
+static gboolean
+e_o365_read_no_response_cb (EO365Connection *cnc,
+ SoupMessage *message,
+ GInputStream *raw_data_stream,
+ gpointer user_data,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* This is used when no response is expected from the server.
+ Read the data stream only if debugging is on, in case
+ the server returns anything interesting. */
+
+ if (o365_log_enabled ()) {
+ gchar buffer[4096];
+
+ while (g_input_stream_read (raw_data_stream, buffer, sizeof (buffer), cancellable, error) >
0) {
+ /* Do nothing, just read it, thus it's shown in the debug output */
+ }
+ }
+
+ return TRUE;
+}
+
typedef struct _EO365ResponseData {
EO365ConnectionJsonFunc json_func;
gpointer func_user_data;
@@ -1432,6 +1455,28 @@ e_o365_read_json_object_response_cb (EO365Connection *cnc,
return TRUE;
}
+static SoupMessage *
+o365_connection_new_soup_message (const gchar *method,
+ const gchar *uri,
+ GError **error)
+{
+ SoupMessage *message;
+
+ g_return_val_if_fail (method != NULL, NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ message = soup_message_new (method, uri);
+
+ if (message) {
+ soup_message_headers_append (message->request_headers, "Connection", "Keep-Alive");
+ soup_message_headers_append (message->request_headers, "User-Agent", "Evolution-O365/"
VERSION);
+ } else {
+ g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), uri);
+ }
+
+ return message;
+}
+
gboolean
e_o365_connection_get_ssl_error_details (EO365Connection *cnc,
gchar **out_certificate_pem,
@@ -1480,10 +1525,9 @@ e_o365_connection_authenticate_sync (EO365Connection *cnc,
"$top", "1",
NULL);
- message = soup_message_new (SOUP_METHOD_GET, uri);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
if (!message) {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), uri);
g_free (uri);
return FALSE;
@@ -1837,10 +1881,9 @@ e_o365_connection_batch_request_internal_sync (EO365Connection *cnc,
uri = e_o365_connection_construct_uri (cnc, FALSE, NULL, api_version, "",
"$batch", NULL, NULL, NULL);
- message = soup_message_new (SOUP_METHOD_POST, uri);
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, error);
if (!message) {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), uri);
g_free (uri);
return FALSE;
@@ -2094,10 +2137,9 @@ e_o365_connection_list_mail_folders_sync (EO365Connection *cnc,
"$select", select,
NULL);
- message = soup_message_new (SOUP_METHOD_GET, uri);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
if (!message) {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), uri);
g_free (uri);
return FALSE;
@@ -2137,7 +2179,7 @@ e_o365_connection_get_mail_folders_delta_sync (EO365Connection *cnc,
g_return_val_if_fail (func != NULL, FALSE);
if (delta_link)
- message = soup_message_new (SOUP_METHOD_GET, delta_link);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, delta_link, NULL);
if (!message) {
gchar *uri;
@@ -2149,10 +2191,9 @@ e_o365_connection_get_mail_folders_delta_sync (EO365Connection *cnc,
"$select", select,
NULL);
- message = soup_message_new (SOUP_METHOD_GET, uri);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
if (!message) {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"),
uri);
g_free (uri);
return FALSE;
@@ -2211,10 +2252,155 @@ e_o365_connection_create_mail_folder_sync (EO365Connection *cnc,
parent_folder_id ? "childFolders" : NULL,
NULL);
- message = soup_message_new (SOUP_METHOD_POST, uri);
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, error);
+
+ if (!message) {
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ builder = json_builder_new_immutable ();
+
+ json_builder_begin_object (builder);
+ json_builder_set_member_name (builder, "displayName");
+ json_builder_add_string_value (builder, display_name);
+ json_builder_end_object (builder);
+
+ e_o365_connection_set_json_body (message, builder);
+
+ g_object_unref (builder);
+
+ success = o365_connection_send_request_sync (cnc, message, e_o365_read_json_object_response_cb, NULL,
out_mail_folder, cancellable, error);
+
+ g_clear_object (&message);
+
+ return success;
+}
+
+/* https://docs.microsoft.com/en-us/graph/api/mailfolder-delete?view=graph-rest-1.0&tabs=http */
+
+gboolean
+e_o365_connection_delete_mail_folder_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the
account user */
+ const gchar *folder_id,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessage *message = NULL;
+ gboolean success;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (folder_id != NULL, FALSE);
+
+ uri = e_o365_connection_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "mailFolders", folder_id, NULL, NULL);
+
+ message = o365_connection_new_soup_message (SOUP_METHOD_DELETE, uri, error);
+
+ if (!message) {
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ success = o365_connection_send_request_sync (cnc, message, NULL, e_o365_read_no_response_cb, NULL,
cancellable, error);
+
+ g_clear_object (&message);
+
+ return success;
+}
+
+/* https://docs.microsoft.com/en-us/graph/api/mailfolder-copy?view=graph-rest-1.0&tabs=http
+ https://docs.microsoft.com/en-us/graph/api/mailfolder-move?view=graph-rest-1.0&tabs=http
+ */
+gboolean
+e_o365_connection_copy_move_mail_folder_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the
account user */
+ const gchar *src_folder_id,
+ const gchar *des_folder_id,
+ gboolean do_copy,
+ EO365MailFolder **out_mail_folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessage *message = NULL;
+ JsonBuilder *builder;
+ gboolean success;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (src_folder_id != NULL, FALSE);
+ g_return_val_if_fail (des_folder_id != NULL, FALSE);
+
+ uri = e_o365_connection_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "mailFolders",
+ src_folder_id,
+ do_copy ? "copy" : "move",
+ NULL);
+
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, error);
+
+ if (!message) {
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ builder = json_builder_new_immutable ();
+
+ json_builder_begin_object (builder);
+ json_builder_set_member_name (builder, "destinationId");
+ json_builder_add_string_value (builder, des_folder_id);
+ json_builder_end_object (builder);
+
+ e_o365_connection_set_json_body (message, builder);
+
+ g_object_unref (builder);
+
+ success = o365_connection_send_request_sync (cnc, message, e_o365_read_json_object_response_cb, NULL,
out_mail_folder, cancellable, error);
+
+ g_clear_object (&message);
+
+ return success;
+}
+
+/* https://docs.microsoft.com/en-us/graph/api/mailfolder-update?view=graph-rest-1.0&tabs=http */
+
+gboolean
+e_o365_connection_rename_mail_folder_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the
account user */
+ const gchar *folder_id,
+ const gchar *display_name,
+ EO365MailFolder **out_mail_folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessage *message = NULL;
+ JsonBuilder *builder;
+ gboolean success;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (folder_id != NULL, FALSE);
+ g_return_val_if_fail (display_name != NULL, FALSE);
+
+ uri = e_o365_connection_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "mailFolders",
+ folder_id,
+ NULL,
+ NULL);
+
+ message = o365_connection_new_soup_message ("PATCH", uri, error);
if (!message) {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), uri);
g_free (uri);
return FALSE;
@@ -2265,7 +2451,7 @@ e_o365_connection_get_mail_messages_delta_sync (EO365Connection *cnc,
g_return_val_if_fail (func != NULL, FALSE);
if (delta_link)
- message = soup_message_new (SOUP_METHOD_GET, delta_link);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, delta_link, NULL);
if (!message) {
gchar *uri;
@@ -2278,10 +2464,9 @@ e_o365_connection_get_mail_messages_delta_sync (EO365Connection *cnc,
"$select", select,
NULL);
- message = soup_message_new (SOUP_METHOD_GET, uri);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
if (!message) {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"),
uri);
g_free (uri);
return FALSE;
@@ -2342,10 +2527,9 @@ e_o365_connection_get_mail_message_sync (EO365Connection *cnc,
"", "$value",
NULL);
- message = soup_message_new (SOUP_METHOD_GET, uri);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
if (!message) {
- g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: “%s”"), uri);
g_free (uri);
return FALSE;
diff --git a/src/Office365/common/e-o365-connection.h b/src/Office365/common/e-o365-connection.h
index cc1de355..4335190e 100644
--- a/src/Office365/common/e-o365-connection.h
+++ b/src/Office365/common/e-o365-connection.h
@@ -186,6 +186,29 @@ gboolean e_o365_connection_create_mail_folder_sync
EO365MailFolder **out_mail_folder,
GCancellable *cancellable,
GError **error);
+gboolean e_o365_connection_delete_mail_folder_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const gchar *folder_id,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_o365_connection_copy_move_mail_folder_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const gchar *src_folder_id,
+ const gchar *des_folder_id,
+ gboolean do_copy,
+ EO365MailFolder **out_mail_folder,
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_o365_connection_rename_mail_folder_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const gchar *folder_id,
+ const gchar *display_name,
+ EO365MailFolder **out_mail_folder,
+ GCancellable *cancellable,
+ GError **error);
gboolean e_o365_connection_get_mail_messages_delta_sync
(EO365Connection *cnc,
const gchar *user_override, /* for which user, NULL to use
the account user */
diff --git a/src/Office365/common/e-o365-json-utils.h b/src/Office365/common/e-o365-json-utils.h
index 12aeecc4..1f480853 100644
--- a/src/Office365/common/e-o365-json-utils.h
+++ b/src/Office365/common/e-o365-json-utils.h
@@ -54,13 +54,13 @@ typedef enum _EO365ItemBodyContentTypeType {
} EO365ItemBodyContentTypeType;
/* Just for better readability */
-#define EO365MailFolder JsonObject
-#define EO365Recipient JsonObject
-#define EO365DateTimeWithZone JsonObject
-#define EO365FollowupFlag JsonObject
-#define EO365InternetMessageHeader JsonObject
-#define EO365ItemBody JsonObject
-#define EO365MailMessage JsonObject
+#define EO365DateTimeWithZone JsonObject
+#define EO365FollowupFlag JsonObject
+#define EO365InternetMessageHeader JsonObject
+#define EO365ItemBody JsonObject
+#define EO365MailFolder JsonObject
+#define EO365MailMessage JsonObject
+#define EO365Recipient JsonObject
JsonArray * e_o365_json_get_array_member (JsonObject *object,
const gchar *member_name);
diff --git a/src/Office365/evolution/e-mail-config-o365-backend.c
b/src/Office365/evolution/e-mail-config-o365-backend.c
index e0e76b6d..5045758f 100644
--- a/src/Office365/evolution/e-mail-config-o365-backend.c
+++ b/src/Office365/evolution/e-mail-config-o365-backend.c
@@ -83,63 +83,6 @@ mail_config_o365_backend_set_oauth2_tooltip (GtkWidget *widget,
g_free (when_value_filled);
}
-static void
-test_clicked_cb (GtkButton *button,
- EMailConfigServiceBackend *backend)
-{
- CamelSettings *settings;
- 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);
- source = e_mail_config_service_backend_get_collection (backend);
-
- cnc = e_o365_connection_new (source, CAMEL_O365_SETTINGS (settings));
- g_return_if_fail (cnc != NULL);
-
- //success = e_o365_connection_list_mail_folders_sync (cnc, NULL, NULL, NULL, &folders, NULL, &error);
- success = e_o365_connection_get_mail_folders_delta_sync (cnc, NULL, NULL, delta_link, 0,
e_o365_connection_call_gather_into_slist, &folders, &new_delta_link, 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) {
- printf ("%s: succeeded, but has set error: '%s'\n", __FUNCTION__, error->message);
- }
-
- printf ("%s: returned %d objects:\n", __FUNCTION__, g_slist_length (folders));
-
- for (link = folders; link; link = g_slist_next (link)) {
- JsonObject *folder = link->data;
-
- 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));
- }
- }
-
- g_slist_free_full (folders, (GDestroyNotify) json_object_unref);
- g_clear_error (&error);
- g_clear_object (&cnc);
-}
-
static void
mail_config_o365_backend_insert_widgets (EMailConfigServiceBackend *backend,
GtkBox *parent)
@@ -403,12 +346,6 @@ mail_config_o365_backend_insert_widgets (EMailConfigServiceBackend *backend,
e_source_authentication_set_host (auth_extension, "graph.microsoft.com");
e_source_authentication_set_port (auth_extension, 442);
e_source_authentication_set_method (auth_extension, "Office365");
-
- /* The following is for easier debugging only */
- widget = gtk_button_new_with_mnemonic ("_Test");
- g_signal_connect (widget, "clicked", G_CALLBACK (test_clicked_cb), o365_backend);
- gtk_widget_show (widget);
- gtk_box_pack_start (GTK_BOX (parent), widget, FALSE, FALSE, 0);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]