[evolution-ews/wip/mcrha/office365] Add few more Camel stubs (copied from EWS and adapted)
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/mcrha/office365] Add few more Camel stubs (copied from EWS and adapted)
- Date: Thu, 18 Jun 2020 14:13:27 +0000 (UTC)
commit 75b5192099118e4dbda56f5f14edacfdf9e01abd
Author: Milan Crha <mcrha redhat com>
Date: Thu Jun 18 16:13:00 2020 +0200
Add few more Camel stubs (copied from EWS and adapted)
src/Office365/camel/CMakeLists.txt | 6 +
src/Office365/camel/camel-o365-folder-summary.c | 317 +++++++++++++
src/Office365/camel/camel-o365-folder-summary.h | 83 ++++
src/Office365/camel/camel-o365-folder.c | 571 ++++++++++++++++++++++++
src/Office365/camel/camel-o365-folder.h | 70 +++
src/Office365/camel/camel-o365-message-info.c | 420 +++++++++++++++++
src/Office365/camel/camel-o365-message-info.h | 81 ++++
src/Office365/camel/camel-o365-store-summary.c | 121 +++++
src/Office365/camel/camel-o365-store-summary.h | 12 +
src/Office365/camel/camel-o365-store.c | 178 +++++---
src/Office365/camel/camel-o365-store.h | 12 +
11 files changed, 1800 insertions(+), 71 deletions(-)
---
diff --git a/src/Office365/camel/CMakeLists.txt b/src/Office365/camel/CMakeLists.txt
index 64167043..acdd56ec 100644
--- a/src/Office365/camel/CMakeLists.txt
+++ b/src/Office365/camel/CMakeLists.txt
@@ -7,6 +7,12 @@ set(DEPENDENCIES
)
set(SOURCES
+ camel-o365-folder.c
+ camel-o365-folder.h
+ camel-o365-folder-summary.c
+ camel-o365-folder-summary.h
+ camel-o365-message-info.c
+ camel-o365-message-info.h
camel-o365-provider.c
camel-o365-store.c
camel-o365-store.h
diff --git a/src/Office365/camel/camel-o365-folder-summary.c b/src/Office365/camel/camel-o365-folder-summary.c
new file mode 100644
index 00000000..fe5f5fc3
--- /dev/null
+++ b/src/Office365/camel/camel-o365-folder-summary.c
@@ -0,0 +1,317 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat (www.redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "evolution-ews-config.h"
+
+#include <glib.h>
+
+#include "camel-o365-folder.h"
+
+#include "camel-o365-folder-summary.h"
+
+#define LOCK(_summary) g_mutex_lock (&_summary->priv->property_lock)
+#define UNLOCK(_summary) g_mutex_unlock (&_summary->priv->property_lock)
+
+struct _CamelO365FolderSummaryPrivate {
+ GMutex property_lock;
+ gchar *delta_link;
+ gint32 version;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (CamelO365FolderSummary, camel_o365_folder_summary, CAMEL_TYPE_FOLDER_SUMMARY)
+
+static gboolean
+o365_folder_summary_header_load (CamelFolderSummary *summary,
+ CamelFIRecord *mir)
+{
+ CamelO365FolderSummary *o365_summary = CAMEL_O365_FOLDER_SUMMARY (summary);
+ const gchar *delta_link = NULL;
+ gchar *part;
+
+ if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_o365_folder_summary_parent_class)->summary_header_load
(summary, mir))
+ return FALSE;
+
+ o365_summary->priv->version = 0;
+
+ part = mir->bdata;
+
+ if (part)
+ o365_summary->priv->version = camel_util_bdata_get_number (&part, 0);
+
+ if (part && *part && part[1])
+ delta_link = part + 1;
+
+ /* Do not call camel_o365_folder_summary_set_sync_state() here,
+ to not mark the summary dirty after load. */
+ LOCK (o365_summary);
+
+ if (g_strcmp0 (o365_summary->priv->delta_link, delta_link) != 0) {
+ g_free (o365_summary->priv->delta_link);
+ o365_summary->priv->delta_link = g_strdup (delta_link);
+ }
+
+ UNLOCK (o365_summary);
+
+ return TRUE;
+}
+
+static CamelFIRecord *
+o365_folder_summary_header_save (CamelFolderSummary *summary,
+ GError **error)
+{
+ CamelO365FolderSummary *o365_summary = CAMEL_O365_FOLDER_SUMMARY (summary);
+ CamelFIRecord *fir;
+ gchar *delta_link;
+
+ fir = CAMEL_FOLDER_SUMMARY_CLASS (camel_o365_folder_summary_parent_class)->summary_header_save
(summary, error);
+
+ if (!fir)
+ return NULL;
+
+ delta_link = camel_o365_folder_summary_dup_delta_link (o365_summary);
+
+ fir->bdata = g_strdup_printf ("%d %s", CAMEL_O365_FOLDER_SUMMARY_VERSION, delta_link ? delta_link :
"");
+
+ g_free (delta_link);
+
+ LOCK (o365_summary);
+
+ o365_summary->priv->version = CAMEL_O365_FOLDER_SUMMARY_VERSION;
+
+ UNLOCK (o365_summary);
+
+ return fir;
+}
+
+static void
+o365_folder_summary_finalize (GObject *object)
+{
+ CamelO365FolderSummary *o365_summary = CAMEL_O365_FOLDER_SUMMARY (object);
+
+ g_free (o365_summary->priv->delta_link);
+ g_mutex_clear (&o365_summary->priv->property_lock);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_o365_folder_summary_parent_class)->finalize (object);
+}
+
+static void
+camel_o365_folder_summary_class_init (CamelO365FolderSummaryClass *class)
+{
+ CamelFolderSummaryClass *folder_summary_class;
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = o365_folder_summary_finalize;
+
+ folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (class);
+ folder_summary_class->message_info_type = CAMEL_TYPE_O365_MESSAGE_INFO;
+ folder_summary_class->summary_header_save = o365_folder_summary_header_save;
+ folder_summary_class->summary_header_load = o365_folder_summary_header_load;
+}
+
+static void
+camel_o365_folder_summary_init (CamelO365FolderSummary *o365_summary)
+{
+ o365_summary->priv = camel_o365_folder_summary_get_instance_private (o365_summary);
+
+ g_mutex_init (&o365_summary->priv->property_lock);
+}
+
+CamelFolderSummary *
+camel_o365_folder_summary_new (struct _CamelFolder *folder)
+{
+ CamelFolderSummary *summary;
+
+ summary = g_object_new (CAMEL_TYPE_O365_FOLDER_SUMMARY, "folder", folder, NULL);
+
+ camel_folder_summary_load (summary, NULL);
+
+ return summary;
+}
+
+gint
+camel_o365_folder_summary_get_version (CamelO365FolderSummary *o365_summary)
+{
+ gint version;
+
+ g_return_val_if_fail (CAMEL_IS_O365_FOLDER_SUMMARY (o365_summary), -1);
+
+ LOCK (o365_summary);
+
+ version = o365_summary->priv->version;
+
+ UNLOCK (o365_summary);
+
+ return version;
+}
+
+void
+camel_o365_folder_summary_set_delta_link (CamelO365FolderSummary *o365_summary,
+ const gchar *delta_link)
+{
+ gboolean changed = FALSE;
+
+ g_return_if_fail (CAMEL_IS_O365_FOLDER_SUMMARY (o365_summary));
+
+ LOCK (o365_summary);
+
+ if (g_strcmp0 (o365_summary->priv->delta_link, delta_link) != 0) {
+ gchar *dup = g_strdup (delta_link);
+
+ g_free (o365_summary->priv->delta_link);
+ o365_summary->priv->delta_link = dup;
+
+ changed = TRUE;
+ }
+
+ UNLOCK (o365_summary);
+
+ if (changed)
+ camel_folder_summary_touch (CAMEL_FOLDER_SUMMARY (o365_summary));
+}
+
+gchar *
+camel_o365_folder_summary_dup_delta_link (CamelO365FolderSummary *o365_summary)
+{
+ gchar *delta_link;
+
+ g_return_val_if_fail (CAMEL_IS_O365_FOLDER_SUMMARY (o365_summary), NULL);
+
+ LOCK (o365_summary);
+
+ delta_link = g_strdup (o365_summary->priv->delta_link);
+
+ UNLOCK (o365_summary);
+
+ return delta_link;
+}
+
+void
+camel_o365_folder_summary_clear (CamelFolderSummary *summary)
+{
+ CamelFolderChangeInfo *changes;
+ GPtrArray *known_uids;
+ gint i;
+
+ changes = camel_folder_change_info_new ();
+ known_uids = camel_folder_summary_get_array (summary);
+
+ for (i = 0; i < known_uids->len; i++) {
+ const gchar *uid = g_ptr_array_index (known_uids, i);
+
+ if (!uid)
+ continue;
+
+ camel_folder_change_info_remove_uid (changes, uid);
+ }
+
+ camel_folder_summary_clear (summary, NULL);
+
+ if (camel_folder_change_info_changed (changes))
+ camel_folder_changed (camel_folder_summary_get_folder (summary), changes);
+ camel_folder_change_info_free (changes);
+ camel_folder_summary_free_array (known_uids);
+}
+
+static gboolean
+o365_folder_summary_update_user_flags (CamelMessageInfo *info,
+ const CamelNamedFlags *server_user_flags)
+{
+ gboolean changed = FALSE;
+ gboolean set_cal = FALSE, set_note = FALSE;
+
+ if (camel_message_info_get_user_flag (info, "$has_cal"))
+ set_cal = TRUE;
+ if (camel_message_info_get_user_flag (info, "$has_note"))
+ set_note = TRUE;
+
+ changed = camel_message_info_take_user_flags (info, camel_named_flags_copy (server_user_flags));
+
+ /* reset the flags as they were set in messageinfo before */
+ if (set_cal)
+ camel_message_info_set_user_flag (info, "$has_cal", TRUE);
+ if (set_note)
+ camel_message_info_set_user_flag (info, "$has_note", TRUE);
+
+ return changed;
+}
+
+gboolean
+camel_o365_folder_summary_update_message_info_flags (CamelFolderSummary *summary,
+ CamelMessageInfo *info,
+ guint32 server_flags,
+ const CamelNamedFlags *server_user_flags)
+{
+ CamelO365MessageInfo *omi;
+ gboolean changed = FALSE;
+
+ g_return_val_if_fail (CAMEL_IS_O365_FOLDER_SUMMARY (summary), FALSE);
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (info), FALSE);
+
+ omi = CAMEL_O365_MESSAGE_INFO (info);
+
+ if (server_flags != camel_o365_message_info_get_server_flags (omi)) {
+ guint32 server_set, server_cleared;
+
+ server_set = server_flags & ~camel_o365_message_info_get_server_flags (omi);
+ server_cleared = camel_o365_message_info_get_server_flags (omi) & ~server_flags;
+
+ camel_message_info_set_flags (info, server_set | server_cleared,
(camel_message_info_get_flags (info) | server_set) & ~server_cleared);
+ camel_o365_message_info_set_server_flags (omi, server_flags);
+ changed = TRUE;
+ }
+
+ if (server_user_flags && o365_folder_summary_update_user_flags (info, server_user_flags))
+ changed = TRUE;
+
+ return changed;
+}
+
+gboolean
+camel_o365_folder_summary_add_message (CamelFolderSummary *summary,
+ const gchar *uid,
+ const gchar *change_key,
+ CamelMessageInfo *info,
+ CamelMimeMessage *message)
+{
+ CamelMessageInfo *mi;
+
+ g_return_val_if_fail (uid != NULL, FALSE);
+ g_return_val_if_fail (info != NULL, FALSE);
+ g_return_val_if_fail (message != NULL, FALSE);
+
+ mi = camel_folder_summary_info_new_from_message (summary, message);
+ g_return_val_if_fail (mi != NULL, FALSE);
+
+ camel_message_info_set_abort_notifications (mi, TRUE);
+
+ camel_o365_message_info_set_change_key (CAMEL_O365_MESSAGE_INFO (mi), change_key);
+ camel_message_info_set_flags (mi, ~0, camel_message_info_get_flags (info));
+ camel_message_info_take_user_flags (mi, camel_message_info_dup_user_flags (info));
+ camel_message_info_take_user_tags (mi, camel_message_info_dup_user_tags (info));
+ camel_message_info_set_size (mi, camel_message_info_get_size (info));
+ camel_message_info_set_uid (mi, uid);
+
+ camel_message_info_set_abort_notifications (mi, FALSE);
+
+ camel_folder_summary_add (summary, mi, FALSE);
+
+ g_object_unref (mi);
+
+ return TRUE;
+}
diff --git a/src/Office365/camel/camel-o365-folder-summary.h b/src/Office365/camel/camel-o365-folder-summary.h
new file mode 100644
index 00000000..a8c79b59
--- /dev/null
+++ b/src/Office365/camel/camel-o365-folder-summary.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat (www.redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAMEL_O365_FOLDER_SUMMARY_H
+#define CAMEL_O365_FOLDER_SUMMARY_H
+
+#include <camel/camel.h>
+
+#include "camel-o365-message-info.h"
+
+#define CAMEL_O365_FOLDER_SUMMARY_VERSION (1)
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_O365_FOLDER_SUMMARY \
+ (camel_o365_folder_summary_get_type ())
+#define CAMEL_O365_FOLDER_SUMMARY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_O365_FOLDER_SUMMARY, CamelO365FolderSummary))
+#define CAMEL_O365_FOLDER_SUMMARY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_O365_FOLDER_SUMMARY, CamelO365FolderSummaryClass))
+#define CAMEL_IS_O365_FOLDER_SUMMARY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_O365_FOLDER_SUMMARY))
+#define CAMEL_IS_O365_FOLDER_SUMMARY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_O365_FOLDER_SUMMARY))
+#define CAMEL_O365_FOLDER_SUMMARY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_O365_FOLDER_SUMMARY, CamelO365FolderSummaryClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelO365FolderSummary CamelO365FolderSummary;
+typedef struct _CamelO365FolderSummaryClass CamelO365FolderSummaryClass;
+typedef struct _CamelO365FolderSummaryPrivate CamelO365FolderSummaryPrivate;
+
+struct _CamelO365FolderSummary {
+ CamelFolderSummary parent;
+ CamelO365FolderSummaryPrivate *priv;
+};
+
+struct _CamelO365FolderSummaryClass {
+ CamelFolderSummaryClass parent_class;
+};
+
+GType camel_o365_folder_summary_get_type (void);
+
+CamelFolderSummary *
+ camel_o365_folder_summary_new (CamelFolder *folder);
+gint camel_o365_folder_summary_get_version (CamelO365FolderSummary *o365_summary);
+void camel_o365_folder_summary_set_delta_link(CamelO365FolderSummary *o365_summary,
+ const gchar *delta_link);
+gchar * camel_o365_folder_summary_dup_delta_link(CamelO365FolderSummary *o365_summary);
+void camel_o365_folder_summary_clear (CamelFolderSummary *summary);
+gboolean camel_o365_folder_summary_update_message_info_flags
+ (CamelFolderSummary *summary,
+ CamelMessageInfo *info,
+ guint32 server_flags,
+ const CamelNamedFlags *server_user_flags);
+gboolean camel_o365_folder_summary_add_message (CamelFolderSummary *summary,
+ const gchar *uid,
+ const gchar *change_key,
+ CamelMessageInfo *info,
+ CamelMimeMessage *message);
+
+G_END_DECLS
+
+#endif /* CAMEL_O365_FOLDER_SUMMARY_H */
diff --git a/src/Office365/camel/camel-o365-folder.c b/src/Office365/camel/camel-o365-folder.c
new file mode 100644
index 00000000..7d4f9e42
--- /dev/null
+++ b/src/Office365/camel/camel-o365-folder.c
@@ -0,0 +1,571 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat (www.redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "evolution-ews-config.h"
+
+#include <string.h>
+
+#include <glib/gi18n-lib.h>
+
+#include "common/camel-o365-settings.h"
+#include "common/e-o365-connection.h"
+
+#include "camel-o365-folder-summary.h"
+#include "camel-o365-store.h"
+#include "camel-o365-store-summary.h"
+
+#include "camel-o365-folder.h"
+
+#define O365_LOCAL_CACHE_PATH "cur"
+
+#define LOCK_CACHE(_folder) g_rec_mutex_lock (&_folder->priv->cache_lock)
+#define UNLOCK_CACHE(_folder) g_rec_mutex_unlock (&_folder->priv->cache_lock)
+
+#define LOCK_SEARCH(_folder) g_mutex_lock (&_folder->priv->search_lock)
+#define UNLOCK_SEARCH(_folder) g_mutex_unlock (&_folder->priv->search_lock)
+
+struct _CamelO365FolderPrivate {
+ GRecMutex cache_lock;
+ CamelDataCache *cache;
+
+ GMutex search_lock;
+ CamelFolderSearch *search;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (CamelO365Folder, camel_o365_folder, CAMEL_TYPE_OFFLINE_FOLDER)
+
+static GChecksum *
+o365_folder_cache_new_checksum (const gchar *id)
+{
+ GChecksum *checksum;
+
+ g_return_val_if_fail (id != NULL, NULL);
+
+ /* No need to use SHA here, the string is short, will not collide with the others */
+ checksum = g_checksum_new (G_CHECKSUM_MD5);
+
+ g_checksum_update (checksum, (const guchar *) id, strlen (id));
+
+ return checksum;
+}
+
+static CamelStream *
+o365_folder_cache_add (CamelO365Folder *o365_folder,
+ const gchar *id,
+ GError **error)
+{
+ GIOStream *base_stream;
+ CamelStream *stream = NULL;
+ GChecksum *checksum;
+
+ checksum = o365_folder_cache_new_checksum (id);
+
+ LOCK_CACHE (o365_folder);
+ base_stream = camel_data_cache_add (o365_folder->priv->cache, O365_LOCAL_CACHE_PATH,
g_checksum_get_string (checksum), error);
+ UNLOCK_CACHE (o365_folder);
+
+ g_checksum_free (checksum);
+
+ if (base_stream) {
+ stream = camel_stream_new (base_stream);
+ g_object_unref (base_stream);
+ }
+
+ return stream;
+}
+
+static gint
+o365_folder_cache_remove (CamelO365Folder *o365_folder,
+ const gchar *id,
+ GError **error)
+{
+ GChecksum *checksum;
+ gint ret;
+
+ checksum = o365_folder_cache_new_checksum (id);
+
+ LOCK_CACHE (o365_folder);
+ ret = camel_data_cache_remove (o365_folder->priv->cache, O365_LOCAL_CACHE_PATH, g_checksum_get_string
(checksum), error);
+ UNLOCK_CACHE (o365_folder);
+
+ g_checksum_free (checksum);
+
+ return ret;
+}
+
+static CamelStream *
+o365_folder_cache_get (CamelO365Folder *o365_folder,
+ const gchar *id,
+ GError **error)
+{
+ GChecksum *checksum;
+ CamelStream *stream = NULL;
+ GIOStream *base_stream;
+
+ checksum = o365_folder_cache_new_checksum (id);
+
+ LOCK_CACHE (o365_folder);
+ base_stream = camel_data_cache_get (o365_folder->priv->cache, O365_LOCAL_CACHE_PATH,
g_checksum_get_string (checksum), error);
+ UNLOCK_CACHE (o365_folder);
+
+ g_checksum_free (checksum);
+
+ if (base_stream) {
+ stream = camel_stream_new (base_stream);
+ g_object_unref (base_stream);
+ }
+
+ return stream;
+}
+
+static gchar *
+o365_folder_cache_dup_filename (CamelO365Folder *o365_folder,
+ const gchar *id)
+{
+ GChecksum *checksum;
+ gchar *filename;
+
+ checksum = o365_folder_cache_new_checksum (id);
+
+ LOCK_CACHE (o365_folder);
+ filename = camel_data_cache_get_filename (o365_folder->priv->cache, O365_LOCAL_CACHE_PATH,
g_checksum_get_string (checksum));
+ UNLOCK_CACHE (o365_folder);
+
+ g_checksum_free (checksum);
+
+ return filename;
+}
+
+static CamelMimeMessage *
+o365_folder_get_message_from_cache (CamelO365Folder *o365_folder,
+ const gchar *uid,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStream *stream;
+ CamelMimeMessage *msg;
+
+ stream = o365_folder_cache_get (o365_folder, uid, error);
+
+ if (!stream)
+ return NULL;
+
+ msg = camel_mime_message_new ();
+
+ if (!camel_data_wrapper_construct_from_stream_sync (CAMEL_DATA_WRAPPER (msg), stream, cancellable,
error))
+ g_clear_object (&msg);
+
+ g_object_unref (stream);
+
+ return msg;
+}
+
+static gchar *
+o365_folder_get_filename (CamelFolder *folder,
+ const gchar *uid,
+ GError **error)
+{
+ CamelO365Folder *o365_folder = CAMEL_O365_FOLDER (folder);
+
+ return o365_folder_cache_dup_filename (o365_folder, uid);
+}
+
+static void
+o365_folder_save_summary (CamelO365Folder *o365_folder)
+{
+ CamelFolderSummary *summary;
+
+ g_return_if_fail (CAMEL_IS_O365_FOLDER (o365_folder));
+
+ summary = camel_folder_get_folder_summary (CAMEL_FOLDER (o365_folder));
+
+ if (summary) {
+ GError *error = NULL;
+
+ if (!camel_folder_summary_save (summary, &error))
+ g_warning ("%s: Failed to save summary: %s", G_STRFUNC, error ? error->message :
"Unknown error");
+
+ g_clear_error (&error);
+ }
+}
+
+static guint32
+o365_folder_get_permanent_flags (CamelFolder *folder)
+{
+ return CAMEL_MESSAGE_ANSWERED |
+ CAMEL_MESSAGE_DELETED |
+ CAMEL_MESSAGE_DRAFT |
+ CAMEL_MESSAGE_FLAGGED |
+ CAMEL_MESSAGE_SEEN |
+ CAMEL_MESSAGE_FORWARDED |
+ CAMEL_MESSAGE_USER;
+}
+
+static CamelMimeMessage *
+o365_folder_get_message_cached (CamelFolder *folder,
+ const gchar *message_uid,
+ GCancellable *cancellable)
+{
+ return o365_folder_get_message_from_cache (CAMEL_O365_FOLDER (folder), message_uid, cancellable,
NULL);
+}
+
+static void
+o365_folder_exec_search (CamelFolder *folder,
+ const gchar *expression,
+ GPtrArray *uids,
+ GPtrArray **out_matches,
+ guint32 *out_count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelO365Folder *o365_folder;
+
+ g_return_if_fail (CAMEL_IS_O365_FOLDER (folder));
+
+ o365_folder = CAMEL_O365_FOLDER (folder);
+
+ LOCK_SEARCH (o365_folder);
+
+ camel_folder_search_set_folder (o365_folder->priv->search, folder);
+
+ if (out_matches)
+ *out_matches = camel_folder_search_search (o365_folder->priv->search, expression, uids,
cancellable, error);
+
+ if (out_count)
+ *out_count = camel_folder_search_count (o365_folder->priv->search, expression, cancellable,
error);
+
+ UNLOCK_SEARCH (o365_folder);
+}
+
+static GPtrArray *
+o365_folder_search_by_expression (CamelFolder *folder,
+ const gchar *expression,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GPtrArray *matches = NULL;
+
+ o365_folder_exec_search (folder, expression, NULL, &matches, NULL, cancellable, error);
+
+ return matches;
+}
+
+static guint32
+o365_folder_count_by_expression (CamelFolder *folder,
+ const gchar *expression,
+ GCancellable *cancellable,
+ GError **error)
+{
+ guint32 count = 0;
+
+ o365_folder_exec_search (folder, expression, NULL, NULL, &count, cancellable, error);
+
+ return count;
+}
+
+static GPtrArray *
+o365_folder_search_by_uids (CamelFolder *folder,
+ const gchar *expression,
+ GPtrArray *uids,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GPtrArray *matches = NULL;
+
+ if (uids->len == 0)
+ return g_ptr_array_new ();
+
+ o365_folder_exec_search (folder, expression, uids, &matches, NULL, cancellable, error);
+
+ return matches;
+}
+
+static void
+o365_folder_search_free (CamelFolder *folder,
+ GPtrArray *uids)
+{
+ CamelO365Folder *o365_folder;
+
+ if (!uids)
+ return;
+
+ g_return_if_fail (CAMEL_IS_O365_FOLDER (folder));
+
+ o365_folder = CAMEL_O365_FOLDER (folder);
+
+ LOCK_SEARCH (o365_folder);
+
+ camel_folder_search_free_result (o365_folder->priv->search, uids);
+
+ UNLOCK_SEARCH (o365_folder);
+}
+
+static gint
+o365_folder_cmp_uids (CamelFolder *folder,
+ const gchar *uid1,
+ const gchar *uid2)
+{
+ g_return_val_if_fail (uid1 != NULL, 0);
+ g_return_val_if_fail (uid2 != NULL, 0);
+
+ return strcmp (uid1, uid2);
+}
+
+static void
+o365_folder_constructed (GObject *object)
+{
+ CamelSettings *settings;
+ CamelStore *parent_store;
+ CamelService *service;
+ CamelFolder *folder;
+ const gchar *full_name;
+ gchar *description;
+ gchar *user;
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_o365_folder_parent_class)->constructed (object);
+
+ folder = CAMEL_FOLDER (object);
+ full_name = camel_folder_get_full_name (folder);
+ parent_store = camel_folder_get_parent_store (folder);
+
+ service = CAMEL_SERVICE (parent_store);
+
+ settings = camel_service_ref_settings (service);
+ user = camel_network_settings_dup_user (CAMEL_NETWORK_SETTINGS (settings));
+
+ g_object_unref (settings);
+
+ description = g_strdup_printf ("%s@Office365:%s", user, full_name);
+ camel_folder_set_description (folder, description);
+ g_free (description);
+
+ g_free (user);
+}
+
+static void
+o365_folder_dispose (GObject *object)
+{
+ CamelO365Folder *o365_folder = CAMEL_O365_FOLDER (object);
+ CamelFolderSummary *summary;
+
+ summary = camel_folder_get_folder_summary (CAMEL_FOLDER (o365_folder));
+
+ if (summary)
+ o365_folder_save_summary (o365_folder);
+
+ LOCK_CACHE (o365_folder);
+ g_clear_object (&o365_folder->priv->cache);
+ UNLOCK_CACHE (o365_folder);
+
+ LOCK_SEARCH (o365_folder);
+ g_clear_object (&o365_folder->priv->search);
+ UNLOCK_SEARCH (o365_folder);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_o365_folder_parent_class)->dispose (object);
+}
+
+static void
+o365_folder_finalize (GObject *object)
+{
+ CamelO365Folder *o365_folder = CAMEL_O365_FOLDER (object);
+
+ g_rec_mutex_clear (&o365_folder->priv->cache_lock);
+ g_mutex_clear (&o365_folder->priv->search_lock);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_o365_folder_parent_class)->finalize (object);
+}
+
+static void
+camel_o365_folder_class_init (CamelO365FolderClass *klass)
+{
+ GObjectClass *object_class;
+ CamelFolderClass *folder_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = o365_folder_constructed;
+ object_class->dispose = o365_folder_dispose;
+ object_class->finalize = o365_folder_finalize;
+
+ folder_class = CAMEL_FOLDER_CLASS (klass);
+ folder_class->get_permanent_flags = o365_folder_get_permanent_flags;
+ folder_class->get_message_cached = o365_folder_get_message_cached;
+ folder_class->search_by_expression = o365_folder_search_by_expression;
+ folder_class->count_by_expression = o365_folder_count_by_expression;
+ folder_class->search_by_uids = o365_folder_search_by_uids;
+ folder_class->search_free = o365_folder_search_free;
+ folder_class->cmp_uids = o365_folder_cmp_uids;
+#if 0
+ 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;
+ 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;
+ folder_class->prepare_content_refresh = o365_folder_prepare_content_refresh;
+#endif
+ folder_class->get_filename = o365_folder_get_filename;
+}
+
+static void
+camel_o365_folder_init (CamelO365Folder *o365_folder)
+{
+ CamelFolder *folder = CAMEL_FOLDER (o365_folder);
+
+ o365_folder->priv = camel_o365_folder_get_instance_private (o365_folder);
+
+ g_rec_mutex_init (&o365_folder->priv->cache_lock);
+ g_mutex_init (&o365_folder->priv->search_lock);
+
+ camel_folder_set_flags (folder, CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY);
+ camel_folder_set_lock_async (folder, TRUE);
+}
+
+static gboolean
+o365_folder_has_inbox_type (CamelO365Store *o365_store,
+ const gchar *full_name)
+{
+ CamelO365StoreSummary *summary;
+ guint32 flags;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE (o365_store), FALSE);
+ g_return_val_if_fail (full_name != NULL, FALSE);
+
+ summary = camel_o365_store_ref_store_summary (o365_store);
+
+ if (!summary)
+ return FALSE;
+
+ flags = camel_o365_store_summary_get_folder_flags_for_full_name (summary, full_name);
+
+ g_object_unref (summary);
+
+ return (flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX;
+}
+
+CamelFolder *
+camel_o365_folder_new (CamelStore *store,
+ const gchar *display_name,
+ const gchar *full_name,
+ const gchar *folder_dir,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolder *folder;
+ CamelFolderSummary *folder_summary;
+ CamelO365Folder *o365_folder;
+ CamelSettings *settings;
+ gboolean filter_inbox = FALSE;
+ gboolean filter_junk = FALSE;
+ gboolean filter_junk_inbox = FALSE;
+ gboolean offline_limit_by_age = FALSE;
+ CamelTimeUnit offline_limit_unit;
+ gint offline_limit_value = 0;
+ guint32 add_folder_flags = 0;
+ gchar *state_file;
+
+ folder = g_object_new (CAMEL_TYPE_O365_FOLDER,
+ "display_name", display_name,
+ "full-name", full_name,
+ "parent_store", store,
+ NULL);
+
+ o365_folder = CAMEL_O365_FOLDER (folder);
+
+ folder_summary = camel_o365_folder_summary_new (folder);
+
+ if (!folder_summary) {
+ g_object_unref (folder);
+ g_set_error (
+ error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
+ _("Could not load summary for %s"), full_name);
+ return NULL;
+ }
+
+ settings = camel_service_ref_settings (CAMEL_SERVICE (store));
+
+ g_object_get (
+ settings,
+ "filter-inbox", &filter_inbox,
+ "filter-junk", &filter_junk,
+ "filter-junk-inbox", &filter_junk_inbox,
+ "limit-by-age", &offline_limit_by_age,
+ "limit-unit", &offline_limit_unit,
+ "limit-value", &offline_limit_value,
+ NULL);
+
+ g_clear_object (&settings);
+
+ camel_folder_take_folder_summary (folder, folder_summary);
+
+ /* set/load persistent state */
+ state_file = g_build_filename (folder_dir, "cmeta", NULL);
+ camel_object_set_state_filename (CAMEL_OBJECT (folder), state_file);
+ camel_object_state_read (CAMEL_OBJECT (folder));
+ g_free (state_file);
+
+ o365_folder->priv->cache = camel_data_cache_new (folder_dir, error);
+ if (!o365_folder->priv->cache) {
+ g_object_unref (folder);
+ return NULL;
+ }
+
+ if (camel_offline_folder_can_downsync (CAMEL_OFFLINE_FOLDER (folder))) {
+ time_t when = (time_t) 0;
+
+ if (offline_limit_by_age)
+ when = camel_time_value_apply (when, offline_limit_unit, offline_limit_value);
+
+ if (when <= (time_t) 0)
+ when = (time_t) -1;
+
+ /* Ensure cache will expire when set up, otherwise
+ * it causes redownload of messages too soon. */
+ camel_data_cache_set_expire_age (o365_folder->priv->cache, when);
+ camel_data_cache_set_expire_access (o365_folder->priv->cache, when);
+ } else {
+ /* Set cache expiration for one week. */
+ camel_data_cache_set_expire_age (o365_folder->priv->cache, 60 * 60 * 24 * 7);
+ camel_data_cache_set_expire_access (o365_folder->priv->cache, 60 * 60 * 24 * 7);
+ }
+
+ camel_binding_bind_property (store, "online",
+ o365_folder->priv->cache, "expire-enabled",
+ G_BINDING_SYNC_CREATE);
+
+ if (o365_folder_has_inbox_type (CAMEL_O365_STORE (store), full_name)) {
+ if (filter_inbox)
+ add_folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
+
+ if (filter_junk)
+ add_folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
+ } else {
+ if (filter_junk && !filter_junk_inbox)
+ add_folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
+ }
+
+ if (add_folder_flags)
+ camel_folder_set_flags (folder, camel_folder_get_flags (folder) | add_folder_flags);
+
+ camel_o365_store_connect_folder_summary (CAMEL_O365_STORE (store), folder_summary);
+
+ o365_folder->priv->search = camel_folder_search_new ();
+
+ return folder;
+}
diff --git a/src/Office365/camel/camel-o365-folder.h b/src/Office365/camel/camel-o365-folder.h
new file mode 100644
index 00000000..d189e72d
--- /dev/null
+++ b/src/Office365/camel/camel-o365-folder.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat (www.redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAMEL_O365_FOLDER_H
+#define CAMEL_O365_FOLDER_H
+
+#include <camel/camel.h>
+
+#include "camel-o365-folder-summary.h"
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_O365_FOLDER \
+ (camel_o365_folder_get_type ())
+#define CAMEL_O365_FOLDER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_O365_FOLDER, CamelO365Folder))
+#define CAMEL_O365_FOLDER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_O365_FOLDER, CamelO365FolderClass))
+#define CAMEL_IS_O365_FOLDER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_O365_FOLDER))
+#define CAMEL_IS_O365_FOLDER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_O365_FOLDER))
+#define CAMEL_O365_FOLDER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_O365_FOLDER, CamelO365FolderClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelO365Folder CamelO365Folder;
+typedef struct _CamelO365FolderClass CamelO365FolderClass;
+typedef struct _CamelO365FolderPrivate CamelO365FolderPrivate;
+
+struct _CamelO365Folder {
+ CamelOfflineFolder parent;
+ CamelO365FolderPrivate *priv;
+};
+
+struct _CamelO365FolderClass {
+ CamelOfflineFolderClass parent_class;
+};
+
+GType camel_o365_folder_get_type (void);
+
+CamelFolder * camel_o365_folder_new (CamelStore *store,
+ const gchar *display_name,
+ const gchar *full_name,
+ const gchar *folder_dir,
+ GCancellable *cancellable,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* CAMEL_O365_FOLDER_H */
diff --git a/src/Office365/camel/camel-o365-message-info.c b/src/Office365/camel/camel-o365-message-info.c
new file mode 100644
index 00000000..9d738624
--- /dev/null
+++ b/src/Office365/camel/camel-o365-message-info.c
@@ -0,0 +1,420 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat (www.redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "evolution-ews-config.h"
+
+#include <stdio.h>
+
+#include "camel/camel.h"
+
+#include "camel-o365-message-info.h"
+
+struct _CamelO365MessageInfoPrivate {
+ guint32 server_flags;
+ gint32 item_type;
+ gchar *change_key;
+};
+
+enum {
+ PROP_0,
+ PROP_SERVER_FLAGS,
+ PROP_ITEM_TYPE,
+ PROP_CHANGE_KEY,
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (CamelO365MessageInfo, camel_o365_message_info, CAMEL_TYPE_MESSAGE_INFO_BASE)
+
+static CamelMessageInfo *
+o365_message_info_clone (const CamelMessageInfo *mi,
+ CamelFolderSummary *assign_summary)
+{
+ CamelMessageInfo *result;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (mi), NULL);
+
+ result = CAMEL_MESSAGE_INFO_CLASS (camel_o365_message_info_parent_class)->clone (mi, assign_summary);
+ if (!result)
+ return NULL;
+
+ if (CAMEL_IS_O365_MESSAGE_INFO (result)) {
+ CamelO365MessageInfo *omi, *omi_result;
+
+ omi = CAMEL_O365_MESSAGE_INFO (mi);
+ omi_result = CAMEL_O365_MESSAGE_INFO (result);
+
+ camel_o365_message_info_set_server_flags (omi_result,
camel_o365_message_info_get_server_flags (omi));
+ camel_o365_message_info_set_item_type (omi_result, camel_o365_message_info_get_item_type
(omi));
+ camel_o365_message_info_take_change_key (omi_result, camel_o365_message_info_dup_change_key
(omi));
+ }
+
+ return result;
+}
+
+static gboolean
+o365_message_info_load (CamelMessageInfo *mi,
+ const CamelMIRecord *record,
+ /* const */ gchar **bdata_ptr)
+{
+ CamelO365MessageInfo *omi;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_ptr != NULL, FALSE);
+
+ if (!CAMEL_MESSAGE_INFO_CLASS (camel_o365_message_info_parent_class)->load ||
+ !CAMEL_MESSAGE_INFO_CLASS (camel_o365_message_info_parent_class)->load (mi, record, bdata_ptr))
+ return FALSE;
+
+ omi = CAMEL_O365_MESSAGE_INFO (mi);
+
+ if (*bdata_ptr) {
+ gchar **values;
+
+ values = g_strsplit (*bdata_ptr, " ", -1);
+
+ if (values && values[0] && values[1] && values[2]) {
+ camel_o365_message_info_set_server_flags (omi, g_ascii_strtoll (values[0], NULL, 10));
+ camel_o365_message_info_set_item_type (omi, g_ascii_strtoll (values[1], NULL, 10));
+ camel_o365_message_info_set_change_key (omi, values[2]);
+ }
+
+ g_strfreev (values);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+o365_message_info_save (const CamelMessageInfo *mi,
+ CamelMIRecord *record,
+ GString *bdata_str)
+{
+ CamelO365MessageInfo *omi;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (mi), FALSE);
+ g_return_val_if_fail (record != NULL, FALSE);
+ g_return_val_if_fail (bdata_str != NULL, FALSE);
+
+ if (!CAMEL_MESSAGE_INFO_CLASS (camel_o365_message_info_parent_class)->save ||
+ !CAMEL_MESSAGE_INFO_CLASS (camel_o365_message_info_parent_class)->save (mi, record, bdata_str))
+ return FALSE;
+
+ omi = CAMEL_O365_MESSAGE_INFO (mi);
+
+ g_string_append_printf (bdata_str, "%u %d %s",
+ camel_o365_message_info_get_server_flags (omi),
+ camel_o365_message_info_get_item_type (omi),
+ camel_o365_message_info_get_change_key (omi));
+
+ return TRUE;
+}
+
+static void
+o365_message_info_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CamelO365MessageInfo *omi = CAMEL_O365_MESSAGE_INFO (object);
+
+ switch (property_id) {
+ case PROP_SERVER_FLAGS:
+ camel_o365_message_info_set_server_flags (omi, g_value_get_uint (value));
+ return;
+
+ case PROP_ITEM_TYPE:
+ camel_o365_message_info_set_item_type (omi, g_value_get_int (value));
+ return;
+
+ case PROP_CHANGE_KEY:
+ camel_o365_message_info_set_change_key (omi, g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+o365_message_info_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CamelO365MessageInfo *omi = CAMEL_O365_MESSAGE_INFO (object);
+
+ switch (property_id) {
+
+ case PROP_SERVER_FLAGS:
+ g_value_set_uint (value, camel_o365_message_info_get_server_flags (omi));
+ return;
+
+ case PROP_ITEM_TYPE:
+ g_value_set_int (value, camel_o365_message_info_get_item_type (omi));
+ return;
+
+ case PROP_CHANGE_KEY:
+ g_value_take_string (value, camel_o365_message_info_dup_change_key (omi));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+o365_message_info_dispose (GObject *object)
+{
+ CamelO365MessageInfo *omi = CAMEL_O365_MESSAGE_INFO (object);
+
+ g_free (omi->priv->change_key);
+ omi->priv->change_key = NULL;
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (camel_o365_message_info_parent_class)->dispose (object);
+}
+
+static void
+camel_o365_message_info_class_init (CamelO365MessageInfoClass *class)
+{
+ CamelMessageInfoClass *mi_class;
+ GObjectClass *object_class;
+
+ mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
+ mi_class->clone = o365_message_info_clone;
+ mi_class->load = o365_message_info_load;
+ mi_class->save = o365_message_info_save;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = o365_message_info_set_property;
+ object_class->get_property = o365_message_info_get_property;
+ object_class->dispose = o365_message_info_dispose;
+
+ /*
+ * CamelO365MessageInfo:server-flags
+ *
+ * Last known server flags of the message.
+ */
+ g_object_class_install_property (
+ object_class,
+ PROP_SERVER_FLAGS,
+ g_param_spec_uint (
+ "server-flags",
+ "Server Flags",
+ NULL,
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READWRITE));
+
+ /*
+ * CamelO365MessageInfo:item-type
+ *
+ * Item type of the message.
+ */
+ g_object_class_install_property (
+ object_class,
+ PROP_ITEM_TYPE,
+ g_param_spec_int (
+ "item-type",
+ "Item Type",
+ NULL,
+ 0, G_MAXINT32, 0,
+ G_PARAM_READWRITE));
+
+ /*
+ * CamelO365MessageInfo:change-key
+ *
+ * Change key of the message on the server.
+ */
+ g_object_class_install_property (
+ object_class,
+ PROP_CHANGE_KEY,
+ g_param_spec_string (
+ "change-key",
+ "Change Key",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+}
+
+static void
+camel_o365_message_info_init (CamelO365MessageInfo *omi)
+{
+ omi->priv = camel_o365_message_info_get_instance_private (omi);
+}
+
+guint32
+camel_o365_message_info_get_server_flags (const CamelO365MessageInfo *omi)
+{
+ CamelMessageInfo *mi;
+ guint32 result;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (omi), 0);
+
+ mi = CAMEL_MESSAGE_INFO (omi);
+
+ camel_message_info_property_lock (mi);
+ result = omi->priv->server_flags;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gboolean
+camel_o365_message_info_set_server_flags (CamelO365MessageInfo *omi,
+ guint32 server_flags)
+{
+ CamelMessageInfo *mi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (omi), FALSE);
+
+ mi = CAMEL_MESSAGE_INFO (omi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = omi->priv->server_flags != server_flags;
+
+ if (changed)
+ omi->priv->server_flags = server_flags;
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !camel_message_info_get_abort_notifications (mi)) {
+ g_object_notify (G_OBJECT (omi), "server-flags");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
+
+gint32
+camel_o365_message_info_get_item_type (const CamelO365MessageInfo *omi)
+{
+ CamelMessageInfo *mi;
+ gint32 result;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (omi), 0);
+
+ mi = CAMEL_MESSAGE_INFO (omi);
+
+ camel_message_info_property_lock (mi);
+ result = omi->priv->item_type;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gboolean
+camel_o365_message_info_set_item_type (CamelO365MessageInfo *omi,
+ gint32 item_type)
+{
+ CamelMessageInfo *mi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (omi), FALSE);
+
+ mi = CAMEL_MESSAGE_INFO (omi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = omi->priv->item_type != item_type;
+
+ if (changed)
+ omi->priv->item_type = item_type;
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !camel_message_info_get_abort_notifications (mi)) {
+ g_object_notify (G_OBJECT (omi), "item-type");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
+
+const gchar *
+camel_o365_message_info_get_change_key (const CamelO365MessageInfo *omi)
+{
+ CamelMessageInfo *mi;
+ const gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (omi), NULL);
+
+ mi = CAMEL_MESSAGE_INFO (omi);
+
+ camel_message_info_property_lock (mi);
+ result = omi->priv->change_key;
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gchar *
+camel_o365_message_info_dup_change_key (const CamelO365MessageInfo *omi)
+{
+ CamelMessageInfo *mi;
+ gchar *result;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (omi), NULL);
+
+ mi = CAMEL_MESSAGE_INFO (omi);
+
+ camel_message_info_property_lock (mi);
+ result = g_strdup (omi->priv->change_key);
+ camel_message_info_property_unlock (mi);
+
+ return result;
+}
+
+gboolean
+camel_o365_message_info_set_change_key (CamelO365MessageInfo *omi,
+ const gchar *change_key)
+{
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (omi), FALSE);
+
+ return camel_o365_message_info_take_change_key (omi, g_strdup (change_key));
+}
+
+gboolean
+camel_o365_message_info_take_change_key (CamelO365MessageInfo *omi,
+ gchar *change_key)
+{
+ CamelMessageInfo *mi;
+ gboolean changed;
+
+ g_return_val_if_fail (CAMEL_IS_O365_MESSAGE_INFO (omi), FALSE);
+
+ mi = CAMEL_MESSAGE_INFO (omi);
+
+ camel_message_info_property_lock (mi);
+
+ changed = g_strcmp0 (omi->priv->change_key, change_key) != 0;
+
+ if (changed) {
+ g_free (omi->priv->change_key);
+ omi->priv->change_key = change_key;
+ } else if (change_key != omi->priv->change_key) {
+ g_free (change_key);
+ }
+
+ camel_message_info_property_unlock (mi);
+
+ if (changed && !camel_message_info_get_abort_notifications (mi)) {
+ g_object_notify (G_OBJECT (omi), "change-key");
+ camel_message_info_set_dirty (mi, TRUE);
+ }
+
+ return changed;
+}
diff --git a/src/Office365/camel/camel-o365-message-info.h b/src/Office365/camel/camel-o365-message-info.h
new file mode 100644
index 00000000..78f9ba8e
--- /dev/null
+++ b/src/Office365/camel/camel-o365-message-info.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat (www.redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAMEL_O365_MESSAGE_INFO_H
+#define CAMEL_O365_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_O365_MESSAGE_INFO \
+ (camel_o365_message_info_get_type ())
+#define CAMEL_O365_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), CAMEL_TYPE_O365_MESSAGE_INFO, CamelO365MessageInfo))
+#define CAMEL_O365_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), CAMEL_TYPE_O365_MESSAGE_INFO, CamelO365MessageInfoClass))
+#define CAMEL_IS_O365_MESSAGE_INFO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), CAMEL_TYPE_O365_MESSAGE_INFO))
+#define CAMEL_IS_O365_MESSAGE_INFO_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), CAMEL_TYPE_O365_MESSAGE_INFO))
+#define CAMEL_O365_MESSAGE_INFO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), CAMEL_TYPE_O365_MESSAGE_INFO, CamelO365MessageInfoClass))
+
+G_BEGIN_DECLS
+
+/* extra summary flags*/
+enum {
+ CAMEL_O365_MESSAGE_MSGFLAG_RN_PENDING = CAMEL_MESSAGE_FOLDER_FLAGGED << 1
+};
+
+typedef struct _CamelO365MessageInfo CamelO365MessageInfo;
+typedef struct _CamelO365MessageInfoClass CamelO365MessageInfoClass;
+typedef struct _CamelO365MessageInfoPrivate CamelO365MessageInfoPrivate;
+
+struct _CamelO365MessageInfo {
+ CamelMessageInfoBase parent;
+ CamelO365MessageInfoPrivate *priv;
+};
+
+struct _CamelO365MessageInfoClass {
+ CamelMessageInfoBaseClass parent_class;
+};
+
+GType camel_o365_message_info_get_type (void);
+
+guint32 camel_o365_message_info_get_server_flags(const CamelO365MessageInfo *omi);
+gboolean camel_o365_message_info_set_server_flags(CamelO365MessageInfo *omi,
+ guint32 server_flags);
+gint32 camel_o365_message_info_get_item_type (const CamelO365MessageInfo *omi);
+gboolean camel_o365_message_info_set_item_type (CamelO365MessageInfo *omi,
+ gint32 item_type);
+const gchar * camel_o365_message_info_get_change_key (const CamelO365MessageInfo *omi);
+gchar * camel_o365_message_info_dup_change_key (const CamelO365MessageInfo *omi);
+gboolean camel_o365_message_info_set_change_key (CamelO365MessageInfo *omi,
+ const gchar *change_key);
+gboolean camel_o365_message_info_take_change_key (CamelO365MessageInfo *omi,
+ gchar *change_key);
+
+G_END_DECLS
+
+#endif /* CAMEL_O365_MESSAGE_INFO_H */
diff --git a/src/Office365/camel/camel-o365-store-summary.c b/src/Office365/camel/camel-o365-store-summary.c
index 05ab38da..163d3a43 100644
--- a/src/Office365/camel/camel-o365-store-summary.c
+++ b/src/Office365/camel/camel-o365-store-summary.c
@@ -647,6 +647,57 @@ camel_o365_store_summary_dup_folder_full_name (CamelO365StoreSummary *store_summ
return value;
}
+gchar *
+camel_o365_store_summary_dup_folder_id_for_full_name (CamelO365StoreSummary *store_summary,
+ const gchar *full_name)
+{
+ gchar *id;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE_SUMMARY (store_summary), NULL);
+ g_return_val_if_fail (full_name != NULL, NULL);
+
+ LOCK (store_summary);
+
+ id = g_strdup (g_hash_table_lookup (store_summary->priv->full_name_id_hash, full_name));
+
+ UNLOCK (store_summary);
+
+ return id;
+}
+
+gchar *
+camel_o365_store_summary_dup_folder_id_for_type (CamelO365StoreSummary *store_summary,
+ guint32 folder_type)
+{
+ GHashTableIter iter;
+ gpointer key;
+ gchar *id = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE_SUMMARY (store_summary), NULL);
+
+ folder_type = folder_type & CAMEL_FOLDER_TYPE_MASK;
+ g_return_val_if_fail (folder_type != 0, NULL);
+
+ LOCK (store_summary);
+
+ g_hash_table_iter_init (&iter, store_summary->priv->id_full_name_hash);
+
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ guint32 flags;
+
+ flags = camel_o365_store_summary_get_folder_flags (store_summary, key);
+
+ if ((flags & CAMEL_FOLDER_TYPE_MASK) == folder_type) {
+ id = g_strdup (key);
+ break;
+ }
+ }
+
+ UNLOCK (store_summary);
+
+ return id;
+}
+
typedef struct _IdFullNameData {
gchar *id;
gchar *full_name;
@@ -955,6 +1006,28 @@ camel_o365_store_summary_get_folder_flags (CamelO365StoreSummary *store_summary,
return value;
}
+guint32
+camel_o365_store_summary_get_folder_flags_for_full_name (CamelO365StoreSummary *store_summary,
+ const gchar *full_name)
+{
+ const gchar *id;
+ guint32 flags = 0;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE_SUMMARY (store_summary), 0);
+ g_return_val_if_fail (full_name != NULL, 0);
+
+ LOCK (store_summary);
+
+ id = g_hash_table_lookup (store_summary->priv->full_name_id_hash, full_name);
+
+ if (id)
+ flags = camel_o365_store_summary_get_folder_flags (store_summary, id);
+
+ UNLOCK (store_summary);
+
+ return flags;
+}
+
EO365FolderKind
camel_o365_store_summary_get_folder_kind (CamelO365StoreSummary *store_summary,
const gchar *id)
@@ -1090,3 +1163,51 @@ camel_o365_store_summary_build_folder_info (CamelO365StoreSummary *store_summary
return info;
}
+
+static void
+o365_store_summary_folder_count_notify_cb (CamelFolderSummary *folder_summary,
+ GParamSpec *param,
+ CamelO365StoreSummary *store_summary)
+{
+ CamelFolder *folder;
+ gchar *folder_id;
+ gint count;
+
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (folder_summary));
+ g_return_if_fail (param != NULL);
+ g_return_if_fail (CAMEL_IS_O365_STORE_SUMMARY (store_summary));
+
+ folder = camel_folder_summary_get_folder (folder_summary);
+
+ if (!folder)
+ return;
+
+ folder_id = camel_o365_store_summary_dup_folder_id_for_full_name (store_summary,
camel_folder_get_full_name (folder));
+
+ /* This can happen on folder delete/unsubscribe, after folder summary clear */
+ if (!folder_id)
+ return;
+
+ if (g_strcmp0 (g_param_spec_get_name (param), "saved-count") == 0) {
+ count = camel_folder_summary_get_saved_count (folder_summary);
+ camel_o365_store_summary_set_folder_total_count (store_summary, folder_id, count);
+ } else if (g_strcmp0 (g_param_spec_get_name (param), "unread-count") == 0) {
+ count = camel_folder_summary_get_unread_count (folder_summary);
+ camel_o365_store_summary_set_folder_unread_count (store_summary, folder_id, count);
+ } else {
+ g_warn_if_reached ();
+ }
+
+ g_free (folder_id);
+}
+
+void
+camel_o365_store_summary_connect_folder_summary (CamelO365StoreSummary *store_summary,
+ CamelFolderSummary *folder_summary)
+{
+ g_return_if_fail (CAMEL_IS_O365_STORE_SUMMARY (store_summary));
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (folder_summary));
+
+ g_signal_connect_object (folder_summary, "notify::saved-count", G_CALLBACK
(o365_store_summary_folder_count_notify_cb), store_summary, 0);
+ g_signal_connect_object (folder_summary, "notify::unread-count", G_CALLBACK
(o365_store_summary_folder_count_notify_cb), store_summary, 0);
+}
diff --git a/src/Office365/camel/camel-o365-store-summary.h b/src/Office365/camel/camel-o365-store-summary.h
index b07cc493..a83783e9 100644
--- a/src/Office365/camel/camel-o365-store-summary.h
+++ b/src/Office365/camel/camel-o365-store-summary.h
@@ -108,6 +108,12 @@ gboolean camel_o365_store_summary_get_folder (CamelO365StoreSummary *store_summa
gchar * camel_o365_store_summary_dup_folder_full_name
(CamelO365StoreSummary *store_summary,
const gchar *id);
+gchar * camel_o365_store_summary_dup_folder_id_for_full_name
+ (CamelO365StoreSummary *store_summary,
+ const gchar *full_name);
+gchar * camel_o365_store_summary_dup_folder_id_for_type
+ (CamelO365StoreSummary *store_summary,
+ guint32 folder_type); /* The CAMEL_FOLDER_TYPE_...
of the CamelFolderInfoFlags */
gboolean camel_o365_store_summary_set_folder_display_name
(CamelO365StoreSummary *store_summary,
const gchar *id,
@@ -144,6 +150,9 @@ void camel_o365_store_summary_set_folder_flags
guint32 camel_o365_store_summary_get_folder_flags
(CamelO365StoreSummary *store_summary,
const gchar *id);
+guint32 camel_o365_store_summary_get_folder_flags_for_full_name
+ (CamelO365StoreSummary *store_summary,
+ const gchar *full_name);
EO365FolderKind camel_o365_store_summary_get_folder_kind(CamelO365StoreSummary *store_summary,
const gchar *id);
gboolean camel_o365_store_summary_get_folder_is_foreign
@@ -161,6 +170,9 @@ CamelFolderInfo *
(CamelO365StoreSummary *store_summary,
const gchar *top,
gboolean recursive);
+void camel_o365_store_summary_connect_folder_summary
+ (CamelO365StoreSummary *store_summary,
+ CamelFolderSummary *folder_summary);
G_END_DECLS
#endif /* CAMEL_O365_STORE_SUMMARY_H */
diff --git a/src/Office365/camel/camel-o365-store.c b/src/Office365/camel/camel-o365-store.c
index 70d966b8..65596703 100644
--- a/src/Office365/camel/camel-o365-store.c
+++ b/src/Office365/camel/camel-o365-store.c
@@ -258,23 +258,6 @@ o365_store_read_default_folders (CamelO365Store *o365_store,
return success;
}
-static EO365Connection *
-o365_store_ref_connection (CamelO365Store *o365_store)
-{
- EO365Connection *cnc = NULL;
-
- g_return_val_if_fail (CAMEL_IS_O365_STORE (o365_store), NULL);
-
- LOCK (o365_store);
-
- if (o365_store->priv->cnc)
- cnc = g_object_ref (o365_store->priv->cnc);
-
- UNLOCK (o365_store);
-
- return cnc;
-}
-
static gboolean
o365_store_connect_sync (CamelService *service,
GCancellable *cancellable,
@@ -292,7 +275,7 @@ o365_store_connect_sync (CamelService *service,
return FALSE;
o365_store = CAMEL_O365_STORE (service);
- cnc = o365_store_ref_connection (o365_store);
+ cnc = camel_o365_store_ref_connection (o365_store);
if (!cnc) {
LOCK (o365_store);
@@ -328,7 +311,7 @@ o365_store_disconnect_sync (CamelService *service,
EO365Connection *cnc;
gboolean success = TRUE;
- cnc = o365_store_ref_connection (o365_store);
+ cnc = camel_o365_store_ref_connection (o365_store);
if (cnc) {
success = e_o365_connection_disconnect_sync (cnc, cancellable, error);
@@ -354,7 +337,7 @@ o365_store_authenticate_sync (CamelService *service,
EO365Connection *cnc;
o365_store = CAMEL_O365_STORE (service);
- cnc = o365_store_ref_connection (o365_store);
+ cnc = camel_o365_store_ref_connection (o365_store);
if (!cnc)
return CAMEL_AUTHENTICATION_ERROR;
@@ -381,48 +364,6 @@ o365_store_authenticate_sync (CamelService *service,
return result;
}
-gboolean
-camel_o365_store_connected (CamelO365Store *o365_store,
- GCancellable *cancellable,
- GError **error)
-{
- if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (o365_store))) {
- g_set_error (
- error, CAMEL_SERVICE_ERROR,
- CAMEL_SERVICE_ERROR_UNAVAILABLE,
- _("You must be working online to complete this operation"));
- return FALSE;
- }
-
- if (!camel_service_connect_sync ((CamelService *) o365_store, cancellable, error))
- return FALSE;
-
- return TRUE;
-}
-
-void
-camel_o365_store_maybe_disconnect (CamelO365Store *store,
- const GError *error)
-{
- CamelService *service;
-
- g_return_if_fail (store != NULL);
-
- if (!error)
- return;
-
- service = CAMEL_SERVICE (store);
-
- if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED)
- return;
-
-#if 0
- if (g_error_matches (error, O365_CONNECTION_ERROR, O365_CONNECTION_ERROR_NORESPONSE) ||
- g_error_matches (error, O365_CONNECTION_ERROR, O365_CONNECTION_ERROR_AUTHENTICATION_FAILED))
- camel_service_disconnect_sync (service, FALSE, NULL, NULL);
-#endif
-}
-
static void
o365_store_save_summary_locked (CamelO365StoreSummary *summary,
const gchar *where)
@@ -565,7 +506,7 @@ o365_get_folder_info_sync (CamelStore *store,
if (refresh_online) {
EO365Connection *cnc;
- cnc = o365_store_ref_connection (o365_store);
+ cnc = camel_o365_store_ref_connection (o365_store);
if (cnc) {
FoldersDeltaData fdd;
@@ -770,17 +711,17 @@ camel_o365_store_class_init (CamelO365StoreClass *class)
store_class = CAMEL_STORE_CLASS (class);
#if 0
- store_class->get_folder_sync = o365_get_folder_sync;
- store_class->create_folder_sync = o365_create_folder_sync;
- store_class->delete_folder_sync = o365_delete_folder_sync;
- store_class->rename_folder_sync = o365_rename_folder_sync;
+ store_class->get_folder_sync = o365_store_get_folder_sync;
+ store_class->create_folder_sync = o365_store_create_folder_sync;
+ 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;
#if 0
- store_class->initial_setup_sync = o365_initial_setup_sync;
- store_class->get_trash_folder_sync = o365_get_trash_folder_sync;
- store_class->get_junk_folder_sync = o365_get_junk_folder_sync;
- store_class->can_refresh_folder = o365_can_refresh_folder;
+ store_class->initial_setup_sync = o365_store_initial_setup_sync;
+ store_class->get_trash_folder_sync = o365_store_get_trash_folder_sync;
+ store_class->get_junk_folder_sync = o365_store_get_junk_folder_sync;
+ store_class->can_refresh_folder = o365_store_can_refresh_folder;
#endif
}
@@ -810,3 +751,98 @@ camel_o365_store_init (CamelO365Store *o365_store)
g_rec_mutex_init (&o365_store->priv->property_lock);
o365_store->priv->default_folders = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
+
+CamelO365StoreSummary *
+camel_o365_store_ref_store_summary (CamelO365Store *store)
+{
+ CamelO365StoreSummary *summary;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE (store), NULL);
+
+ LOCK (store);
+
+ summary = store->priv->summary;
+
+ if (summary)
+ g_object_ref (summary);
+
+ UNLOCK (store);
+
+ return summary;
+}
+
+EO365Connection *
+camel_o365_store_ref_connection (CamelO365Store *o365_store)
+{
+ EO365Connection *cnc = NULL;
+
+ g_return_val_if_fail (CAMEL_IS_O365_STORE (o365_store), NULL);
+
+ LOCK (o365_store);
+
+ if (o365_store->priv->cnc)
+ cnc = g_object_ref (o365_store->priv->cnc);
+
+ UNLOCK (o365_store);
+
+ return cnc;
+}
+
+gboolean
+camel_o365_store_connected (CamelO365Store *o365_store,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (CAMEL_IS_O365_STORE (o365_store), FALSE);
+
+ if (!camel_offline_store_get_online (CAMEL_OFFLINE_STORE (o365_store))) {
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_UNAVAILABLE,
+ _("You must be working online to complete this operation"));
+ return FALSE;
+ }
+
+ if (!camel_service_connect_sync ((CamelService *) o365_store, cancellable, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+camel_o365_store_maybe_disconnect (CamelO365Store *store,
+ const GError *error)
+{
+ CamelService *service;
+
+ g_return_if_fail (CAMEL_IS_O365_STORE (store));
+
+ if (!error)
+ return;
+
+ service = CAMEL_SERVICE (store);
+
+ if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED)
+ return;
+
+#if 0
+ if (g_error_matches (error, O365_CONNECTION_ERROR, O365_CONNECTION_ERROR_NORESPONSE) ||
+ g_error_matches (error, O365_CONNECTION_ERROR, O365_CONNECTION_ERROR_AUTHENTICATION_FAILED))
+ camel_service_disconnect_sync (service, FALSE, NULL, NULL);
+#endif
+}
+
+void
+camel_o365_store_connect_folder_summary (CamelO365Store *store,
+ CamelFolderSummary *folder_summary)
+{
+ g_return_if_fail (CAMEL_IS_O365_STORE (store));
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (folder_summary));
+
+ LOCK (store);
+
+ if (store->priv->summary)
+ camel_o365_store_summary_connect_folder_summary (store->priv->summary, folder_summary);
+
+ UNLOCK (store);
+}
diff --git a/src/Office365/camel/camel-o365-store.h b/src/Office365/camel/camel-o365-store.h
index 1567d012..af42cd33 100644
--- a/src/Office365/camel/camel-o365-store.h
+++ b/src/Office365/camel/camel-o365-store.h
@@ -20,6 +20,9 @@
#include <camel/camel.h>
+#include "common/e-o365-connection.h"
+#include "camel-o365-store-summary.h"
+
/* Standard GObject macros */
#define CAMEL_TYPE_O365_STORE \
(camel_o365_store_get_type ())
@@ -55,12 +58,21 @@ struct _CamelO365StoreClass {
};
GType camel_o365_store_get_type (void);
+
+CamelO365StoreSummary *
+ camel_o365_store_ref_store_summary
+ (CamelO365Store *store);
+EO365Connection *
+ camel_o365_store_ref_connection (CamelO365Store *o365_store);
gboolean camel_o365_store_connected (CamelO365Store *store,
GCancellable *cancellable,
GError **error);
void camel_o365_store_maybe_disconnect
(CamelO365Store *store,
const GError *error);
+void camel_o365_store_connect_folder_summary
+ (CamelO365Store *store,
+ CamelFolderSummary *folder_summary);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]