aboutsummaryrefslogtreecommitdiffstats
path: root/modules/online-accounts
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2012-01-20 23:05:35 +0800
committerMatthew Barnes <mbarnes@redhat.com>2012-06-03 11:00:41 +0800
commit188de7815704c3a94ae02af4bb27156e204cac5c (patch)
tree2e41ad305eced2181a132169e1b5a12202777648 /modules/online-accounts
parent502cd6c33c1f33f33b944a6d24b51bf5dfe7416f (diff)
downloadgsoc2013-evolution-188de7815704c3a94ae02af4bb27156e204cac5c.tar
gsoc2013-evolution-188de7815704c3a94ae02af4bb27156e204cac5c.tar.gz
gsoc2013-evolution-188de7815704c3a94ae02af4bb27156e204cac5c.tar.bz2
gsoc2013-evolution-188de7815704c3a94ae02af4bb27156e204cac5c.tar.lz
gsoc2013-evolution-188de7815704c3a94ae02af4bb27156e204cac5c.tar.xz
gsoc2013-evolution-188de7815704c3a94ae02af4bb27156e204cac5c.tar.zst
gsoc2013-evolution-188de7815704c3a94ae02af4bb27156e204cac5c.zip
Adapt modules/online-accounts to the new ESource API.
Diffstat (limited to 'modules/online-accounts')
-rw-r--r--modules/online-accounts/Makefile.am5
-rw-r--r--modules/online-accounts/camel-sasl-xoauth.c58
-rw-r--r--modules/online-accounts/e-online-accounts-google.c494
-rw-r--r--modules/online-accounts/e-online-accounts-google.h32
-rw-r--r--modules/online-accounts/evolution-online-accounts.c494
5 files changed, 47 insertions, 1036 deletions
diff --git a/modules/online-accounts/Makefile.am b/modules/online-accounts/Makefile.am
index 6c2f16883a..9b30ced4f0 100644
--- a/modules/online-accounts/Makefile.am
+++ b/modules/online-accounts/Makefile.am
@@ -10,15 +10,14 @@ module_online_accounts_la_CPPFLAGS = \
module_online_accounts_la_SOURCES = \
evolution-online-accounts.c \
- e-online-accounts-google.c \
- e-online-accounts-google.h \
camel-sasl-xoauth.c \
camel-sasl-xoauth.h
module_online_accounts_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
$(top_builddir)/shell/libeshell.la \
- $(top_builddir)/libemail-utils/libemail-utils.la \
+ $(top_builddir)/libemail-engine/libemail-engine.la \
+ $(top_builddir)/libemail-utils/libemail-utils.la \
$(EVOLUTION_DATA_SERVER_LIBS) \
$(GNOME_PLATFORM_LIBS) \
$(GOA_LIBS)
diff --git a/modules/online-accounts/camel-sasl-xoauth.c b/modules/online-accounts/camel-sasl-xoauth.c
index e3cbb69f80..10e3223976 100644
--- a/modules/online-accounts/camel-sasl-xoauth.c
+++ b/modules/online-accounts/camel-sasl-xoauth.c
@@ -24,7 +24,9 @@
#include <goa/goa.h>
-#include <libemail-utils/e-account-utils.h>
+#include <libedataserver/e-source-goa.h>
+
+#include <libemail-engine/e-mail-session.h>
#include "camel-sasl-xoauth.h"
@@ -313,6 +315,39 @@ calculate_xoauth_param (const gchar *request_uri,
/****************************************************************************/
+static gchar *
+sasl_xoauth_find_account_id (ESourceRegistry *registry,
+ const gchar *uid)
+{
+ ESource *source;
+ const gchar *extension_name;
+
+ extension_name = E_SOURCE_EXTENSION_GOA;
+
+ while (uid != NULL) {
+ ESourceGoa *extension;
+ gchar *account_id;
+
+ source = e_source_registry_ref_source (registry, uid);
+ g_return_val_if_fail (source != NULL, NULL);
+
+ if (!e_source_has_extension (source, extension_name)) {
+ uid = e_source_get_parent (source);
+ g_object_unref (source);
+ continue;
+ }
+
+ extension = e_source_get_extension (source, extension_name);
+ account_id = e_source_goa_dup_account_id (extension);
+
+ g_object_unref (source);
+
+ return account_id;
+ }
+
+ return NULL;
+}
+
static GoaObject *
sasl_xoauth_get_account_by_id (GoaClient *client,
const gchar *account_id)
@@ -356,29 +391,26 @@ sasl_xoauth_challenge_sync (CamelSasl *sasl,
GoaAccount *goa_account;
GByteArray *parameters = NULL;
CamelService *service;
- EAccount *account;
- CamelURL *url;
- const gchar *account_id;
+ CamelSession *session;
+ ESourceRegistry *registry;
const gchar *uid;
+ gchar *account_id;
gchar *xoauth_param = NULL;
gboolean success;
service = camel_sasl_get_service (sasl);
- uid = camel_service_get_uid (service);
- account = e_get_account_by_uid (uid);
- g_return_val_if_fail (account != NULL, NULL);
+ session = camel_service_get_session (service);
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
goa_client = goa_client_new_sync (cancellable, error);
if (goa_client == NULL)
return NULL;
- url = camel_url_new (account->source->url, error);
- if (url == NULL)
- return NULL;
-
- account_id = camel_url_get_param (url, GOA_KEY);
+ uid = camel_service_get_uid (service);
+ account_id = sasl_xoauth_find_account_id (registry, uid);
goa_object = sasl_xoauth_get_account_by_id (goa_client, account_id);
- camel_url_free (url);
+
+ g_free (account_id);
if (goa_object == NULL) {
g_set_error_literal (
diff --git a/modules/online-accounts/e-online-accounts-google.c b/modules/online-accounts/e-online-accounts-google.c
deleted file mode 100644
index ab394f622e..0000000000
--- a/modules/online-accounts/e-online-accounts-google.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * e-online-accounts-google.c
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- */
-
-#include "e-online-accounts-google.h"
-
-#include <config.h>
-#include <glib/gi18n-lib.h>
-
-/* XXX Just use the deprecated APIs for now.
- * We'll be switching away soon enough. */
-#undef E_CAL_DISABLE_DEPRECATED
-#undef E_BOOK_DISABLE_DEPRECATED
-
-#include <libecal/e-cal.h>
-#include <libebook/e-book.h>
-
-#include <libemail-utils/e-account-utils.h>
-
-/* This is the property name or URL parameter under which we
- * embed the GoaAccount ID into an EAccount or ESource object. */
-#define GOA_KEY "goa-account-id"
-
-#define GOOGLE_BASE_URI "google://"
-
-/**
- * XXX Once the key-file based ESource API is merged, I'd
- * like to structure the ESources something like this:
- *
- * * Maybe add an "Enabled" key to the [Data Source] group,
- * so we have an easy way to hide/show individual sources
- * without destroying custom settings. Would replace the
- * "Enabled" key in [Mail Account], and rename the same
- * key in ESourceSelectable to "Active".
- *
- * +---------------------------------------------------+
- * | [Data Source] |
- * | DisplayName: <<GoaAccount:presentation-identity>> |
- * | Backend: google |
- * | Enabled: true # What would 'false' mean? |
- * | |
- * | [GNOME Online Accounts] |
- * | Id: <<GoaAccount:id>> |
- * +---------------------------------------------------+
- * |
- * | (child ESources)
- * |
- * | +------------------------------------------+
- * | | [Data Source] |
- * | | DisplayName: (same as parent) |
- * | | Enabled: true |
- * | | |
- * | | [Authentication] |
- * | | Host: imap.gmail.com |
- * | | blah, blah, blah... |
- * | | |
- * +----| [Mail Account] |
- * | | blah, blah, blah... |
- * | | |
- * | | [Mail Identity] |
- * | | Name: Matthew Barnes |
- * | | Address: <<my-gmail-address>> |
- * | | blah, blah, blah... |
- * | +------------------------------------------+
- * |
- * | +------------------------------------------+
- * | | [Data Source] |
- * | | DisplayName: GMail SMTP Server |
- * | | Enabled: true |
- * | | |
- * | | [Authentication] |
- * | | Host: smtp.gmail.com |
- * +----| blah, blah, blah... |
- * | | |
- * | | [Mail Transport] |
- * | | blah, blah, blah... |
- * | +------------------------------------------+
- * |
- * | +------------------------------------------+
- * | | [Data Source] |
- * | | DisplayName: Contacts |
- * | | Enabled: true |
- * | | |
- * | | [Authentication] |
- * | | blah, blah, blah... |
- * +----| |
- * | | [Address Book] |
- * | | blah, blah, blah... |
- * | +------------------------------------------+
- * |
- * | +------------------------------------------+
- * | | [Data Source] |
- * | | DisplayName: Calendar |
- * | | Backend: caldav |
- * | | Enabled: true |
- * | | |
- * | | [Authentication] |
- * | | blah, blah, blah... |
- * +----| |
- * | [Calendar] |
- * | blah, blah, blah... |
- * +------------------------------------------+
- */
-
-/* XXX Copy part of the private struct here so we can set our own UID.
- * Since EAccountList and ESourceList forces the different aspects
- * of the Google account to be disjoint, we can reuse the UID to
- * link them back together. */
-struct _ESourcePrivate {
- ESourceGroup *group;
-
- gchar *uid;
- /* ... yadda, yadda, yadda ... */
-};
-
-static void
-online_accounts_google_sync_mail (GoaObject *goa_object,
- const gchar *evo_id)
-{
- GoaMail *goa_mail;
- GoaAccount *goa_account;
- EAccountList *account_list;
- EAccount *account;
- CamelURL *url;
- const gchar *string;
- gboolean new_account = FALSE;
-
- account_list = e_get_account_list ();
- account = e_get_account_by_uid (evo_id);
-
- if (account) {
- /* the account is already configured,
- * do not change user's changes */
- return;
- }
-
- /* XXX There's nothing particularly GMail-specific about this.
- * Maybe break this off into a more generic IMAP/SMTP sync
- * function and then apply any GMail-specific tweaks. */
-
- goa_mail = goa_object_get_mail (goa_object);
- goa_account = goa_object_get_account (goa_object);
-
- if (account == NULL) {
- account = g_object_new (E_TYPE_ACCOUNT, NULL);
- account->uid = g_strdup (evo_id);
- account->enabled = TRUE;
- new_account = TRUE;
- }
-
- /*** Account Name ***/
-
- g_free (account->name);
- string = goa_account_get_presentation_identity (goa_account);
- account->name = g_strdup (string);
-
- /*** Mail Identity ***/
-
- if (account->id->name == NULL)
- account->id->name = g_strdup (g_get_real_name ());
-
- g_free (account->id->address);
- string = goa_mail_get_email_address (goa_mail);
- account->id->address = g_strdup (string);
-
- /*** Mail Storage ***/
-
- /* This quietly handles NULL strings sanely. */
- url = camel_url_new (account->source->url, NULL);
-
- if (url == NULL)
- url = g_new0 (CamelURL, 1);
-
- camel_url_set_protocol (url, "imapx");
-
- string = goa_account_get_identity (goa_account);
- camel_url_set_user (url, string);
-
- string = goa_mail_get_imap_host (goa_mail);
- camel_url_set_host (url, string);
-
- /* Use CamelSaslXOAuth. */
- camel_url_set_authmech (url, "XOAUTH");
-
- /* Always == SSL (port 993) */
- if (goa_mail_get_imap_use_tls (goa_mail))
- string = "ssl-on-alternate-port";
- else
- string = "none";
- camel_url_set_param (url, "security-method", string);
-
- string = goa_account_get_id (goa_account);
- camel_url_set_param (url, GOA_KEY, string);
-
- if (new_account) {
- e_account_set_bool (account, E_ACCOUNT_SOURCE_AUTO_CHECK, TRUE);
- e_account_set_int (account, E_ACCOUNT_SOURCE_AUTO_CHECK_TIME, 10);
-
- camel_url_set_param (url, "filter-inbox", "true");
- }
-
- g_free (account->source->url);
- account->source->url = camel_url_to_string (url, 0);
-
- camel_url_free (url);
-
- /*** Mail Transport ***/
-
- /* This quietly handles NULL strings sanely. */
- url = camel_url_new (account->transport->url, NULL);
-
- if (url == NULL)
- url = g_new0 (CamelURL, 1);
-
- camel_url_set_protocol (url, "smtp");
-
- string = goa_account_get_identity (goa_account);
- camel_url_set_user (url, string);
-
- string = goa_mail_get_smtp_host (goa_mail);
- camel_url_set_host (url, string);
-
- /* Message Submission port */
- camel_url_set_port (url, 587);
-
- /* Use CamelSaslXOAuth. */
- camel_url_set_authmech (url, "XOAUTH");
-
- /* When-Possible == STARTTLS */
- if (goa_mail_get_smtp_use_tls (goa_mail))
- string = "starttls-on-standard-port";
- else
- string = "none";
- camel_url_set_param (url, "security-method", string);
-
- string = goa_account_get_id (goa_account);
- camel_url_set_param (url, GOA_KEY, string);
-
- g_free (account->transport->url);
- account->transport->url = camel_url_to_string (url, 0);
-
- camel_url_free (url);
-
- /* Clean up. */
-
- if (new_account) {
- e_account_list_add (account_list, account);
- g_object_unref (account);
- }
-
- e_account_list_save (account_list);
-
- g_object_unref (goa_account);
- g_object_unref (goa_mail);
-}
-
-static void
-online_accounts_google_sync_calendar (GoaObject *goa_object,
- const gchar *evo_id)
-{
- GoaAccount *goa_account;
- ESourceList *source_list = NULL;
- ESourceGroup *source_group;
- ECalSourceType source_type;
- ESource *source;
- const gchar *string;
- gchar *encoded;
- gchar *uri_string;
- gboolean new_source = FALSE;
- GError *error = NULL;
-
- source_type = E_CAL_SOURCE_TYPE_EVENT;
-
- if (!e_cal_get_sources (&source_list, source_type, &error)) {
- g_warn_if_fail (source_list == NULL);
- g_warn_if_fail (error != NULL);
- g_warning ("%s", error->message);
- g_error_free (error);
- return;
- }
-
- g_return_if_fail (E_IS_SOURCE_LIST (source_list));
-
- goa_account = goa_object_get_account (goa_object);
-
- /* This returns a new reference to the source group. */
- source_group = e_source_list_ensure_group (
- source_list, _("Google"), GOOGLE_BASE_URI, TRUE);
-
- source = e_source_group_peek_source_by_uid (source_group, evo_id);
-
- if (source == NULL) {
- source = g_object_new (E_TYPE_SOURCE, NULL);
- source->priv->uid = g_strdup (evo_id);
- e_source_set_name (source, _("Calendar"));
-
- /* XXX Choose a fixed color from the list in
- * calendar-setup.c. I like purple. */
- e_source_set_color_spec (source, "#E2C6E1");
-
- new_source = TRUE;
- }
-
- string = goa_account_get_identity (goa_account);
-
- encoded = camel_url_encode (string, "@");
- uri_string = g_strdup_printf (
- "caldav://%s@www.google.com/calendar/dav/%s/events",
- encoded, string);
- e_source_set_relative_uri (source, uri_string);
- e_source_set_absolute_uri (source, uri_string);
- g_free (uri_string);
- g_free (encoded);
-
- e_source_set_property (source, "ssl", "1");
- e_source_set_property (source, "username", string);
- e_source_set_property (source, "setup-username", string);
-
- /* XXX Not sure this needs to be set since the backend
- * will authenticate itself if it sees a GOA ID. */
- e_source_set_property (source, "auth", "1");
-
- string = goa_account_get_id (goa_account);
- e_source_set_property (source, GOA_KEY, string);
-
- if (new_source) {
- e_source_group_add_source (source_group, source, -1);
- g_object_unref (source);
- }
-
- e_source_list_sync (source_list, NULL);
-
- g_object_unref (source_group);
- g_object_unref (source_list);
- g_object_unref (goa_account);
-}
-
-static void
-online_accounts_google_sync_contacts (GoaObject *goa_object,
- const gchar *evo_id)
-{
- GoaAccount *goa_account;
- ESourceList *source_list = NULL;
- ESourceGroup *source_group;
- ESource *source;
- const gchar *string;
- gboolean new_source = FALSE;
- GError *error = NULL;
-
- if (!e_book_get_addressbooks (&source_list, &error)) {
- g_warn_if_fail (source_list == NULL);
- g_warn_if_fail (error != NULL);
- g_warning ("%s", error->message);
- g_error_free (error);
- return;
- }
-
- g_return_if_fail (E_IS_SOURCE_LIST (source_list));
-
- goa_account = goa_object_get_account (goa_object);
-
- /* This returns a new reference to the source group. */
- source_group = e_source_list_ensure_group (
- source_list, _("Google"), GOOGLE_BASE_URI, TRUE);
-
- source = e_source_group_peek_source_by_uid (source_group, evo_id);
-
- if (source == NULL) {
- source = g_object_new (E_TYPE_SOURCE, NULL);
- source->priv->uid = g_strdup (evo_id);
- e_source_set_name (source, _("Contacts"));
- new_source = TRUE;
- }
-
- string = goa_account_get_identity (goa_account);
-
- e_source_set_relative_uri (source, string);
-
- e_source_set_property (source, "use-ssl", "true");
- e_source_set_property (source, "username", string);
-
- /* XXX Not sure this needs to be set since the backend
- * will authenticate itself if it sees a GOA ID. */
- e_source_set_property (source, "auth", "plain/password");
-
- string = goa_account_get_id (goa_account);
- e_source_set_property (source, GOA_KEY, string);
-
- if (new_source) {
- e_source_group_add_source (source_group, source, -1);
- g_object_unref (source);
- }
-
- e_source_list_sync (source_list, NULL);
-
- g_object_unref (source_group);
- g_object_unref (source_list);
- g_object_unref (goa_account);
-}
-
-void
-e_online_accounts_google_sync (GoaObject *goa_object,
- const gchar *evo_id)
-{
- GoaMail *goa_mail;
- GoaCalendar *goa_calendar;
- GoaContacts *goa_contacts;
-
- g_return_if_fail (GOA_IS_OBJECT (goa_object));
- g_return_if_fail (evo_id != NULL);
-
- /*** Google Mail ***/
-
- goa_mail = goa_object_get_mail (goa_object);
- if (goa_mail != NULL) {
- online_accounts_google_sync_mail (goa_object, evo_id);
- g_object_unref (goa_mail);
- } else {
- EAccountList *account_list;
- EAccount *account;
-
- account_list = e_get_account_list ();
- account = e_get_account_by_uid (evo_id);
-
- if (account != NULL) {
- e_account_list_remove (account_list, account);
- e_account_list_save (account_list);
- }
- }
-
- /*** Google Calendar ***/
-
- goa_calendar = goa_object_get_calendar (goa_object);
- if (goa_calendar != NULL) {
- online_accounts_google_sync_calendar (goa_object, evo_id);
- g_object_unref (goa_calendar);
- } else {
- ESourceList *source_list = NULL;
- ECalSourceType source_type;
- GError *error = NULL;
-
- source_type = E_CAL_SOURCE_TYPE_EVENT;
- if (e_cal_get_sources (&source_list, source_type, &error)) {
- e_source_list_remove_source_by_uid (
- source_list, evo_id);
- e_source_list_sync (source_list, NULL);
- g_object_unref (source_list);
- } else {
- g_warn_if_fail (source_list == NULL);
- g_warn_if_fail (error != NULL);
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- /* XXX Would be nice to support Google Tasks as well. */
- }
-
- /*** Google Contacts ***/
-
- goa_contacts = goa_object_get_contacts (goa_object);
- if (goa_contacts != NULL) {
- online_accounts_google_sync_contacts (goa_object, evo_id);
- g_object_unref (goa_contacts);
- } else {
- ESourceList *source_list = NULL;
- GError *error = NULL;
-
- if (e_book_get_addressbooks (&source_list, &error)) {
- e_source_list_remove_source_by_uid (
- source_list, evo_id);
- e_source_list_sync (source_list, NULL);
- g_object_unref (source_list);
- } else {
- g_warn_if_fail (source_list == NULL);
- g_warn_if_fail (error != NULL);
- g_warning ("%s", error->message);
- g_error_free (error);
- }
- }
-}
diff --git a/modules/online-accounts/e-online-accounts-google.h b/modules/online-accounts/e-online-accounts-google.h
deleted file mode 100644
index 10973f3298..0000000000
--- a/modules/online-accounts/e-online-accounts-google.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * e-online-accounts-google.h
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- */
-
-#ifndef E_ONLINE_ACCOUNTS_GOOGLE_H
-#define E_ONLINE_ACCOUNTS_GOOGLE_H
-
-#define GOA_API_IS_SUBJECT_TO_CHANGE
-#include <goa/goa.h>
-
-G_BEGIN_DECLS
-
-void e_online_accounts_google_sync (GoaObject *goa_object,
- const gchar *evo_id);
-
-G_END_DECLS
-
-#endif /* E_ONLINE_ACCOUNTS_GOOGLE_H */
diff --git a/modules/online-accounts/evolution-online-accounts.c b/modules/online-accounts/evolution-online-accounts.c
index 3cdfc423c7..9f80c93c7a 100644
--- a/modules/online-accounts/evolution-online-accounts.c
+++ b/modules/online-accounts/evolution-online-accounts.c
@@ -16,509 +16,15 @@
*
*/
-#include <config.h>
-#include <glib/gi18n-lib.h>
-
-/* XXX Just use the deprecated APIs for now.
- * We'll be switching away soon enough. */
-#undef E_CAL_DISABLE_DEPRECATED
-#undef E_BOOK_DISABLE_DEPRECATED
-
-#include <libecal/e-cal.h>
-#include <libebook/e-book.h>
-#include <libedataserver/e-uid.h>
-#include <libedataserver/e-account-list.h>
-
-#include <shell/e-shell.h>
-
-#include <libemail-utils/e-account-utils.h>
-
#include "camel-sasl-xoauth.h"
-#include "e-online-accounts-google.h"
-
-/* Standard GObject macros */
-#define E_TYPE_ONLINE_ACCOUNTS \
- (e_online_accounts_get_type ())
-#define E_ONLINE_ACCOUNTS(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_ONLINE_ACCOUNTS, EOnlineAccounts))
-
-/* This is the property name or URL parameter under which we
- * embed the GoaAccount ID into an EAccount or ESource object. */
-#define GOA_KEY "goa-account-id"
-
-typedef struct _EOnlineAccounts EOnlineAccounts;
-typedef struct _EOnlineAccountsClass EOnlineAccountsClass;
-
-typedef struct _AccountNode AccountNode;
-
-struct _EOnlineAccounts {
- EExtension parent;
-
- /* GoaAccount ID -> EAccount/ESource ID */
- GHashTable *accounts;
-
- GoaClient *goa_client;
- EActivity *connecting;
-};
-
-struct _EOnlineAccountsClass {
- EExtensionClass parent_class;
-};
-
-struct _AccountNode {
- gchar *goa_id; /* GoaAccount ID */
- gchar *evo_id; /* EAccount/ESource ID */
-};
/* Module Entry Points */
void e_module_load (GTypeModule *type_module);
void e_module_unload (GTypeModule *type_module);
-/* Forward Declarations */
-GType e_online_accounts_get_type (void);
-
-G_DEFINE_DYNAMIC_TYPE (EOnlineAccounts, e_online_accounts, E_TYPE_EXTENSION)
-
-static EShell *
-online_accounts_get_shell (EOnlineAccounts *extension)
-{
- EExtensible *extensible;
-
- extensible = e_extension_get_extensible (E_EXTENSION (extension));
-
- return E_SHELL (extensible);
-}
-
-static void
-online_accounts_account_added_cb (GoaClient *goa_client,
- GoaObject *goa_object,
- EOnlineAccounts *extension)
-{
- GoaAccount *goa_account;
- const gchar *provider_type;
- const gchar *goa_id;
- const gchar *evo_id;
-
- goa_account = goa_object_get_account (goa_object);
- provider_type = goa_account_get_provider_type (goa_account);
-
- goa_id = goa_account_get_id (goa_account);
- evo_id = g_hash_table_lookup (extension->accounts, goa_id);
-
- if (g_strcmp0 (provider_type, "google") == 0) {
- if (evo_id == NULL) {
- gchar *uid = e_uid_new ();
- g_hash_table_insert (
- extension->accounts,
- g_strdup (goa_id), uid);
- evo_id = uid;
- }
-
- e_online_accounts_google_sync (goa_object, evo_id);
- }
-
- g_object_unref (goa_account);
-}
-
-static void
-online_accounts_account_changed_cb (GoaClient *goa_client,
- GoaObject *goa_object,
- EOnlineAccounts *extension)
-{
- /* XXX We'll be able to handle changes more sanely once we have
- * key-file based ESources with proper change notifications. */
- online_accounts_account_added_cb (goa_client, goa_object, extension);
-}
-
-static void
-online_accounts_account_removed_cb (GoaClient *goa_client,
- GoaObject *goa_object,
- EOnlineAccounts *extension)
-{
- GoaAccount *goa_account;
- EAccountList *account_list;
- ESourceList *source_list;
- ECalSourceType type;
- EAccount *account;
- const gchar *goa_id;
- const gchar *evo_id;
-
- goa_account = goa_object_get_account (goa_object);
- goa_id = goa_account_get_id (goa_account);
- evo_id = g_hash_table_lookup (extension->accounts, goa_id);
-
- if (evo_id == NULL)
- goto exit;
-
- /* Remove the mail account. */
-
- account_list = e_get_account_list ();
- account = e_get_account_by_uid (evo_id);
-
- if (account != NULL) {
- e_account_list_remove (account_list, account);
- e_account_list_save (account_list);
- }
-
- /* Remove the address book. */
-
- if (e_book_get_addressbooks (&source_list, NULL)) {
- e_source_list_remove_source_by_uid (source_list, evo_id);
- e_source_list_sync (source_list, NULL);
- g_object_unref (source_list);
- }
-
- /* Remove the calendar. */
-
- for (type = 0; type < E_CAL_SOURCE_TYPE_LAST; type++) {
- if (e_cal_get_sources (&source_list, type, NULL)) {
- e_source_list_remove_source_by_uid (
- source_list, evo_id);
- e_source_list_sync (source_list, NULL);
- g_object_unref (source_list);
- }
- }
-
-exit:
- g_object_unref (goa_account);
-}
-
-static gint
-online_accounts_compare_id (GoaObject *goa_object,
- const gchar *goa_id)
-{
- GoaAccount *goa_account;
- gint result;
-
- goa_account = goa_object_get_account (goa_object);
- result = g_strcmp0 (goa_account_get_id (goa_account), goa_id);
- g_object_unref (goa_account);
-
- return result;
-}
-
-static void
-online_accounts_handle_uid (EOnlineAccounts *extension,
- const gchar *goa_id,
- const gchar *evo_id)
-{
- const gchar *match;
-
- /* If the GNOME Online Account ID is already registered, the
- * corresponding Evolution ID better match what was passed in. */
- match = g_hash_table_lookup (extension->accounts, goa_id);
- g_return_if_fail (match == NULL || g_strcmp0 (match, evo_id) == 0);
-
- if (match == NULL)
- g_hash_table_insert (
- extension->accounts,
- g_strdup (goa_id),
- g_strdup (evo_id));
-}
-
-static void
-online_accounts_search_source_list (EOnlineAccounts *extension,
- GList *goa_objects,
- ESourceList *source_list)
-{
- GSList *list_a;
-
- list_a = e_source_list_peek_groups (source_list);
-
- while (list_a != NULL) {
- ESourceGroup *source_group;
- GQueue trash = G_QUEUE_INIT;
- GSList *list_b;
-
- source_group = E_SOURCE_GROUP (list_a->data);
- list_a = g_slist_next (list_a);
-
- list_b = e_source_group_peek_sources (source_group);
-
- while (list_b != NULL) {
- ESource *source;
- const gchar *property;
- const gchar *uid;
- GList *match;
-
- source = E_SOURCE (list_b->data);
- list_b = g_slist_next (list_b);
-
- uid = e_source_get_uid (source);
- property = e_source_get_property (source, GOA_KEY);
-
- if (property == NULL)
- continue;
-
- /* Verify the GOA account still exists. */
- match = g_list_find_custom (
- goa_objects, property, (GCompareFunc)
- online_accounts_compare_id);
-
- /* If a matching GoaObject was found, add its ID
- * to our accounts hash table. Otherwise remove
- * the ESource after we finish looping. */
- if (match != NULL)
- online_accounts_handle_uid (
- extension, property, uid);
- else
- g_queue_push_tail (&trash, source);
- }
-
- /* Empty the trash. */
- while (!g_queue_is_empty (&trash)) {
- ESource *source = g_queue_pop_head (&trash);
- e_source_group_remove_source (source_group, source);
- }
- }
-
- e_source_list_sync (source_list, NULL);
-}
-
-static void
-online_accounts_populate_accounts_table (EOnlineAccounts *extension,
- GList *goa_objects)
-{
- EAccountList *account_list;
- ESourceList *source_list;
- EIterator *iterator;
- ECalSourceType type;
- GQueue trash = G_QUEUE_INIT;
-
- /* XXX All this messy logic will be much prettier once the new
- * key-file based ESource API is merged. For now though,
- * we trudge through it the old and cumbersome way. */
-
- /* Search mail accounts. */
-
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
-
- while (e_iterator_is_valid (iterator)) {
- EAccount *account;
- CamelURL *url;
- const gchar *param;
-
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iterator);
- e_iterator_next (iterator);
-
- if (account->source == NULL)
- continue;
-
- if (account->source->url == NULL)
- continue;
-
- url = camel_url_new (account->source->url, NULL);
- if (url == NULL)
- continue;
-
- param = camel_url_get_param (url, GOA_KEY);
- if (param != NULL) {
- GList *match;
-
- /* Verify the GOA account still exists. */
- match = g_list_find_custom (
- goa_objects, param, (GCompareFunc)
- online_accounts_compare_id);
-
- /* If a matching GoaObject was found, add its ID
- * to our accounts hash table. Otherwise remove
- * the EAccount after we finish looping. */
- if (match != NULL)
- online_accounts_handle_uid (
- extension, param, account->uid);
- else
- g_queue_push_tail (&trash, account);
- }
-
- camel_url_free (url);
- }
-
- g_object_unref (iterator);
-
- /* Empty the trash. */
- while (!g_queue_is_empty (&trash)) {
- EAccount *account = g_queue_pop_head (&trash);
- e_account_list_remove (account_list, account);
- }
-
- e_account_list_save (account_list);
-
- /* Search address book sources. */
-
- if (e_book_get_addressbooks (&source_list, NULL)) {
- online_accounts_search_source_list (
- extension, goa_objects, source_list);
- g_object_unref (source_list);
- }
-
- /* Search calendar-related sources. */
-
- for (type = 0; type < E_CAL_SOURCE_TYPE_LAST; type++) {
- if (e_cal_get_sources (&source_list, type, NULL)) {
- online_accounts_search_source_list (
- extension, goa_objects, source_list);
- g_object_unref (source_list);
- }
- }
-}
-
-static void
-online_accounts_connect_done (GObject *source_object,
- GAsyncResult *result,
- EOnlineAccounts *extension)
-{
- GList *list, *link;
- GError *error = NULL;
-
- extension->goa_client = goa_client_new_finish (result, &error);
-
- /* FIXME Add an EAlert for this? */
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- return;
- }
-
- list = goa_client_get_accounts (extension->goa_client);
-
- /* This populates a hash table of GOA ID -> Evo ID strings by
- * searching through all Evolution sources for ones tagged with
- * a GOA ID. If a GOA ID tag is found, but no corresponding GOA
- * account (presumably meaning the GOA account was deleted between
- * Evo sessions), then the EAccount or ESource on which the tag was
- * found gets deleted. */
- online_accounts_populate_accounts_table (extension, list);
-
- for (link = list; link != NULL; link = g_list_next (link))
- online_accounts_account_added_cb (
- extension->goa_client,
- GOA_OBJECT (link->data),
- extension);
-
- g_list_free_full (list, (GDestroyNotify) g_object_unref);
-
- /* Listen for Online Account changes. */
- g_signal_connect (
- extension->goa_client, "account-added",
- G_CALLBACK (online_accounts_account_added_cb), extension);
- g_signal_connect (
- extension->goa_client, "account-changed",
- G_CALLBACK (online_accounts_account_changed_cb), extension);
- g_signal_connect (
- extension->goa_client, "account-removed",
- G_CALLBACK (online_accounts_account_removed_cb), extension);
-
- /* This will allow the Evolution Setup Assistant to proceed. */
- g_object_unref (extension->connecting);
- extension->connecting = NULL;
-}
-
-static void
-online_accounts_connect (EShell *shell,
- EActivity *activity,
- EOnlineAccounts *extension)
-{
- /* This will inhibit the Evolution Setup Assistant until
- * we've synchronized with the OnlineAccounts service. */
- extension->connecting = g_object_ref (activity);
-
- /* We don't really need to reference the extension in the
- * async closure since its lifetime is bound to the EShell. */
- goa_client_new (
- NULL, (GAsyncReadyCallback)
- online_accounts_connect_done, extension);
-}
-
-static void
-online_accounts_dispose (GObject *object)
-{
- EOnlineAccounts *extension;
-
- extension = E_ONLINE_ACCOUNTS (object);
-
- /* This should never fail... in theory. */
- g_warn_if_fail (extension->connecting == NULL);
-
- if (extension->goa_client != NULL) {
- g_signal_handlers_disconnect_matched (
- extension->goa_client, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, object);
- g_object_unref (extension->goa_client);
- extension->goa_client = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_online_accounts_parent_class)->dispose (object);
-}
-
-static void
-online_accounts_finalize (GObject *object)
-{
- EOnlineAccounts *extension;
-
- extension = E_ONLINE_ACCOUNTS (object);
-
- g_hash_table_destroy (extension->accounts);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_online_accounts_parent_class)->finalize (object);
-}
-
-static void
-online_accounts_constructed (GObject *object)
-{
- EOnlineAccounts *extension;
- EShell *shell;
-
- extension = E_ONLINE_ACCOUNTS (object);
- shell = online_accounts_get_shell (extension);
-
- /* This event is emitted from the "startup-wizard" module. */
- g_signal_connect (
- shell, "event::load-accounts",
- G_CALLBACK (online_accounts_connect), extension);
-
- /* Chain up to parent's constructed() method. */
- G_OBJECT_CLASS (e_online_accounts_parent_class)->constructed (object);
-}
-
-static void
-e_online_accounts_class_init (EOnlineAccountsClass *class)
-{
- GObjectClass *object_class;
- EExtensionClass *extension_class;
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = online_accounts_dispose;
- object_class->finalize = online_accounts_finalize;
- object_class->constructed = online_accounts_constructed;
-
- extension_class = E_EXTENSION_CLASS (class);
- extension_class->extensible_type = E_TYPE_SHELL;
-}
-
-static void
-e_online_accounts_class_finalize (EOnlineAccountsClass *class)
-{
-}
-
-static void
-e_online_accounts_init (EOnlineAccounts *extension)
-{
- extension->accounts = g_hash_table_new_full (
- (GHashFunc) g_str_hash,
- (GEqualFunc) g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_free);
-}
-
G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module)
{
- e_online_accounts_register_type (type_module);
camel_sasl_xoauth_type_register (type_module);
}