[evolution-ews/wip/mcrha/office365: 29/50] Copy/move messages and flag changes save on the server
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/mcrha/office365: 29/50] Copy/move messages and flag changes save on the server
- Date: Mon, 3 Aug 2020 15:24:08 +0000 (UTC)
commit 194fa0930a4479c81ced74ece3aebd080a1ce386
Author: Milan Crha <mcrha redhat com>
Date: Fri Jul 3 16:02:33 2020 +0200
Copy/move messages and flag changes save on the server
src/Office365/camel/camel-o365-folder.c | 473 ++++++++++++++++++++++++++++++-
src/Office365/camel/camel-o365-store.c | 28 +-
src/Office365/camel/camel-o365-store.h | 10 +-
src/Office365/camel/camel-o365-utils.c | 20 +-
src/Office365/camel/camel-o365-utils.h | 4 +
src/Office365/common/e-o365-connection.c | 409 ++++++++++++++++++++++++--
src/Office365/common/e-o365-connection.h | 29 ++
7 files changed, 920 insertions(+), 53 deletions(-)
---
diff --git a/src/Office365/camel/camel-o365-folder.c b/src/Office365/camel/camel-o365-folder.c
index c5ad7a25..e085ebb6 100644
--- a/src/Office365/camel/camel-o365-folder.c
+++ b/src/Office365/camel/camel-o365-folder.c
@@ -1094,6 +1094,477 @@ o365_folder_refresh_info_sync (CamelFolder *folder,
return success;
}
+static gboolean
+o365_folder_copy_move_to_folder_sync (CamelFolder *folder,
+ CamelO365Store *o365_store,
+ const GSList *uids,
+ const gchar *des_folder_id,
+ gboolean do_copy,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelO365StoreSummary *o365_store_summary;
+ EO365Connection *cnc = NULL;
+ GSList *des_ids = NULL;
+ gboolean success;
+
+ g_return_val_if_fail (des_folder_id != NULL, FALSE);
+
+ o365_store_summary = camel_o365_store_ref_store_summary (o365_store);
+
+ if (g_strcmp0 (des_folder_id, "junkemail") == 0) {
+ des_folder_id = camel_o365_store_summary_dup_folder_id_for_type (o365_store_summary,
CAMEL_FOLDER_TYPE_JUNK);
+ } else if (g_strcmp0 (des_folder_id, "deleteditems") == 0) {
+ des_folder_id = camel_o365_store_summary_dup_folder_id_for_type (o365_store_summary,
CAMEL_FOLDER_TYPE_TRASH);
+ } else if (g_strcmp0 (des_folder_id, "inbox") == 0) {
+ des_folder_id = camel_o365_store_summary_dup_folder_id_for_type (o365_store_summary,
CAMEL_FOLDER_TYPE_INBOX);
+ }
+
+ g_clear_object (&o365_store_summary);
+
+ if (!camel_o365_store_ensure_connected (o365_store, &cnc, cancellable, error))
+ return FALSE;
+
+ success = e_o365_connection_copy_move_mail_messages_sync (cnc, NULL, uids, des_folder_id, do_copy,
+ &des_ids, cancellable, error);
+
+ g_clear_object (&cnc);
+
+ if (!do_copy) {
+ CamelFolderChangeInfo *src_changes;
+ CamelO365Folder *o365_folder;
+ GSList *des_link, *src_link;
+ GList *removed_uids = NULL;
+
+ src_changes = camel_folder_change_info_new ();
+ o365_folder = CAMEL_O365_FOLDER (folder);
+
+ camel_folder_lock (folder);
+
+ /* Can succeed partially, thus always check the moved ids */
+ for (src_link = (GSList *) uids, des_link = des_ids;
+ src_link && des_link;
+ src_link = g_slist_next (src_link), des_link = g_slist_next (des_link)) {
+ const gchar *src_uid = src_link->data;
+
+ o365_folder_cache_remove (o365_folder, src_uid, NULL);
+
+ removed_uids = g_list_prepend (removed_uids, (gpointer) src_uid);
+ camel_folder_change_info_remove_uid (src_changes, src_uid);
+ }
+
+ if (removed_uids) {
+ CamelFolderSummary *summary;
+
+ summary = camel_folder_get_folder_summary (folder);
+ camel_folder_summary_remove_uids (summary, removed_uids);
+
+ g_list_free (removed_uids);
+ }
+
+ if (camel_folder_change_info_changed (src_changes))
+ camel_folder_changed (folder, src_changes);
+
+ camel_folder_change_info_free (src_changes);
+
+ camel_folder_unlock (folder);
+ }
+
+ g_slist_free_full (des_ids, (GDestroyNotify) camel_pstring_free);
+
+ return success;
+}
+
+static gboolean
+o365_folder_delete_messages_sync (CamelFolder *folder,
+ CamelO365Store *o365_store,
+ const GSList *uids,
+ gboolean is_trash_folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EO365Connection *cnc = NULL;
+ gboolean success;
+
+ if (!camel_o365_store_ensure_connected (o365_store, &cnc, cancellable, error))
+ return FALSE;
+
+ if (is_trash_folder) {
+ GSList *deleted_uids = NULL, *link;
+
+ success = e_o365_connection_delete_mail_messages_sync (cnc, NULL, uids, &deleted_uids,
cancellable, error);
+
+ if (deleted_uids) {
+ CamelFolderChangeInfo *changes;
+ CamelO365Folder *o365_folder;
+ GList *removed_uids = NULL;
+
+ o365_folder = CAMEL_O365_FOLDER (folder);
+ changes = camel_folder_change_info_new ();
+
+ camel_folder_lock (folder);
+
+ /* Can succeed partially, thus always check the moved ids */
+ for (link = deleted_uids; link; link = g_slist_next (link)) {
+ const gchar *uid = link->data;
+
+ o365_folder_cache_remove (o365_folder, uid, NULL);
+
+ removed_uids = g_list_prepend (removed_uids, (gpointer) uid);
+ camel_folder_change_info_remove_uid (changes, uid);
+ }
+
+ if (removed_uids) {
+ CamelFolderSummary *summary;
+
+ summary = camel_folder_get_folder_summary (folder);
+ camel_folder_summary_remove_uids (summary, removed_uids);
+
+ g_list_free (removed_uids);
+ }
+
+ if (camel_folder_change_info_changed (changes))
+ camel_folder_changed (folder, changes);
+
+ camel_folder_change_info_free (changes);
+
+ camel_folder_unlock (folder);
+
+ g_slist_free (deleted_uids);
+ }
+ } else {
+ success = o365_folder_copy_move_to_folder_sync (folder, o365_store,
+ uids, "deleteditems", FALSE, cancellable, error);
+ }
+
+ g_clear_object (&cnc);
+
+ return success;
+}
+
+static JsonBuilder *
+o365_folder_message_info_changes_to_json (CamelMessageInfo *mi)
+{
+ JsonBuilder *builder;
+
+ builder = json_builder_new_immutable ();
+ e_o365_json_begin_object_member (builder, NULL);
+
+ camel_o365_utils_add_message_flags (builder, mi, NULL);
+
+ e_o365_json_end_object_member (builder);
+
+ return builder;
+}
+
+static gboolean
+o365_folder_save_flags_sync (CamelFolder *folder,
+ CamelO365Store *o365_store,
+ GSList *mi_list, /* CamelMessageInfo * */
+ GCancellable *cancellable,
+ GError **error)
+{
+ EO365Connection *cnc = NULL;
+ gboolean success = TRUE;
+
+ /* Trap an error, but do not stop other processing */
+ g_return_val_if_fail (mi_list != NULL, TRUE);
+
+ if (!camel_o365_store_ensure_connected (o365_store, &cnc, cancellable, error))
+ return FALSE;
+
+ if (mi_list->next) {
+ GSList *link;
+ GPtrArray *requests;
+
+ requests = g_ptr_array_new_full (g_slist_length (mi_list), g_object_unref);
+
+ for (link = mi_list; link && success; link = g_slist_next (link)) {
+ CamelMessageInfo *mi = link->data;
+ SoupMessage *message;
+ JsonBuilder *builder;
+
+ builder = o365_folder_message_info_changes_to_json (mi);
+
+ message = e_o365_connection_prepare_update_mail_message (cnc, NULL,
+ camel_message_info_get_uid (mi), builder, error);
+
+ g_clear_object (&builder);
+
+ if (!message)
+ success = FALSE;
+ else
+ g_ptr_array_add (requests, message);
+ }
+
+ if (success)
+ success = e_o365_connection_batch_request_sync (cnc, E_O365_API_V1_0, requests,
cancellable, error);
+
+ g_ptr_array_free (requests, TRUE);
+ } else {
+ CamelMessageInfo *mi = mi_list->data;
+ JsonBuilder *builder;
+
+ builder = o365_folder_message_info_changes_to_json (mi);
+
+ success = e_o365_connection_update_mail_message_sync (cnc, NULL,
+ camel_message_info_get_uid (mi), builder, cancellable, error);
+
+ g_clear_object (&builder);
+ }
+
+ g_object_unref (cnc);
+
+ if (success) {
+ GSList *link;
+
+ camel_folder_lock (folder);
+
+ for (link = mi_list; link; link = g_slist_next (link)) {
+ CamelMessageInfo *mi = link->data;
+
+ camel_message_info_set_folder_flagged (mi, FALSE);
+ }
+
+ camel_folder_unlock (folder);
+ }
+
+ return success;
+}
+
+static gboolean
+o365_folder_is_of_type (CamelFolder *folder,
+ guint32 folder_type)
+{
+ CamelStore *parent_store;
+ CamelO365Store *o365_store;
+ CamelO365StoreSummary *o365_store_summary;
+ gboolean is_of_type;
+ const gchar *folder_id;
+
+ g_return_val_if_fail (folder != NULL, FALSE);
+
+ parent_store = camel_folder_get_parent_store (folder);
+
+ if (!parent_store)
+ return FALSE;
+
+ o365_store = CAMEL_O365_STORE (parent_store);
+
+ g_return_val_if_fail (o365_store != NULL, FALSE);
+
+ o365_store_summary = camel_o365_store_ref_store_summary (o365_store);
+
+ folder_type = folder_type & CAMEL_FOLDER_TYPE_MASK;
+ folder_id = camel_o365_folder_get_id (CAMEL_O365_FOLDER (folder));
+ is_of_type = folder_id &&
+ (camel_o365_store_summary_get_folder_flags (o365_store_summary, folder_id) &
CAMEL_FOLDER_TYPE_MASK) == folder_type;
+
+ g_clear_object (&o365_store_summary);
+
+ return is_of_type;
+}
+
+static gboolean
+o365_folder_synchronize_sync (CamelFolder *folder,
+ gboolean expunge,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelO365Store *o365_store;
+ CamelStore *parent_store;
+ CamelFolderSummary *folder_summary;
+ GPtrArray *uids;
+ GSList *mi_list = NULL, *deleted_uids = NULL, *junk_uids = NULL, *inbox_uids = NULL;
+ gint mi_list_len = 0;
+ gboolean is_junk_folder;
+ gboolean success = TRUE;
+ guint ii;
+ GError *local_error = NULL;
+
+ parent_store = camel_folder_get_parent_store (folder);
+
+ if (!parent_store) {
+ g_set_error_literal (error, CAMEL_FOLDER_ERROR, CAMEL_FOLDER_ERROR_INVALID_STATE,
+ _("Invalid folder state (missing parent store)"));
+ return FALSE;
+ }
+
+ o365_store = CAMEL_O365_STORE (parent_store);
+
+ if (!camel_o365_store_ensure_connected (o365_store, NULL, cancellable, error))
+ return FALSE;
+
+ folder_summary = camel_folder_get_folder_summary (folder);
+
+ if (camel_folder_summary_get_deleted_count (folder_summary) > 0 ||
+ camel_folder_summary_get_junk_count (folder_summary) > 0) {
+ camel_folder_summary_prepare_fetch_all (folder_summary, NULL);
+ uids = camel_folder_summary_get_array (folder_summary);
+ } else {
+ uids = camel_folder_summary_get_changed (folder_summary);
+ }
+
+ if (!uids || !uids->len) {
+ camel_folder_summary_free_array (uids);
+ return TRUE;
+ }
+
+ is_junk_folder = o365_folder_is_of_type (folder, CAMEL_FOLDER_TYPE_JUNK);
+
+ for (ii = 0; success && ii < uids->len; ii++) {
+ guint32 flags_changed, flags_set;
+ CamelMessageInfo *mi;
+ const gchar *uid;
+
+ uid = uids->pdata[ii];
+ mi = camel_folder_summary_get (folder_summary, uid);
+
+ if (!mi)
+ continue;
+
+ flags_set = camel_message_info_get_flags (mi);
+ flags_changed = camel_o365_message_info_get_server_flags (CAMEL_O365_MESSAGE_INFO (mi)) ^
flags_set;
+
+ if ((flags_set & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0 &&
+ (flags_changed & (CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_FORWARDED |
CAMEL_MESSAGE_FLAGGED)) != 0) {
+ mi_list = g_slist_prepend (mi_list, mi);
+ mi_list_len++;
+
+ if (flags_set & CAMEL_MESSAGE_DELETED)
+ deleted_uids = g_slist_prepend (deleted_uids, (gpointer) camel_pstring_strdup
(uid));
+ else if (flags_set & CAMEL_MESSAGE_JUNK)
+ junk_uids = g_slist_prepend (junk_uids, (gpointer) camel_pstring_strdup
(uid));
+ else if (is_junk_folder && (flags_set & CAMEL_MESSAGE_NOTJUNK) != 0)
+ inbox_uids = g_slist_prepend (inbox_uids, (gpointer) camel_pstring_strdup
(uid));
+ } else if (flags_set & CAMEL_MESSAGE_DELETED) {
+ deleted_uids = g_slist_prepend (deleted_uids, (gpointer) camel_pstring_strdup (uid));
+ g_clear_object (&mi);
+ } else if (flags_set & CAMEL_MESSAGE_JUNK) {
+ junk_uids = g_slist_prepend (junk_uids, (gpointer) camel_pstring_strdup (uid));
+ g_clear_object (&mi);
+ } else if (is_junk_folder && (flags_set & CAMEL_MESSAGE_NOTJUNK) != 0) {
+ inbox_uids = g_slist_prepend (inbox_uids, (gpointer) camel_pstring_strdup (uid));
+ g_clear_object (&mi);
+ } else if ((flags_set & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
+ /* OK, the change must have been the labels */
+ mi_list = g_slist_prepend (mi_list, mi);
+ mi_list_len++;
+ } else {
+ g_clear_object (&mi);
+ }
+
+ if (mi_list_len == E_O365_BATCH_MAX_REQUESTS) {
+ success = o365_folder_save_flags_sync (folder, o365_store, mi_list, cancellable,
&local_error);
+ g_slist_free_full (mi_list, g_object_unref);
+ mi_list = NULL;
+ mi_list_len = 0;
+ }
+ }
+
+ if (mi_list != NULL && success)
+ success = o365_folder_save_flags_sync (folder, o365_store, mi_list, cancellable,
&local_error);
+ g_slist_free_full (mi_list, g_object_unref);
+
+ if (deleted_uids && success)
+ success = o365_folder_delete_messages_sync (folder, o365_store, deleted_uids,
o365_folder_is_of_type (folder, CAMEL_FOLDER_TYPE_TRASH), cancellable, &local_error);
+ g_slist_free_full (deleted_uids, (GDestroyNotify) camel_pstring_free);
+
+ if (junk_uids && success)
+ success = o365_folder_copy_move_to_folder_sync (folder, o365_store, junk_uids, "junkemail",
FALSE, cancellable, &local_error);
+ g_slist_free_full (junk_uids, (GDestroyNotify) camel_pstring_free);
+
+ if (inbox_uids && success)
+ success = o365_folder_copy_move_to_folder_sync (folder, o365_store, inbox_uids, "inbox",
FALSE, cancellable, &local_error);
+ g_slist_free_full (inbox_uids, (GDestroyNotify) camel_pstring_free);
+
+ camel_folder_summary_save (folder_summary, NULL);
+ camel_folder_summary_free_array (uids);
+
+ if (local_error) {
+ camel_o365_store_maybe_disconnect (o365_store, local_error);
+ g_propagate_error (error, local_error);
+ }
+
+ return success;
+}
+
+static gboolean
+o365_folder_expunge_sync (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* it does nothing special here, everything is done as part of the o365_folder_synchronize_sync() */
+
+ return TRUE;
+}
+
+static gboolean
+o365_folder_transfer_messages_to_sync (CamelFolder *source,
+ GPtrArray *uids,
+ CamelFolder *destination,
+ gboolean delete_originals,
+ GPtrArray **transferred_uids,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStore *parent_store;
+ CamelO365Store *o365_store;
+ GSList *uids_list = NULL;
+ gboolean success;
+ guint ii;
+ GError *local_error = NULL;
+
+ /* The parent class ensures this, but recheck anyway, for completeness */
+ g_return_val_if_fail (CAMEL_IS_O365_FOLDER (source), FALSE);
+ g_return_val_if_fail (CAMEL_IS_O365_FOLDER (destination), FALSE);
+ g_return_val_if_fail (uids != NULL, FALSE);
+
+ parent_store = camel_folder_get_parent_store (source);
+
+ if (!parent_store) {
+ g_set_error_literal (error, CAMEL_FOLDER_ERROR, CAMEL_FOLDER_ERROR_INVALID_STATE,
+ _("Invalid folder state (missing parent store)"));
+ return FALSE;
+ }
+
+ /* The parent class ensures this, but recheck anyway, for completeness */
+ g_return_val_if_fail (camel_folder_get_parent_store (destination) == parent_store, FALSE);
+
+ o365_store = CAMEL_O365_STORE (parent_store);
+
+ if (!camel_o365_store_ensure_connected (o365_store, NULL, cancellable, error))
+ return FALSE;
+
+ for (ii = 0; ii < uids->len; ii++) {
+ uids_list = g_slist_prepend (uids_list, g_ptr_array_index (uids, ii));
+ }
+
+ uids_list = g_slist_reverse (uids_list);
+
+ success = o365_folder_copy_move_to_folder_sync (source, o365_store,
+ uids_list, camel_o365_folder_get_id (CAMEL_O365_FOLDER (destination)),
+ !delete_originals, cancellable, &local_error);
+
+ g_slist_free (uids_list);
+
+ /* Update destination folder only if not frozen, to not update
+ for each single message transfer during filtering.
+ */
+ if (success && !camel_folder_is_frozen (destination)) {
+ camel_operation_progress (cancellable, -1);
+
+ o365_folder_refresh_info_sync (destination, cancellable, NULL);
+ }
+
+ if (local_error) {
+ camel_o365_store_maybe_disconnect (o365_store, local_error);
+ g_propagate_error (error, local_error);
+ }
+
+ return success;
+}
+
static void
o365_folder_prepare_content_refresh (CamelFolder *folder)
{
@@ -1207,11 +1678,9 @@ camel_o365_folder_class_init (CamelO365FolderClass *klass)
folder_class->append_message_sync = o365_folder_append_message_sync;
folder_class->get_message_sync = o365_folder_get_message_sync;
folder_class->refresh_info_sync = o365_folder_refresh_info_sync;
-#if 0
folder_class->synchronize_sync = o365_folder_synchronize_sync;
folder_class->expunge_sync = o365_folder_expunge_sync;
folder_class->transfer_messages_to_sync = o365_folder_transfer_messages_to_sync;
-#endif
folder_class->prepare_content_refresh = o365_folder_prepare_content_refresh;
folder_class->get_filename = o365_folder_get_filename;
}
diff --git a/src/Office365/camel/camel-o365-store.c b/src/Office365/camel/camel-o365-store.c
index c9b1ddf4..c54af794 100644
--- a/src/Office365/camel/camel-o365-store.c
+++ b/src/Office365/camel/camel-o365-store.c
@@ -1732,20 +1732,20 @@ camel_o365_store_init (CamelO365Store *o365_store)
}
CamelO365StoreSummary *
-camel_o365_store_ref_store_summary (CamelO365Store *store)
+camel_o365_store_ref_store_summary (CamelO365Store *o365_store)
{
CamelO365StoreSummary *summary;
- g_return_val_if_fail (CAMEL_IS_O365_STORE (store), NULL);
+ g_return_val_if_fail (CAMEL_IS_O365_STORE (o365_store), NULL);
- LOCK (store);
+ LOCK (o365_store);
- summary = store->priv->summary;
+ summary = o365_store->priv->summary;
if (summary)
g_object_ref (summary);
- UNLOCK (store);
+ UNLOCK (o365_store);
return summary;
}
@@ -1800,17 +1800,17 @@ camel_o365_store_ensure_connected (CamelO365Store *o365_store,
}
void
-camel_o365_store_maybe_disconnect (CamelO365Store *store,
+camel_o365_store_maybe_disconnect (CamelO365Store *o365_store,
const GError *error)
{
CamelService *service;
- g_return_if_fail (CAMEL_IS_O365_STORE (store));
+ g_return_if_fail (CAMEL_IS_O365_STORE (o365_store));
if (!error)
return;
- service = CAMEL_SERVICE (store);
+ service = CAMEL_SERVICE (o365_store);
if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED)
return;
@@ -1823,16 +1823,16 @@ camel_o365_store_maybe_disconnect (CamelO365Store *store,
}
void
-camel_o365_store_connect_folder_summary (CamelO365Store *store,
+camel_o365_store_connect_folder_summary (CamelO365Store *o365_store,
CamelFolderSummary *folder_summary)
{
- g_return_if_fail (CAMEL_IS_O365_STORE (store));
+ g_return_if_fail (CAMEL_IS_O365_STORE (o365_store));
g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (folder_summary));
- LOCK (store);
+ LOCK (o365_store);
- if (store->priv->summary)
- camel_o365_store_summary_connect_folder_summary (store->priv->summary, folder_summary);
+ if (o365_store->priv->summary)
+ camel_o365_store_summary_connect_folder_summary (o365_store->priv->summary, folder_summary);
- UNLOCK (store);
+ UNLOCK (o365_store);
}
diff --git a/src/Office365/camel/camel-o365-store.h b/src/Office365/camel/camel-o365-store.h
index eb6ad5d2..68e08013 100644
--- a/src/Office365/camel/camel-o365-store.h
+++ b/src/Office365/camel/camel-o365-store.h
@@ -61,19 +61,19 @@ GType camel_o365_store_get_type (void);
CamelO365StoreSummary *
camel_o365_store_ref_store_summary
- (CamelO365Store *store);
+ (CamelO365Store *o365_store);
EO365Connection *
camel_o365_store_ref_connection (CamelO365Store *o365_store);
gboolean camel_o365_store_ensure_connected
- (CamelO365Store *store,
- EO365Connection **out_cnc, /* out, nullable, trasnfer full */
+ (CamelO365Store *o365_store,
+ EO365Connection **out_cnc, /* out, nullable, transfer full */
GCancellable *cancellable,
GError **error);
void camel_o365_store_maybe_disconnect
- (CamelO365Store *store,
+ (CamelO365Store *o365_store,
const GError *error);
void camel_o365_store_connect_folder_summary
- (CamelO365Store *store,
+ (CamelO365Store *o365_store,
CamelFolderSummary *folder_summary);
G_END_DECLS
diff --git a/src/Office365/camel/camel-o365-utils.c b/src/Office365/camel/camel-o365-utils.c
index f2e9c585..20f51181 100644
--- a/src/Office365/camel/camel-o365-utils.c
+++ b/src/Office365/camel/camel-o365-utils.c
@@ -163,11 +163,11 @@ camel_o365_utils_rename_label (const gchar *cat,
/* This is a mapping from Outlook categories to
* Evolution labels based on the standard colors */
const gchar *labels[] = {
- "Red Category", "$Labelimportant",
- "Orange Category", "$Labelwork",
- "Green Category", "$Labelpersonal",
- "Blue Category", "$Labeltodo",
- "Purple Category", "$Labellater",
+ "Red category", "$Labelimportant",
+ "Orange category", "$Labelwork",
+ "Green category", "$Labelpersonal",
+ "Blue category", "$Labeltodo",
+ "Purple category", "$Labellater",
NULL, NULL
};
@@ -663,10 +663,10 @@ o365_utils_get_body_part (CamelMimeMessage *message,
return body_part;
}
-static void
-o365_utils_add_message_flags (JsonBuilder *builder,
- CamelMessageInfo *info,
- CamelMimeMessage *message)
+void
+camel_o365_utils_add_message_flags (JsonBuilder *builder,
+ CamelMessageInfo *info,
+ CamelMimeMessage *message)
{
guint32 flags = 0;
@@ -865,7 +865,7 @@ camel_o365_utils_create_message_sync (EO365Connection *cnc,
}
if (info || is_send)
- o365_utils_add_message_flags (builder, info, is_send ? message : NULL);
+ camel_o365_utils_add_message_flags (builder, info, is_send ? message : NULL);
e_o365_json_end_object_member (builder);
diff --git a/src/Office365/camel/camel-o365-utils.h b/src/Office365/camel/camel-o365-utils.h
index f719c2f0..3815c322 100644
--- a/src/Office365/camel/camel-o365-utils.h
+++ b/src/Office365/camel/camel-o365-utils.h
@@ -33,6 +33,10 @@ gboolean camel_o365_utils_is_system_user_flag
(const gchar *name);
const gchar * camel_o365_utils_rename_label (const gchar *cat,
gboolean from_cat);
+void camel_o365_utils_add_message_flags
+ (JsonBuilder *builder,
+ CamelMessageInfo *info,
+ CamelMimeMessage *message);
gboolean camel_o365_utils_create_message_sync
(EO365Connection *cnc,
const gchar *folder_id,
diff --git a/src/Office365/common/e-o365-connection.c b/src/Office365/common/e-o365-connection.c
index f2627358..9ceb2486 100644
--- a/src/Office365/common/e-o365-connection.c
+++ b/src/Office365/common/e-o365-connection.c
@@ -32,6 +32,11 @@
#define X_EVO_O365_DATA "X-EVO-O365-DATA"
+typedef enum _CSMFlags {
+ CSM_DEFAULT = 0,
+ CSM_DISABLE_RESPONSE = 1 << 0
+} CSMFlags;
+
struct _EO365ConnectionPrivate {
GRecMutex property_lock;
@@ -1457,6 +1462,7 @@ e_o365_read_json_object_response_cb (EO365Connection *cnc,
static SoupMessage *
o365_connection_new_soup_message (const gchar *method,
const gchar *uri,
+ CSMFlags csm_flags,
GError **error)
{
SoupMessage *message;
@@ -1469,6 +1475,9 @@ o365_connection_new_soup_message (const gchar *method,
if (message) {
soup_message_headers_append (message->request_headers, "Connection", "Close");
soup_message_headers_append (message->request_headers, "User-Agent", "Evolution-O365/"
VERSION);
+
+ if ((csm_flags & CSM_DISABLE_RESPONSE) != 0)
+ soup_message_headers_append (message->request_headers, "Prefer", "return=minimal");
} else {
g_set_error (error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: ā%sā"), uri);
}
@@ -1524,7 +1533,7 @@ e_o365_connection_authenticate_sync (EO365Connection *cnc,
"$top", "1",
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -1880,7 +1889,7 @@ 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 = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2123,7 +2132,7 @@ e_o365_connection_get_categories_sync (EO365Connection *cnc,
NULL,
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2170,7 +2179,7 @@ e_o365_connection_list_mail_folders_sync (EO365Connection *cnc,
"$select", select,
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2212,7 +2221,7 @@ e_o365_connection_get_mail_folders_delta_sync (EO365Connection *cnc,
g_return_val_if_fail (func != NULL, FALSE);
if (delta_link)
- message = o365_connection_new_soup_message (SOUP_METHOD_GET, delta_link, NULL);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, delta_link, CSM_DEFAULT, NULL);
if (!message) {
gchar *uri;
@@ -2224,7 +2233,7 @@ e_o365_connection_get_mail_folders_delta_sync (EO365Connection *cnc,
"$select", select,
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2270,7 +2279,7 @@ e_o365_connection_create_mail_folder_sync (EO365Connection *cnc,
GCancellable *cancellable,
GError **error)
{
- SoupMessage *message = NULL;
+ SoupMessage *message;
JsonBuilder *builder;
gboolean success;
gchar *uri;
@@ -2285,7 +2294,7 @@ e_o365_connection_create_mail_folder_sync (EO365Connection *cnc,
parent_folder_id ? "childFolders" : NULL,
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2321,7 +2330,7 @@ e_o365_connection_delete_mail_folder_sync (EO365Connection *cnc,
GCancellable *cancellable,
GError **error)
{
- SoupMessage *message = NULL;
+ SoupMessage *message;
gboolean success;
gchar *uri;
@@ -2331,7 +2340,7 @@ e_o365_connection_delete_mail_folder_sync (EO365Connection *cnc,
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);
+ message = o365_connection_new_soup_message (SOUP_METHOD_DELETE, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2361,7 +2370,7 @@ e_o365_connection_copy_move_mail_folder_sync (EO365Connection *cnc,
GCancellable *cancellable,
GError **error)
{
- SoupMessage *message = NULL;
+ SoupMessage *message;
JsonBuilder *builder;
gboolean success;
gchar *uri;
@@ -2376,7 +2385,7 @@ e_o365_connection_copy_move_mail_folder_sync (EO365Connection *cnc,
do_copy ? "copy" : "move",
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2414,7 +2423,7 @@ e_o365_connection_rename_mail_folder_sync (EO365Connection *cnc,
GCancellable *cancellable,
GError **error)
{
- SoupMessage *message = NULL;
+ SoupMessage *message;
JsonBuilder *builder;
gboolean success;
gchar *uri;
@@ -2429,7 +2438,7 @@ e_o365_connection_rename_mail_folder_sync (EO365Connection *cnc,
NULL,
NULL);
- message = o365_connection_new_soup_message ("PATCH", uri, error);
+ message = o365_connection_new_soup_message ("PATCH", uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2481,7 +2490,7 @@ e_o365_connection_get_mail_messages_delta_sync (EO365Connection *cnc,
g_return_val_if_fail (func != NULL, FALSE);
if (delta_link)
- message = o365_connection_new_soup_message (SOUP_METHOD_GET, delta_link, NULL);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, delta_link, CSM_DEFAULT, NULL);
if (!message) {
gchar *uri;
@@ -2494,7 +2503,7 @@ e_o365_connection_get_mail_messages_delta_sync (EO365Connection *cnc,
"$select", select,
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2540,7 +2549,7 @@ e_o365_connection_get_mail_message_sync (EO365Connection *cnc,
GCancellable *cancellable,
GError **error)
{
- SoupMessage *message = NULL;
+ SoupMessage *message;
gboolean success;
gchar *uri;
@@ -2557,7 +2566,7 @@ e_o365_connection_get_mail_message_sync (EO365Connection *cnc,
"", "$value",
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_GET, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2585,7 +2594,7 @@ e_o365_connection_create_mail_message_sync (EO365Connection *cnc,
GCancellable *cancellable,
GError **error)
{
- SoupMessage *message = NULL;
+ SoupMessage *message;
gboolean success;
gchar *uri;
@@ -2599,7 +2608,7 @@ e_o365_connection_create_mail_message_sync (EO365Connection *cnc,
folder_id ? "messages" : NULL,
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2629,7 +2638,7 @@ e_o365_connection_add_mail_message_attachment_sync (EO365Connection *cnc,
GCancellable *cancellable,
GError **error)
{
- SoupMessage *message = NULL;
+ SoupMessage *message;
JsonObject *added_attachment = NULL;
gboolean success;
gchar *uri;
@@ -2643,7 +2652,7 @@ e_o365_connection_add_mail_message_attachment_sync (EO365Connection *cnc,
"attachments",
NULL);
- message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, error);
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
if (!message) {
g_free (uri);
@@ -2667,3 +2676,359 @@ e_o365_connection_add_mail_message_attachment_sync (EO365Connection *cnc,
return success;
}
+
+/* https://docs.microsoft.com/en-us/graph/api/message-update?view=graph-rest-1.0&tabs=http */
+
+SoupMessage *
+e_o365_connection_prepare_update_mail_message (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the
account user */
+ const gchar *message_id,
+ JsonBuilder *mail_message, /* values to update, as a
mailMessage object */
+ GError **error)
+{
+ SoupMessage *message;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), NULL);
+ g_return_val_if_fail (message_id != NULL, NULL);
+ g_return_val_if_fail (mail_message != NULL, NULL);
+
+ uri = e_o365_connection_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "messages",
+ message_id,
+ NULL,
+ NULL);
+
+ /* The server returns the mailMessage object back, but it can be ignored here */
+ message = o365_connection_new_soup_message ("PATCH", uri, CSM_DISABLE_RESPONSE, error);
+
+ if (!message) {
+ g_free (uri);
+
+ return NULL;
+ }
+
+ g_free (uri);
+
+ e_o365_connection_set_json_body (message, mail_message);
+
+ return message;
+}
+
+gboolean
+e_o365_connection_update_mail_message_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the
account user */
+ const gchar *message_id,
+ JsonBuilder *mail_message, /* values to update, as a mailMessage
object */
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessage *message;
+ gboolean success;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (message_id != NULL, FALSE);
+ g_return_val_if_fail (mail_message != NULL, FALSE);
+
+ message = e_o365_connection_prepare_update_mail_message (cnc, user_override, message_id,
mail_message, error);
+
+ if (!message)
+ return FALSE;
+
+ 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/message-copy?view=graph-rest-1.0&tabs=http
+ https://docs.microsoft.com/en-us/graph/api/message-move?view=graph-rest-1.0&tabs=http
+ */
+static SoupMessage *
+e_o365_connection_prepare_copy_move_mail_message (EO365Connection *cnc,
+ const gchar *user_override,
+ const gchar *message_id,
+ const gchar *des_folder_id,
+ gboolean do_copy,
+ GError **error)
+{
+ SoupMessage *message;
+ JsonBuilder *builder;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), NULL);
+ g_return_val_if_fail (message_id != NULL, NULL);
+
+ uri = e_o365_connection_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "messages",
+ message_id,
+ do_copy ? "copy" : "move",
+ NULL);
+
+ message = o365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
+
+ if (!message) {
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ builder = json_builder_new_immutable ();
+
+ e_o365_json_begin_object_member (builder, NULL);
+ e_o365_json_add_string_member (builder, "destinationId", des_folder_id);
+ e_o365_json_end_object_member (builder);
+
+ e_o365_connection_set_json_body (message, builder);
+
+ g_object_unref (builder);
+
+ return message;
+}
+
+/* out_des_message_ids: Camel-pooled gchar *, new ids, in the same order as in message_ids; can be partial */
+gboolean
+e_o365_connection_copy_move_mail_messages_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const GSList *message_ids, /* const gchar * */
+ const gchar *des_folder_id,
+ gboolean do_copy,
+ GSList **out_des_message_ids, /* Camel-pooled gchar * */
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean success;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (message_ids != NULL, FALSE);
+ g_return_val_if_fail (des_folder_id != NULL, FALSE);
+ g_return_val_if_fail (out_des_message_ids != NULL, FALSE);
+
+ *out_des_message_ids = NULL;
+
+ if (g_slist_next (message_ids)) {
+ GPtrArray *requests;
+ GSList *link;
+ guint total, done = 0;
+
+ total = g_slist_length ((GSList *) message_ids);
+ requests = g_ptr_array_new_full (MIN (E_O365_BATCH_MAX_REQUESTS, 50), g_object_unref);
+
+ for (link = (GSList *) message_ids; link && success; link = g_slist_next (link)) {
+ const gchar *id = link->data;
+ SoupMessage *message;
+
+ message = e_o365_connection_prepare_copy_move_mail_message (cnc, user_override, id,
des_folder_id, do_copy, error);
+
+ if (!message) {
+ success = FALSE;
+ break;
+ }
+
+ g_ptr_array_add (requests, message);
+
+ if (requests->len == E_O365_BATCH_MAX_REQUESTS || !link->next) {
+ if (requests->len == 1) {
+ JsonObject *response = NULL;
+
+ success = o365_connection_send_request_sync (cnc, message,
e_o365_read_json_object_response_cb, NULL, &response, cancellable, error);
+
+ if (response) {
+ *out_des_message_ids = g_slist_prepend (*out_des_message_ids,
+ (gpointer) camel_pstring_strdup
(e_o365_mail_message_get_id (response)));
+ json_object_unref (response);
+ } else {
+ success = FALSE;
+ }
+ } else {
+ success = e_o365_connection_batch_request_sync (cnc, E_O365_API_V1_0,
requests, cancellable, error);
+
+ if (success) {
+ guint ii;
+
+ for (ii = 0; success && ii < requests->len; ii++) {
+ JsonNode *node = NULL;
+
+ message = g_ptr_array_index (requests, ii);
+
+ success = e_o365_connection_json_node_from_message
(message, NULL, &node, cancellable, error);
+
+ if (success && node && JSON_NODE_HOLDS_OBJECT (node))
{
+ JsonObject *response;
+
+ response = json_node_get_object (node);
+
+ if (response) {
+ *out_des_message_ids =
g_slist_prepend (*out_des_message_ids,
+ (gpointer)
camel_pstring_strdup (e_o365_mail_message_get_id (response)));
+ } else {
+ success = FALSE;
+ }
+ } else {
+ success = FALSE;
+ }
+
+ if (node)
+ json_node_unref (node);
+ }
+ }
+ }
+
+ g_ptr_array_remove_range (requests, 0, requests->len);
+
+ done += requests->len;
+
+ camel_operation_progress (cancellable, done * 100.0 / total);
+ }
+ }
+
+ g_ptr_array_free (requests, TRUE);
+ } else {
+ SoupMessage *message;
+
+ message = e_o365_connection_prepare_copy_move_mail_message (cnc, user_override,
message_ids->data, des_folder_id, do_copy, error);
+
+ if (message) {
+ JsonObject *response = NULL;
+
+ success = o365_connection_send_request_sync (cnc, message,
e_o365_read_json_object_response_cb, NULL, &response, cancellable, error);
+
+ if (response) {
+ *out_des_message_ids = g_slist_prepend (*out_des_message_ids,
+ (gpointer) camel_pstring_strdup (e_o365_mail_message_get_id
(response)));
+ json_object_unref (response);
+ } else {
+ success = FALSE;
+ }
+
+ g_clear_object (&message);
+ } else {
+ success = FALSE;
+ }
+ }
+
+ *out_des_message_ids = g_slist_reverse (*out_des_message_ids);
+
+ return success;
+}
+
+/* https://docs.microsoft.com/en-us/graph/api/message-delete?view=graph-rest-1.0&tabs=http */
+
+static SoupMessage *
+e_o365_connection_prepare_delete_mail_message (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the
account user */
+ const gchar *message_id,
+ GError **error)
+{
+ SoupMessage *message;
+ gchar *uri;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), NULL);
+ g_return_val_if_fail (message_id != NULL, NULL);
+
+ uri = e_o365_connection_construct_uri (cnc, TRUE, user_override, E_O365_API_V1_0, NULL,
+ "messages",
+ message_id,
+ NULL,
+ NULL);
+
+ message = o365_connection_new_soup_message (SOUP_METHOD_DELETE, uri, CSM_DEFAULT, error);
+
+ if (!message) {
+ g_free (uri);
+
+ return NULL;
+ }
+
+ g_free (uri);
+
+ return message;
+}
+
+gboolean
+e_o365_connection_delete_mail_messages_sync (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use the
account user */
+ const GSList *message_ids, /* const gchar * */
+ GSList **out_deleted_ids, /* (transfer container): const gchar
*, borrowed from message_ids */
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean success;
+
+ g_return_val_if_fail (E_IS_O365_CONNECTION (cnc), FALSE);
+ g_return_val_if_fail (message_ids != NULL, FALSE);
+
+ if (g_slist_next (message_ids)) {
+ GPtrArray *requests;
+ GSList *link, *from_link = (GSList *) message_ids;
+ guint total, done = 0;
+
+ total = g_slist_length ((GSList *) message_ids);
+ requests = g_ptr_array_new_full (MIN (E_O365_BATCH_MAX_REQUESTS, 50), g_object_unref);
+
+ for (link = (GSList *) message_ids; link && success; link = g_slist_next (link)) {
+ const gchar *id = link->data;
+ SoupMessage *message;
+
+ message = e_o365_connection_prepare_delete_mail_message (cnc, user_override, id,
error);
+
+ if (!message) {
+ success = FALSE;
+ break;
+ }
+
+ g_ptr_array_add (requests, message);
+
+ if (requests->len == E_O365_BATCH_MAX_REQUESTS || !link->next) {
+ if (requests->len == 1) {
+ success = o365_connection_send_request_sync (cnc, message, NULL,
e_o365_read_no_response_cb, NULL, cancellable, error);
+ } else {
+ success = e_o365_connection_batch_request_sync (cnc, E_O365_API_V1_0,
requests, cancellable, error);
+ }
+
+ if (success && out_deleted_ids) {
+ while (from_link) {
+ *out_deleted_ids = g_slist_prepend (*out_deleted_ids,
from_link->data);
+
+ if (from_link == link)
+ break;
+
+ from_link = g_slist_next (from_link);
+ }
+ }
+
+ g_ptr_array_remove_range (requests, 0, requests->len);
+ from_link = g_slist_next (link);
+
+ done += requests->len;
+
+ camel_operation_progress (cancellable, done * 100.0 / total);
+ }
+ }
+
+ g_ptr_array_free (requests, TRUE);
+ } else {
+ SoupMessage *message;
+
+ message = e_o365_connection_prepare_delete_mail_message (cnc, user_override,
message_ids->data, error);
+
+ if (message) {
+ success = o365_connection_send_request_sync (cnc, message, NULL,
e_o365_read_no_response_cb, NULL, cancellable, error);
+
+ if (success && out_deleted_ids)
+ *out_deleted_ids = g_slist_prepend (*out_deleted_ids, message_ids->data);
+
+ g_clear_object (&message);
+ } else {
+ success = FALSE;
+ }
+ }
+
+ if (out_deleted_ids && *out_deleted_ids && g_slist_next (*out_deleted_ids))
+ *out_deleted_ids = g_slist_reverse (*out_deleted_ids);
+
+ return success;
+}
diff --git a/src/Office365/common/e-o365-connection.h b/src/Office365/common/e-o365-connection.h
index 1ab45af2..f8af1cfd 100644
--- a/src/Office365/common/e-o365-connection.h
+++ b/src/Office365/common/e-o365-connection.h
@@ -252,6 +252,35 @@ gboolean e_o365_connection_add_mail_message_attachment_sync
gchar **out_attachment_id,
GCancellable *cancellable,
GError **error);
+SoupMessage * e_o365_connection_prepare_update_mail_message
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const gchar *message_id,
+ JsonBuilder *mail_message, /* values to update, as a
mailMessage object */
+ GError **error);
+gboolean e_o365_connection_update_mail_message_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const gchar *message_id,
+ JsonBuilder *mail_message, /* values to update, as a
mailMessage object */
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_o365_connection_copy_move_mail_messages_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const GSList *message_ids, /* const gchar * */
+ const gchar *des_folder_id,
+ gboolean do_copy,
+ GSList **out_des_message_ids, /* Camel-pooled gchar *, can
be partial */
+ GCancellable *cancellable,
+ GError **error);
+gboolean e_o365_connection_delete_mail_messages_sync
+ (EO365Connection *cnc,
+ const gchar *user_override, /* for which user, NULL to use
the account user */
+ const GSList *message_ids, /* const gchar * */
+ GSList **out_deleted_ids, /* (transfer container): const
gchar *, borrowed from message_ids */
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]