[evolution-mapi] Bug #611557 - Update calendar/addressbook sources on start
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Bug #611557 - Update calendar/addressbook sources on start
- Date: Tue, 8 Jun 2010 13:02:46 +0000 (UTC)
commit b6c95e5bf687ef8b3ecac0f132d0cfdaef768c7d
Author: Milan Crha <mcrha redhat com>
Date: Tue Jun 8 15:02:10 2010 +0200
Bug #611557 - Update calendar/addressbook sources on start
.../exchange-mapi-account-listener.c | 298 +++++++++++++++-----
1 files changed, 220 insertions(+), 78 deletions(-)
---
diff --git a/src/account-setup-eplugin/exchange-mapi-account-listener.c b/src/account-setup-eplugin/exchange-mapi-account-listener.c
index 93fa84f..7846aab 100644
--- a/src/account-setup-eplugin/exchange-mapi-account-listener.c
+++ b/src/account-setup-eplugin/exchange-mapi-account-listener.c
@@ -149,6 +149,30 @@ lookup_account_info (const gchar *key)
return NULL;
}
+static ESource *
+find_source_by_fid (GSList *sources, const gchar *fid)
+{
+ GSList *s;
+
+ g_return_val_if_fail (fid != NULL, NULL);
+
+ if (!sources)
+ return NULL;
+
+ for (s = sources; s; s = s->next) {
+ ESource *source = s->data;
+
+ if (source && E_IS_SOURCE (source)) {
+ const gchar *has_fid = e_source_get_property (source, "folder-id");
+
+ if (has_fid && g_str_equal (fid, has_fid))
+ return source;
+ }
+ }
+
+ return NULL;
+}
+
#define CALENDAR_SOURCES "/apps/evolution/calendar/sources"
#define TASK_SOURCES "/apps/evolution/tasks/sources"
#define JOURNAL_SOURCES "/apps/evolution/memos/sources"
@@ -159,15 +183,16 @@ lookup_account_info (const gchar *key)
#define ITIP_MESSAGE_HANDLING "/apps/evolution/itip/delete_processed"
static void
-add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType folder_type, CamelURL *url)
+add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType folder_type, CamelURL *url, mapi_id_t trash_fid)
{
ESourceList *source_list = NULL;
ESourceGroup *group = NULL;
const gchar *conf_key = NULL, *source_selection_key = NULL;
- GSList *temp_list = NULL;
GConfClient* client;
- GSList *ids, *temp;
+ GSList *ids, *temp_list, *old_sources = NULL;
gchar *base_uri = NULL;
+ gboolean is_new_group = FALSE;
+
if (folder_type == MAPI_FOLDER_TYPE_APPOINTMENT) {
conf_key = CALENDAR_SOURCES;
@@ -188,10 +213,19 @@ add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType fold
source_list = e_source_list_new_for_gconf (client, conf_key);
base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, url->user, url->host);
group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
- if (group)
+ if (group) {
e_source_group_set_name (group, account->name);
- else
+ g_object_ref (group);
+ is_new_group = FALSE;
+ old_sources = NULL;
+ for (temp_list = e_source_group_peek_sources (group); temp_list; temp_list = temp_list->next) {
+ old_sources = g_slist_prepend (old_sources, temp_list->data);
+ }
+ } else {
group = e_source_group_new (account->name, base_uri);
+ is_new_group = TRUE;
+ old_sources = NULL;
+ }
g_free (base_uri);
e_source_group_set_property (group, "create_source", "yes");
e_source_group_set_property (group, "username", url->user);
@@ -209,13 +243,24 @@ add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType fold
ExchangeMAPIFolder *folder = temp_list->data;
ESource *source = NULL;
gchar *relative_uri = NULL, *fid = NULL;
+ gboolean is_new_source = FALSE;
- if (folder->container_class != folder_type)
+ if (folder->container_class != folder_type || trash_fid == exchange_mapi_folder_get_parent_id (folder))
continue;
fid = exchange_mapi_util_mapi_id_to_string (folder->folder_id);
relative_uri = g_strconcat (";", fid, NULL);
- source = e_source_new (folder->folder_name, relative_uri);
+ source = find_source_by_fid (old_sources, fid);
+ if (source) {
+ is_new_source = FALSE;
+ g_object_ref (source);
+ old_sources = g_slist_remove (old_sources, source);
+ e_source_set_name (source, folder->folder_name);
+ e_source_set_relative_uri (source, relative_uri);
+ } else {
+ source = e_source_new (folder->folder_name, relative_uri);
+ is_new_source = TRUE;
+ }
e_source_set_property (source, "auth", "1");
e_source_set_property (source, "auth-domain", EXCHANGE_MAPI_PASSWORD_COMPONENT);
e_source_set_property (source, "auth-type", "plain/password");
@@ -242,16 +287,15 @@ add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType fold
e_source_set_property (source, "acl-owner-name", account->id->name);
e_source_set_property (source, "acl-owner-email", account->id->address);
- e_source_group_add_source (group, source, -1);
+ if (is_new_source)
+ e_source_group_add_source (group, source, -1);
if (source_selection_key && folder->is_default) {
ids = gconf_client_get_list (client, source_selection_key , GCONF_VALUE_STRING, NULL);
ids = g_slist_append (ids, g_strdup (e_source_peek_uid (source)));
gconf_client_set_list (client, source_selection_key, GCONF_VALUE_STRING, ids, NULL);
- for (temp = ids; temp != NULL; temp = g_slist_next (temp))
- g_free (temp->data);
-
+ g_slist_foreach (ids, (GFunc) g_free, NULL);
g_slist_free (ids);
}
@@ -260,11 +304,23 @@ add_cal_esource (EAccount *account, GSList *folders, ExchangeMAPIFolderType fold
g_free (fid);
}
- if (!e_source_list_add_group (source_list, group, -1))
- return;
+ if (old_sources) {
+ /* these were not found on the server by fid, thus remove them */
+ for (temp_list = old_sources; temp_list; temp_list = temp_list->next) {
+ ESource *source = temp_list->data;
+
+ if (source && E_IS_SOURCE (source))
+ e_source_group_remove_source (group, source);
+ }
+
+ g_slist_free (old_sources);
+ }
+
+ if (is_new_group && !e_source_list_add_group (source_list, group, -1))
+ g_warning ("%s: Failed to add new group", G_STRFUNC);
if (!e_source_list_sync (source_list, NULL))
- return;
+ g_warning ("%s: Failed to sync source list", G_STRFUNC);
g_object_unref (group);
g_object_unref (source_list);
@@ -344,16 +400,16 @@ remove_cal_esource (EAccount *existing_account_info, ExchangeMAPIFolderType fold
adds the new account info to mapi_accounts list */
static void
-add_calendar_sources (EAccount *account, GSList *folders)
+add_calendar_sources (EAccount *account, GSList *folders, mapi_id_t trash_fid)
{
CamelURL *url;
url = camel_url_new (account->source->url, NULL);
if (url) {
- add_cal_esource (account, folders, MAPI_FOLDER_TYPE_APPOINTMENT, url);
- add_cal_esource (account, folders, MAPI_FOLDER_TYPE_TASK, url);
- add_cal_esource (account, folders, MAPI_FOLDER_TYPE_MEMO, url);
+ add_cal_esource (account, folders, MAPI_FOLDER_TYPE_APPOINTMENT, url, trash_fid);
+ add_cal_esource (account, folders, MAPI_FOLDER_TYPE_TASK, url, trash_fid);
+ add_cal_esource (account, folders, MAPI_FOLDER_TYPE_MEMO, url, trash_fid);
}
camel_url_free (url);
@@ -379,15 +435,16 @@ remove_calendar_sources (EAccount *account)
}
static gboolean
-add_addressbook_sources (EAccount *account, GSList *folders)
+add_addressbook_sources (EAccount *account, GSList *folders, mapi_id_t trash_fid)
{
CamelURL *url;
ESourceList *list;
ESourceGroup *group;
ESource *source;
gchar *base_uri;
- GSList *temp_list;
+ GSList *temp_list, *old_sources = NULL;
GConfClient* client;
+ gboolean is_new_group = FALSE;
url = camel_url_new (account->source->url, NULL);
if (url == NULL) {
@@ -398,10 +455,19 @@ add_addressbook_sources (EAccount *account, GSList *folders)
client = gconf_client_get_default ();
list = e_source_list_new_for_gconf (client, "/apps/evolution/addressbook/sources" );
group = e_source_list_peek_group_by_base_uri (list, base_uri);
- if (group)
+ if (group) {
e_source_group_set_name (group, account->name);
- else
+ g_object_ref (group);
+ is_new_group = FALSE;
+ old_sources = NULL;
+ for (temp_list = e_source_group_peek_sources (group); temp_list; temp_list = temp_list->next) {
+ old_sources = g_slist_prepend (old_sources, temp_list->data);
+ }
+ } else {
group = e_source_group_new (account->name, base_uri);
+ is_new_group = TRUE;
+ old_sources = NULL;
+ }
e_source_group_set_property (group, "user", url->user);
e_source_group_set_property (group, "host", url->host);
e_source_group_set_property (group, "profile", camel_url_get_param (url, "profile"));
@@ -409,20 +475,32 @@ add_addressbook_sources (EAccount *account, GSList *folders)
for (temp_list = folders; temp_list != NULL; temp_list = g_slist_next (temp_list)) {
ExchangeMAPIFolder *folder = temp_list->data;
- gchar *tmp = NULL;
- if (folder->container_class != MAPI_FOLDER_TYPE_CONTACT)
+ gchar *fid, *relative_uri;
+ gboolean is_new_source = FALSE;
+
+ if (folder->container_class != MAPI_FOLDER_TYPE_CONTACT || trash_fid == exchange_mapi_folder_get_parent_id (folder))
continue;
- source = e_source_new (folder->folder_name, g_strconcat (";",folder->folder_name, NULL));
+ fid = exchange_mapi_util_mapi_id_to_string (folder->folder_id);
+ relative_uri = g_strconcat (";", folder->folder_name, NULL);
+ source = find_source_by_fid (old_sources, fid);
+ if (source) {
+ is_new_source = FALSE;
+ g_object_ref (source);
+ old_sources = g_slist_remove (old_sources, source);
+ e_source_set_name (source, folder->folder_name);
+ e_source_set_relative_uri (source, relative_uri);
+ } else {
+ source = e_source_new (folder->folder_name, relative_uri);
+ is_new_source = TRUE;
+ }
e_source_set_property (source, "auth", "plain/password");
e_source_set_property (source, "auth-domain", EXCHANGE_MAPI_PASSWORD_COMPONENT);
e_source_set_property(source, "user", url->user);
e_source_set_property(source, "host", url->host);
e_source_set_property(source, "profile", camel_url_get_param (url, "profile"));
e_source_set_property(source, "domain", camel_url_get_param (url, "domain"));
- tmp = exchange_mapi_util_mapi_id_to_string (folder->folder_id);
- e_source_set_property(source, "folder-id", tmp);
- g_free (tmp);
+ e_source_set_property(source, "folder-id", fid);
e_source_set_property (source, "offline_sync",
camel_url_get_param (url, "offline_sync") ? "1" : "0");
e_source_set_property (source, "completion", "true");
@@ -433,18 +511,38 @@ add_addressbook_sources (EAccount *account, GSList *folders)
e_source_set_property (source, "parent-fid", tmp);
g_free (tmp);
}
- e_source_group_add_source (group, source, -1);
+ if (is_new_source)
+ e_source_group_add_source (group, source, -1);
g_object_unref (source);
+ g_free (fid);
+ g_free (relative_uri);
}
//Add GAL
{
gchar *uri;
+ gboolean is_new_source = FALSE;
+
+ uri = g_strdup_printf ("mapigal://%s %s/;Global Address List", url->user, url->host);
+ for (temp_list = old_sources; temp_list; temp_list = temp_list->next) {
+ source = temp_list->data;
- uri = g_strdup_printf("mapigal://%s %s/;Global Address List", url->user, url->host);
- source = e_source_new_with_absolute_uri ("Global Address List", uri);
+ if (source && E_IS_SOURCE (source)
+ && e_source_peek_absolute_uri (source)
+ && g_str_equal (e_source_peek_absolute_uri (source), uri))
+ break;
+ }
+
+ if (source) {
+ is_new_source = FALSE;
+ g_object_ref (source);
+ old_sources = g_slist_remove (old_sources, source);
+ e_source_set_name (source, _("Global Address List"));
+ } else {
+ source = e_source_new_with_absolute_uri (_("Global Address List"), uri);
+ is_new_source = TRUE;
+ }
g_free (uri);
- // source = e_source_new ("Global Address List", g_strconcat (";","Global Address List" , NULL));
e_source_set_property (source, "auth", "plain/password");
e_source_set_property (source, "auth-domain", "MAPIGAL");
@@ -459,12 +557,29 @@ add_addressbook_sources (EAccount *account, GSList *folders)
e_source_set_property(source, "offline_sync", "1");
e_source_set_property (source, "completion", "true");
e_source_set_property (source, "delete", "no");
- e_source_group_add_source (group, source, -1);
+ if (is_new_source)
+ e_source_group_add_source (group, source, -1);
g_object_unref (source);
}
- e_source_list_add_group (list, group, -1);
- e_source_list_sync (list, NULL);
+ if (old_sources) {
+ /* these were not found on the server by fid, thus remove them */
+ for (temp_list = old_sources; temp_list; temp_list = temp_list->next) {
+ ESource *source = temp_list->data;
+
+ if (source && E_IS_SOURCE (source))
+ e_source_group_remove_source (group, source);
+ }
+
+ g_slist_free (old_sources);
+ }
+
+ if (is_new_group && !e_source_list_add_group (list, group, -1))
+ g_warning ("%s: Failed to add new group", G_STRFUNC);
+
+ if (!e_source_list_sync (list, NULL))
+ g_warning ("%s: Failed to sync source list", G_STRFUNC);
+
g_object_unref (group);
g_object_unref (list);
g_object_unref (client);
@@ -513,20 +628,20 @@ remove_addressbook_sources (ExchangeMAPIAccountInfo *existing_account_info)
camel_url_free (url);
}
-static void
-update_sources_fn (gpointer data, gpointer user_data)
+static gboolean
+update_sources_idle_cb (gpointer data)
{
ExchangeMapiConnection *conn = data;
EAccount *account;
GSList *folders_list;
- g_return_if_fail (conn != NULL);
+ g_return_val_if_fail (conn != NULL, FALSE);
account = g_object_get_data (G_OBJECT (conn), "EAccount");
if (!account) {
g_object_unref (conn);
- g_return_if_fail (account != NULL);
- return;
+ g_return_val_if_fail (account != NULL, FALSE);
+ return FALSE;
}
g_object_set_data (G_OBJECT (conn), "EAccount", NULL);
@@ -534,12 +649,31 @@ update_sources_fn (gpointer data, gpointer user_data)
folders_list = exchange_mapi_connection_peek_folders_list (conn);
if (account->enabled && lookup_account_info (account->uid)) {
- add_addressbook_sources (account, folders_list);
- add_calendar_sources (account, folders_list);
+ mapi_id_t trash_fid = exchange_mapi_connection_get_default_folder_id (conn, olFolderDeletedItems);
+
+ add_addressbook_sources (account, folders_list, trash_fid);
+ add_calendar_sources (account, folders_list, trash_fid);
}
g_object_unref (conn);
g_object_unref (account);
+
+ return FALSE;
+}
+
+static void
+update_sources_fn (gpointer data, gpointer user_data)
+{
+ ExchangeMapiConnection *conn = data;
+
+ g_return_if_fail (conn != NULL);
+
+ /* this fetches folder_list to the connection cache,
+ thus next call will be quick as much as possible */
+ exchange_mapi_connection_peek_folders_list (conn);
+
+ /* run a job in a main thread */
+ g_idle_add (update_sources_idle_cb, conn);
}
static void
@@ -577,7 +711,7 @@ check_for_account_conn_cb (gpointer data)
g_return_val_if_fail (csd->profile_name != NULL, FALSE);
g_return_val_if_fail (csd->account != NULL, FALSE);
- if (csd->account->enabled && !lookup_account_info (csd->account->uid)) {
+ if (csd->account->enabled && lookup_account_info (csd->account->uid)) {
ExchangeMapiConnection *conn;
conn = exchange_mapi_connection_find (csd->profile_name);
@@ -597,6 +731,42 @@ check_for_account_conn_cb (gpointer data)
}
static void
+update_account_sources (EAccount *account, gboolean can_create_profile)
+{
+ CamelURL *url;
+ ExchangeMapiConnection *conn;
+
+ url = camel_url_new (account->source->url, NULL);
+ g_return_if_fail (url != NULL);
+
+ conn = exchange_mapi_connection_find (camel_url_get_param (url, "profile"));
+ if (!conn && can_create_profile) {
+ /* connect to the server when not connected yet */
+ if (!create_profile_entry (url, account)) {
+ camel_url_free (url);
+ g_warning ("%s: Failed to create MAPI profile for '%s'", G_STRFUNC, account->name);
+ return;
+ }
+
+ conn = exchange_mapi_connection_find (camel_url_get_param (url, "profile"));
+ }
+
+ if (conn) {
+ run_update_sources_thread (conn, account);
+ } else {
+ struct create_sources_data *csd;
+
+ csd = g_new0 (struct create_sources_data, 1);
+ csd->profile_name = g_strdup (camel_url_get_param (url, "profile"));
+ csd->account = g_object_ref (account);
+
+ g_timeout_add_seconds (1, check_for_account_conn_cb, csd);
+ }
+
+ camel_url_free (url);
+}
+
+static void
mapi_account_added (EAccountList *account_listener, EAccount *account)
{
ExchangeMAPIAccountInfo *info = NULL;
@@ -612,39 +782,8 @@ mapi_account_added (EAccountList *account_listener, EAccount *account)
mapi_accounts = g_list_append (mapi_accounts, info);
- if (account->enabled) {
- CamelURL *url;
- ExchangeMapiConnection *conn;
-
- url = camel_url_new (info->source_url, NULL);
- g_return_if_fail (url != NULL);
-
- conn = exchange_mapi_connection_find (camel_url_get_param (url, "profile"));
- if (!conn) {
- /* connect to the server when not connected yet */
- if (!create_profile_entry (url, account)) {
- camel_url_free (url);
- g_warning ("%s: Failed to create MAPI profile for '%s'", G_STRFUNC, account->name);
- return;
- }
-
- conn = exchange_mapi_connection_find (camel_url_get_param (url, "profile"));
- }
-
- if (conn) {
- run_update_sources_thread (conn, account);
- } else {
- struct create_sources_data *csd;
-
- csd = g_new0 (struct create_sources_data, 1);
- csd->profile_name = g_strdup (camel_url_get_param (url, "profile"));
- csd->account = g_object_ref (account);
-
- g_timeout_add_seconds (1, check_for_account_conn_cb, csd);
- }
-
- camel_url_free (url);
- }
+ if (account->enabled)
+ update_account_sources (account, TRUE);
}
static void
@@ -862,12 +1001,15 @@ exchange_mapi_account_listener_construct (ExchangeMAPIAccountListener *config_li
info->source_url = g_strdup (account->source->url);
info->enabled = account->enabled;
+ mapi_accounts = g_list_append (mapi_accounts, info);
+
if (!account->enabled) {
remove_addressbook_sources (info);
remove_calendar_sources (account);
+ } else {
+ /* fetch new calendars/remove dropped from a server, if any */
+ update_account_sources (account, FALSE);
}
-
- mapi_accounts = g_list_append (mapi_accounts, info);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]