summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2009-07-19 16:48:31 +0100
committerPhilip Withnall <philip@tecnocode.co.uk>2009-07-19 16:48:31 +0100
commitd2872bbe103b43e87d8469513df4f4ec55ea71ef (patch)
tree4a079e71912c418b94c1973fa689a5004ce1b3fc
parentc0d41063dc52788d6597554280a7b0142a880dbf (diff)
downloadevolution-data-server-libgdata-port.tar.gz
Cleaned up error handling and fixed some attribute bugs in the Google Contacts backendlibgdata-port
-rw-r--r--addressbook/backends/google/e-book-backend-google.c68
-rw-r--r--addressbook/backends/google/google-book.c175
-rw-r--r--addressbook/backends/google/google-book.h15
-rw-r--r--addressbook/backends/google/util.c8
4 files changed, 111 insertions, 155 deletions
diff --git a/addressbook/backends/google/e-book-backend-google.c b/addressbook/backends/google/e-book-backend-google.c
index fc0ff618c..3a2b962f1 100644
--- a/addressbook/backends/google/e-book-backend-google.c
+++ b/addressbook/backends/google/e-book-backend-google.c
@@ -1,6 +1,7 @@
/* e-book-backend-google.c - Google contact backendy.
*
* Copyright (C) 2008 Joergen Scheibengruber
+ * Copyright (C) 2009 Philip Withnall
*
* 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
@@ -27,6 +28,7 @@
#include <libedata-book/e-data-book.h>
#include <libedata-book/e-data-book-view.h>
#include <libedata-book/e-book-backend-sexp.h>
+#include <gdata/gdata-service.h>
#include "e-book-backend-google.h"
#include "google-book.h"
@@ -48,7 +50,7 @@ struct _EBookBackendGooglePrivate
gboolean __e_book_backend_google_debug__;
-static EBookBackendSyncStatus e_book_backend_status_from_google_book_error (GoogleBookError error_code);
+static EBookBackendSyncStatus e_book_backend_status_from_google_book_error (GError *error);
static EBookBackendSyncStatus
e_book_backend_google_create_contact (EBookBackendSync *backend,
@@ -76,7 +78,7 @@ e_book_backend_google_create_contact (EBookBackendSync *backend,
google_book_add_contact (priv->book, contact, out_contact, &error);
g_object_unref (contact);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
+ status = e_book_backend_status_from_google_book_error (error);
__debug__ ("Creating contact failed: %s", error->message);
g_clear_error (&error);
*out_contact = NULL;
@@ -114,7 +116,7 @@ e_book_backend_google_remove_contacts (EBookBackendSync *backend,
google_book_remove_contact (priv->book, uid, &error);
if (error) {
/* Only last error will be reported */
- status = e_book_backend_status_from_google_book_error (error->code);
+ status = e_book_backend_status_from_google_book_error (error);
__debug__ ("Deleting contact %s failed: %s", uid, error->message);
g_clear_error (&error);
} else {
@@ -154,7 +156,7 @@ e_book_backend_google_modify_contact (EBookBackendSync *backend,
google_book_update_contact (priv->book, contact, out_contact, &error);
g_object_unref (contact);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
+ status = e_book_backend_status_from_google_book_error (error);
__debug__ ("Modifying contact failed: %s", error->message);
g_clear_error (&error);
*out_contact = NULL;
@@ -181,7 +183,7 @@ e_book_backend_google_get_contact (EBookBackendSync *backend,
contact = google_book_get_contact (priv->book, uid, &error);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
+ status = e_book_backend_status_from_google_book_error (error);
__debug__ ("Getting contact with uid %s failed: %s", uid, error->message);
g_clear_error (&error);
return status;
@@ -212,7 +214,7 @@ e_book_backend_google_get_contact_list (EBookBackendSync *backend,
all_contacts = google_book_get_all_contacts (priv->book, &error);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
+ status = e_book_backend_status_from_google_book_error (error);
__debug__ ("Getting all contacts failed: %s", error->message);
g_clear_error (&error);
return status;
@@ -283,9 +285,8 @@ on_google_book_sequence_complete (GoogleBook *book, GError *error, gpointer user
priv = GET_PRIVATE (user_data);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
+ status = e_book_backend_status_from_google_book_error (error);
__debug__ ("Book-view query failed: %s", error->message);
- status = e_book_backend_status_from_google_book_error (error->code);
g_clear_error (&error);
}
for (iter = priv->bookviews; iter; iter = iter->next) {
@@ -378,9 +379,8 @@ e_book_backend_google_authenticate_user (EBookBackendSync *backend,
google_book_connect_to_google (priv->book, password, &error);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
+ status = e_book_backend_status_from_google_book_error (error);
__debug__ ("Authentication failed: %s", error->message);
- status = e_book_backend_status_from_google_book_error (error->code);
g_clear_error (&error);
} else {
e_book_backend_notify_writable (E_BOOK_BACKEND (backend), TRUE);
@@ -686,8 +686,54 @@ e_book_backend_google_new (void)
}
static EBookBackendSyncStatus
-e_book_backend_status_from_google_book_error (GoogleBookError error_code)
+e_book_backend_status_from_google_book_error (GError *error)
{
+ if (!error)
+ return GNOME_Evolution_Addressbook_Success;
+
+ if (error->domain == GDATA_AUTHENTICATION_ERROR) {
+ /* Authentication errors */
+ switch (error->code) {
+ case GDATA_AUTHENTICATION_ERROR_BAD_AUTHENTICATION:
+ return GNOME_Evolution_Addressbook_AuthenticationFailed;
+ case GDATA_AUTHENTICATION_ERROR_NOT_VERIFIED:
+ case GDATA_AUTHENTICATION_ERROR_TERMS_NOT_AGREED:
+ case GDATA_AUTHENTICATION_ERROR_CAPTCHA_REQUIRED:
+ case GDATA_AUTHENTICATION_ERROR_ACCOUNT_DELETED:
+ case GDATA_AUTHENTICATION_ERROR_ACCOUNT_DISABLED:
+ return GNOME_Evolution_Addressbook_PermissionDenied;
+ case GDATA_AUTHENTICATION_ERROR_SERVICE_DISABLED:
+ return GNOME_Evolution_Addressbook_RepositoryOffline;
+ default:
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
+ } else if (error->domain == GDATA_SERVICE_ERROR) {
+ /* General service errors */
+ switch (error->code) {
+ case GDATA_SERVICE_ERROR_UNAVAILABLE:
+ return GNOME_Evolution_Addressbook_RepositoryOffline;
+ case GDATA_SERVICE_ERROR_PROTOCOL_ERROR:
+ return GNOME_Evolution_Addressbook_InvalidQuery;
+ case GDATA_SERVICE_ERROR_ENTRY_ALREADY_INSERTED:
+ return GNOME_Evolution_Addressbook_ContactIdAlreadyExists;
+ case GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED:
+ return GNOME_Evolution_Addressbook_AuthenticationRequired;
+ case GDATA_SERVICE_ERROR_NOT_FOUND:
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ case GDATA_SERVICE_ERROR_CONFLICT:
+ return GNOME_Evolution_Addressbook_ContactIdAlreadyExists;
+ case GDATA_SERVICE_ERROR_FORBIDDEN:
+ return GNOME_Evolution_Addressbook_QueryRefused;
+ case GDATA_SERVICE_ERROR_WITH_QUERY:
+ case GDATA_SERVICE_ERROR_WITH_INSERTION:
+ case GDATA_SERVICE_ERROR_WITH_UPDATE:
+ case GDATA_SERVICE_ERROR_WITH_DELETION:
+ return GNOME_Evolution_Addressbook_InvalidQuery;
+ default:
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
+ }
+
return GNOME_Evolution_Addressbook_OtherError;
}
diff --git a/addressbook/backends/google/google-book.c b/addressbook/backends/google/google-book.c
index 1dd5160c6..b23f0383a 100644
--- a/addressbook/backends/google/google-book.c
+++ b/addressbook/backends/google/google-book.c
@@ -26,6 +26,7 @@
#include <libedataserver/e-proxy.h>
#include <gdata/gdata-service.h>
#include <gdata/services/contacts/gdata-contacts-service.h>
+#include <gdata/services/contacts/gdata-contacts-query.h>
#include <gdata/services/contacts/gdata-contacts-contact.h>
#include "util.h"
@@ -101,11 +102,6 @@ google_book_get_new_contacts_in_chunks (GoogleBook *book,
GError **error);
static void
-google_book_error_from_soup_error (GError *soup_error,
- GError **error,
- const char *message);
-
-static void
google_book_cache_init (GoogleBook *book, gboolean on_disk)
{
GoogleBookPrivate *priv = GET_PRIVATE (book);
@@ -284,9 +280,8 @@ google_book_cache_get_last_update (GoogleBook *book)
case ON_DISK_CACHE:
return e_book_backend_cache_get_time (priv->cache.on_disk);
case IN_MEMORY_CACHE:
- if (priv->cache.in_memory.contacts) {
+ if (priv->cache.in_memory.contacts)
return g_time_val_to_iso8601 (&priv->cache.in_memory.last_updated);
- }
break;
case NO_CACHE:
default:
@@ -762,7 +757,6 @@ google_book_connect_to_google (GoogleBook *book, const char *password, GError **
{
GoogleBookPrivate *priv;
GDataService *service;
- GError *soup_error = NULL;
__debug__ (G_STRFUNC);
g_return_val_if_fail (IS_GOOGLE_BOOK (book), FALSE);
@@ -782,11 +776,7 @@ google_book_connect_to_google (GoogleBook *book, const char *password, GError **
proxy_settings_changed (priv->proxy, priv);
priv->service = NULL;
- gdata_service_authenticate (service, priv->username, password, NULL, &soup_error);
-
- if (soup_error) {
- google_book_error_from_soup_error (soup_error, error,
- "Connecting to Google failed");
+ if (!gdata_service_authenticate (service, priv->username, password, NULL, error)) {
priv->service = NULL;
g_object_unref (service);
g_object_unref (priv->proxy);
@@ -839,7 +829,6 @@ google_book_add_contact (GoogleBook *book,
GoogleBookPrivate *priv;
GDataEntry *entry, *new_entry;
gchar *xml;
- GError *soup_error = NULL;
*out_contact = NULL;
@@ -856,16 +845,12 @@ google_book_add_contact (GoogleBook *book,
g_free (xml);
new_entry = GDATA_ENTRY (gdata_contacts_service_insert_contact (GDATA_CONTACTS_SERVICE (priv->service), GDATA_CONTACTS_CONTACT (entry),
- NULL, &soup_error));
+ NULL, error));
g_object_unref (entry);
- if (soup_error) {
- google_book_error_from_soup_error (soup_error, error,
- "Adding entry failed");
+ if (!new_entry)
return FALSE;
- }
*out_contact = google_book_cache_add_contact (book, new_entry);
-
g_object_unref (new_entry);
return TRUE;
@@ -879,7 +864,6 @@ google_book_update_contact (GoogleBook *book,
{
GoogleBookPrivate *priv;
GDataEntry *entry, *new_entry;
- GError *soup_error = NULL;
EContact *cached_contact;
gchar *xml;
const char *uid;
@@ -899,9 +883,9 @@ google_book_update_contact (GoogleBook *book,
cached_contact = google_book_cache_get_contact (book, uid, &entry);
if (NULL == cached_contact) {
g_set_error (error,
- GOOGLE_BOOK_ERROR,
- GOOGLE_BOOK_ERROR_CONTACT_NOT_FOUND,
- "Contact with uid %s not found in cache.", uid);
+ GDATA_SERVICE_ERROR,
+ GDATA_SERVICE_ERROR_NOT_FOUND,
+ "Contact with uid %s not found in cache.", uid);
return FALSE;
}
g_object_unref (cached_contact);
@@ -912,14 +896,11 @@ google_book_update_contact (GoogleBook *book,
g_free (xml);
new_entry = GDATA_ENTRY (gdata_contacts_service_update_contact (GDATA_CONTACTS_SERVICE (priv->service), GDATA_CONTACTS_CONTACT (entry),
- NULL, &soup_error));
+ NULL, error));
g_object_unref (entry);
- if (soup_error) {
- google_book_error_from_soup_error (soup_error, error,
- "Updating entry failed");
+ if (!new_entry)
return FALSE;
- }
xml = NULL;
if (new_entry)
@@ -928,7 +909,6 @@ google_book_update_contact (GoogleBook *book,
g_free (xml);
*out_contact = google_book_cache_add_contact (book, new_entry);
-
g_object_unref (new_entry);
return TRUE;
@@ -939,8 +919,8 @@ google_book_remove_contact (GoogleBook *book, const char *uid, GError **error)
{
GoogleBookPrivate *priv;
GDataEntry *entry = NULL;
- GError *soup_error = NULL;
EContact *cached_contact;
+ gboolean success;
__debug__ (G_STRFUNC);
g_return_val_if_fail (IS_GOOGLE_BOOK (book), FALSE);
@@ -951,25 +931,16 @@ google_book_remove_contact (GoogleBook *book, const char *uid, GError **error)
cached_contact = google_book_cache_get_contact (book, uid, &entry);
if (NULL == cached_contact) {
- g_set_error (error,
- GOOGLE_BOOK_ERROR,
- GOOGLE_BOOK_ERROR_CONTACT_NOT_FOUND,
- "Contact with uid %s not found in cache.", uid);
+ g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NOT_FOUND, "Contact with uid %s not found in cache.", uid);
return FALSE;
}
google_book_cache_remove_contact (book, uid);
- gdata_service_delete_entry (GDATA_SERVICE (priv->service), entry, NULL, &soup_error);
+ success = gdata_service_delete_entry (GDATA_SERVICE (priv->service), entry, NULL, error);
g_object_unref (entry);
g_object_unref (cached_contact);
- if (soup_error) {
- google_book_error_from_soup_error (soup_error, error,
- "Removing entry failed");
- return FALSE;
- }
-
- return TRUE;
+ return success;
}
static void
@@ -1038,10 +1009,13 @@ google_book_get_new_contacts_in_chunks (GoogleBook *book,
GError **error)
{
GoogleBookPrivate *priv;
- int start_index = 1;
+ GDataFeed *feed;
+ GDataQuery *query;
char *last_updated;
GError *our_error = NULL;
gboolean rv = TRUE;
+ GTimeVal current_time;
+ int results;
priv = GET_PRIVATE (book);
@@ -1052,29 +1026,24 @@ google_book_get_new_contacts_in_chunks (GoogleBook *book,
google_book_cache_freeze (book);
- while (start_index > 0) {
- GDataFeed *feed;
+ /* Build our query */
+ query = GDATA_QUERY (gdata_contacts_query_new_with_limits (NULL, 1, chunk_size));
+ if (last_updated) {
+ GTimeVal updated;
+
+ g_assert (g_time_val_from_iso8601 (last_updated, &updated) == TRUE);
+ gdata_query_set_updated_min (query, &updated);
+ gdata_contacts_query_set_show_deleted (GDATA_CONTACTS_QUERY (query), TRUE);
+ }
+
+ /* Get the paginated results */
+ do {
GList *entries;
- GString *uri;
- int results;
- GError *soup_error = NULL;
-
- /* TODO: Convert to GDataQuery */
- uri = g_string_new (priv->base_uri);
- g_string_append_printf (uri, "?max-results=%d&start-index=%d",
- chunk_size, start_index);
- if (last_updated) {
- g_string_append_printf (uri, "&updated-min=%s&showdeleted=true",
- last_updated);
- }
- __debug__ ("URI is '%s'", uri->str);
- feed = gdata_service_query (priv->service, uri->str, NULL, GDATA_TYPE_CONTACTS_CONTACT, NULL, NULL, NULL, &soup_error);
- g_string_free (uri, TRUE);
+ /* Run the query */
+ feed = gdata_contacts_service_query_contacts (GDATA_CONTACTS_SERVICE (priv->service), query, NULL, NULL, NULL, &our_error);
- if (soup_error) {
- google_book_error_from_soup_error (soup_error, &our_error,
- "Downloading feed failed");
+ if (our_error) {
google_book_emit_sequence_complete (book, our_error);
g_propagate_error (error, our_error);
@@ -1086,24 +1055,22 @@ google_book_get_new_contacts_in_chunks (GoogleBook *book,
results = entries ? g_list_length (entries) : 0;
__debug__ ("Feed has %d entries", results);
- if (last_updated) {
+ /* Process the entries from this page */
+ if (last_updated)
g_list_foreach (entries, process_subsequent_entry, book);
- } else {
+ else
g_list_foreach (entries, process_initial_entry, book);
- }
+ g_object_unref (feed);
- if (results == chunk_size) {
- start_index += results;
- } else {
- GTimeVal current_time;
+ /* Move to the next page */
+ gdata_query_next_page (query);
+ } while (results == chunk_size);
+
+ /* Finish updating the cache */
+ g_get_current_time (&current_time);
+ google_book_cache_set_last_update (book, &current_time);
+ google_book_emit_sequence_complete (book, NULL);
- start_index = -1;
- g_get_current_time (&current_time);
- google_book_cache_set_last_update (book, &current_time);
- google_book_emit_sequence_complete (book, NULL);
- }
- g_object_unref (feed);
- }
out:
g_free (last_updated);
google_book_cache_thaw (book);
@@ -1136,12 +1103,8 @@ google_book_get_contact (GoogleBook *book,
}
return contact;
} else {
- if (NULL == *error) {
- g_set_error (error,
- GOOGLE_BOOK_ERROR,
- GOOGLE_BOOK_ERROR_CONTACT_NOT_FOUND,
- "Contact with uid %s not found in cache.", uid);
- }
+ if (NULL == *error)
+ g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NOT_FOUND, "Contact with uid %s not found in cache.", uid);
}
return NULL;
}
@@ -1235,47 +1198,3 @@ google_book_set_live_mode (GoogleBook *book, gboolean live_mode)
google_book_cache_refresh_if_needed (book, NULL);
}
}
-
-static void
-google_book_error_from_soup_error (GError *soup_error,
- GError **error,
- const char *message)
-{
- GoogleBookError code;
-
- g_assert (soup_error);
-
- /* TODO: Convert this to deal with libgdata codes */
- if (soup_error->code < 100) {
- code = GOOGLE_BOOK_ERROR_NETWORK_ERROR;
- } else
- if (soup_error->code == 200) {
- code = GOOGLE_BOOK_ERROR_NONE;
- } else
- if (soup_error->code == 400) {
- code = GOOGLE_BOOK_ERROR_INVALID_CONTACT;
- } else
- if (soup_error->code == 401) {
- code = GOOGLE_BOOK_ERROR_AUTH_REQUIRED;
- } else
- if (soup_error->code == 403) {
- code = GOOGLE_BOOK_ERROR_AUTH_FAILED;
- } else
- if (soup_error->code == 404) {
- code = GOOGLE_BOOK_ERROR_CONTACT_NOT_FOUND;
- } else
- if (soup_error->code == 409) {
- code = GOOGLE_BOOK_ERROR_CONFLICT;
- } else {
- code = GOOGLE_BOOK_ERROR_HTTP_ERROR;
- }
- g_set_error (error,
- GOOGLE_BOOK_ERROR,
- GOOGLE_BOOK_ERROR_HTTP_ERROR,
- "%s due to '%s' (HTTP code %d)",
- message ? message : "Action failed",
- soup_error->message,
- soup_error->code);
- g_clear_error (&soup_error);
-}
-
diff --git a/addressbook/backends/google/google-book.h b/addressbook/backends/google/google-book.h
index 0d390ae32..6accbb410 100644
--- a/addressbook/backends/google/google-book.h
+++ b/addressbook/backends/google/google-book.h
@@ -45,7 +45,6 @@ G_BEGIN_DECLS
typedef struct _GoogleBook GoogleBook;
typedef struct _GoogleBookClass GoogleBookClass;
-typedef enum _GoogleBookError GoogleBookError;
struct _GoogleBook
{
@@ -64,20 +63,6 @@ struct _GoogleBookClass
void (*auth_required) (void);
};
-enum _GoogleBookError
-{
- GOOGLE_BOOK_ERROR_NONE,
- GOOGLE_BOOK_ERROR_CONTACT_NOT_FOUND,
- GOOGLE_BOOK_ERROR_INVALID_CONTACT,
- GOOGLE_BOOK_ERROR_CONFLICT,
- GOOGLE_BOOK_ERROR_AUTH_FAILED,
- GOOGLE_BOOK_ERROR_AUTH_REQUIRED,
- GOOGLE_BOOK_ERROR_NETWORK_ERROR,
- GOOGLE_BOOK_ERROR_HTTP_ERROR
-};
-
-#define GOOGLE_BOOK_ERROR (g_quark_from_string ("GoogleBookError"))
-
typedef void (*GoogleBookContactRetrievedCallback) (EContact *contact, gpointer user_data);
GType google_book_get_type (void);
diff --git a/addressbook/backends/google/util.c b/addressbook/backends/google/util.c
index bddd440b3..7696f995c 100644
--- a/addressbook/backends/google/util.c
+++ b/addressbook/backends/google/util.c
@@ -101,6 +101,12 @@ _gdata_entry_update_from_e_contact (GDataEntry *entry,
e_contact_name_free (name);
}
+ /* Clear out all the old attributes */
+ gdata_contacts_contact_remove_all_email_addresses (GDATA_CONTACTS_CONTACT (entry));
+ gdata_contacts_contact_remove_all_phone_numbers (GDATA_CONTACTS_CONTACT (entry));
+ gdata_contacts_contact_remove_all_postal_addresses (GDATA_CONTACTS_CONTACT (entry));
+ gdata_contacts_contact_remove_all_im_addresses (GDATA_CONTACTS_CONTACT (entry));
+
/* We walk them in reverse order, so we can find
* the correct primaries */
iter = g_list_last (attributes);
@@ -158,7 +164,7 @@ _gdata_entry_update_from_e_contact (GDataEntry *entry,
(attr, &have_im_primary);
if (im)
gdata_contacts_contact_add_im_address (GDATA_CONTACTS_CONTACT (entry), im);
- } else if (e_vcard_attribute_is_single_valued (attr)) {
+ } else if (e_vcard_attribute_is_single_valued (attr) && g_ascii_strcasecmp (name, "X-MOZILLA-HTML") != 0) {
gchar *value;
/* Add the attribute as an extended property */