[evolution-data-server] google: Add a new custom vCard property containing Google system groups
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] google: Add a new custom vCard property containing Google system groups
- Date: Sun, 24 Jun 2012 10:57:19 +0000 (UTC)
commit 1cfc48f58873ee448f2bb7853c9d3c0f0f48caab
Author: Philip Withnall <philip tecnocode co uk>
Date: Sun Jun 24 09:55:46 2012 +0100
google: Add a new custom vCard property containing Google system groups
This can then be picked up by libfolks (and other interested clients) to
allow them to detect which system groups a Google contact is in. Previously,
they had to infer this from the categories the contact was in, which are
localised. This was tricky and fragile.
Helps: https://bugzilla.gnome.org/show_bug.cgi?id=676383
.../backends/google/e-book-backend-google.c | 23 +++++++++++++---
addressbook/backends/google/e-book-google-utils.c | 27 ++++++++++++++++++-
addressbook/backends/google/e-book-google-utils.h | 3 +-
3 files changed, 45 insertions(+), 8 deletions(-)
---
diff --git a/addressbook/backends/google/e-book-backend-google.c b/addressbook/backends/google/e-book-backend-google.c
index 8c14f85..ab3a392 100644
--- a/addressbook/backends/google/e-book-backend-google.c
+++ b/addressbook/backends/google/e-book-backend-google.c
@@ -83,6 +83,8 @@ struct _EBookBackendGooglePrivate {
GHashTable *groups_by_name;
/* Mapping system_group_id to entry ID */
GHashTable *system_groups_by_id;
+ /* Mapping entry ID to system_group_id */
+ GHashTable *system_groups_by_entry_id;
/* Time when the groups were last queried */
GTimeVal last_groups_update;
@@ -165,13 +167,13 @@ cache_add_contact (EBookBackend *backend,
switch (priv->cache_type) {
case ON_DISK_CACHE:
- contact = e_contact_new_from_gdata_entry (entry, priv->groups_by_id);
+ contact = e_contact_new_from_gdata_entry (entry, priv->groups_by_id, priv->system_groups_by_entry_id);
e_contact_add_gdata_entry_xml (contact, entry);
e_book_backend_cache_add_contact (priv->cache.on_disk, contact);
e_contact_remove_gdata_entry_xml (contact);
return contact;
case IN_MEMORY_CACHE:
- contact = e_contact_new_from_gdata_entry (entry, priv->groups_by_id);
+ contact = e_contact_new_from_gdata_entry (entry, priv->groups_by_id, priv->system_groups_by_entry_id);
uid = e_contact_get_const (contact, E_CONTACT_UID);
g_hash_table_insert (priv->cache.in_memory.contacts, g_strdup (uid), g_object_ref (contact));
g_hash_table_insert (priv->cache.in_memory.gdata_entries, g_strdup (uid), g_object_ref (entry));
@@ -904,10 +906,19 @@ process_group (GDataEntry *entry,
if (system_group_id) {
__debug__ ("Processing %ssystem group %s, %s", is_deleted ? "(deleted) " : "", system_group_id, uid);
- if (is_deleted)
+ if (is_deleted) {
+ gchar *entry_id = g_hash_table_lookup (priv->system_groups_by_id, system_group_id);
+ g_hash_table_remove (priv->system_groups_by_entry_id, entry_id);
g_hash_table_remove (priv->system_groups_by_id, system_group_id);
- else
- g_hash_table_replace (priv->system_groups_by_id, g_strdup (system_group_id), e_contact_sanitise_google_group_id (uid));
+ } else {
+ gchar *entry_id, *system_group_id_dup;
+
+ entry_id = e_contact_sanitise_google_group_id (uid);
+ system_group_id_dup = g_strdup (system_group_id);
+
+ g_hash_table_replace (priv->system_groups_by_entry_id, entry_id, system_group_id_dup);
+ g_hash_table_replace (priv->system_groups_by_id, system_group_id_dup, entry_id);
+ }
g_free (name);
@@ -2208,6 +2219,7 @@ e_book_backend_google_open (EBookBackend *backend,
priv->groups_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->groups_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->system_groups_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ priv->system_groups_by_entry_id = g_hash_table_new (g_str_hash, g_str_equal); /* shares keys and values with system_groups_by_id */
priv->cancellables = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
}
@@ -2512,6 +2524,7 @@ e_book_backend_google_finalize (GObject *object)
if (priv->cancellables) {
g_hash_table_destroy (priv->groups_by_id);
g_hash_table_destroy (priv->groups_by_name);
+ g_hash_table_destroy (priv->system_groups_by_entry_id);
g_hash_table_destroy (priv->system_groups_by_id);
g_hash_table_destroy (priv->cancellables);
}
diff --git a/addressbook/backends/google/e-book-google-utils.c b/addressbook/backends/google/e-book-google-utils.c
index 8d63e66..ce8ab12 100644
--- a/addressbook/backends/google/e-book-google-utils.c
+++ b/addressbook/backends/google/e-book-google-utils.c
@@ -39,6 +39,8 @@
#define GDATA_URIS_TYPE_PROFILE "X-PROFILE"
#define GDATA_URIS_TYPE_FTP "X-FTP"
+#define GOOGLE_SYSTEM_GROUP_ATTR "X-GOOGLE-SYSTEM-GROUP-IDS"
+
#define MULTIVALUE_ATTRIBUTE_SUFFIX "-MULTIVALUE"
gboolean __e_book_google_utils_debug__;
@@ -509,10 +511,11 @@ foreach_extended_props_cb (const gchar *name,
EContact *
e_contact_new_from_gdata_entry (GDataEntry *entry,
- GHashTable *groups_by_id)
+ GHashTable *groups_by_id,
+ GHashTable *system_groups_by_entry_id)
{
EVCard *vcard;
- EVCardAttribute *attr;
+ EVCardAttribute *attr, *system_group_ids_attr;
EContactPhoto *photo;
const gchar *photo_etag;
GList *email_addresses, *im_addresses, *phone_numbers, *postal_addresses, *orgs, *category_names, *category_ids;
@@ -536,6 +539,9 @@ e_contact_new_from_gdata_entry (GDataEntry *entry,
#endif
#endif
+ g_return_val_if_fail (system_groups_by_entry_id != NULL, NULL);
+ g_return_val_if_fail (g_hash_table_size (system_groups_by_entry_id) > 0, FALSE);
+
uid = gdata_entry_get_id (entry);
if (NULL == uid)
return NULL;
@@ -652,8 +658,11 @@ e_contact_new_from_gdata_entry (GDataEntry *entry,
/* CATEGORIES */
category_ids = gdata_contacts_contact_get_groups (GDATA_CONTACTS_CONTACT (entry));
category_names = NULL;
+ system_group_ids_attr = e_vcard_attribute_new ("", GOOGLE_SYSTEM_GROUP_ATTR);
+
for (itr = category_ids; itr != NULL; itr = g_list_delete_link (itr, itr)) {
gchar *category_id, *category_name;
+ const gchar *system_group_id;
category_id = e_contact_sanitise_google_group_id (itr->data);
category_name = g_hash_table_lookup (groups_by_id, category_id);
@@ -664,12 +673,26 @@ e_contact_new_from_gdata_entry (GDataEntry *entry,
} else
g_warning ("Couldn't find name for category with ID '%s'.", category_id);
+ /* Maintain a list of the IDs of the system groups the contact is in. */
+ system_group_id = g_hash_table_lookup (system_groups_by_entry_id, category_id);
+ if (system_group_id != NULL) {
+ e_vcard_attribute_add_value (system_group_ids_attr, system_group_id);
+ }
+
g_free (category_id);
}
e_contact_set (E_CONTACT (vcard), E_CONTACT_CATEGORY_LIST, category_names);
g_list_free (category_names);
+ /* Expose the IDs of the system groups the contact is in so that libfolks (and other clients) can use the information
+ * without having to reverse-engineer it from the (localised) category names on the contact. */
+ if (e_vcard_attribute_get_values (system_group_ids_attr) != NULL) {
+ e_vcard_add_attribute (vcard, system_group_ids_attr);
+ } else {
+ e_vcard_attribute_free (system_group_ids_attr);
+ }
+
/* Extended properties */
extended_props = gdata_contacts_contact_get_extended_properties (GDATA_CONTACTS_CONTACT (entry));
g_hash_table_foreach (extended_props, (GHFunc) foreach_extended_props_cb, vcard);
diff --git a/addressbook/backends/google/e-book-google-utils.h b/addressbook/backends/google/e-book-google-utils.h
index 2a758dd..fb0e371 100644
--- a/addressbook/backends/google/e-book-google-utils.h
+++ b/addressbook/backends/google/e-book-google-utils.h
@@ -36,7 +36,8 @@ gboolean gdata_entry_update_from_e_contact (GDataEntry *entry, EContact *contact
GHashTable *system_groups_by_id,
EContactGoogleCreateGroupFunc create_group, gpointer create_group_user_data);
-EContact *e_contact_new_from_gdata_entry (GDataEntry *entry, GHashTable *groups_by_id) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+EContact *e_contact_new_from_gdata_entry (GDataEntry *entry, GHashTable *groups_by_id,
+ GHashTable *system_groups_by_entry_id) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
void e_contact_add_gdata_entry_xml (EContact *contact, GDataEntry *entry);
void e_contact_remove_gdata_entry_xml (EContact *contact);
const gchar *e_contact_get_gdata_entry_xml (EContact *contact, const gchar **edit_uri);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]