[evolution-kolab/ek-wip-porting] EBookBackendKolab: implemented online/offline state switching
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab/ek-wip-porting] EBookBackendKolab: implemented online/offline state switching
- Date: Fri, 16 Mar 2012 19:14:28 +0000 (UTC)
commit 552a51664d6b554a93210c85a9f9e2202be851a1
Author: Christian Hilberg <hilberg kernelconcepts de>
Date: Fri Mar 16 20:09:43 2012 +0100
EBookBackendKolab: implemented online/offline state switching
* implemented state switching (offline, online)
* state is set initially according to the
E-D-S status
* state can subsequently be toggled by the
online state button in Evolution
src/addressbook/e-book-backend-kolab.c | 245 +++++++++++++++++++++++++++++---
1 files changed, 226 insertions(+), 19 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-kolab.c b/src/addressbook/e-book-backend-kolab.c
index 743085b..29ac5c4 100644
--- a/src/addressbook/e-book-backend-kolab.c
+++ b/src/addressbook/e-book-backend-kolab.c
@@ -58,11 +58,12 @@ typedef struct _EBookBackendKolabPrivate EBookBackendKolabPrivate;
struct _EBookBackendKolabPrivate
{
/* GNOME_Evolution_Addressbook_BookMode book_mode; */
- EBookBackendCache *book_cache;
- KolabMailAccess *book_koma;
- gchar *book_uri;
- GHashTable *koma_table;
- gboolean auth_received;
+ EBookBackendCache *book_cache;
+ KolabMailAccess *book_koma;
+ gchar *book_uri;
+ GHashTable *koma_table;
+ gboolean auth_received;
+ GError *mode_switch_err;
};
#define E_BOOK_BACKEND_KOLAB_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_BOOK_BACKEND_KOLAB, EBookBackendKolabPrivate))
@@ -74,13 +75,116 @@ G_DEFINE_TYPE (EBookBackendKolab, e_book_backend_kolab, E_TYPE_BOOK_BACKEND_SYNC
/* internal statics */
static void
+book_backend_kolab_signal_online_cb (GObject *object)
+{
+ EBackend *backend = NULL;
+ EBookBackendKolab *self = NULL;
+ EBookBackendKolabPrivate *priv = NULL;
+ gboolean online = FALSE;
+ gboolean ok = FALSE;
+
+ g_return_if_fail (E_IS_BOOK_BACKEND_KOLAB (object));
+
+ backend = E_BACKEND (object);
+ self = E_BOOK_BACKEND_KOLAB (object);
+ priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
+
+ online = e_backend_get_online (backend);
+
+ g_debug ("%s()[%u] backend mode: %i",
+ __func__, __LINE__, online);
+
+ /* FIXME
+ *
+ * This callback is for online state notifications only.
+ * Doing I/O, which can fail, is the wrong thing to do
+ * here since we do not have a proper way to let the user
+ * cancel the I/O. Getting KolabMailAccess online can hang.
+ * Thus, cancellation would be needed.
+ *
+ * e_backend_get_online (backend) could be called in the
+ * "other" operations and the KolabMailAccess state changed
+ * if needed, Problem: KolabMailAccess online/offline state
+ * change involves synchronization with the server, which
+ * may take long time and is not expected by the user if
+ * they e.g. just add a contact or event.
+ *
+ * For now, we'll leave the cancellation issue aside
+ * (we could not have cancelled in 2.30 either), but
+ * at least bind a GError to our backend object, if we
+ * have one. We can then propagate this error in the
+ * first "other" operation the user triggers.
+ *
+ * It has been supposed by upstream to use a global static
+ * GCancellable for the cancellation issue, but it will
+ * not help us here since the Evolution online/offline
+ * toggle button does not seem to expect heavy I/O to
+ * be triggered. Our local GCancellabe would need transfer
+ * to Evo and be registered there so the online/offline
+ * switching in evo-kolab could be cancelled from the
+ * frontend. Moreover, there is no telling how long a
+ * synchronization run with the Kolab server may take,
+ * so we also cannot set a sensible timeout here.
+ *
+ */
+
+ if (priv->mode_switch_err != NULL) {
+ g_warning ("%s()[%u]: Online mode switching error pending (%s)",
+ __func__, __LINE__, priv->mode_switch_err->message);
+ g_error_free (priv->mode_switch_err);
+ priv->mode_switch_err = NULL;
+ }
+ ok = kolab_util_backend_deploy_mode_by_backend (priv->book_koma,
+ online,
+ NULL, /* GCancellable (see above )*/
+ &(priv->mode_switch_err));
+ if (priv->mode_switch_err) {
+ g_warning ("%s()[%u]: Online mode switching error pending (%s)",
+ __func__, __LINE__, priv->mode_switch_err->message);
+ }
+
+ if (ok) {
+ e_book_backend_notify_online (E_BOOK_BACKEND (self), online);
+ }
+}
+
+static gboolean
+book_backend_kolab_notify_open (EBookBackendKolab *self,
+ GError **err)
+{
+ EBookBackend *bbackend = NULL;
+ EBookBackendKolabPrivate *priv = NULL;
+ KolabMailAccessOpmodeID tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_INVAL;
+ GError *tmp_err = NULL;
+
+ g_assert (E_IS_BOOK_BACKEND_KOLAB (self));
+ g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
+
+ priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
+ bbackend = E_BOOK_BACKEND (self);
+
+ tmp_mode = kolab_mail_access_get_opmode (priv->book_koma, &tmp_err);
+ if (tmp_err != NULL) {
+ g_propagate_error (err, tmp_err);
+ return FALSE;
+ }
+ e_book_backend_notify_online (bbackend,
+ tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE ? TRUE : FALSE);
+ e_book_backend_notify_opened (bbackend, NULL);
+
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------------*/
+/* class functions */
+
+static void
e_book_backend_kolab_open (EBookBackendSync *backend,
EDataBook *book,
GCancellable *cancellable,
gboolean only_if_exists,
GError **error)
{
- EBookBackend *bbackend = NULL;
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
ESource *source = NULL;
@@ -88,15 +192,15 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
KolabSettingsHandler *ksettings = NULL;
KolabMailAccess *tmp_koma = NULL;
KolabSyncStrategyID sync_value = KOLAB_SYNC_STRATEGY_DEFAULT;
- KolabMailAccessOpmodeID tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_INVAL;
gchar *sourcename = NULL;
gchar *servername = NULL;
gchar *username = NULL;
gchar *user_at_server = NULL;
gchar *tmp_key = NULL;
const gchar *sync_prop = NULL;
- GError *tmp_err = NULL;
+ gboolean online = FALSE;
gboolean ok = FALSE;
+ GError *tmp_err = NULL;
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
e_return_data_book_error_if_fail (E_IS_DATA_BOOK (book), E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -106,7 +210,6 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- bbackend = E_BOOK_BACKEND (backend);
kolab_util_glib_init ();
kolab_util_http_init ();
@@ -163,6 +266,8 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
sync_value = kolab_util_misc_sync_value_from_property (sync_prop);
sourcename = kolab_util_backend_get_relative_path_from_uri (priv->book_uri);
+ /* Check whether we have a KolabMailAccess (KoMA) instance already */
+
user_at_server = g_strdup_printf ("%s %s",
username, servername);
@@ -171,7 +276,9 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
(gpointer *) &tmp_key,
(gpointer *) &tmp_koma);
if (ok) {
- /* There is already a KoMA instance for $servername. Use it and return */
+ /* There already is a KoMA instance for user_at_server.
+ * Use it and return
+ */
g_object_ref (tmp_koma);
priv->book_koma = tmp_koma;
g_free (servername);
@@ -185,7 +292,29 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
NULL,
sourcename,
&sync_value);
- goto notifications;
+ g_object_unref (ksettings);
+ /* We should have received authentication data (password)
+ * at this point, since it was requested and stored when
+ * the KolabMailAccess object was initially created.
+ * We can just skip the AuthenticationRequested part here
+ * and move along...
+ */
+ online = e_backend_get_online (E_BACKEND (backend));
+ ok = kolab_util_backend_deploy_mode_by_backend (priv->book_koma,
+ online,
+ cancellable,
+ &tmp_err);
+ if (! ok) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+ ok = book_backend_kolab_notify_open (self, &tmp_err);
+ if (! ok) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ }
+ return;
}
/* Nope, we need to setup a new KoMA instance and a settings handler */
@@ -255,7 +384,17 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
return;
}
- notifications:
+ /* If we are here (just created a fresh KolabMailAccess),
+ * we did not yet receive authentication data. Though we
+ * do not need it if we want to stay in offline mode, once
+ * we're asked to go online, we'll need the credentials
+ * (password in our case) anyway, so we can just request
+ * it once the book gets opened.
+ */
+ e_book_backend_notify_auth_required (E_BOOK_BACKEND (self), TRUE, NULL);
+
+ /* FIXME may need to move the notifications to authenticate_user() */
+#if 0
/* e_book_backend_kolab_set_mode (backend, priv->book_mode); */
tmp_mode = kolab_mail_access_get_opmode (priv->book_koma, &tmp_err);
if (tmp_err != NULL) {
@@ -264,8 +403,6 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
return;
}
-#if 0 /* FIXME */
- e_book_backend_notify_auth_required (bbackend, TRUE, NULL);
e_book_backend_set_is_loaded (bbackend, TRUE);
e_book_backend_notify_connection_status (bbackend,
tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE ? TRUE : FALSE);
@@ -337,6 +474,7 @@ e_book_backend_kolab_refresh (EBookBackendSync *backend,
g_error ("%s: FIXME implement me", __func__);
}
+#if 0 /* probably not needed */
static gboolean
e_book_backend_kolab_get_backend_property (EBookBackendSync *backend,
EDataBook *book,
@@ -362,7 +500,9 @@ e_book_backend_kolab_get_backend_property (EBookBackendSync *backend,
return TRUE;
}
+#endif
+#if 0 /* probably not needed */
static gboolean
e_book_backend_kolab_set_backend_property (EBookBackendSync *backend,
EDataBook *book,
@@ -386,6 +526,7 @@ e_book_backend_kolab_set_backend_property (EBookBackendSync *backend,
g_error ("%s: FIXME implement me", __func__);
}
+#endif
static void
e_book_backend_kolab_create_contacts (EBookBackendSync *backend,
@@ -683,6 +824,13 @@ e_book_backend_kolab_authenticate_user (EBookBackendSync *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
+ KolabSettingsHandler *ksettings = NULL;
+ const gchar *cred_user = NULL;
+ const gchar *cred_pwd = NULL;
+ const gchar *kset_user = NULL;
+ gboolean online = FALSE;
+ gboolean ok = FALSE;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -692,11 +840,60 @@ e_book_backend_kolab_authenticate_user (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ g_debug ("%s()[%u] called.", __func__, __LINE__);
+
+ ksettings = kolab_mail_access_get_settings_handler (priv->book_koma);
+
+ /* warn about a possible inconsistency in user names */
+ kset_user = kolab_settings_handler_get_char_field (ksettings,
+ KOLAB_SETTINGS_HANDLER_CHAR_FIELD_KOLAB_USER_NAME,
+ &tmp_err);
+ if (tmp_err != NULL) {
+ g_object_unref (ksettings);
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+ cred_user = e_credentials_peek (credentials,
+ E_CREDENTIALS_KEY_USERNAME);
+ if (g_strcmp0 (kset_user, cred_user) != 0) {
+ g_warning ("%s()[%u] username from argument and username in "
+ "KolabSettingsHandler do not match: %s vs. %s",
+ __func__, __LINE__, cred_user, kset_user);
+ }
+
+ cred_pwd = e_credentials_peek (credentials,
+ E_CREDENTIALS_KEY_PASSWORD);
+
+ kolab_util_backend_prepare_settings (ksettings,
+ NULL,
+ NULL,
+ NULL,
+ cred_pwd,
+ NULL,
+ NULL);
+ g_object_unref (ksettings);
+
+ priv->auth_received = TRUE;
+
+ online = e_backend_get_online (E_BACKEND (backend));
+ ok = kolab_util_backend_deploy_mode_by_backend (priv->book_koma,
+ online,
+ cancellable,
+ &tmp_err);
+ if (! ok) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+
+ ok = book_backend_kolab_notify_open (self, &tmp_err);
+ if (! ok) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ }
#if 0 /* FIXME old */
- g_debug ("%s()[%u] called.",
- __func__, __LINE__);
g_debug (" + user: %s\n + auth_method: %s",
user, auth_method);
g_debug ("%s()[%u] username = %s",
@@ -734,7 +931,7 @@ e_book_backend_kolab_authenticate_user (EBookBackendSync *backend,
NULL);
priv->auth_received = TRUE;
- ok = kolab_util_contact_deploy_mode_by_backend (priv->book_koma,
+ ok = kolab_util_backend_deploy_mode_by_backend (priv->book_koma,
priv->book_mode);
return GNOME_Evolution_Addressbook_Success;
@@ -869,6 +1066,9 @@ e_book_backend_kolab_init (EBookBackendKolab *backend)
priv->book_uri = NULL;
priv->book_koma = NULL;
priv->auth_received = FALSE;
+ priv->mode_switch_err = NULL;
+
+ g_signal_connect (E_BACKEND (backend), "notify::online", G_CALLBACK (book_backend_kolab_signal_online_cb), NULL);
} /* e_book_backend_kolab_init () */
static void
@@ -913,6 +1113,11 @@ e_book_backend_kolab_finalize (GObject *object)
if (priv->book_uri != NULL)
g_free (priv->book_uri);
+ if (priv->mode_switch_err != NULL) {
+ g_warning ("%s()[%u]: %s",
+ __func__, __LINE__, priv->mode_switch_err->message);
+ g_error_free (priv->mode_switch_err);
+ }
G_OBJECT_CLASS (e_book_backend_kolab_parent_class)->finalize (object);
} /* e_book_backend_kolab_finalize () */
@@ -940,8 +1145,10 @@ e_book_backend_kolab_class_init (EBookBackendKolabClass *klass)
sync_class->open_sync = e_book_backend_kolab_open;
sync_class->remove_sync = e_book_backend_kolab_remove;
sync_class->refresh_sync = e_book_backend_kolab_refresh;
+#if 0 /* probably not needed */
sync_class->get_backend_property_sync = e_book_backend_kolab_get_backend_property;
sync_class->set_backend_property_sync = e_book_backend_kolab_set_backend_property;
+#endif
sync_class->create_contacts_sync = e_book_backend_kolab_create_contacts;
sync_class->remove_contacts_sync = e_book_backend_kolab_remove_contacts;
sync_class->modify_contacts_sync = e_book_backend_kolab_modify_contacts;
@@ -1053,7 +1260,7 @@ e_book_backend_kolab_set_mode (EBookBackend *backend,
}
if (priv->auth_received == TRUE)
- tmp_mode = kolab_util_contact_deploy_mode_by_koma (priv->book_koma,
+ tmp_mode = kolab_util_backend_deploy_mode_by_koma (priv->book_koma,
koma_mode);
else
tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_OFFLINE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]