-I$(top_builddir) \
-I$(top_srcdir)/addressbook \
-I$(top_builddir)/addressbook \
- -I$(top_srcdir)/servers/google/libgdata \
- -I$(top_builddir)/servers/google/libgdata \
- -I$(top_srcdir)/servers/google/libgdata-google \
- -I$(top_builddir)/servers/google/libgdata-google \
$(SOUP_CFLAGS) \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
+ $(EVOLUTION_ADDRESSBOOK_CFLAGS) \
+ $(GDATA_CFLAGS)
libebookbackendgoogle_la_SOURCES = \
util.h \
$(top_builddir)/addressbook/libebook/libebook-1.2.la \
$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
- $(top_builddir)/servers/google/libgdata/libgdata-1.2.la \
- $(top_builddir)/servers/google/libgdata-google/libgdata-google-1.2.la \
$(top_builddir)/libebackend/libebackend-1.2.la \
$(SOUP_LIBS) \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
+ $(EVOLUTION_ADDRESSBOOK_LIBS) \
+ $(GDATA_LIBS)
libebookbackendgoogle_la_LDFLAGS = \
-module -avoid-version $(NO_UNDEFINED)
/* e-book-backend-google.c - Google contact backendy.
*
* Copyright (C) 2008 Joergen Scheibengruber
+ * Copyright (C) 2010 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
#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"
struct _EBookBackendGooglePrivate
{
- gint mode;
+ GNOME_Evolution_Addressbook_BookMode mode;
GoogleBook *book;
GList *bookviews;
};
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,
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;
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 {
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;
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;
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;
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) {
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);
E_CONTACT_ADDRESS,
E_CONTACT_ADDRESS_HOME,
E_CONTACT_ADDRESS_WORK,
- E_CONTACT_ADDRESS_OTHER
+ E_CONTACT_ADDRESS_OTHER,
+ E_CONTACT_NAME,
+ E_CONTACT_GIVEN_NAME,
+ E_CONTACT_FAMILY_NAME,
+ E_CONTACT_PHONE_ASSISTANT,
+ E_CONTACT_PHONE_BUSINESS_2,
+ E_CONTACT_PHONE_CALLBACK,
+ E_CONTACT_PHONE_CAR,
+ E_CONTACT_PHONE_COMPANY,
+ E_CONTACT_PHONE_HOME_2,
+ E_CONTACT_PHONE_ISDN,
+ E_CONTACT_PHONE_OTHER,
+ E_CONTACT_PHONE_OTHER_FAX,
+ E_CONTACT_PHONE_PRIMARY,
+ E_CONTACT_PHONE_RADIO,
+ E_CONTACT_PHONE_TELEX,
+ E_CONTACT_PHONE_TTYTDD,
+ E_CONTACT_IM_AIM_HOME_1,
+ E_CONTACT_IM_AIM_HOME_2,
+ E_CONTACT_IM_AIM_HOME_3,
+ E_CONTACT_IM_AIM_WORK_1,
+ E_CONTACT_IM_AIM_WORK_2,
+ E_CONTACT_IM_AIM_WORK_3,
+ E_CONTACT_IM_GROUPWISE_HOME_1,
+ E_CONTACT_IM_GROUPWISE_HOME_2,
+ E_CONTACT_IM_GROUPWISE_HOME_3,
+ E_CONTACT_IM_GROUPWISE_WORK_1,
+ E_CONTACT_IM_GROUPWISE_WORK_2,
+ E_CONTACT_IM_GROUPWISE_WORK_3,
+ E_CONTACT_IM_JABBER_HOME_1,
+ E_CONTACT_IM_JABBER_HOME_2,
+ E_CONTACT_IM_JABBER_HOME_3,
+ E_CONTACT_IM_JABBER_WORK_1,
+ E_CONTACT_IM_JABBER_WORK_2,
+ E_CONTACT_IM_JABBER_WORK_3,
+ E_CONTACT_IM_YAHOO_HOME_1,
+ E_CONTACT_IM_YAHOO_HOME_2,
+ E_CONTACT_IM_YAHOO_HOME_3,
+ E_CONTACT_IM_YAHOO_WORK_1,
+ E_CONTACT_IM_YAHOO_WORK_2,
+ E_CONTACT_IM_YAHOO_WORK_3,
+ E_CONTACT_IM_MSN_HOME_1,
+ E_CONTACT_IM_MSN_HOME_2,
+ E_CONTACT_IM_MSN_HOME_3,
+ E_CONTACT_IM_MSN_WORK_1,
+ E_CONTACT_IM_MSN_WORK_2,
+ E_CONTACT_IM_MSN_WORK_3,
+ E_CONTACT_IM_ICQ_HOME_1,
+ E_CONTACT_IM_ICQ_HOME_2,
+ E_CONTACT_IM_ICQ_HOME_3,
+ E_CONTACT_IM_ICQ_WORK_1,
+ E_CONTACT_IM_ICQ_WORK_2,
+ E_CONTACT_IM_ICQ_WORK_3,
+ E_CONTACT_EMAIL,
+ E_CONTACT_IM_GADUGADU_HOME_1,
+ E_CONTACT_IM_GADUGADU_HOME_2,
+ E_CONTACT_IM_GADUGADU_HOME_3,
+ E_CONTACT_IM_GADUGADU_WORK_1,
+ E_CONTACT_IM_GADUGADU_WORK_2,
+ E_CONTACT_IM_GADUGADU_WORK_3,
+ E_CONTACT_TEL,
+ E_CONTACT_IM_SKYPE_HOME_1,
+ E_CONTACT_IM_SKYPE_HOME_2,
+ E_CONTACT_IM_SKYPE_HOME_3,
+ E_CONTACT_IM_SKYPE_WORK_1,
+ E_CONTACT_IM_SKYPE_WORK_2,
+ E_CONTACT_IM_SKYPE_WORK_3,
+ E_CONTACT_SIP
};
GList *fields = NULL;
- gint i;
+ guint i;
__debug__ (G_STRFUNC);
e_book_backend_google_set_mode (EBookBackend *backend, GNOME_Evolution_Addressbook_BookMode mode)
{
EBookBackendGooglePrivate *priv = GET_PRIVATE (backend);
+ gboolean online = (mode == GNOME_Evolution_Addressbook_MODE_REMOTE);
__debug__ (G_STRFUNC);
priv->mode = mode;
- if (NULL == priv->book) {
- return;
- }
+ if (priv->book)
+ google_book_set_offline_mode (priv->book, !online);
+ e_book_backend_notify_connection_status (backend, online);
- if (mode == GNOME_Evolution_Addressbook_MODE_REMOTE) {
- google_book_set_offline_mode (priv->book, FALSE);
- } else {
- google_book_set_offline_mode (priv->book, TRUE);
- }
+ /* Mark the book as unwriteable if we're going offline, but don't do the inverse when we go online;
+ * e_book_backend_google_authenticate_user() will mark us as writeable again once the user's authenticated again. */
+ if (!online)
+ e_book_backend_notify_writable (backend, FALSE);
}
static void
}
static EBookBackendSyncStatus
-e_book_backend_status_from_google_book_error (GoogleBookError error_code)
+e_book_backend_status_from_google_book_error (GError *error)
{
- switch (error_code) {
- case GOOGLE_BOOK_ERROR_NONE:
- return GNOME_Evolution_Addressbook_Success;
- case GOOGLE_BOOK_ERROR_CONTACT_NOT_FOUND:
- return GNOME_Evolution_Addressbook_ContactNotFound;
- case GOOGLE_BOOK_ERROR_CONFLICT:
- return GNOME_Evolution_Addressbook_ContactIdAlreadyExists;
- case GOOGLE_BOOK_ERROR_AUTH_FAILED:
- return GNOME_Evolution_Addressbook_AuthenticationFailed;
- case GOOGLE_BOOK_ERROR_AUTH_REQUIRED:
- return GNOME_Evolution_Addressbook_AuthenticationRequired;
- case GOOGLE_BOOK_ERROR_INVALID_CONTACT:
- case GOOGLE_BOOK_ERROR_NETWORK_ERROR:
- case GOOGLE_BOOK_ERROR_HTTP_ERROR:
- break;
- }
+ 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_BAD_QUERY_PARAMETER:
+ return GNOME_Evolution_Addressbook_InvalidQuery;
+ default:
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
+ }
- return GNOME_Evolution_Addressbook_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
/* goggle-book.c - Google contact list abstraction with caching.
*
* Copyright (C) 2008 Joergen Scheibengruber
+ * Copyright (C) 2010 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
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * Author: Joergen Scheibengruber <joergen.scheibengruber AT googlemail.com>
+ * Author: Joergen Scheibengruber <joergen.scheibengruber AT googlemail.com>,
+ * Philip Withnall <philip@tecnocode.co.uk>
*/
#include <string.h>
#include <libedata-book/e-book-backend-cache.h>
#include <libedataserver/e-proxy.h>
-#include <gdata-service-iface.h>
-#include <gdata-google-service.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"
#include "google-book.h"
G_DEFINE_TYPE (GoogleBook, google_book, G_TYPE_OBJECT)
+#define URI_GET_CONTACTS "://www.google.com/m8/feeds/contacts/default/full"
+
#define GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_GOOGLE_BOOK, GoogleBookPrivate))
GDataService *service;
EProxy *proxy;
guint refresh_interval;
- gchar *base_uri;
- /* FIXME - this one should not be needed */
- gchar *add_base_uri;
+ gboolean use_ssl;
gboolean live_mode;
GError **error);
static void
-google_book_error_from_soup_error (GError *soup_error,
- GError **error,
- const gchar *message);
-
-static void
google_book_cache_init (GoogleBook *book, gboolean on_disk)
{
GoogleBookPrivate *priv = GET_PRIVATE (book);
g_strdup (uid), g_object_ref (entry));
return contact;
case NO_CACHE:
+ default:
break;
}
return NULL;
success = g_hash_table_remove (priv->cache.in_memory.contacts, uid);
return success && g_hash_table_remove (priv->cache.in_memory.gdata_entries, uid);
case NO_CACHE:
- break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean
+google_book_cache_has_contact (GoogleBook *book, const gchar *uid)
+{
+ GoogleBookPrivate *priv = GET_PRIVATE (book);
+
+ switch (priv->cache_type) {
+ case ON_DISK_CACHE:
+ return e_book_backend_cache_check_contact (priv->cache.on_disk, uid);
+ case IN_MEMORY_CACHE:
+ return g_hash_table_lookup (priv->cache.in_memory.contacts, uid) ? TRUE : FALSE;
+ case NO_CACHE:
+ default:
+ break;
}
return FALSE;
}
contact = e_book_backend_cache_get_contact (priv->cache.on_disk, uid);
if (contact) {
if (entry) {
- const gchar *entry_xml;
- entry_xml = _e_contact_get_gdata_entry_xml (contact);
- *entry = gdata_entry_new_from_xml (entry_xml);
+ const gchar *entry_xml, *edit_link;
+
+ entry_xml = _e_contact_get_gdata_entry_xml (contact, &edit_link);
+ *entry = GDATA_ENTRY (gdata_parsable_new_from_xml (GDATA_TYPE_CONTACTS_CONTACT, entry_xml, -1, NULL));
+
+ if (*entry != NULL) {
+ GDataLink *link = gdata_link_new (edit_link, GDATA_LINK_EDIT);
+ gdata_entry_add_link (*entry, link);
+ g_object_unref (link);
+ }
}
_e_contact_remove_gdata_entry_xml (contact);
}
}
return contact;
case NO_CACHE:
+ default:
break;
}
return NULL;
case IN_MEMORY_CACHE:
return _g_hash_table_to_list (priv->cache.in_memory.contacts);
case NO_CACHE:
+ default:
break;
}
return NULL;
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:
break;
}
return NULL;
memcpy (tv, &priv->cache.in_memory.last_updated, sizeof (GTimeVal));
return priv->cache.in_memory.contacts != NULL;
case NO_CACHE:
+ default:
break;
}
return FALSE;
google_book_cache_set_last_update (GoogleBook *book, GTimeVal *tv)
{
GoogleBookPrivate *priv = GET_PRIVATE (book);
- gchar *time;
+ gchar *_time;
switch (priv->cache_type) {
case ON_DISK_CACHE:
- time = g_time_val_to_iso8601 (tv);
+ _time = g_time_val_to_iso8601 (tv);
/* Work around a bug in EBookBackendCache */
e_file_cache_remove_object (E_FILE_CACHE (priv->cache.on_disk), "last_update_time");
- e_book_backend_cache_set_time (priv->cache.on_disk, time);
- g_free (time);
+ e_book_backend_cache_set_time (priv->cache.on_disk, _time);
+ g_free (_time);
return;
case IN_MEMORY_CACHE:
memcpy (&priv->cache.in_memory.last_updated, tv, sizeof (GTimeVal));
case NO_CACHE:
+ default:
break;
}
}
g_hash_table_destroy (priv->cache.in_memory.gdata_entries);
break;
case NO_CACHE:
+ default:
break;
}
priv->cache_type = NO_CACHE;
}
static void
-google_book_construct_base_uri (GoogleBook *book, gboolean use_ssl)
-{
- const gchar format[] = "%swww.google.com/m8/feeds/contacts/%s/base";
- gchar *esc_username;
- GoogleBookPrivate *priv = GET_PRIVATE (book);
-
- __debug__ (G_STRFUNC);
- g_free (priv->base_uri);
- g_free (priv->add_base_uri);
-
- esc_username = g_uri_escape_string (priv->username, NULL, FALSE);
- priv->base_uri = g_strdup_printf (format, use_ssl ? "https://" : "http://", esc_username);
- /* FIXME - always use non ssl mode when adding entries. Somehow this does not
- * work on SSL; i.e. get duplicate entries and SOUP returns error 7 - connection
- * terminated unexpectedly
- */
- priv->add_base_uri = g_strdup_printf (format, "http://", esc_username);
- g_free (esc_username);
-}
-
-static void
google_book_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{
GoogleBookPrivate *priv = GET_PRIVATE (object);
- gboolean use_ssl = FALSE;
switch (property_id) {
case PROP_USERNAME:
g_value_set_uint (value, priv->refresh_interval);
break;
case PROP_USE_SSL:
- if (priv->base_uri) {
- if (strstr (priv->base_uri, "https://")) {
- use_ssl = TRUE;
- }
- }
- g_value_set_boolean (value, use_ssl);
+ g_value_set_boolean (value, priv->use_ssl);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
case PROP_REFRESH_INTERVAL:
priv->refresh_interval = g_value_get_uint (value);
- /* FIXME - actually apply this */
+
+ /* Remove and re-add the timeout */
+ if (priv->refresh_id != 0) {
+ g_source_remove (priv->refresh_id);
+ priv->refresh_id = g_timeout_add_seconds (priv->refresh_interval, on_refresh_timeout, GOOGLE_BOOK (object));
+ }
break;
case PROP_USE_SSL:
- google_book_construct_base_uri (GOOGLE_BOOK (object), g_value_get_boolean (value));
+ priv->use_ssl = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
priv->idle_id = 0;
}
- if (priv->service) {
+ if (priv->service)
g_object_unref (priv->service);
- priv->service = NULL;
- }
- if (priv->proxy) {
+ priv->service = NULL;
+
+ if (priv->proxy)
g_object_unref (priv->proxy);
- priv->proxy = NULL;
- }
+ priv->proxy = NULL;
+
google_book_cache_destroy (GOOGLE_BOOK (object));
if (G_OBJECT_CLASS (google_book_parent_class)->dispose)
{
GoogleBookPrivate *priv = GET_PRIVATE (object);
- g_free (priv->base_uri);
- g_free (priv->add_base_uri);
g_free (priv->username);
if (G_OBJECT_CLASS (google_book_parent_class)->finalize)
PROP_USERNAME,
g_param_spec_string ("username",
"Username",
- "The username",
+ "The username.",
NULL,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_USE_CACHE,
g_param_spec_boolean ("use-cache",
- "UseCache",
- "Whether a on-disk cache should be used",
+ "Use Cache?",
+ "Whether an on-disk cache should be used.",
TRUE,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_REFRESH_INTERVAL,
g_param_spec_uint ("refresh-interval",
- "RefreshInterval",
+ "Refresh Interval",
"Specifies the number of seconds until "
"the local cache is updated from the "
"server. 0 means no updates.",
g_object_class_install_property (object_class,
PROP_USE_SSL,
g_param_spec_boolean ("use-ssl",
- "UseSSL",
- "Whether SSL should be used or not",
+ "Use SSL?",
+ "Whether SSL should be used.",
TRUE,
G_PARAM_READWRITE));
google_book_signals [CONTACT_CHANGED] =
proxy_settings_changed (EProxy *proxy, gpointer user_data)
{
SoupURI *proxy_uri = NULL;
-
+ gchar *uri;
GoogleBookPrivate *priv = (GoogleBookPrivate*) user_data;
- if (!priv || !priv->base_uri)
+
+ if (!priv || !priv->service)
return;
+ /* Build the URI which libgdata would use to query contacts */
+ uri = g_strconcat (priv->use_ssl ? "https" : "http", URI_GET_CONTACTS, NULL);
+
/* use proxy if necessary */
- if (e_proxy_require_proxy_for_uri (proxy, priv->base_uri)) {
- proxy_uri = e_proxy_peek_uri_for (proxy, priv->base_uri);
- }
- gdata_service_set_proxy (GDATA_SERVICE (priv->service), proxy_uri);
+ if (e_proxy_require_proxy_for_uri (proxy, uri))
+ proxy_uri = e_proxy_peek_uri_for (proxy, uri);
+ gdata_service_set_proxy_uri (GDATA_SERVICE (priv->service), proxy_uri);
+
+ g_free (uri);
}
gboolean
google_book_connect_to_google (GoogleBook *book, const gchar *password, GError **error)
{
GoogleBookPrivate *priv;
- GDataService *service;
- GError *soup_error = NULL;
__debug__ (G_STRFUNC);
g_return_val_if_fail (IS_GOOGLE_BOOK (book), FALSE);
priv = GET_PRIVATE (book);
if (priv->service) {
- g_warning ("Connection to google already established.");
+ g_warning ("Connection to Google already established.");
return TRUE;
}
- service = (GDataService*)gdata_google_service_new ("cp", "evolution-client-0.0.1");
+ priv->service = GDATA_SERVICE (gdata_contacts_service_new ("evolution-client-0.0.1"));
priv->proxy = e_proxy_new ();
e_proxy_setup_proxy (priv->proxy);
- priv->service = service;
proxy_settings_changed (priv->proxy, priv);
- priv->service = NULL;
-
- gdata_service_set_credentials (GDATA_SERVICE (service), priv->username, password);
- gdata_google_service_authenticate (GDATA_GOOGLE_SERVICE (service), &soup_error);
- if (soup_error) {
- google_book_error_from_soup_error (soup_error, error,
- "Connecting to google failed");
- priv->service = NULL;
- g_object_unref (service);
+ if (!gdata_service_authenticate (priv->service, priv->username, password, NULL, error)) {
+ g_object_unref (priv->service);
+ priv->service = NULL;
g_object_unref (priv->proxy);
priv->proxy = NULL;
return FALSE;
}
g_signal_connect (priv->proxy, "changed", G_CALLBACK (proxy_settings_changed), priv);
- priv->service = service;
return google_book_cache_refresh_if_needed (book, error);
}
priv->offline = offline;
if (offline) {
- if (priv->service) {
+ /* Going offline, so we can free our service and proxy */
+ if (priv->service)
g_object_unref (priv->service);
- priv->service = NULL;
- }
- if (priv->proxy) {
+ priv->service = NULL;
+
+ if (priv->proxy)
g_object_unref (priv->proxy);
- priv->proxy = NULL;
- }
- }
- if (offline == FALSE) {
- if (priv->service) {
- google_book_cache_refresh_if_needed (book, NULL);
- } else {
- google_book_emit_auth_required (book);
- }
+ priv->proxy = NULL;
+ } else {
+ /* Going online, so we need to re-authenticate and re-create the service and proxy.
+ * This is done in google_book_connect_to_google(), which is called by EBookBackendGoogle when it gets the authentication data. */
+ google_book_emit_auth_required (book);
}
}
{
GoogleBookPrivate *priv;
GDataEntry *entry, *new_entry;
- GError *soup_error = NULL;
+ gchar *xml;
*out_contact = NULL;
g_return_val_if_fail (priv->service, FALSE);
entry = _gdata_entry_new_from_e_contact (contact);
- __debug__ ("new entry with xml: %s", gdata_entry_generate_xml (entry));
- new_entry = gdata_service_insert_entry (GDATA_SERVICE (priv->service),
- priv->add_base_uri, entry, &soup_error);
+ xml = gdata_parsable_get_xml (GDATA_PARSABLE (entry));
+ __debug__ ("new entry with xml: %s", xml);
+ g_free (xml);
+
+ new_entry = GDATA_ENTRY (gdata_contacts_service_insert_contact (GDATA_CONTACTS_SERVICE (priv->service), GDATA_CONTACTS_CONTACT (entry),
+ 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;
{
GoogleBookPrivate *priv;
GDataEntry *entry, *new_entry;
- GError *soup_error = NULL;
EContact *cached_contact;
+ gchar *xml;
const gchar *uid;
*out_contact = NULL;
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);
_gdata_entry_update_from_e_contact (entry, contact);
- __debug__ ("Before:\n%s", gdata_entry_generate_xml (entry));
- new_entry = gdata_service_update_entry (GDATA_SERVICE (priv->service), entry, &soup_error);
+ xml = gdata_parsable_get_xml (GDATA_PARSABLE (entry));
+ __debug__ ("Before:\n%s", xml);
+ g_free (xml);
+
+ new_entry = GDATA_ENTRY (gdata_contacts_service_update_contact (GDATA_CONTACTS_SERVICE (priv->service), GDATA_CONTACTS_CONTACT (entry),
+ 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;
- }
- __debug__ ("After:\n%s", new_entry ? gdata_entry_generate_xml (new_entry) : NULL);
- *out_contact = google_book_cache_add_contact (book, new_entry);
+ xml = NULL;
+ if (new_entry)
+ xml = gdata_parsable_get_xml (GDATA_PARSABLE (new_entry));
+ __debug__ ("After:\n%s", xml);
+ g_free (xml);
+ *out_contact = google_book_cache_add_contact (book, new_entry);
g_object_unref (new_entry);
return TRUE;
{
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);
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, &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
GoogleBookPrivate *priv;
GoogleBook *book = user_data;
GDataEntry *entry;
- EContact *cached_contact;
- gboolean is_deleted;
+ gboolean is_deleted, is_cached;
const gchar *uid;
__debug__ (G_STRFUNC);
priv = GET_PRIVATE (book);
entry = GDATA_ENTRY (list_data);
uid = gdata_entry_get_id (entry);
- is_deleted = gdata_entry_is_deleted (entry);
+ is_deleted = gdata_contacts_contact_is_deleted (GDATA_CONTACTS_CONTACT (entry));
- cached_contact = google_book_cache_get_contact (book, uid, NULL);
+ is_cached = google_book_cache_has_contact (book, uid);
if (is_deleted) {
/* Do we have this item in our cache? */
- if (NULL != cached_contact) {
+ if (is_cached) {
google_book_cache_remove_contact (book, uid);
google_book_emit_contact_removed (book, uid);
}
contact = google_book_cache_add_contact (book, entry);
- if (cached_contact) {
+ if (is_cached) {
google_book_emit_contact_changed (book, contact);
} else {
google_book_emit_contact_added (book, contact);
}
g_object_unref (contact);
}
- if (cached_contact) {
- g_object_unref (cached_contact);
- }
}
static void
GoogleBookPrivate *priv;
GoogleBook *book = user_data;
GDataEntry *entry;
- const gchar * uid;
EContact *contact;
__debug__ (G_STRFUNC);
priv = GET_PRIVATE (book);
entry = GDATA_ENTRY (list_data);
- uid = gdata_entry_get_id (entry);
contact = google_book_cache_add_contact (book, entry);
GError **error)
{
GoogleBookPrivate *priv;
- gint start_index = 1;
+ GDataFeed *feed;
+ GDataQuery *query;
gchar *last_updated;
GError *our_error = NULL;
gboolean rv = TRUE;
+ GTimeVal current_time;
+ int results;
priv = GET_PRIVATE (book);
google_book_cache_freeze (book);
- while (start_index > 0) {
- GDataFeed *feed;
- GSList *entries;
- GString *uri;
- gint results;
- GError *soup_error = NULL;
-
- 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);
- }
+ /* 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);
+ }
- __debug__ ("URI is '%s'", uri->str);
- feed = gdata_service_get_feed (priv->service, uri->str, &soup_error);
- g_string_free (uri, TRUE);
+ /* Get the paginated results */
+ do {
+ GList *entries;
- if (soup_error) {
- google_book_error_from_soup_error (soup_error, &our_error,
- "Downloading feed failed");
+ /* Run the query */
+ feed = gdata_contacts_service_query_contacts (GDATA_CONTACTS_SERVICE (priv->service), query, NULL, NULL, NULL, &our_error);
+
+ if (our_error) {
google_book_emit_sequence_complete (book, our_error);
g_propagate_error (error, our_error);
}
entries = gdata_feed_get_entries (feed);
- results = entries ? g_slist_length (entries) : 0;
+ results = entries ? g_list_length (entries) : 0;
__debug__ ("Feed has %d entries", results);
- if (last_updated) {
- g_slist_foreach (entries, process_subsequent_entry, book);
- } else {
- g_slist_foreach (entries, process_initial_entry, book);
- }
+ /* Process the entries from this page */
+ if (last_updated)
+ g_list_foreach (entries, process_subsequent_entry, book);
+ 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 (¤t_time);
+ google_book_cache_set_last_update (book, ¤t_time);
+ google_book_emit_sequence_complete (book, NULL);
- start_index = -1;
- g_get_current_time (¤t_time);
- google_book_cache_set_last_update (book, ¤t_time);
- google_book_emit_sequence_complete (book, NULL);
- }
- g_object_unref (feed);
- }
out:
g_free (last_updated);
google_book_cache_thaw (book);
{
GoogleBookPrivate *priv;
EContact *contact;
+ GError *child_error = NULL;
priv = GET_PRIVATE (book);
__debug__ (G_STRFUNC);
g_return_val_if_fail (IS_GOOGLE_BOOK (book), NULL);
- google_book_cache_refresh_if_needed (book, error);
+ google_book_cache_refresh_if_needed (book, &child_error);
contact = google_book_cache_get_contact (book, uid, NULL);
if (contact) {
- if (*error) {
+ if (child_error) {
/* We found the contact, so forget about errors during refresh */
- g_clear_error (error);
+ g_error_free (child_error);
}
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 (!child_error)
+ g_propagate_error (error, child_error);
+ else
+ g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_NOT_FOUND, "Contact with uid %s not found in cache.", uid);
+
return NULL;
}
{
GoogleBookPrivate *priv;
GList *contacts;
+ GError *child_error = NULL;
priv = GET_PRIVATE (book);
__debug__ (G_STRFUNC);
g_return_val_if_fail (IS_GOOGLE_BOOK (book), NULL);
- google_book_cache_refresh_if_needed (book, error);
+ google_book_cache_refresh_if_needed (book, &child_error);
contacts = google_book_cache_get_contacts (book);
if (contacts) {
- if (*error) {
+ if (child_error) {
/* We found the contact, so forget about errors during refresh */
- g_clear_error (error);
+ g_error_free (child_error);
}
return contacts;
}
+
+ g_propagate_error (error, child_error);
return NULL;
}
google_book_cache_refresh_if_needed (book, NULL);
}
}
-
-static void
-google_book_error_from_soup_error (GError *soup_error,
- GError **error,
- const gchar *message)
-{
- GoogleBookError code;
-
- g_assert (soup_error);
-
- 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,
- code,
- "%s due to '%s' (HTTP code %d)",
- message ? message : "Action failed",
- soup_error->message,
- soup_error->code);
- g_clear_error (&soup_error);
-}
-
typedef struct _GoogleBook GoogleBook;
typedef struct _GoogleBookClass GoogleBookClass;
-typedef enum _GoogleBookError GoogleBookError;
struct _GoogleBook
{
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);
/* util.c - Google contact backend utility functions.
*
* Copyright (C) 2008 Joergen Scheibengruber
+ * Copyright (C) 2010 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
#include <string.h>
#include <libsoup/soup.h>
+#include <gdata/gdata.h>
+#include <gdata/services/contacts/gdata-contacts-contact.h>
#include "util.h"
-/*#define GOOGLE_PRIMARY_PARAM "X-GOOGLE-PRIMARY"*/
#define GOOGLE_PRIMARY_PARAM "X-EVOLUTION-UI-SLOT"
#define GOOGLE_LABEL_PARAM "X-GOOGLE-LABEL"
+#define GDATA_ENTRY_XML_ATTR "X-GDATA-ENTRY-XML"
+#define GDATA_ENTRY_LINK_ATTR "X-GDATA-ENTRY-LINK"
-static EVCardAttribute*
-attribute_from_gdata_entry_email_address (GDataEntryEmailAddress *email);
-
-static EVCardAttribute*
-attribute_from_gdata_entry_im_address (GDataEntryIMAddress *im);
-
-static EVCardAttribute*
-attribute_from_gdata_entry_phone_number (GDataEntryPhoneNumber *number);
-
-static EVCardAttribute*
-attribute_from_gdata_entry_postal_address (GDataEntryPostalAddress *address);
-
-static GDataEntryEmailAddress*
-gdata_entry_email_address_from_attribute (EVCardAttribute *attr,
- gboolean *primary);
-
-static GDataEntryIMAddress*
-gdata_entry_im_address_from_attribute (EVCardAttribute *attr,
- gboolean *primary);
-
-static GDataEntryPhoneNumber*
-gdata_entry_phone_number_from_attribute (EVCardAttribute *attr,
- gboolean *primary);
+static void add_attribute_from_gdata_gd_email_address (EVCard *vcard, GDataGDEmailAddress *email);
+static void add_attribute_from_gdata_gd_im_address (EVCard *vcard, GDataGDIMAddress *im);
+static void add_attribute_from_gdata_gd_phone_number (EVCard *vcard, GDataGDPhoneNumber *number);
+static void add_attribute_from_gdata_gd_postal_address (EVCard *vcard, GDataGDPostalAddress *address);
-static GDataEntryPostalAddress*
-gdata_entry_postal_address_from_attribute (EVCardAttribute *attr,
- gboolean *primary);
+static GDataGDEmailAddress *gdata_gd_email_address_from_attribute (EVCardAttribute *attr, gboolean *primary);
+static GDataGDIMAddress *gdata_gd_im_address_from_attribute (EVCardAttribute *attr, gboolean *primary);
+static GDataGDPhoneNumber *gdata_gd_phone_number_from_attribute (EVCardAttribute *attr, gboolean *primary);
+static GDataGDPostalAddress *gdata_gd_postal_address_from_attribute (EVCardAttribute *attr, gboolean *primary);
static gboolean
is_known_google_im_protocol (const gchar *protocol);
GDataEntry*
_gdata_entry_new_from_e_contact (EContact *contact)
{
- GDataEntry *entry;
- GDataEntryCategory *category;
-
- entry = gdata_entry_new ();
-
- category = g_new0 (GDataEntryCategory, 1);
- category->scheme = g_strdup ("http://schemas.google.com/g/2005#kind");
- category->term = g_strdup ("http://schemas.google.com/contact/2008#contact");
- gdata_entry_set_categories (entry, g_slist_append (NULL, category));
+ GDataEntry *entry = GDATA_ENTRY (gdata_contacts_contact_new (NULL));
if (_gdata_entry_update_from_e_contact (entry, contact))
return entry;
EContact *contact)
{
GList *attributes, *iter;
- gchar *fullname = NULL;
- GSList *email_addresses = NULL;
- GSList *im_addresses = NULL;
- GSList *phone_numbers = NULL;
- GSList *postal_addresses = NULL;
+ EContactName *name_struct = NULL;
gboolean have_email_primary = FALSE;
gboolean have_im_primary = FALSE;
gboolean have_phone_primary = FALSE;
attributes = e_vcard_get_attributes (E_VCARD (contact));
- fullname = g_strdup (e_contact_get (contact, E_CONTACT_FULL_NAME));
- if (NULL == fullname) {
- EContactName *name = e_contact_get (contact, E_CONTACT_NAME);
-
- fullname = e_contact_name_to_string (name);
- e_contact_name_free (name);
+ /* N and FN */
+ name_struct = e_contact_get (contact, E_CONTACT_NAME);
+ if (name_struct) {
+ GDataGDName *name;
+ const gchar *given = NULL, *family = NULL;
+
+ if (name_struct->given && *(name_struct->given) != '\0')
+ given = name_struct->given;
+ if (name_struct->family && *(name_struct->family) != '\0')
+ family = name_struct->family;
+
+ name = gdata_gd_name_new (given, family);
+ if (name_struct->additional && *(name_struct->additional) != '\0')
+ gdata_gd_name_set_additional_name (name, name_struct->additional);
+ if (name_struct->prefixes && *(name_struct->prefixes) != '\0')
+ gdata_gd_name_set_prefix (name, name_struct->prefixes);
+ if (name_struct->suffixes && *(name_struct->suffixes) != '\0')
+ gdata_gd_name_set_suffix (name, name_struct->suffixes);
+ gdata_gd_name_set_full_name (name, e_contact_get (contact, E_CONTACT_FULL_NAME));
+
+ gdata_contacts_contact_set_name (GDATA_CONTACTS_CONTACT (entry), name);
+ g_object_unref (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);
/* EMAIL */
- /* Ignore UID, VERSION, X-EVOLUTION-FILE-AS, N, FN */
+ /* Ignore UID, VERSION, X-EVOLUTION-FILE-AS, N, FN, LABEL */
if (0 == g_ascii_strcasecmp (name, EVC_UID) ||
0 == g_ascii_strcasecmp (name, EVC_N) ||
0 == g_ascii_strcasecmp (name, EVC_FN) ||
+ 0 == g_ascii_strcasecmp (name, EVC_LABEL) ||
0 == g_ascii_strcasecmp (name, EVC_VERSION) ||
0 == g_ascii_strcasecmp (name, EVC_X_FILE_AS)) {
} else
if (0 == g_ascii_strcasecmp (name, EVC_EMAIL)) {
- GDataEntryEmailAddress *email;
+ GDataGDEmailAddress *email;
- email = gdata_entry_email_address_from_attribute
+ email = gdata_gd_email_address_from_attribute
(attr, &have_email_primary);
if (email) {
- email_addresses = g_slist_append (email_addresses,
- email);
+ gdata_contacts_contact_add_email_address (GDATA_CONTACTS_CONTACT (entry), email);
+ g_object_unref (email);
}
} else
/* TEL */
if (0 == g_ascii_strcasecmp (name, EVC_TEL)) {
- GDataEntryPhoneNumber *number;
+ GDataGDPhoneNumber *number;
- number = gdata_entry_phone_number_from_attribute
+ number = gdata_gd_phone_number_from_attribute
(attr, &have_phone_primary);
if (number) {
- phone_numbers = g_slist_append (phone_numbers,
- number);
+ gdata_contacts_contact_add_phone_number (GDATA_CONTACTS_CONTACT (entry), number);
+ g_object_unref (number);
}
} else
- /* LABEL */
- if (0 == g_ascii_strcasecmp (name, EVC_LABEL)) {
- GDataEntryPostalAddress *address;
+ /* ADR (we ignore LABEL, since it should be the same as ADR, and ADR is more structured) */
+ if (0 == g_ascii_strcasecmp (name, EVC_ADR)) {
+ GDataGDPostalAddress *address;
- address = gdata_entry_postal_address_from_attribute
+ address = gdata_gd_postal_address_from_attribute
(attr, &have_postal_primary);
if (address) {
- postal_addresses = g_slist_append (postal_addresses,
- address);
+ gdata_contacts_contact_add_postal_address (GDATA_CONTACTS_CONTACT (entry), address);
+ g_object_unref (address);
}
} else
/* X-IM */
if (0 == g_ascii_strncasecmp (name, "X-", 2) &&
is_known_google_im_protocol (name + 2)) {
- GDataEntryIMAddress *im;
+ GDataGDIMAddress *im;
- im = gdata_entry_im_address_from_attribute
+ im = gdata_gd_im_address_from_attribute
(attr, &have_im_primary);
if (im) {
- im_addresses = g_slist_append (im_addresses,
- im);
+ gdata_contacts_contact_add_im_address (GDATA_CONTACTS_CONTACT (entry), im);
+ g_object_unref (im);
}
+ } else if (e_vcard_attribute_is_single_valued (attr)) {
+ gchar *value;
+
+ /* Add the attribute as an extended property */
+ value = e_vcard_attribute_get_value (attr);
+ gdata_contacts_contact_set_extended_property (GDATA_CONTACTS_CONTACT (entry), name, value);
+ g_free (value);
} else {
GList *values;
}
}
}
- gdata_entry_set_title (entry, fullname);
- g_free (fullname);
- gdata_entry_set_email_addresses (entry, email_addresses);
- gdata_entry_set_im_addresses (entry, im_addresses);
- gdata_entry_set_phone_numbers (entry, phone_numbers);
- gdata_entry_set_postal_addresses (entry, postal_addresses);
return TRUE;
}
+static void
+foreach_extended_props_cb (const gchar *name, const gchar *value, EVCard *vcard)
+{
+ EVCardAttribute *attr;
+
+ attr = e_vcard_attribute_new (NULL, name);
+ e_vcard_add_attribute_with_value (vcard, attr, value);
+}
+
EContact*
_e_contact_new_from_gdata_entry (GDataEntry *entry)
{
EVCard *vcard;
EVCardAttribute *attr;
- GSList *email_addresses, *im_addresses, *phone_numbers, *postal_addresses;
- const gchar *name;
+ GList *email_addresses, *im_addresses, *phone_numbers, *postal_addresses;
const gchar *uid;
- GSList *itr;
- GDataEntryEmailAddress *email;
- GDataEntryIMAddress *im;
- GDataEntryPhoneNumber *phone_number;
- GDataEntryPostalAddress *postal_address;
+ GList *itr;
+ GDataGDName *name;
+ GDataGDEmailAddress *email;
+ GDataGDIMAddress *im;
+ GDataGDPhoneNumber *phone_number;
+ GDataGDPostalAddress *postal_address;
+ GHashTable *extended_props;
uid = gdata_entry_get_id (entry);
if (NULL == uid) {
attr = e_vcard_attribute_new (NULL, EVC_UID);
e_vcard_add_attribute_with_value (vcard, attr, uid);
- /* FN - TODO: get title */
- name = gdata_entry_get_title (entry);
+ /* FN, N */
+ name = gdata_contacts_contact_get_name (GDATA_CONTACTS_CONTACT (entry));
if (name) {
- e_contact_set (E_CONTACT (vcard), E_CONTACT_FULL_NAME, (gconstpointer)name);
+ EContactName name_struct;
+
+ /* Set the full name */
+ e_contact_set (E_CONTACT (vcard), E_CONTACT_FULL_NAME, gdata_gd_name_get_full_name (name));
+
+ /* We just need to set the E_CONTACT_NAME field, and all the other name attribute values
+ * in the EContact will be populated automatically from that */
+ name_struct.family = (gchar*) gdata_gd_name_get_family_name (name);
+ name_struct.given = (gchar*) gdata_gd_name_get_given_name (name);
+ name_struct.additional = (gchar*) gdata_gd_name_get_additional_name (name);
+ name_struct.prefixes = (gchar*) gdata_gd_name_get_prefix (name);
+ name_struct.suffixes = (gchar*) gdata_gd_name_get_suffix (name);
+
+ e_contact_set (E_CONTACT (vcard), E_CONTACT_NAME, &name_struct);
}
/* EMAIL - primary first */
- email = gdata_entry_get_primary_email_address (entry);
- attr = attribute_from_gdata_entry_email_address (email);
- if (attr) {
- e_vcard_add_attribute (vcard, attr);
- }
+ email = gdata_contacts_contact_get_primary_email_address (GDATA_CONTACTS_CONTACT (entry));
+ add_attribute_from_gdata_gd_email_address (vcard, email);
- email_addresses = gdata_entry_get_email_addresses (entry);
+ email_addresses = gdata_contacts_contact_get_email_addresses (GDATA_CONTACTS_CONTACT (entry));
for (itr = email_addresses; itr; itr = itr->next) {
email = itr->data;
- if (TRUE == email->primary)
+ if (gdata_gd_email_address_is_primary (email) == TRUE)
continue;
- attr = attribute_from_gdata_entry_email_address (email);
- if (attr) {
- e_vcard_add_attribute (vcard, attr);
- }
+ add_attribute_from_gdata_gd_email_address (vcard, email);
}
/* X-IM - primary first */
- im = gdata_entry_get_primary_im_address (entry);
- attr = attribute_from_gdata_entry_im_address (im);
- if (attr) {
- e_vcard_add_attribute (vcard, attr);
- }
- im_addresses = gdata_entry_get_im_addresses (entry);
+ im = gdata_contacts_contact_get_primary_im_address (GDATA_CONTACTS_CONTACT (entry));
+ add_attribute_from_gdata_gd_im_address (vcard, im);
+
+ im_addresses = gdata_contacts_contact_get_im_addresses (GDATA_CONTACTS_CONTACT (entry));
for (itr = im_addresses; itr; itr = itr->next) {
im = itr->data;
- if (TRUE == im->primary)
+ if (gdata_gd_im_address_is_primary (im) == TRUE)
continue;
- attr = attribute_from_gdata_entry_im_address (im);
- if (attr) {
- e_vcard_add_attribute (vcard, attr);
- }
+ add_attribute_from_gdata_gd_im_address (vcard, im);
}
/* TEL - primary first */
- phone_number = gdata_entry_get_primary_phone_number (entry);
- attr = attribute_from_gdata_entry_phone_number (phone_number);
- if (attr) {
- e_vcard_add_attribute (vcard, attr);
- }
- phone_numbers = gdata_entry_get_phone_numbers (entry);
+ phone_number = gdata_contacts_contact_get_primary_phone_number (GDATA_CONTACTS_CONTACT (entry));
+ add_attribute_from_gdata_gd_phone_number (vcard, phone_number);
+
+ phone_numbers = gdata_contacts_contact_get_phone_numbers (GDATA_CONTACTS_CONTACT (entry));
for (itr = phone_numbers; itr; itr = itr->next) {
phone_number = itr->data;
- if (TRUE == phone_number->primary)
+ if (gdata_gd_phone_number_is_primary (phone_number) == TRUE)
continue;
- attr = attribute_from_gdata_entry_phone_number (phone_number);
- if (attr) {
- e_vcard_add_attribute (vcard, attr);
- }
+ add_attribute_from_gdata_gd_phone_number (vcard, phone_number);
}
- /* LABEL - primary first TODO: ADR */
- postal_address = gdata_entry_get_primary_postal_address (entry);
- attr = attribute_from_gdata_entry_postal_address (postal_address);
- if (attr) {
- e_vcard_add_attribute (vcard, attr);
- }
- postal_addresses = gdata_entry_get_postal_addresses (entry);
+ /* LABEL and ADR - primary first */
+ postal_address = gdata_contacts_contact_get_primary_postal_address (GDATA_CONTACTS_CONTACT (entry));
+ add_attribute_from_gdata_gd_postal_address (vcard, postal_address);
+
+ postal_addresses = gdata_contacts_contact_get_postal_addresses (GDATA_CONTACTS_CONTACT (entry));
for (itr = postal_addresses; itr; itr = itr->next) {
postal_address = itr->data;
- if (TRUE == postal_address->primary)
+ if (gdata_gd_postal_address_is_primary (postal_address) == TRUE)
continue;
- attr = attribute_from_gdata_entry_postal_address (postal_address);
- if (attr) {
- e_vcard_add_attribute (vcard, attr);
- }
+ add_attribute_from_gdata_gd_postal_address (vcard, postal_address);
}
+ /* 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);
+
return E_CONTACT (vcard);
}
-#define GDATA_ENTRY_XML_ATTR "X-GDATA-ENTRY-XML"
-
void
_e_contact_add_gdata_entry_xml (EContact *contact, GDataEntry *entry)
{
EVCardAttribute *attr;
- const gchar * entry_xml;
-
- entry_xml = gdata_entry_generate_xml (entry);
+ gchar *entry_xml;
+ GDataLink *link;
+ /* Cache the XML representing the entry */
+ entry_xml = gdata_parsable_get_xml (GDATA_PARSABLE (entry));
attr = e_vcard_attribute_new ("", GDATA_ENTRY_XML_ATTR);
e_vcard_attribute_add_value (attr, entry_xml);
e_vcard_add_attribute (E_VCARD (contact), attr);
+ g_free (entry_xml);
+
+ /* Also add the update URI for the entry, since that's not serialised by gdata_parsable_get_xml */
+ link = gdata_entry_look_up_link (entry, GDATA_LINK_EDIT);
+ if (link != NULL) {
+ attr = e_vcard_attribute_new ("", GDATA_ENTRY_LINK_ATTR);
+ e_vcard_attribute_add_value (attr, gdata_link_get_uri (link));
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+ }
}
void
_e_contact_remove_gdata_entry_xml (EContact *contact)
{
e_vcard_remove_attributes (E_VCARD (contact), NULL, GDATA_ENTRY_XML_ATTR);
+ e_vcard_remove_attributes (E_VCARD (contact), NULL, GDATA_ENTRY_LINK_ATTR);
}
const gchar *
-_e_contact_get_gdata_entry_xml (EContact *contact)
+_e_contact_get_gdata_entry_xml (EContact *contact, const gchar **edit_link)
{
EVCardAttribute *attr;
- GList *values;
+ GList *values = NULL;
+ /* Return the edit link if asked */
+ if (edit_link != NULL) {
+ attr = e_vcard_get_attribute (E_VCARD (contact), GDATA_ENTRY_LINK_ATTR);
+ if (attr != NULL)
+ values = e_vcard_attribute_get_values (attr);
+ if (values != NULL)
+ *edit_link = values->data;
+ }
+
+ /* Return the entry's XML */
attr = e_vcard_get_attribute (E_VCARD (contact), GDATA_ENTRY_XML_ATTR);
values = e_vcard_attribute_get_values (attr);
}
struct RelTypeMap {
- const gchar * rel;
- const gchar * types[3];
+ const gchar *rel;
+ const gchar *types[2];
};
+/* NOTE: These maps must be kept ordered with the one-to-many types first */
static const struct RelTypeMap rel_type_map_phone[] = {
- {"fax", { "FAX", NULL, NULL}},
- {"home", { "HOME", "VOICE", NULL}},
- {"home_fax", { "HOME", "FAX", NULL}},
- {"mobile", { "CELL", NULL, NULL}},
- {"other", { "VOICE", NULL, NULL}},
- {"pager", { "PAGER", NULL, NULL}},
- {"work", { "WORK", "VOICE", NULL}},
- {"work_fax", { "WORK", "FAX", NULL}}
+ {"home", { "HOME", "VOICE"}},
+ {"home_fax", { "HOME", "FAX"}},
+ {"work", { "WORK", "VOICE"}},
+ {"work_fax", { "WORK", "FAX"}},
+ {"work_mobile", { "WORK", "CELL"}},
+ {"work_pager", { "WORK", "PAGER"}},
+ {"assistant", { EVC_X_ASSISTANT, NULL}},
+ {"callback", { EVC_X_CALLBACK, NULL}},
+ {"car", { "CAR", NULL}},
+ {"company_main", {EVC_X_COMPANY, NULL}},
+ {"fax", { "FAX", NULL}},
+ {"isdn", { "ISDN", NULL}},
+ {"main", { "PREF", NULL}},
+ {"mobile", { "CELL", NULL}},
+ {"other", { "VOICE", NULL}},
+ {"other_fax", { "FAX", NULL}},
+ {"pager", { "PAGER", NULL}},
+ {"radio", { EVC_X_RADIO, NULL}},
+ {"telex", { EVC_X_TELEX, NULL}},
+ {"tty_tdd", { EVC_X_TTYTDD, NULL}}
+};
+
+static const struct RelTypeMap rel_type_map_im[] = {
+ {"home", { "HOME", NULL}},
+ {"netmeeting", { "NETMEETING", NULL}},
+ {"other", { "OTHER", NULL}},
+ {"work", { "WORK", NULL}},
};
static const struct RelTypeMap rel_type_map_others[] = {
- {"home", { "HOME", NULL, NULL}},
- {"other", { "OTHER", NULL, NULL}},
- {"work", { "WORK", NULL, NULL}},
+ {"home", { "HOME", NULL}},
+ {"other", { "OTHER", NULL}},
+ {"work", { "WORK", NULL}},
};
static gboolean
_add_type_param_from_google_rel (EVCardAttribute *attr,
const struct RelTypeMap rel_type_map[],
- gint map_len,
+ guint map_len,
const gchar *rel)
{
const gchar * field;
- gint i;
+ guint i;
field = strstr (rel ? rel : "", "#");
if (NULL == field)
for (i = 0; i < map_len; i++) {
if (0 == g_ascii_strcasecmp (rel_type_map[i].rel, field)) {
EVCardAttributeParam *param;
- const gchar * const * type;
param = e_vcard_attribute_param_new ("TYPE");
- for (type = rel_type_map[i].types; *type; type++) {
- e_vcard_attribute_param_add_value (param, *type);
- }
+ e_vcard_attribute_param_add_value (param, rel_type_map[i].types[0]);
+ if (rel_type_map[i].types[1])
+ e_vcard_attribute_param_add_value (param, rel_type_map[i].types[1]);
e_vcard_attribute_add_param (attr, param);
return TRUE;
}
}
static gboolean
+add_type_param_from_google_rel_im (EVCardAttribute *attr, const gchar *rel)
+{
+ return _add_type_param_from_google_rel (attr,
+ rel_type_map_im,
+ G_N_ELEMENTS (rel_type_map_im),
+ rel);
+}
+
+static gboolean
add_type_param_from_google_rel (EVCardAttribute *attr, const gchar *rel)
{
return _add_type_param_from_google_rel (attr,
static gchar *
_google_rel_from_types (GList *types,
const struct RelTypeMap rel_type_map[],
- gint map_len)
+ guint map_len)
{
const gchar format[] = "http://schemas.google.com/g/2005#%s";
+ guint i;
- while (types) {
- gint i;
- GList *cur = types;
- types = types->next;
-
- for (i = 0; i < map_len; i++) {
- if (0 == g_ascii_strcasecmp (rel_type_map[i].types[0], cur->data)) {
- while (types && rel_type_map[i].types[1]) {
- if (0 == g_ascii_strcasecmp (rel_type_map[i].types[1], types->data)) {
- return g_strdup_printf (format, rel_type_map[i].rel);
- }
- types = types->next;
- }
+ /* For each of the entries in the map... */
+ for (i = 0; i < map_len; i++) {
+ GList *cur;
+ gboolean first_matched = FALSE, second_matched = rel_type_map[i].types[1] ? FALSE : TRUE;
+
+ /* ...iterate through all the vCard's types and see if two of them match the types in the current map entry. */
+ for (cur = types; cur != NULL; cur = cur->next) {
+ if (0 == g_ascii_strcasecmp (rel_type_map[i].types[0], cur->data))
+ first_matched = TRUE;
+ else if (!rel_type_map[i].types[1] || 0 == g_ascii_strcasecmp (rel_type_map[i].types[1], cur->data))
+ second_matched = TRUE;
+
+ /* If they do, return the rel value from that entry... */
+ if (first_matched && second_matched)
return g_strdup_printf (format, rel_type_map[i].rel);
- }
}
}
+ /* ...otherwise return an "other" result. */
return g_strdup_printf (format, "other");
}
"AIM", "MSN", "YAHOO", "SKYPE", "QQ",
"GOOGLE_TALK", "ICQ", "JABBER"
};
- gint i;
+ guint i;
if (NULL == protocol)
return FALSE;
}
static gchar *
-field_name_from_google_im_protocol (const gchar * google_protocol)
+field_name_from_google_im_protocol (const gchar *google_protocol)
{
gchar *protocol;
if (NULL == google_protocol)
}
static gchar *
-google_im_protocol_from_field_name (const gchar * field_name)
+google_im_protocol_from_field_name (const gchar *field_name)
{
const gchar format[] = "http://schemas.google.com/g/2005#%s";
return types;
}
-static EVCardAttribute*
-attribute_from_gdata_entry_email_address (GDataEntryEmailAddress *email)
+static void
+add_attribute_from_gdata_gd_email_address (EVCard *vcard, GDataGDEmailAddress *email)
{
EVCardAttribute *attr;
gboolean has_type;
- if (NULL == email || NULL == email->address)
- return NULL;;
+ if (NULL == email || NULL == gdata_gd_email_address_get_address (email))
+ return;
attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
- has_type = add_type_param_from_google_rel (attr, email->rel);
- if (email->primary) {
+ has_type = add_type_param_from_google_rel (attr, gdata_gd_email_address_get_relation_type (email));
+ if (gdata_gd_email_address_is_primary (email) == TRUE)
add_primary_param (attr, has_type);
- }
- add_label_param (attr, email->label);
- e_vcard_attribute_add_value (attr, email->address);
- return attr;
+ add_label_param (attr, gdata_gd_email_address_get_label (email));
+
+ e_vcard_attribute_add_value (attr, gdata_gd_email_address_get_address (email));
+
+ if (attr)
+ e_vcard_add_attribute (vcard, attr);
}
-static EVCardAttribute*
-attribute_from_gdata_entry_im_address (GDataEntryIMAddress *im)
+static void
+add_attribute_from_gdata_gd_im_address (EVCard *vcard, GDataGDIMAddress *im)
{
EVCardAttribute *attr;
gboolean has_type;
gchar *field_name;
- if (NULL == im || NULL == im->address)
- return NULL;;
+ if (NULL == im || NULL == gdata_gd_im_address_get_address (im))
+ return;
- field_name = field_name_from_google_im_protocol (im->protocol);
+ field_name = field_name_from_google_im_protocol (gdata_gd_im_address_get_protocol (im));
if (NULL == field_name)
- return NULL;
+ return;
attr = e_vcard_attribute_new (NULL, field_name);
- has_type = add_type_param_from_google_rel (attr, im->rel);
- if (im->primary) {
+ has_type = add_type_param_from_google_rel_im (attr, gdata_gd_im_address_get_relation_type (im));
+ if (gdata_gd_im_address_is_primary (im))
add_primary_param (attr, has_type);
- }
- add_label_param (attr, im->label);
- e_vcard_attribute_add_value (attr, im->address);
- return attr;
+ add_label_param (attr, gdata_gd_im_address_get_label (im));
+
+ e_vcard_attribute_add_value (attr, gdata_gd_im_address_get_address (im));
+
+ if (attr)
+ e_vcard_add_attribute (vcard, attr);
}
-static EVCardAttribute*
-attribute_from_gdata_entry_phone_number (GDataEntryPhoneNumber *number)
+static void
+add_attribute_from_gdata_gd_phone_number (EVCard *vcard, GDataGDPhoneNumber *number)
{
EVCardAttribute *attr;
gboolean has_type;
- if (NULL == number || NULL == number->number)
- return NULL;;
+ if (NULL == number || NULL == gdata_gd_phone_number_get_number (number))
+ return;
attr = e_vcard_attribute_new (NULL, EVC_TEL);
- has_type = add_type_param_from_google_rel_phone (attr, number->rel);
- if (number->primary) {
+ has_type = add_type_param_from_google_rel_phone (attr, gdata_gd_phone_number_get_relation_type (number));
+ if (gdata_gd_phone_number_is_primary (number))
add_primary_param (attr, has_type);
- }
- add_label_param (attr, number->label);
- e_vcard_attribute_add_value (attr, number->number);
- return attr;
+ add_label_param (attr, gdata_gd_phone_number_get_label (number));
+
+ e_vcard_attribute_add_value (attr, gdata_gd_phone_number_get_number (number));
+
+ if (attr)
+ e_vcard_add_attribute (vcard, attr);
}
-static EVCardAttribute*
-attribute_from_gdata_entry_postal_address (GDataEntryPostalAddress *address)
+static void
+add_attribute_from_gdata_gd_postal_address (EVCard *vcard, GDataGDPostalAddress *address)
{
EVCardAttribute *attr;
gboolean has_type;
- if (NULL == address || NULL == address->address)
- return NULL;;
+ if (NULL == address || NULL == gdata_gd_postal_address_get_address (address))
+ return;
+ /* Add the LABEL */
attr = e_vcard_attribute_new (NULL, EVC_LABEL);
- has_type = add_type_param_from_google_rel (attr, address->rel);
- if (address->primary) {
+ has_type = add_type_param_from_google_rel (attr, gdata_gd_postal_address_get_relation_type (address));
+ if (gdata_gd_postal_address_is_primary (address))
add_primary_param (attr, has_type);
- }
- add_label_param (attr, address->label);
- e_vcard_attribute_add_value (attr, address->address);
- return attr;
+ add_label_param (attr, gdata_gd_postal_address_get_label (address));
+
+ e_vcard_attribute_add_value (attr, gdata_gd_postal_address_get_address (address));
+
+ if (attr)
+ e_vcard_add_attribute (vcard, attr);
+
+ /* Add the ADR */
+ attr = e_vcard_attribute_new (NULL, EVC_ADR);
+ has_type = add_type_param_from_google_rel (attr, gdata_gd_postal_address_get_relation_type (address));
+ if (gdata_gd_postal_address_is_primary (address))
+ add_primary_param (attr, has_type);
+ add_label_param (attr, gdata_gd_postal_address_get_label (address));
+
+ e_vcard_attribute_add_value (attr, gdata_gd_postal_address_get_po_box (address));
+ e_vcard_attribute_add_value (attr, gdata_gd_postal_address_get_house_name (address));
+ e_vcard_attribute_add_value (attr, gdata_gd_postal_address_get_street (address));
+ e_vcard_attribute_add_value (attr, gdata_gd_postal_address_get_city (address));
+ e_vcard_attribute_add_value (attr, gdata_gd_postal_address_get_region (address));
+ e_vcard_attribute_add_value (attr, gdata_gd_postal_address_get_postcode (address));
+ e_vcard_attribute_add_value (attr, gdata_gd_postal_address_get_country (address));
+
+ /* The following bits of data provided by the Google Contacts API can't be fitted into the vCard format:
+ * gdata_gd_postal_address_get_mail_class
+ * gdata_gd_postal_address_get_usage
+ * gdata_gd_postal_address_get_agent
+ * gdata_gd_postal_address_get_neighborhood
+ * gdata_gd_postal_address_get_subregion
+ * gdata_gd_postal_address_get_country_code */
+
+ if (attr)
+ e_vcard_add_attribute (vcard, attr);
}
-static GDataEntryEmailAddress*
-gdata_entry_email_address_from_attribute (EVCardAttribute *attr, gboolean *have_primary)
+static GDataGDEmailAddress*
+gdata_gd_email_address_from_attribute (EVCardAttribute *attr, gboolean *have_primary)
{
- GDataEntryEmailAddress *email = NULL;
+ GDataGDEmailAddress *email = NULL;
GList *values;
values = e_vcard_attribute_get_values (attr);
if (values) {
GList *types;
+ gchar *rel;
const gchar *label;
gboolean primary;
primary = FALSE;
}
- email = g_new0 (GDataEntryEmailAddress, 1);
- email->address = g_strdup (values->data);
- email->rel = google_rel_from_types (types);
- email->label = g_strdup (label);
- email->primary = primary;
+ rel = google_rel_from_types (types);
+ email = gdata_gd_email_address_new (values->data, rel, label, primary);
+ g_free (rel);
+
__debug__ ("New %semail entry %s (%s/%s)",
- email->primary ? "primary " : "",
- email->address,
- email->rel,
- email->label);
+ gdata_gd_email_address_is_primary (email) ? "primary " : "",
+ gdata_gd_email_address_get_address (email),
+ gdata_gd_email_address_get_relation_type (email),
+ gdata_gd_email_address_get_label (email));
}
return email;
}
-static GDataEntryIMAddress*
-gdata_entry_im_address_from_attribute (EVCardAttribute *attr, gboolean *have_primary)
+static GDataGDIMAddress*
+gdata_gd_im_address_from_attribute (EVCardAttribute *attr, gboolean *have_primary)
{
- GDataEntryIMAddress *im = NULL;
+ GDataGDIMAddress *im = NULL;
GList *values;
const gchar *name;
values = e_vcard_attribute_get_values (attr);
if (values) {
GList *types;
+ gchar *protocol, *rel;
const gchar *label;
gboolean primary;
primary = FALSE;
}
- im = g_new0 (GDataEntryIMAddress, 1);
- im->address = g_strdup (values->data);
- im->rel = google_rel_from_types (types);
- im->label = g_strdup (label);
- im->primary = primary;
- im->protocol = google_im_protocol_from_field_name (name);
+ rel = google_rel_from_types (types);
+ protocol = google_im_protocol_from_field_name (name);
+ im = gdata_gd_im_address_new (values->data, protocol, rel, label, primary);
+ g_free (rel);
+ g_free (protocol);
+
__debug__ ("New %s%s entry %s (%s/%s)",
- im->primary ? "primary " : "",
- im->protocol,
- im->address,
- im->rel,
- im->label);
+ gdata_gd_im_address_is_primary (im) ? "primary " : "",
+ gdata_gd_im_address_get_protocol (im),
+ gdata_gd_im_address_get_address (im),
+ gdata_gd_im_address_get_relation_type (im),
+ gdata_gd_im_address_get_label (im));
}
return im;
}
-static GDataEntryPhoneNumber*
-gdata_entry_phone_number_from_attribute (EVCardAttribute *attr, gboolean *have_primary)
+static GDataGDPhoneNumber*
+gdata_gd_phone_number_from_attribute (EVCardAttribute *attr, gboolean *have_primary)
{
- GDataEntryPhoneNumber *number = NULL;
+ GDataGDPhoneNumber *number = NULL;
GList *values;
values = e_vcard_attribute_get_values (attr);
if (values) {
GList *types;
gboolean primary;
+ gchar *rel;
const gchar *label;
types = get_google_primary_type_label (attr, &primary, &label);
primary = FALSE;
}
- number = g_new0 (GDataEntryPhoneNumber, 1);
- number->number = g_strdup (values->data);
- number->rel = google_rel_from_types_phone (types);
- number->label = g_strdup (label);
- number->primary = primary;
+ rel = google_rel_from_types_phone (types);
+ number = gdata_gd_phone_number_new (values->data, rel, label, NULL, primary);
+ g_free (rel);
+
__debug__ ("New %sphone-number entry %s (%s/%s)",
- number->primary ? "primary " : "",
- number->number,
- number->rel,
- number->label);
+ gdata_gd_phone_number_is_primary (number) ? "primary " : "",
+ gdata_gd_phone_number_get_number (number),
+ gdata_gd_phone_number_get_relation_type (number),
+ gdata_gd_phone_number_get_label (number));
}
return number;
}
-static GDataEntryPostalAddress*
-gdata_entry_postal_address_from_attribute (EVCardAttribute *attr, gboolean *have_primary)
+static GDataGDPostalAddress*
+gdata_gd_postal_address_from_attribute (EVCardAttribute *attr, gboolean *have_primary)
{
- GDataEntryPostalAddress *address = NULL;
+ GDataGDPostalAddress *address = NULL;
GList *values;
values = e_vcard_attribute_get_values (attr);
if (values) {
- GList *types;
+ GList *types, *value;
+ gchar *rel;
const gchar *label;
gboolean primary;
primary = FALSE;
}
- address = g_new0 (GDataEntryPostalAddress, 1);
- address->address = g_strdup (values->data);
- address->rel = google_rel_from_types (types);
- address->label = g_strdup (label);
- address->primary = primary;
+ rel = google_rel_from_types (types);
+ address = gdata_gd_postal_address_new (rel, label, primary);
+ g_free (rel);
+
__debug__ ("New %spostal address entry %s (%s/%s)",
- address->primary ? "primary " : "",
- address->address,
- address->rel,
- address->label);
+ gdata_gd_postal_address_is_primary (address) ? "primary " : "",
+ gdata_gd_postal_address_get_address (address),
+ gdata_gd_postal_address_get_relation_type (address),
+ gdata_gd_postal_address_get_label (address));
+
+ /* Set the components of the address from the vCard's attribute values */
+ value = values;
+ if (!value)
+ return address;
+ gdata_gd_postal_address_set_po_box (address, (*((gchar*) value->data) != '\0') ? value->data : NULL);
+ value = value->next;
+ if (!value)
+ return address;
+ gdata_gd_postal_address_set_house_name (address, (*((gchar*) value->data) != '\0') ? value->data : NULL);
+ value = value->next;
+ if (!value)
+ return address;
+ gdata_gd_postal_address_set_street (address, (*((gchar*) value->data) != '\0') ? value->data : NULL);
+ value = value->next;
+ if (!value)
+ return address;
+ gdata_gd_postal_address_set_city (address, (*((gchar*) value->data) != '\0') ? value->data : NULL);
+ value = value->next;
+ if (!value)
+ return address;
+ gdata_gd_postal_address_set_region (address, (*((gchar*) value->data) != '\0') ? value->data : NULL);
+ value = value->next;
+ if (!value)
+ return address;
+ gdata_gd_postal_address_set_postcode (address, (*((gchar*) value->data) != '\0') ? value->data : NULL);
+ value = value->next;
+ if (!value)
+ return address;
+ gdata_gd_postal_address_set_country (address, (*((gchar*) value->data) != '\0') ? value->data : NULL, NULL);
}
return address;
/* util.h - Google contact backend utility functions.
*
* Copyright (C) 2008 Joergen Scheibengruber
+ * Copyright (C) 2010 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
#include <libebook/e-vcard.h>
#include <libebook/e-contact.h>
-#include <servers/google/libgdata/gdata-entry.h>
+#include <gdata/gdata-entry.h>
extern gboolean __e_book_backend_google_debug__;
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 *_e_contact_get_gdata_entry_xml (EContact *contact,
+ const gchar **edit_link);
#endif
-I$(top_builddir) \
-I$(top_srcdir)/calendar \
-I$(top_builddir)/calendar \
- -I$(top_srcdir)/servers/google/libgdata \
- -I$(top_builddir)/servers/google/libgdata \
- -I$(top_srcdir)/servers/google/libgdata-google \
- -I$(top_builddir)/servers/google/libgdata-google\
$(EVOLUTION_CALENDAR_CFLAGS) \
$(SOUP_CFLAGS) \
- $(DEBUG_CFLAGS)
+ $(DEBUG_CFLAGS) \
+ $(GDATA_CFLAGS)
libecalbackendgoogle_la_SOURCES = \
e-cal-backend-google-factory.c \
$(top_builddir)/calendar/libedata-cal/libedata-cal-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
$(top_builddir)/libebackend/libebackend-1.2.la \
- $(top_builddir)/servers/google/libgdata/libgdata-1.2.la \
- $(top_builddir)/servers/google/libgdata-google/libgdata-google-1.2.la \
$(EVOLUTION_CALENDAR_LIBS) \
- $(SOUP_LIBS)
+ $(SOUP_LIBS) \
+ $(GDATA_LIBS)
libecalbackendgoogle_la_LDFLAGS = \
-module -avoid-version $(NO_UNDEFINED)
/*
* Authors :
* Ebby Wiselyn <ebbyw@gnome.org>
+ * Philip Withnall <philip@tecnocode.co.uk>
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
#include "e-cal-backend-google.h"
#include "e-cal-backend-google-utils.h"
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#define GDATA_SCHEMA "http://schemas.google.com/g/2005#"
#define CACHE_REFRESH_INTERVAL 10000
/****************************************************** Google Connection Helper Functions ***********************************************/
-static gboolean gd_date_to_ical (EGoItem *item, const gchar *google_time_string, struct icaltimetype *itt, ECalComponentDateTime *dt, icaltimezone *default_zone);
-static gchar * get_date (ECalComponentDateTime dt);
+static gboolean gd_timeval_to_ical (GTimeVal *timeval, struct icaltimetype *itt, ECalComponentDateTime *dt, icaltimezone *default_zone);
+static void get_timeval (ECalComponentDateTime dt, GTimeVal *timeval);
static gint utils_compare_ids (gconstpointer cache_id, gconstpointer modified_cache_id);
static gchar * utils_form_query (const gchar *query);
static gboolean get_deltas_timeout (gpointer cbgo);
-static void utils_update_insertion (ECalBackendGoogle *cbgo, ECalBackendCache *cache, EGoItem *item, GSList *cache_keys);
+static void utils_update_insertion (ECalBackendGoogle *cbgo, ECalBackendCache *cache, GDataFeed *feed, GSList *cache_keys);
static void utils_update_deletion (ECalBackendGoogle *cbgo, ECalBackendCache *cache, GSList *cache_keys);
/**
*
* e_cal_backend_google_utils_populate_cache:
* @cbgo ECalBackendGoogle Object
- * Populates the cache with intial values
+ * Populates the cache with initial values
*
**/
static void
{
ECalComponent *comp=NULL;
ECalBackendCache *cache;
- EGoItem *item;
+ GDataFeed *feed;
ECalBackendGooglePrivate *priv;
icalcomponent_kind kind;
- GSList *entries = NULL, *list = NULL;
+ GList *entries = NULL, *list = NULL;
cache = e_cal_backend_google_get_cache (cbgo);
kind = e_cal_backend_get_kind (E_CAL_BACKEND(cbgo));
- item = e_cal_backend_google_get_item (cbgo);
- entries = gdata_feed_get_entries (item->feed);
+ feed = e_cal_backend_google_get_feed (cbgo);
+ entries = gdata_feed_get_entries (feed);
priv = cbgo->priv;
for (list = entries; list != NULL; list = list->next) {
- item->entry = (GDataEntry *)list->data;
- comp = e_go_item_to_cal_component (item, cbgo);
+ comp = e_gdata_event_to_cal_component (GDATA_CALENDAR_EVENT (list->data), cbgo);
if (comp && E_IS_CAL_COMPONENT(comp)) {
gchar *comp_str;
e_cal_component_commit_sequence (comp);
* e_cal_backend_google_utils_update:
*
* @handle:
- * Call this to Update changes, made to the calendar.
+ * Call this to update changes made to the calendar.
*
- * Returns: TRUE if update is successful FALSE otherwise .
+ * Returns: %TRUE if update is successful, %FALSE otherwise
**/
gpointer
e_cal_backend_google_utils_update (gpointer handle)
static gint max_results = -1;
ECalBackendGoogle *cbgo;
ECalBackendGooglePrivate *priv;
- EGoItem *item;
+ GDataFeed *feed;
+ GError *error = NULL;
+
ECalBackendCache *cache;
- GDataGoogleService *service;
+
+ GDataService *service;
static GStaticMutex updating = G_STATIC_MUTEX_INIT;
icalcomponent_kind kind;
- GSList *ids_list = NULL, *cache_keys = NULL, *entries_list = NULL;
- GSList *uid_list = NULL, *iter_list = NULL, *remove = NULL;
+
+ GList *entries_list = NULL, *iter_list = NULL, *ids_list = NULL;
+ GSList *uid_list = NULL, *cache_keys = NULL;
gboolean needs_to_insert = FALSE;
gchar *uri, *full_uri;
priv = cbgo->priv;
cache = e_cal_backend_google_get_cache (cbgo);
- item = e_cal_backend_google_get_item (cbgo);
- service = e_cal_backend_google_get_service (cbgo);
+ service = GDATA_SERVICE (e_cal_backend_google_get_service (cbgo));
uri = e_cal_backend_google_get_uri (cbgo);
if (max_results <= 0) {
}
full_uri = g_strdup_printf ("%s?max-results=%d", uri, max_results);
- item->feed = gdata_service_get_feed (GDATA_SERVICE(service), full_uri, NULL);
+ feed = gdata_service_query (GDATA_SERVICE(service), full_uri, NULL, GDATA_TYPE_CALENDAR_EVENT, NULL, NULL, NULL, &error);
g_free (full_uri);
- entries_list = gdata_feed_get_entries (item->feed);
+ if (feed == NULL) {
+ g_warning ("Error querying Google Calendar %s: %s", uri, error->message);
+ g_error_free (error);
+ g_static_mutex_unlock (&updating);
+ return NULL;
+ }
+
+ e_cal_backend_google_set_feed (cbgo, feed);
+ g_object_unref (feed);
+ entries_list = gdata_feed_get_entries (feed);
cache_keys = e_cal_backend_cache_get_keys (cache);
kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbgo));
for (iter_list = entries_list; iter_list != NULL; iter_list = iter_list->next) {
- gchar *id;
- id = gdata_entry_get_id ((GDataEntry *)iter_list->data);
- ids_list = g_slist_prepend (ids_list, id);
+ const gchar *id;
+ id = gdata_entry_get_id (GDATA_ENTRY (iter_list->data));
+ ids_list = g_list_prepend (ids_list, (gchar*) id);
}
/* Find the Removed Item */
iter_list = NULL;
for (iter_list = ids_list; iter_list != NULL; iter_list = iter_list->next) {
- GCompareFunc func = NULL;
- GSList *remove = NULL;
-
- func = (GCompareFunc)utils_compare_ids;
+ GSList *remove_list = g_slist_find_custom (cache_keys, iter_list->data, (GCompareFunc) utils_compare_ids);
- if (!(remove = g_slist_find_custom (cache_keys, iter_list->data, func))) {
+ if (!remove_list) {
uid_list = g_slist_prepend (uid_list, g_strdup ((gchar *)iter_list->data));
needs_to_insert = TRUE;
- }else {
- cache_keys = g_slist_remove_link (cache_keys, remove);
+ } else {
+ cache_keys = g_slist_remove_link (cache_keys, remove_list);
+ g_slist_free (remove_list);
}
-
- if (remove)
- g_slist_free (remove);
}
/* Update the deleted entries */
/* Update the inserted entries */
if (needs_to_insert) {
- utils_update_insertion (cbgo, cache, item,uid_list);
+ utils_update_insertion (cbgo, cache, feed, uid_list);
needs_to_insert = FALSE;
}
- if (ids_list) {
- ids_list = NULL;
- g_slist_free (ids_list);
- }
-
- if (uid_list) {
- /*FIXME could crash while freeing*/
- uid_list = NULL;
- g_slist_free (uid_list);
- }
-
- if (entries_list) {
- /* FIXME could crash while freeing */
- entries_list = NULL;
- g_slist_free (entries_list);
- }
-
- if (remove) {
- remove = NULL;
- g_slist_free (remove);
- }
+ g_list_free (ids_list);
+ g_slist_free (uid_list);
g_static_mutex_unlock (&updating);
+
return NULL;
}
e_cal_backend_google_utils_connect (ECalBackendGoogle *cbgo)
{
ECalBackendCache *cache;
- EGoItem *item;
ESource *source;
GDataFeed *feed;
- GDataGoogleService *service;
+ GDataCalendarService *service;
ECalSourceType source_type;
icalcomponent_kind kind;
icaltimezone *default_zone;
- GSList *entries;
GError *error = NULL;
GThread *thread;
gchar *username, *password;
source = e_cal_backend_get_source (E_CAL_BACKEND(cbgo));
- service = gdata_google_service_new ("cl", "evolution-client-0.0.1");
+ service = gdata_calendar_service_new ("evolution-client-0.0.1");
e_cal_backend_google_set_service (cbgo, service);
+ /* Get the query URI */
+ /* TODO: Would be better as a GDataCalendarQuery */
suri = e_source_get_uri (source);
uri = utils_form_query (suri);
e_cal_backend_google_set_uri (cbgo, uri);
-
g_free (suri);
+ /* Authenticate with the service */
username = e_cal_backend_google_get_username (cbgo);
password = e_cal_backend_google_get_password (cbgo);
- gdata_service_set_credentials (GDATA_SERVICE(service), username, password);
- feed = gdata_service_get_feed (GDATA_SERVICE(service), uri, NULL);
-
- if (!feed) {
+ if (!gdata_service_authenticate (GDATA_SERVICE(service), username, password, NULL, NULL)) {
g_critical ("%s, Authentication Failed \n ", G_STRLOC);
if (username || password)
return GNOME_Evolution_Calendar_AuthenticationFailed;
return GNOME_Evolution_Calendar_AuthenticationRequired;
}
- entries = gdata_feed_get_entries (feed);
-
- item = g_new0 (EGoItem, 1);
- item->entry = e_cal_backend_google_get_entry (cbgo);
- item->feed = feed;
+ /* Query for calendar events */
+ feed = gdata_service_query (GDATA_SERVICE(service), uri, NULL, GDATA_TYPE_CALENDAR_EVENT, NULL, NULL, NULL, NULL);
cache = e_cal_backend_google_get_cache (cbgo);
service = e_cal_backend_google_get_service (cbgo);
- e_cal_backend_google_set_item (cbgo, item);
+ e_cal_backend_google_set_feed (cbgo, feed);
+ g_object_unref (feed);
/* For event sync */
if (cache && service) {
}
/* Creating cache when in remote */
- if (GDATA_IS_GOOGLE_SERVICE (service)) {
+ if (GDATA_IS_CALENDAR_SERVICE (service)) {
cache = e_cal_backend_cache_new (e_cal_backend_get_uri (E_CAL_BACKEND (cbgo)),source_type);
e_cal_backend_google_set_cache (cbgo, cache);
}
}
-/*************************************************** EGoItem Functions*********************************************/
+/*************************************************** GDataCalendarEvent Functions*********************************************/
/**
- * e_go_item_to_cal_component:
- * @item a EGoItem object
- * @cbgo a ECalBackendGoogle object
+ * e_gdata_event_to_cal_component:
+ * @event: a #GDataCalendarEvent
+ * @cbgo: an #ECalBackendGoogle
*
- * Creates a EGoItem from ECalComponent
+ * Creates an #ECalComponent from a #GDataCalendarEvent
**/
ECalComponent *
-e_go_item_to_cal_component (EGoItem *item, ECalBackendGoogle *cbgo)
+e_gdata_event_to_cal_component (GDataCalendarEvent *event, ECalBackendGoogle *cbgo)
{
ECalComponent *comp;
ECalComponentText text;
- ECalComponentDateTime dt;
+ ECalComponentDateTime dt, dt_start;
ECalComponentOrganizer *org = NULL;
icaltimezone *default_zone;
- const gchar *description, *uid, *temp;
+ const gchar *description, *temp, *location = NULL;
+ GTimeVal timeval, timeval2;
struct icaltimetype itt;
- GSList *category_ids;
- GSList *go_attendee_list = NULL, *l = NULL, *attendee_list = NULL;
+ GList *category_ids;
+ GList *go_attendee_list = NULL, *go_location_list = NULL, *l = NULL;
+ GSList *attendee_list = NULL;
comp = e_cal_component_new ();
default_zone = e_cal_backend_google_get_default_zone (cbgo);
e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
/* Description*/
- description = gdata_entry_get_content (item->entry);
+ description = gdata_entry_get_content (GDATA_ENTRY (event));
if (description) {
- GSList l;
+ GSList li;
text.value = description;
text.altrep = NULL;
- l.data = &text;
- l.next = NULL;
- e_cal_component_set_description_list (comp, &l);
-
+ li.data = &text;
+ li.next = NULL;
+ e_cal_component_set_description_list (comp, &li);
}
/* Creation/Last update */
- if (gd_date_to_ical (item, gdata_entry_get_custom (item->entry, "published"), &itt, &dt, default_zone))
+ gdata_entry_get_published (GDATA_ENTRY (event), &timeval);
+ if (gd_timeval_to_ical (&timeval, &itt, &dt, default_zone))
e_cal_component_set_created (comp, &itt);
- if (gd_date_to_ical (item, gdata_entry_get_custom (item->entry, "updated"), &itt, &dt, default_zone))
+ gdata_entry_get_updated (GDATA_ENTRY (event), &timeval);
+ if (gd_timeval_to_ical (&timeval, &itt, &dt, default_zone))
e_cal_component_set_dtstamp (comp, &itt);
- /* Start time */
- if (gd_date_to_ical (item, gdata_entry_get_start_time (item->entry), &itt, &dt, default_zone))
- e_cal_component_set_dtstart (comp, &dt);
-
- /* End time */
- if (gd_date_to_ical (item, gdata_entry_get_end_time (item->entry), &itt, &dt, default_zone))
+ /* Start/End times */
+ /* TODO: deal with multiple time periods */
+ gdata_calendar_event_get_primary_time (event, &timeval, &timeval2, NULL);
+ if (gd_timeval_to_ical (&timeval, &itt, &dt_start, default_zone))
+ e_cal_component_set_dtstart (comp, &dt_start);
+ if (gd_timeval_to_ical (&timeval2, &itt, &dt, default_zone))
e_cal_component_set_dtend (comp, &dt);
- /* Summary of the Entry */
- text.value = gdata_entry_get_title (item->entry);
+ /* Summary of the event */
+ text.value = gdata_entry_get_title (GDATA_ENTRY (event));
text.altrep = NULL;
if (text.value != NULL)
e_cal_component_set_summary (comp, &text);
/* Categories or Kinds */
category_ids = NULL;
- category_ids = gdata_entry_get_categories (item->entry);
+ category_ids = gdata_entry_get_categories (GDATA_ENTRY (event));
/* Classification or Visibility */
temp = NULL;
- temp = gdata_entry_get_visibility (item->entry);
+ temp = gdata_calendar_event_get_visibility (event);
- if (temp)
+ if (strcmp (temp, "public") == 0)
e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PUBLIC);
else
e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_NONE);
temp = NULL;
/* Transparency */
- temp = gdata_entry_get_transparency (item->entry);
- e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT);
+ temp = gdata_calendar_event_get_transparency (event);
+ if (strcmp (temp, "http://schemas.google.com/g/2005#event.opaque") == 0)
+ e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_OPAQUE);
+ else if (strcmp (temp, "http://schemas.google.com/g/2005#event.transparent") == 0)
+ e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT);
+ else
+ e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_UNKNOWN);
/* Attendees */
- go_attendee_list = gdata_entry_get_attendee_list (item->entry);
+ go_attendee_list = gdata_calendar_event_get_people (event);
- if (go_attendee_list != NULL) {
+ for (l = go_attendee_list; l != NULL; l = l->next) {
+ GDataGDWho *go_attendee;
+ ECalComponentAttendee *attendee;
- for (l = go_attendee_list; l != NULL; l = l->next) {
- Attendee *go_attendee;
- ECalComponentAttendee *attendee;
+ go_attendee = (GDataGDWho *)l->data;
- go_attendee = (Attendee *)l->data;
-
- attendee = g_new0 (ECalComponentAttendee, 1);
+ attendee = g_new0 (ECalComponentAttendee, 1);
#if 0
- _print_attendee ((Attendee *)l->data);
+ _print_attendee ((Attendee *)l->data);
#endif
- attendee->value = g_strconcat ("MAILTO:", go_attendee->attendee_email, NULL);
- attendee->cn = g_strdup (go_attendee->attendee_value);
- attendee->role = ICAL_ROLE_OPTPARTICIPANT;
- attendee->status = ICAL_PARTSTAT_NEEDSACTION;
- attendee->cutype = ICAL_CUTYPE_INDIVIDUAL;
-
- /* Check for Organizer */
- if (go_attendee->attendee_rel) {
- gchar *val;
- val = strstr ((const gchar *)go_attendee->attendee_rel, (const gchar *)"organizer");
- if (val != NULL && !strcmp ("organizer", val)) {
- org = g_new0 (ECalComponentOrganizer, 1);
-
- if (go_attendee->attendee_email)
- org->value = g_strconcat("MAILTO:", go_attendee->attendee_email, NULL);
- if (go_attendee->attendee_value)
- org->cn = g_strdup (go_attendee->attendee_value);
- }
- }
-
- attendee_list = g_slist_prepend (attendee_list, attendee);
+ attendee->value = g_strconcat ("MAILTO:", gdata_gd_who_get_email_address (go_attendee), NULL);
+ attendee->cn = g_strdup (gdata_gd_who_get_value_string (go_attendee));
+ /* TODO: This could be made less static once the GData API's in place */
+ attendee->role = ICAL_ROLE_OPTPARTICIPANT;
+ attendee->status = ICAL_PARTSTAT_NEEDSACTION;
+ attendee->cutype = ICAL_CUTYPE_INDIVIDUAL;
+
+ /* Check for Organizer */
+ if (gdata_gd_who_get_relation_type (go_attendee)) {
+ gchar *val;
+ val = strstr (gdata_gd_who_get_relation_type (go_attendee), "organizer");
+ if (val != NULL && !strcmp ("organizer", val)) {
+ org = g_new0 (ECalComponentOrganizer, 1);
+
+ if (gdata_gd_who_get_email_address (go_attendee))
+ org->value = g_strconcat ("MAILTO:", gdata_gd_who_get_email_address (go_attendee), NULL);
+ if (gdata_gd_who_get_value_string (go_attendee))
+ org->cn = g_strdup (gdata_gd_who_get_value_string (go_attendee));
+ }
}
- e_cal_component_set_attendee_list (comp, attendee_list);
+
+ attendee_list = g_slist_prepend (attendee_list, attendee);
}
+ e_cal_component_set_attendee_list (comp, attendee_list);
/* Set the organizer if any */
if (org)
e_cal_component_set_organizer (comp, org);
/* Location */
- e_cal_component_set_location (comp, gdata_entry_get_location (item->entry));
+ go_location_list = gdata_calendar_event_get_places (event);
-#if 0
- /* temp hack to see how recurrence work */
- ECalComponentRange *recur_id;
- recur_id = g_new0 (ECalComponentRange, 1);
- recur_id->datetime = dt;
- recur_id->type = E_CAL_COMPONENT_RANGE_THISFUTURE;
- e_cal_component_set_recurid (comp, recur_id);
-#endif
- e_cal_component_set_dtend (comp, &dt);
+ for (l = go_location_list; l != NULL; l = l->next) {
+ GDataGDWhere *go_location;
+
+ go_location = (GDataGDWhere *)l->data;
+
+ if (gdata_gd_where_get_relation_type (go_location) == NULL ||
+ strcmp (gdata_gd_where_get_relation_type (go_location), "http://schemas.google.com/g/2005#event") == 0)
+ location = gdata_gd_where_get_value_string (go_location);
+ }
+ e_cal_component_set_location (comp, location);
+
+ /* Recurrence */
+ if (gdata_calendar_event_get_recurrence (event) != NULL) {
+ /* We have to parse something like this (http://code.google.com/apis/gdata/elements.html#gdRecurrence):
+ DTSTART;TZID=America/Los_Angeles:20060314T060000
+ DURATION:PT3600S
+ RRULE:FREQ=DAILY;UNTIL=20060321T220000Z
+ BEGIN:VTIMEZONE
+ ...
+ END:VTIMEZONE
+ * For the moment, we can ignore the vtimezone component. */
+
+ gboolean in_timezone = FALSE;
+ const gchar *recurrence = gdata_calendar_event_get_recurrence (event);
+ const gchar *i = recurrence;
+ GSList *rrule_list = NULL, *rdate_list = NULL, *exrule_list = NULL, *exdate_list = NULL;
+ guint recurrence_length = strlen (recurrence);
+
+ do {
+ icalproperty *prop;
+ const gchar *f = NULL;
+
+ if (i == NULL || *i == '\0' || i - recurrence >= recurrence_length)
+ break;
+
+ f = strchr (i, '\n');
+
+ /* Ignore the timezone component */
+ if (strncmp (i, "BEGIN:VTIMEZONE", 15) == 0) {
+ in_timezone = TRUE;
+ goto next_property;
+ } else if (strncmp (i, "END:VTIMEZONE", 13) == 0) {
+ in_timezone = FALSE;
+ goto next_property;
+ }
+
+ /* Skip any rules inside the timezone block */
+ if (in_timezone == TRUE)
+ goto next_property;
+
+ /* Parse the recurrence properties */
+ if (strncmp (i, "DTSTART", 7) == 0) {
+ struct icaltimetype recur;
+ gchar *recur_string;
+
+ /* Parse the dtstart property; this takes priority over that retrieved from gdata_calendar_event_get_primary_time */
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
+ g_free (recur_string);
+
+ if (icalproperty_isa (prop) != ICAL_DTSTART_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_dtstart (prop);
+ icalproperty_free (prop);
+ itt = icaltime_convert_to_zone (recur, default_zone);
+ dt.value = &itt;
+ dt.tzid = NULL;
+ e_cal_component_set_dtstart (comp, &dt);
+ } else if (strncmp (i, "DTEND", 5) == 0) {
+ struct icaltimetype recur;
+ gchar *recur_string;
+
+ /* Parse the dtend property; this takes priority over that retrieved from gdata_calendar_event_get_primary_time */
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
+ g_free (recur_string);
+
+ if (icalproperty_isa (prop) != ICAL_DTEND_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_dtstart (prop);
+ icalproperty_free (prop);
+ itt = icaltime_convert_to_zone (recur, default_zone);
+ dt.value = &itt;
+ dt.tzid = NULL;
+ e_cal_component_set_dtend (comp, &dt);
+ } else if (strncmp (i, "RRULE", 5) == 0) {
+ struct icalrecurrencetype recur, *recur2;
+ gchar *recur_string;
+
+ /* Parse the rrule property */
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
+ g_free (recur_string);
+
+ if (icalproperty_isa (prop) != ICAL_RRULE_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_rrule (prop);
+ icalproperty_free (prop);
+ recur2 = g_memdup (&recur, sizeof (recur));
+ rrule_list = g_slist_prepend (rrule_list, recur2);
+ } else if (strncmp (i, "RDATE", 5) == 0) {
+ struct icaldatetimeperiodtype recur;
+ ECalComponentPeriod *period;
+ icalvalue *value;
+ gchar *recur_string;
+
+ /* Parse the rdate property */
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
+ g_free (recur_string);
+
+ if (icalproperty_isa (prop) != ICAL_RDATE_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_rdate (prop);
+ value = icalproperty_get_value (prop);
+
+ period = g_new0 (ECalComponentPeriod, 1);
+ period->start = recur.period.start;
+ if (icalvalue_isa (value) == ICAL_VALUE_DATE || icalvalue_isa (value) == ICAL_VALUE_DATETIME) {
+ period->type = E_CAL_COMPONENT_PERIOD_DATETIME;
+ period->u.end = recur.period.end;
+ } else if (icalvalue_isa (value) == ICAL_VALUE_DURATION) {
+ period->type = E_CAL_COMPONENT_PERIOD_DURATION;
+ period->u.duration = recur.period.duration;
+ } else {
+ g_assert_not_reached ();
+ }
+ icalproperty_free (prop);
+
+ rdate_list = g_slist_prepend (rdate_list, period);
+ } else if (strncmp (i, "EXRULE", 6) == 0) {
+ struct icalrecurrencetype recur, *recur2;
+ gchar *recur_string;
+
+ /* Parse the exrule property */
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
+ g_free (recur_string);
+
+ if (icalproperty_isa (prop) != ICAL_EXRULE_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_rrule (prop);
+ icalproperty_free (prop);
+ recur2 = g_memdup (&recur, sizeof (recur));
+ exrule_list = g_slist_prepend (exrule_list, recur2);
+ } else if (strncmp (i, "EXDATE", 6) == 0) {
+ struct icaltimetype recur;
+ ECalComponentDateTime *date_time;
+ gchar *recur_string;
+
+ /* Parse the exdate property */
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
+ recur = icaltime_from_string (recur_string);
+ g_free (recur_string);
+
+ if (icalproperty_isa (prop) != ICAL_EXDATE_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_exdate (prop);
+ icalproperty_free (prop);
+ itt = icaltime_convert_to_zone (recur, default_zone);
+ date_time = g_new0 (ECalComponentDateTime, 1);
+ date_time->value = g_memdup (&itt, sizeof (itt));
+ exdate_list = g_slist_prepend (exdate_list, date_time);
+ }
+
+next_property:
+ /* Advance to the next line, and hence the next property */
+ i = f + 1;
+ } while (TRUE);
+
+ rrule_list = g_slist_reverse (rrule_list);
+ e_cal_component_set_rrule_list (comp, rrule_list);
+ g_slist_foreach (rrule_list, (GFunc) g_free, NULL);
+ g_slist_free (rrule_list);
+
+ rdate_list = g_slist_reverse (rdate_list);
+ e_cal_component_set_rdate_list (comp, rdate_list);
+ g_slist_foreach (rdate_list, (GFunc) g_free, NULL);
+ g_slist_free (rdate_list);
+
+ exrule_list = g_slist_reverse (exrule_list);
+ e_cal_component_set_exrule_list (comp, exrule_list);
+ g_slist_foreach (exrule_list, (GFunc) g_free, NULL);
+ g_slist_free (exrule_list);
+
+ exdate_list = g_slist_reverse (exdate_list);
+ e_cal_component_set_exdate_list (comp, exdate_list);
+ g_slist_foreach (exdate_list, (GFunc) e_cal_component_free_datetime, NULL);
+ g_slist_foreach (exdate_list, (GFunc) g_free, NULL);
+ g_slist_free (exdate_list);
+ }
+
+ /* Recurrence exceptions */
+ if (gdata_calendar_event_is_exception (event)) {
+ ECalComponentRange *recur_id;
+ gchar *original_id = NULL;
+
+ /* Provide the ID of the original event */
+ gdata_calendar_event_get_original_event_details (event, &original_id, NULL);
+ e_cal_component_set_uid (comp, original_id);
+ g_free (original_id);
+
+ /* Set the recurrence id and X-GW-RECORDID */
+ recur_id = g_new0 (ECalComponentRange, 1);
+ recur_id->type = E_CAL_COMPONENT_RANGE_SINGLE;
+ recur_id->datetime = dt_start;
+ e_cal_component_set_recurid (comp, recur_id);
+ g_free (recur_id);
+ } else {
+ /* The event is not an exception to a recurring event */
+ const gchar *uid = gdata_entry_get_id (GDATA_ENTRY (event));
+ e_cal_component_set_uid (comp, uid);
+ }
- uid = gdata_entry_get_id (item->entry);
- e_cal_component_set_uid (comp, (const gchar *)uid);
e_cal_component_commit_sequence (comp);
return comp;
/**
*
- * e_go_item_from_cal_component:
+ * e_gdata_event_from_cal_component:
* @cbgo a ECalBackendGoogle
* @comp a ECalComponent object
- * Creates a ECalComponent from EGoItem
+ * Creates a #GDataCalendarEvent from an #ECalComponent
*
**/
-EGoItem *
-e_go_item_from_cal_component (ECalBackendGoogle *cbgo, ECalComponent *comp)
+GDataCalendarEvent *
+e_gdata_event_from_cal_component (ECalBackendGoogle *cbgo, ECalComponent *comp)
+{
+ const gchar *uid;
+ GDataCalendarEvent *event;
+
+ e_cal_component_get_uid (comp, &uid);
+ event = gdata_calendar_event_new (uid);
+
+ e_gdata_event_update_from_cal_component (cbgo, event, comp);
+
+ return event;
+}
+
+static gchar *
+comp_date_time_as_ical_string (ECalComponentDateTime *dt, icaltimezone *default_zone)
+{
+ icaltimetype itt;
+ icalproperty *prop;
+ char *buf;
+
+ itt = icaltime_convert_to_zone (*(dt->value), default_zone);
+ dt->value = &itt;
+ prop = icalproperty_new_dtend (*(dt->value));
+ buf = icalproperty_get_value_as_string_r (prop);
+ icalproperty_free (prop);
+
+ return buf;
+}
+
+void
+e_gdata_event_update_from_cal_component (ECalBackendGoogle *cbgo, GDataCalendarEvent *event, ECalComponent *comp)
{
ECalBackendGooglePrivate *priv;
- EGoItem *item;
ECalComponentText text;
ECalComponentDateTime dt;
- gchar *temp, *term = NULL;
+ const gchar *term = NULL;
icaltimezone *default_zone;
icaltimetype itt;
- const gchar *uid;
+ icalproperty *prop;
+ GTimeVal timeval, timeval2;
const gchar *location;
GSList *list = NULL;
- GDataEntry *entry;
+ GDataCategory *category;
+ GDataGDWhen *when;
ECalComponentText *t;
GSList *attendee_list = NULL, *l = NULL;
+ GString *recur_string;
+ char *buf;
priv = cbgo->priv;
- item = g_new0 (EGoItem, 1);
- entry = gdata_entry_new ();
-
/* Summary */
e_cal_component_get_summary (comp, &text);
- if (text.value!=NULL)
- gdata_entry_set_title (entry, text.value);
+ if (text.value != NULL)
+ gdata_entry_set_title (GDATA_ENTRY (event), text.value);
default_zone = e_cal_backend_google_get_default_zone (cbgo);
- /* Start time */
+ /* Start/End times */
e_cal_component_get_dtstart (comp, &dt);
itt = icaltime_convert_to_zone (*dt.value, default_zone);
dt.value = &itt;
- temp = get_date (dt);
- gdata_entry_set_start_time (entry, temp);
+ get_timeval (dt, &timeval);
- /* End Time */
e_cal_component_get_dtend (comp, &dt);
itt = icaltime_convert_to_zone (*dt.value, default_zone);
dt.value = &itt;
- temp = get_date (dt);
- gdata_entry_set_end_time (entry, temp);
+ get_timeval (dt, &timeval2);
+
+ /* TODO: deal with pure dates */
+ when = gdata_gd_when_new (&timeval, &timeval2, FALSE);
+ gdata_calendar_event_add_time (event, when);
/* Content / Description */
e_cal_component_get_description_list (comp, &list);
if (list != NULL) {
t = (ECalComponentText *)list->data;
- gdata_entry_set_content (entry, t->value);
- }
- else
- gdata_entry_set_content (entry, "");
-
- e_cal_component_get_uid (comp, &uid);
- gdata_entry_set_id (entry, g_strdup(uid));
+ gdata_entry_set_content (GDATA_ENTRY (event), t->value);
+ } else
+ gdata_entry_set_content (GDATA_ENTRY (event), "");
/* Location */
e_cal_component_get_location (comp, &location);
- if (location)
- gdata_entry_set_location (entry , location);
+ if (location) {
+ GDataGDWhere *where;
+
+ where = gdata_gd_where_new (NULL, location, NULL);
+ gdata_calendar_event_add_place (event, where);
+ }
if (e_cal_backend_get_kind (E_CAL_BACKEND(cbgo)) == ICAL_VEVENT_COMPONENT)
- term = g_strconcat (GDATA_SCHEMA, "event", NULL);
+ term = "http://schemas.google.com/g/2005#event";
+
+ category = gdata_category_new (term, "http://schemas.google.com/g/2005#kind", "label");
+ gdata_entry_add_category (GDATA_ENTRY (event), category);
- gdata_entry_create_categories (entry, g_strconcat (GDATA_SCHEMA, "kind", NULL),
- "label",
- term);
/* Attendee */
e_cal_component_get_attendee_list (comp, &attendee_list);
- for (l = attendee_list; l!=NULL; l=l->next) {
+ for (l = attendee_list; l != NULL; l = l->next) {
ECalComponentAttendee *ecal_att;
- ecal_att = (ECalComponentAttendee *)l->data;
- /* TODO Convert ECalComponentAttendee to Attendee, and change during parsing to store the types */
+ GDataGDWho *who;
+ gchar *email;
+ const gchar *rel;
- }
+ ecal_att = (ECalComponentAttendee *)l->data;
- /* FIXME For transparency and status */
- item->entry = entry;
- return item;
-}
+ /* Extract the attendee's e-mail address from att->value, which should be in the form:
+ * MAILTO:john@foobar.com
+ */
+ email = strstr (ecal_att->value, "MAILTO:");
+ if (!email)
+ continue;
+ email += 7; /* length of MAILTO: */
+
+ rel = "http://schemas.google.com/g/2005#event.attendee";
+ if (e_cal_component_has_organizer (comp)) {
+ ECalComponentOrganizer org;
+
+ e_cal_component_get_organizer (comp, &org);
+ if (strcmp (org.value, ecal_att->value) == 0)
+ rel = "http://schemas.google.com/g/2005#event.organizer";
+ }
-/**
- *
- * e_go_item_get_entry:
- * @item a EGoItem
- * Returns the GDataEntry object
- *
- **/
+ who = gdata_gd_who_new (rel, ecal_att->cn, email);
+ gdata_calendar_event_add_person (event, who);
+ }
-GDataEntry *
-e_go_item_get_entry (EGoItem *item)
-{
- g_return_val_if_fail (item != NULL, NULL);
- return item->entry;
-}
+ /* Recurrence support */
+ recur_string = g_string_new (NULL);
-/**
- *
- * e_go_item_set_entry:
- * @item a EGoItem
- * @entry a GDataEntry
- * Sets the GDataEntry of EGoItem to entry
- *
- **/
-void
-e_go_item_set_entry (EGoItem *item, GDataEntry *entry)
-{
- g_return_if_fail (item != NULL);
- g_return_if_fail (entry != NULL);
+ e_cal_component_get_dtstart (comp, &dt);
+ buf = comp_date_time_as_ical_string (&dt, default_zone);
+ g_string_append_printf (recur_string, "DTSTART:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
- item->entry = entry;
-}
+ e_cal_component_get_dtend (comp, &dt);
+ buf = comp_date_time_as_ical_string (&dt, default_zone);
+ g_string_append_printf (recur_string, "DTEND:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+
+ e_cal_component_get_rrule_list (comp, &list);
+ for (l = list; l != NULL; l = l->next) {
+ /* Append each rrule to recur_string */
+ buf = icalrecurrencetype_as_string_r ((struct icalrecurrencetype*) l->data);
+ g_string_append_printf (recur_string, "RRULE:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+ }
+ e_cal_component_free_recur_list (list);
+
+ e_cal_component_get_rdate_list (comp, &list);
+ for (l = list; l != NULL; l = l->next) {
+ /* Append each rdate to recur_string */
+ struct icaldatetimeperiodtype date_time_period = { { 0, }, };
+ ECalComponentPeriod *period = l->data;
+
+ /* Build a struct icaldatetimeperiodtype… */
+ date_time_period.time = period->start;
+ date_time_period.period.start = period->start;
+ if (period->type == E_CAL_COMPONENT_PERIOD_DATETIME)
+ date_time_period.period.end = period->u.end;
+ else if (period->type == E_CAL_COMPONENT_PERIOD_DURATION)
+ date_time_period.period.duration = period->u.duration;
+ else
+ g_assert_not_reached ();
+
+ /* …allowing us to build an icalproperty and get it in string form */
+ prop = icalproperty_new_rdate (date_time_period);
+
+ buf = icalproperty_get_value_as_string_r (prop);
+ g_string_append_printf (recur_string, "RDATE:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+ icalproperty_free (prop);
+ }
+ e_cal_component_free_period_list (list);
+
+ e_cal_component_get_exrule_list (comp, &list);
+ for (l = list; l != NULL; l = l->next) {
+ /* Append each exrule to recur_string */
+ buf = icalrecurrencetype_as_string_r ((struct icalrecurrencetype*) l->data);
+ g_string_append_printf (recur_string, "EXRULE:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+ }
+ e_cal_component_free_recur_list (list);
-/**
- *
- * gdata_entry_get_entry_by_id:
- * @entries List of entries
- * @id id to retreive
- * Gets the specified entry
- *
- **/
-GDataEntry *
-gdata_entry_get_entry_by_id (GSList *entries, const gchar *id)
-{
- GSList *l = NULL;
+ e_cal_component_get_exdate_list (comp, &list);
+ for (l = list; l != NULL; l = l->next) {
+ /* Append each exdate to recur_string */
+ ECalComponentDateTime *date_time = l->data;
- for (l = entries; l != NULL;l = l->next) {
- if (!strcmp (gdata_entry_get_id ((GDataEntry *)l->data), id)) {
- return l->data;
- }
+ /* Build an icalproperty and get the exdate in string form */
+ buf = comp_date_time_as_ical_string (date_time, default_zone);
+ g_string_append_printf (recur_string, "EXDATE:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
}
+ e_cal_component_free_exdate_list (list);
- return NULL;
+ /* Set the recurrence data on the event */
+ gdata_calendar_event_set_recurrence (event, g_string_free (recur_string, FALSE));
+
+ /* FIXME For transparency and status */
}
/***************************************************************** Utility Functions *********************************************/
}
static void
-utils_update_insertion (ECalBackendGoogle *cbgo, ECalBackendCache *cache, EGoItem *item, GSList *uid_list)
+utils_update_insertion (ECalBackendGoogle *cbgo, ECalBackendCache *cache, GDataFeed *feed, GSList *uid_list)
{
- EGoItem *item_t;
ECalComponent *comp;
- GSList *list = NULL, *entries_list = NULL;
- GDataEntry *entry;
+ GSList *list = NULL;
+ GDataCalendarEvent *event;
gchar *temp;
comp = e_cal_component_new ();
- item_t = g_new0 (EGoItem, 1);
- item_t->feed = item->feed;
- entries_list = gdata_feed_get_entries (item->feed);
for (list = uid_list; list != NULL; list = list->next) {
- entry = gdata_entry_get_entry_by_id (entries_list, list->data);
- item_t->entry = entry;
- comp = e_go_item_to_cal_component (item_t, cbgo);
+ event = GDATA_CALENDAR_EVENT (gdata_feed_look_up_entry (feed, list->data));
+ comp = e_gdata_event_to_cal_component (event, cbgo);
if (comp) {
e_cal_component_commit_sequence (comp);
g_object_unref (comp);
}
}
-
- g_free (item_t);
- if (list)
- g_slist_free (list);
- if (entries_list)
- g_slist_free (entries_list);
}
static void
}
/**
- * get_date: Returns date in gdata format '2006-04-17T17:00:00.000Z'
+ * get_timeval: Returns date in a GTimeVal
* @dt a #ECalComponentDateTime value
+ * @timeval a #GTimeVal
**/
-/* FIXME use proper functions to manipulate the dates */
-static gchar *
-get_date (ECalComponentDateTime dt)
+static void
+get_timeval (ECalComponentDateTime dt, GTimeVal *timeval)
{
- gchar *temp;
- struct icaltimetype itt;
- struct icaltimetype *itt_u;
- gchar *month;
- gchar *day, *minute, *hour, *second;
-
- itt_u = dt.value;
- itt.year = itt_u->year;
- itt.month = itt_u->month;
- itt.day = itt_u->day;
- itt.hour = itt_u->hour;
- itt.minute = itt_u->minute;
- itt.second = itt_u->second;
- itt.is_utc = itt_u->is_utc;
- itt.is_date = itt_u->is_date;
- itt.is_daylight = itt_u->is_daylight;
- itt.zone = itt_u->zone;
-
- month = (itt.month<10) ? g_strdup_printf("0%d", itt.month):g_strdup_printf ("%d", itt.month);
- day = (itt.day < 10) ? g_strdup_printf("0%d", itt.day):g_strdup_printf ("%d", itt.day);
-
- hour = (itt.hour<10) ? g_strdup_printf("0%d", itt.hour):g_strdup_printf ("%d", itt.hour);
- minute = (itt.minute<10) ? g_strdup_printf("0%d", itt.minute):g_strdup_printf ("%d", itt.minute);
- second = (itt.second<10) ? g_strdup_printf ("0%d", itt.second):g_strdup_printf ("%d", itt.second);
-
- /* FIXME not the best way to do this */
- temp = g_strdup_printf ("%d-%s-%sT%s:%s:%s.000", itt.year, month, day, hour, minute, second);
- g_free (month);
- g_free (day);
- g_free (hour);
- g_free (minute);
- g_free (second);
-
- return temp;
+ time_t tt;
+
+ /* GTimeVals are always in UTC */
+ tt = icaltime_as_timet_with_zone (*(dt.value), icaltimezone_get_utc_timezone ());
+
+ timeval->tv_sec = (glong) tt;
+ timeval->tv_usec = 0;
}
static gboolean
/**
*
- * gd_date_to_ical:
+ * gd_timeval_to_ical:
* Helper Function to convert a gdata format date to ical date
- * @item item from which the time comes. It's used to get to the feed's timezone
- * @google_time_string date in gdata format eg: '2006-04-17T17:00:00.000Z' or '2006-04-17T17:00:00.000+07:00'
+ * @event event from which the time comes. It's used to get to the event's timezone
+ * @timeval date as a #GTimeVal
* @iit Resulting icaltimetype.
* @dt Resulting ECalComponentDateTime.
* @default_zone Default time zone for the backend. If set, then the time will be converted to that timezone.
* @note Do not free itt or dt values, those come from buildin structures held by libical
**/
static gboolean
-gd_date_to_ical (EGoItem *item, const gchar *google_time_string, struct icaltimetype *itt, ECalComponentDateTime *dt, icaltimezone *default_zone)
+gd_timeval_to_ical (GTimeVal *timeval, struct icaltimetype *itt, ECalComponentDateTime *dt, icaltimezone *default_zone)
{
- gchar *s, *string, *dup;
- gint count = 0;
- gboolean is_utc = TRUE;
-
+ /* TODO: Event's timezone? */
g_return_val_if_fail (itt != NULL, FALSE);
g_return_val_if_fail (dt != NULL, FALSE);
- if (!google_time_string || !*google_time_string)
+ if (!timeval)
return FALSE;
- dup = g_strdup (google_time_string);
- s = dup;
- string = dup;
-
- /* Strip of the string to the gdata format */
- while (s[0] != '\0') {
- if ((s[0] != '-') && (s[0] != '+') && (s[0] != ':') && (s[0] != '.')) {
- *string = *s;
- string = string + 1;
- s = s + 1;
- count = count + 1;
- }else
- s = s + 1;
-
- if (count == 15) {
- if (strlen (s) >= 5) {
- is_utc = s [4] == 'Z';
- }
-
- string[0] = '\0';
- break;
- }
- if (s[1] == '\0')
- string[0] = '\0';
- }
-
- *itt = icaltime_from_string (dup);
-
- if (!is_utc) {
- const gchar *zone_name = item->feed ? gdata_feed_get_timezone (item->feed) : NULL;
-
- if (zone_name) {
- icaltimezone *zone = icaltimezone_get_builtin_timezone (zone_name);
-
- if (zone)
- icaltime_set_timezone (itt, zone);
- }
- }
-
- if (!icaltime_get_timezone (*itt))
- icaltime_set_timezone (itt, icaltimezone_get_utc_timezone ());
+ *itt = icaltime_from_timet_with_zone (timeval->tv_sec, 0, icaltimezone_get_utc_timezone ());
if (default_zone)
*itt = icaltime_convert_to_zone (*itt, default_zone);
dt->value = itt;
dt->tzid = icaltimezone_get_tzid ((icaltimezone *) icaltime_get_timezone (*itt));
- g_free (dup);
-
return TRUE;
}
/*
* Authors :
* Ebby Wiselyn <ebbywiselyn@gmail.com>
+ * Philip Withnall <philip@tecnocode.co.uk>
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
#endif
#include <e-cal-backend-google.h>
#include <libecal/e-cal-component.h>
-#include <servers/google/libgdata/gdata-entry.h>
-#include <servers/google/libgdata/gdata-feed.h>
-#include <servers/google/libgdata-google/gdata-google-service.h>
-#include <servers/google/libgdata/gdata-service-iface.h>
+#include <gdata/services/calendar/gdata-calendar-event.h>
ECalComponent *
-e_go_item_to_cal_component (EGoItem *item, ECalBackendGoogle *cbgo);
+e_gdata_event_to_cal_component (GDataCalendarEvent *event, ECalBackendGoogle *cbgo);
-void
-e_go_item_set_entry (EGoItem *item, GDataEntry *entry);
-
-GDataEntry *
-e_go_item_get_entry (EGoItem *item);
+GDataCalendarEvent *
+e_gdata_event_from_cal_component (ECalBackendGoogle *cbgo, ECalComponent *comp);
-EGoItem *
-e_go_item_from_cal_component (ECalBackendGoogle *cbgo, ECalComponent *comp);
+void
+e_gdata_event_update_from_cal_component (ECalBackendGoogle *cbgo, GDataCalendarEvent *event, ECalComponent *comp);
gpointer
e_cal_backend_google_utils_update (gpointer handle);
-GDataEntry *
-gdata_entry_get_entry_by_id (GSList *entries, const gchar *id);
-
ECalBackendSyncStatus
e_cal_backend_google_utils_connect (ECalBackendGoogle *cbgo);
/*
* Authors :
* Ebby Wiselyn <ebbyw@gnome.org>
+ * Philip Withnall <philip@tecnocode.co.uk>
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
#include <libecal/e-cal-time-util.h>
#include <libecal/e-cal-util.h>
-#include <servers/google/libgdata/gdata-entry.h>
-#include <servers/google/libgdata/gdata-feed.h>
-#include <servers/google/libgdata-google/gdata-google-service.h>
-#include <servers/google/libgdata/gdata-service-iface.h>
+#include <gdata/gdata-entry.h>
+#include <gdata/gdata-feed.h>
+#include <gdata/services/calendar/gdata-calendar-service.h>
#include "e-cal-backend-google-utils.h"
#include "e-cal-backend-google.h"
ECalBackendCache *cache;
ESource *source;
- GDataGoogleService *service;
+ GDataCalendarService *service;
+ GDataFeed *feed;
GMutex *mutex;
- GDataEntry *entry;
- GSList *entries;
icaltimezone *default_zone;
CalMode mode;
- EGoItem *item;
guint timeout_id;
gchar *username;
gchar *password;
gchar *uri;
- gchar *feed;
- gchar *local_attachments_store;
+ gchar *local_attachments_store;
gboolean read_only;
gboolean mode_changed;
EProxy *proxy;
};
-gint compare_ids (gconstpointer cache_id, gconstpointer modified_cache_id);
-gchar * form_query (const gchar *query);
-
-gint
-compare_ids (gconstpointer cache_id, gconstpointer modified_cache_id)
-{
- return strcmp (cache_id, modified_cache_id);
-}
-
/************************************************** Calendar Backend Methods **********************************/
static ECalBackendSyncStatus
cbgo = E_CAL_BACKEND_GOOGLE (backend);
priv = cbgo->priv;
- if (!priv->mode && priv->mode == mode) {
+ if (priv->mode == mode) {
e_cal_backend_notify_mode (backend, GNOME_Evolution_Calendar_CalListener_MODE_SET,
cal_mode_to_corba (mode));
return;
receive_object (ECalBackendGoogle *cbgo, EDataCal *cal, icalcomponent *icalcomp)
{
ECalBackendGooglePrivate *priv;
- EGoItem *item = NULL;
GDataEntry *entry = NULL, *updated_entry = NULL;
ECalComponent *comp, *modif_comp;
GSList *comps = NULL, *l = NULL;
fetch_attachments (cbgo, comp);
/* Sent to Server */
- item = e_go_item_from_cal_component (cbgo, comp);
- entry = e_go_item_get_entry (item);
+ entry = GDATA_ENTRY (e_gdata_event_from_cal_component (cbgo, comp));
- if (!GDATA_IS_ENTRY(entry))
- return GNOME_Evolution_Calendar_InvalidObject;
+ if (!GDATA_IS_ENTRY (entry))
+ return GNOME_Evolution_Calendar_InvalidObject;
- updated_entry = gdata_service_insert_entry (GDATA_SERVICE(priv->service), priv->uri, entry, NULL);
+ updated_entry = gdata_service_insert_entry (GDATA_SERVICE (priv->service), priv->uri, entry, NULL, NULL);
+ g_object_unref (entry);
if (updated_entry) {
/* FIXME */
}
/* Update the Cache */
-
modif_comp = g_object_ref (comp);
if (instances) {
const gchar *uid;
static ECalBackendSyncStatus
e_cal_backend_google_is_read_only (ECalBackendSync *backend, EDataCal *cal, gboolean *read_only)
{
- /* FIXME */
- *read_only = FALSE;
-
+ *read_only = E_CAL_BACKEND_GOOGLE (backend)->priv->read_only;
return GNOME_Evolution_Calendar_Success;
}
ECalBackendGooglePrivate *priv;
icalcomponent *icalcomp;
ECalComponent *comp = NULL, *cache_comp = NULL;
- EGoItem *item;
- const gchar *uid=NULL, *rid=NULL;
- GDataEntry *entry, *entry_from_server=NULL, *updated_entry=NULL;
- gchar *edit_link;
- GSList *l;
+ const gchar *uid = NULL, *rid = NULL;
+ GDataFeed *feed;
+ GDataEntry *entry, *updated_entry = NULL;
*old_object = NULL;
cbgo = E_CAL_BACKEND_GOOGLE (backend);
return GNOME_Evolution_Calendar_ObjectNotFound;
}
- item = e_go_item_from_cal_component (cbgo, comp);
- item->feed = gdata_service_get_feed (GDATA_SERVICE(priv->service), priv->uri, NULL);
- entry = item->entry;
+ feed = gdata_service_query (GDATA_SERVICE(priv->service), priv->uri, NULL, GDATA_TYPE_CALENDAR_EVENT,
+ NULL, NULL, NULL, NULL);
- if (!item->feed) {
- g_message ("CRITICAL: Could not find feed in EGoItem %s", G_STRLOC);
+ if (!feed) {
+ g_message ("CRITICAL: Could not find feed %s", G_STRLOC);
g_object_unref (comp);
return GNOME_Evolution_Calendar_OtherError;
}
- l = gdata_feed_get_entries (item->feed);
- entry_from_server = gdata_entry_get_entry_by_id (l, uid);
+ e_cal_backend_google_set_feed (cbgo, feed);
+ g_object_unref (feed);
+
+ entry = gdata_feed_look_up_entry (feed, uid);
- if (!GDATA_IS_ENTRY(entry_from_server)) {
+ if (!GDATA_IS_ENTRY (entry)) {
g_object_unref (comp);
return GNOME_Evolution_Calendar_OtherError;
}
- edit_link = gdata_entry_get_edit_link (entry_from_server);
- updated_entry = gdata_service_update_entry_with_link (GDATA_SERVICE (priv->service),
- entry, edit_link, NULL);
+ /* Send the update to the server */
+ e_gdata_event_update_from_cal_component (cbgo, GDATA_CALENDAR_EVENT (entry), comp);
+ updated_entry = gdata_service_update_entry (GDATA_SERVICE (priv->service), entry, NULL, NULL);
if (updated_entry) {
- /* FIXME Response from server contains, additional info about GDataEntry
+ /* FIXME Response from server contains additional info about GDataEntry
* Store and use them later
*/
+ g_object_unref (updated_entry);
}
- break;
+ /* If successful, update the cache instead of breaking out of the switch */
case CAL_MODE_LOCAL:
e_cal_backend_cache_put_component (priv->cache, comp);
break;
GDataEntry *entry;
ECalBackendGooglePrivate *priv;
ECalComponent *comp = NULL;
- gchar *calobj = NULL;
- GSList *entries = NULL;
- EGoItem *item;
+ char *calobj = NULL;
cbgo = E_CAL_BACKEND_GOOGLE (backend);
priv = cbgo->priv;
- item = priv->item;
*old_object = *object = NULL;
- /* FIXME */
- item->feed = gdata_service_get_feed (GDATA_SERVICE(priv->service), priv->uri, NULL);
-
- entries = gdata_feed_get_entries (item->feed);
if (priv->mode == CAL_MODE_REMOTE) {
ECalBackendSyncStatus status;
icalcomponent *icalcomp;
ECalComponentId *id;
- gchar *comp_str;
+ char *comp_str;
+ GDataFeed *feed;
status = e_cal_backend_google_get_object (backend, cal, uid, rid, &calobj);
if (status != GNOME_Evolution_Calendar_Success) {
g_free (calobj);
- if (entries)
- g_slist_free (entries);
return status;
}
if (!icalcomp) {
g_free (calobj);
- if (entries)
- g_slist_free (entries);
return GNOME_Evolution_Calendar_InvalidObject;
}
e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbgo), id, comp_str, NULL);
g_free (comp_str);
- entry = gdata_entry_get_entry_by_id (entries, uid);
+ /* FIXME */
+ feed = gdata_service_query (GDATA_SERVICE(priv->service), priv->uri, NULL, GDATA_TYPE_CALENDAR_EVENT, NULL, NULL, NULL, NULL);
+ e_cal_backend_google_set_feed (cbgo, feed);
+ g_object_unref (feed);
+
+ entry = gdata_feed_look_up_entry (feed, uid);
if (!entry) {
g_free (calobj);
- if (entries)
- g_slist_free (entries);
return GNOME_Evolution_Calendar_InvalidObject;
}
- gdata_service_delete_entry (GDATA_SERVICE(priv->service), entry, NULL);
+ gdata_service_delete_entry (GDATA_SERVICE(priv->service), entry, NULL, NULL);
*object = NULL;
*old_object = strdup (calobj);
}
if (calobj)
g_free (calobj);
- if (entries)
- g_slist_free (entries);
return GNOME_Evolution_Calendar_Success;
}
ECalBackendGooglePrivate *priv;
icalcomponent *icalcomp;
ECalComponent *comp;
- EGoItem *item;
GDataEntry *entry;
- const gchar *id;
cbgo = E_CAL_BACKEND_GOOGLE (backend);
g_return_val_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo), GNOME_Evolution_Calendar_InvalidObject);
- g_return_val_if_fail (calobj != NULL && *calobj!=NULL,GNOME_Evolution_Calendar_InvalidObject);
+ g_return_val_if_fail (calobj != NULL && *calobj!=NULL, GNOME_Evolution_Calendar_InvalidObject);
priv = cbgo->priv;
if (priv->mode == CAL_MODE_LOCAL) {
/*FIXME call offline method */
}
icalcomp = icalparser_parse_string (*calobj);
- if (!icalcomp) {
+ if (!icalcomp)
return GNOME_Evolution_Calendar_InvalidObject;
- }
if (e_cal_backend_get_kind(E_CAL_BACKEND(backend)) != icalcomponent_isa (icalcomp)) {
icalcomponent_free (icalcomp);
case CAL_MODE_REMOTE: {
/* Create an appointment */
GDataEntry *updated_entry;
+ const gchar *id;
+ GError *error = NULL;
- item = e_go_item_from_cal_component (cbgo, comp);
- entry = e_go_item_get_entry (item);
+ entry = GDATA_ENTRY (e_gdata_event_from_cal_component (cbgo, comp));
+ updated_entry = gdata_service_insert_entry (GDATA_SERVICE (priv->service), priv->uri, entry, NULL, &error);
+ g_object_unref (entry);
- updated_entry = gdata_service_insert_entry (GDATA_SERVICE(priv->service),
- priv->uri, entry, NULL);
- if (!GDATA_IS_ENTRY (updated_entry)) {
- g_message ("\n Entry Insertion Failed %s \n", G_STRLOC);
+ if (!updated_entry) {
+ g_message ("\n Entry Insertion Failed %s: %s \n", G_STRLOC, error->message);
+ g_error_free (error);
+ return GNOME_Evolution_Calendar_InvalidObject;
}
id = gdata_entry_get_id (updated_entry);
e_cal_component_set_uid (comp, id);
+ g_object_unref (updated_entry);
break; }
default:
cbgo = E_CAL_BACKEND_GOOGLE (object);
priv = cbgo->priv;
+ if (priv->feed)
+ g_object_unref (priv->feed);
+ priv->feed = NULL;
+
if (G_OBJECT_CLASS (parent_class)->dispose)
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
if (e_proxy_require_proxy_for_uri (proxy, priv->uri)) {
proxy_uri = e_proxy_peek_uri_for (proxy, priv->uri);
}
- gdata_service_set_proxy (GDATA_SERVICE (priv->service), proxy_uri);
+ gdata_service_set_proxy_uri (GDATA_SERVICE (priv->service), proxy_uri);
}
/* Object initialisation function for google backend */
priv = g_new0 (ECalBackendGooglePrivate, 1);
priv->mutex = g_mutex_new ();
+ priv->read_only = FALSE;
priv->username = NULL;
priv->password = NULL;
- priv->entry = NULL;
priv->service = NULL;
priv->timeout_id = 0;
cbgo->priv = priv;
}
/**
- * e_cal_backend_google_set_item:
+ * e_cal_backend_google_set_feed:
* @cbgo a #ECalBackendGoogle object
- * @cache a #EGoItem *item
+ * @feed a #GDataFeed
*
**/
void
-e_cal_backend_google_set_item (ECalBackendGoogle *cbgo, EGoItem *item)
+e_cal_backend_google_set_feed (ECalBackendGoogle *cbgo, GDataFeed *feed)
{
- ECalBackendGooglePrivate *priv;
-
g_return_if_fail (cbgo != NULL);
g_return_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo));
+ g_return_if_fail (GDATA_IS_FEED (feed));
- priv = cbgo->priv;
- priv->item = item;
+ if (cbgo->priv->feed)
+ g_object_unref (cbgo->priv->feed);
+ cbgo->priv->feed = g_object_ref (feed);
}
/**
- * e_cal_backend_google_set_item:
+ * e_cal_backend_google_set_service:
* @cbgo a #ECalBackendGoogle object
- * @cache a #EGoItem *item
- * Sets the #EGoItem item on object
+ * @service a #GDataCalendarService
+ * Sets the #GDataCalendarService service on object
*
**/
void
-e_cal_backend_google_set_service (ECalBackendGoogle *cbgo, GDataGoogleService *service)
+e_cal_backend_google_set_service (ECalBackendGoogle *cbgo, GDataCalendarService *service)
{
ECalBackendGooglePrivate *priv;
proxy_uri = e_proxy_peek_uri_for (priv->proxy, priv->uri);
}
- gdata_service_set_proxy (GDATA_SERVICE (priv->service), proxy_uri);
-}
-
-/**
- * e_cal_backend_google_set_entry:
- * @cbgo a #ECalBackendGoogle object
- * @entry a #GDataEntry entry
- * Sets the entry on object
- *
- **/
-void
-e_cal_backend_google_set_entry (ECalBackendGoogle *cbgo, GDataEntry *entry)
-{
- ECalBackendGooglePrivate *priv;
-
- g_return_if_fail (cbgo != NULL);
- g_return_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo));
-
- priv = cbgo->priv;
- priv->entry = entry;
+ gdata_service_set_proxy_uri (GDATA_SERVICE (priv->service), proxy_uri);
}
/**
/**
* e_cal_backend_google_set_password:
* @cbgo a #ECalBackendGoogle object
- * @cache a #EGoItem *item
- * Sets the #EGoItem item on object
+ * @password a password
+ * Sets the password on object
*
**/
void
-e_cal_backend_google_set_password (ECalBackendGoogle *cbgo,gchar *password)
+e_cal_backend_google_set_password (ECalBackendGoogle *cbgo, gchar *password)
{
ECalBackendGooglePrivate *priv;
priv = cbgo->priv;
}
/**
- * e_cal_backend_google_get_item:
+ * e_cal_backend_google_get_feed:
* @cbgo a #ECalBackendGoogle object
- * Gets the #EGoItem . from cbgo
+ * Gets the #GDataFeed from cbgo
**/
-EGoItem *
-e_cal_backend_google_get_item (ECalBackendGoogle *cbgo)
+GDataFeed *
+e_cal_backend_google_get_feed (ECalBackendGoogle *cbgo)
{
- ECalBackendGooglePrivate *priv;
-
g_return_val_if_fail (cbgo != NULL, NULL);
g_return_val_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo), NULL);
- priv = cbgo->priv;
- return priv->item;
+ return cbgo->priv->feed;
}
/**
* e_cal_backend_google_get_service:
* @cbgo a #ECalBackendGoogle object
- * Gets the #GDataGoogleService service object .
+ * Gets the #GDataCalendarService service object .
*
**/
-GDataGoogleService *
+GDataCalendarService *
e_cal_backend_google_get_service (ECalBackendGoogle *cbgo)
{
ECalBackendGooglePrivate *priv;
}
/**
- * e_cal_backend_google_set_item:
+ * e_cal_backend_google_get_uri:
* @cbgo a #ECalBackendGoogle object
* Gets the uri
**/
}
/**
- * e_cal_backend_google_get_entry:
- * @cbgo a #ECalBackendGoogle object
- * Gets the #GDataEntry object.
- *
- **/
-GDataEntry *
-e_cal_backend_google_get_entry (ECalBackendGoogle *cbgo)
-{
- ECalBackendGooglePrivate *priv;
-
- g_return_val_if_fail (cbgo != NULL, NULL);
- g_return_val_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo), NULL);
-
- priv = cbgo->priv;
- return priv->entry;
-}
-
-/**
* e_cal_backend_google_get_timeout_id:
* @cbgo a #ECalBackendGoogle object
* Gets the timeout id.
/*
* Authors :
* Ebby Wiselyn <ebbywiselyn@gmail.com>
+ * Philip Withnall <philip@tecnocode.co.uk>
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
#include <libedata-cal/e-cal-backend-sync.h>
#include <libedata-cal/e-cal-backend-cache.h>
-#include <servers/google/libgdata/gdata-entry.h>
-#include <servers/google/libgdata/gdata-feed.h>
-#include <servers/google/libgdata-google/gdata-google-service.h>
-#include <servers/google/libgdata/gdata-service-iface.h>
+#include <gdata/gdata-feed.h>
+#include <gdata/services/calendar/gdata-calendar-service.h>
G_BEGIN_DECLS
ECalBackendSyncClass parent_class;
};
-struct _EGoItem {
- GDataEntry *entry;
- GDataFeed *feed;
-};
-typedef struct _EGoItem EGoItem;
-
GType e_cal_backend_google_get_type (void);
-EGoItem * e_cal_backend_google_get_item (ECalBackendGoogle *cbgo);
-GDataEntry * e_cal_backend_google_get_entry (ECalBackendGoogle *cbgo);
+GDataFeed * e_cal_backend_google_get_feed (ECalBackendGoogle *cbgo);
ECalBackendCache * e_cal_backend_google_get_cache (ECalBackendGoogle *cbgo);
-GDataGoogleService * e_cal_backend_google_get_service (ECalBackendGoogle *cbgo);
+GDataCalendarService * e_cal_backend_google_get_service (ECalBackendGoogle *cbgo);
gchar * e_cal_backend_google_get_uri (ECalBackendGoogle *cbgo);
icaltimezone * e_cal_backend_google_get_default_zone (ECalBackendGoogle *cbgo);
gboolean e_cal_backend_google_get_mode_changed (ECalBackendGoogle *cbgo);
gchar * e_cal_backend_google_get_local_attachments_store (ECalBackendGoogle *cbgo);
guint e_cal_backend_google_get_timeout_id (ECalBackendGoogle *cbgo);
-void e_cal_backend_google_set_entry (ECalBackendGoogle *cbgo, GDataEntry *entry);
void e_cal_backend_google_set_cache (ECalBackendGoogle *cbgo, ECalBackendCache *cache);
-void e_cal_backend_google_set_item (ECalBackendGoogle *cbgo, EGoItem *item);
-void e_cal_backend_google_set_service (ECalBackendGoogle *cbgo, GDataGoogleService *service);
+void e_cal_backend_google_set_feed (ECalBackendGoogle *cbgo, GDataFeed *feed);
+void e_cal_backend_google_set_service (ECalBackendGoogle *cbgo, GDataCalendarService *service);
void e_cal_backend_google_set_uri (ECalBackendGoogle *cbgo, gchar *uri);
void e_cal_backend_google_set_mode_changed (ECalBackendGoogle *cbgo, gboolean mode_changed);
void e_cal_backend_google_set_username (ECalBackendGoogle *cbgo, gchar *username);
m4_define([gconf_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([libxml_minimum_version], [2.0.0]) dnl XXX Just a Guess
m4_define([libsoup_minimum_version], [2.3.0])
+m4_define([libgdata_minimum_version], [0.6.3])
m4_define([gnome_keyring_minimum_version], [2.20.1])
m4_define([sqlite_minimum_version], [3.5])
m4_define([gweather_minimum_version], [2.25.4])
LIBCAMEL_REVISION=0
LIBCAMEL_AGE=0
-LIBGDATA_CURRENT=1
-LIBGDATA_REVISION=0
-LIBGDATA_AGE=0
-
-LIBGDATA_GOOGLE_CURRENT=1
-LIBGDATA_GOOGLE_REVISION=0
-LIBGDATA_GOOGLE_AGE=0
-
LIBEBACKEND_CURRENT=0
LIBEBACKEND_REVISION=1
LIBEBACKEND_AGE=0
AC_SUBST(LIBCAMEL_CURRENT)
AC_SUBST(LIBCAMEL_REVISION)
AC_SUBST(LIBCAMEL_AGE)
-AC_SUBST(LIBGDATA_CURRENT)
-AC_SUBST(LIBGDATA_REVISION)
-AC_SUBST(LIBGDATA_AGE)
-AC_SUBST(LIBGDATA_GOOGLE_CURRENT)
-AC_SUBST(LIBGDATA_GOOGLE_REVISION)
-AC_SUBST(LIBGDATA_GOOGLE_AGE)
AC_SUBST(LIBEBACKEND_CURRENT)
AC_SUBST(LIBEBACKEND_REVISION)
AC_SUBST(LIBEBACKEND_AGE)
gtk+-2.0 >= gtk_minimum_version
gconf-2.0 >= gconf_minimum_version
libxml-2.0 >= libxml_minimum_version
- libsoup-2.4 >= libsoup_minimum_version])
+ libsoup-2.4 >= libsoup_minimum_version
+ libgdata >= libgdata_minimum_version])
LIBICAL_REQUIRED=libical_minimum_version
AC_SUBST(LIBICAL_REQUIRED)
dnl ******************************
dnl Google flags
dnl ******************************
-GDATA_DEPS="libsoup-2.4 libxml-2.0"
-EVO_SET_COMPILE_FLAGS(GDATA, $GDATA_DEPS)
+LIBGDATA_REQUIRED=libgdata_minimum_version
+AC_SUBST(LIBGDATA_REQUIRED)
+
+EVO_SET_COMPILE_FLAGS(GDATA, libgdata)
AC_SUBST(GDATA_CFLAGS)
AC_SUBST(GDATA_LIBS)
servers/Makefile
servers/groupwise/Makefile
servers/groupwise/libegroupwise.pc
-servers/google/Makefile
-servers/google/libgdata/Makefile
-servers/google/libgdata/libgdata.pc
-servers/google/libgdata-google/Makefile
-servers/google/libgdata-google/libgdata-google.pc
docs/Makefile
docs/reference/Makefile
docs/reference/addressbook/Makefile
-SUBDIRS = groupwise google
+SUBDIRS = groupwise
-include $(top_srcdir)/git.mk
+++ /dev/null
-SUBDIRS = libgdata libgdata-google
-
--include $(top_srcdir)/git.mk
+++ /dev/null
-lib_LTLIBRARIES = libgdata-google-1.2.la
-
-libgdata_google_1_2_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -DG_LOG_DOMAIN=\"libgdata-google\" \
- -I$(top_srcdir) \
- -I$(top_builddir) \
- -I$(top_srcdir)/servers/google/libgdata \
- $(GDATA_CFLAGS)
-
-libgdata_google_1_2_la_SOURCES = \
- gdata-google-service.c \
- gdata-google-service.h
-
-libgdata_google_1_2_la_LIBADD = \
- $(top_builddir)/servers/google/libgdata/libgdata-1.2.la \
- $(GDATA_LIBS)
-
-libgdata_google_1_2_la_LDFLAGS = \
- -version-info $(LIBGDATA_GOOGLE_CURRENT):$(LIBGDATA_GOOGLE_REVISION):$(LIBGDATA_GOOGLE_AGE) $(NO_UNDEFINED)
-
-libgdata_google_includedir = $(privincludedir)/google/libgdata-google
-
-libgdata_google_include_HEADERS = \
- gdata-google-service.h
-
-%-$(API_VERSION).pc: %.pc
- cp $< $@
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libgdata-google-$(API_VERSION).pc
-
-EXTRA_DIST = $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in)
-
-DISTCLEANFILES = $(pkgconfig_DATA)
-
-
--include $(top_srcdir)/git.mk
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- * Ebby Wiselyn <ebbywiselyn@gmail.com>
- * Jason Willis <zenbrother@gmail.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include <config.h>
-#include <gdata-service-iface.h>
-#include <gdata-google-service.h>
-
-#include <libsoup/soup.h>
-#include <string.h>
-
-#define GDATA_GOOGLE_SERVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GDATA_TYPE_GOOGLE_SERVICE, GDataGoogleServicePrivate))
-
-static void gdata_google_service_iface_init (GDataServiceIface *iface);
-
-G_DEFINE_TYPE_EXTENDED (GDataGoogleService, gdata_google_service, G_TYPE_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (GDATA_TYPE_SERVICE, gdata_google_service_iface_init))
-
-static GDataEntry * gdata_google_service_update_entry_with_link (GDataService *service, GDataEntry *entry, const gchar *edit_link, GError **error);
-static GDataEntry * gdata_google_service_insert_entry (GDataService *service, const gchar *feed_url, GDataEntry *entry, GError **error);
-static gboolean gdata_google_service_delete_entry (GDataService *service, GDataEntry *entry, GError **error);
-static GDataFeed * gdata_google_service_get_feed (GDataService *service, const gchar *feed_url, GError **error);
-static GDataEntry * gdata_google_service_update_entry (GDataService *service, GDataEntry *entry, GError **error);
-static void gdata_google_service_set_credentials (GDataService *service, const gchar *username, const gchar *password);
-static void gdata_google_service_set_proxy (GDataService *service, SoupURI *proxy);
-
-typedef struct _GDataGoogleServiceAuth GDataGoogleServiceAuth;
-struct _GDataGoogleServiceAuth {
- /* Authentication Information */
- gchar *username;
- gchar *password;
-
- gchar *token;
-};
-
-struct _GDataGoogleServicePrivate {
- /* Session information */
- gchar *name;
- gchar *agent;
-
- SoupSession *soup_session;
- GDataGoogleServiceAuth *auth;
-
- gboolean dispose_has_run;
-
-};
-
-enum {
- PROP_0,
- PROP_NAME,
- PROP_AGENT
-};
-
-static const gchar *GOOGLE_CLIENT_LOGIN = "https://www.google.com/accounts/ClientLogin";
-
-GQuark
-gdata_google_error_quark (void)
-{
- static GQuark error;
- return error ? error : (error = g_quark_from_static_string ("gdata_google_error_quark"));
-}
-
-static void
-gdata_google_service_set_proxy (GDataService *service, SoupURI *proxy)
-{
- GDataGoogleServicePrivate *priv;
-
- g_return_if_fail (service != NULL);
- g_return_if_fail (GDATA_IS_GOOGLE_SERVICE(service));
-
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(GDATA_GOOGLE_SERVICE(service));
- if (proxy && priv && priv->soup_session)
- g_object_set (priv->soup_session, SOUP_SESSION_PROXY_URI, proxy, NULL);
-}
-
-/* send a message without redirection and if it was required, then redirects itself */
-static void
-send_and_handle_google_redirection (SoupSession *soup_session, SoupMessage *msg)
-{
- soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
- soup_session_send_message (soup_session, msg);
- soup_message_set_flags (msg, 0);
-
- if (SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
- SoupURI *new_uri;
- const gchar *new_loc;
-
- new_loc = soup_message_headers_get (msg->response_headers, "Location");
- g_return_if_fail (new_loc != NULL);
-
- new_uri = soup_uri_new_with_base (soup_message_get_uri (msg), new_loc);
- if (!new_uri) {
- soup_message_set_status_full (msg,
- SOUP_STATUS_MALFORMED,
- "Invalid Redirect URL");
- return;
- }
-
- soup_message_set_uri (msg, new_uri);
- soup_uri_free (new_uri);
-
- soup_session_send_message (soup_session, msg);
- }
-}
-
-static void
-gdata_google_service_set_credentials (GDataService *service, const gchar *username, const gchar *password)
-{
- GDataGoogleServicePrivate *priv;
- GDataGoogleServiceAuth *auth;
-
- g_return_if_fail (service != NULL);
- g_return_if_fail (GDATA_IS_GOOGLE_SERVICE(service));
-
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(GDATA_GOOGLE_SERVICE(service));
- auth = (GDataGoogleServiceAuth *)priv->auth;
-
- auth->username = g_strdup(username);
- auth->password = g_strdup(password);
-}
-
-static gboolean
-service_is_authenticated (GDataGoogleService *service)
-{
- GDataGoogleServicePrivate *priv;
- GDataGoogleServiceAuth *auth;
-
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(service);
- auth = (GDataGoogleServiceAuth *)priv->auth;
-
- if (auth->token == NULL)
- return FALSE;
- else
- return TRUE;
-}
-
-/**
- *
- * gdata_google_service_get_feed:
- * @service A GDataService Object
- * @feed_url Feed Url , the private url to send request to , needs authentication
- * @entry A GDataFeed Object
- * returns the newly inserted entry
- *
- **/
-
-static GDataFeed *
-gdata_google_service_get_feed (GDataService *service, const gchar *feed_url, GError **error)
-{
- GDataFeed *feed = NULL;
- GDataGoogleServicePrivate *priv;
- GDataGoogleServiceAuth *auth;
- SoupSession *soup_session;
- SoupMessage *msg;
-
- g_return_val_if_fail(service != NULL, NULL);
- g_return_val_if_fail(GDATA_IS_GOOGLE_SERVICE(service),NULL);
-
- if (!service_is_authenticated( GDATA_GOOGLE_SERVICE(service) )) {
- if (FALSE == gdata_google_service_authenticate(GDATA_GOOGLE_SERVICE(service), error))
- return NULL;
- }
-
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE( GDATA_GOOGLE_SERVICE(service) );
- auth = (GDataGoogleServiceAuth *)priv->auth;
- soup_session = (SoupSession *)priv->soup_session;
-
- msg = soup_message_new(SOUP_METHOD_GET, feed_url);
- if (!msg)
- return NULL;
-
- soup_message_headers_append(msg->request_headers,
- "Authorization", (gchar *)g_strdup_printf("GoogleLogin auth=%s", auth->token));
-
- soup_session_send_message (soup_session, msg);
- if (msg->status_code != 200) {
- g_set_error (error, SOUP_HTTP_ERROR,
- msg->status_code, "%s", msg->reason_phrase);
-
- g_object_unref (msg);
- return NULL;
- }
-
- if (msg->response_body->data && strlen (msg->response_body->data) > 0) {
- feed = gdata_feed_new_from_xml(msg->response_body->data,
- msg->response_body->length);
- }
-
- if (NULL == feed) {
- g_set_error (error, GDATA_GOOGLE_ERROR,
- -1, "GData protocol error");
- }
-
- g_object_unref(msg);
-
- return feed;
-}
-
-/**
- *
- * gdata_google_service_insert_entry:
- * @service A #GDataService Object
- * @feed_url Feed Url , this is the private url of the author which requires authentication
- * @entry A #GDataEntry Object
- * returns the newly inserted entry
- *
- **/
-static GDataEntry *
-gdata_google_service_insert_entry (GDataService *service, const gchar *feed_url, GDataEntry *entry, GError **error)
-{
- GDataGoogleServicePrivate *priv;
- GDataGoogleServiceAuth *auth;
- GDataEntry *updated_entry = NULL;
- SoupSession *soup_session;
- SoupMessage *msg;
- gchar *entry_xml;
-
- g_return_val_if_fail(service != NULL, NULL);
- g_return_val_if_fail(GDATA_IS_GOOGLE_SERVICE(service), NULL);
-
- if (!service_is_authenticated( GDATA_GOOGLE_SERVICE(service) )) {
- if (FALSE == gdata_google_service_authenticate(GDATA_GOOGLE_SERVICE(service), error))
- return NULL;
- }
-
- entry_xml = gdata_entry_generate_xml (entry);
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(GDATA_GOOGLE_SERVICE(service));
- auth = (GDataGoogleServiceAuth *)priv->auth;
- soup_session = (SoupSession *)priv->soup_session;
-
- msg = soup_message_new(SOUP_METHOD_POST, feed_url);
- soup_message_set_http_version (msg, SOUP_HTTP_1_0);
-
- soup_message_headers_append(msg->request_headers,
- "Authorization",
- (gchar *)g_strdup_printf("GoogleLogin auth=%s",
- auth->token));
-
- soup_message_set_request (msg,
- "application/atom+xml",
- SOUP_MEMORY_COPY,
- entry_xml,
- strlen(entry_xml));
-
- /* Handle redirects ourself, since soup does not behave like google-api expects */
- send_and_handle_google_redirection (soup_session, msg);
-
- if (msg->status_code != 201) {
- g_set_error (error, SOUP_HTTP_ERROR,
- msg->status_code, "%s", msg->reason_phrase);
- g_object_unref (msg);
- return NULL;
- }
-
- if (msg->response_body->data && strlen (msg->response_body->data) > 0) {
- updated_entry = gdata_entry_new_from_xml (msg->response_body->data);
- }
-
- if (NULL == updated_entry) {
- g_set_error (error, GDATA_GOOGLE_ERROR,
- -1, "GData protocol error");
- }
-
- g_object_unref (msg);
- return updated_entry;
-}
-
-/**
- *
- * gdata_google_service_delete_entry:
- * @service A #GDataService Object
- * @feed_url Feed Url , this is the private url of the author which requires authentication
- * @entry A #GDataEntry Object
- * Removes the entry
- *
- **/
-static gboolean
-gdata_google_service_delete_entry (GDataService *service, GDataEntry *entry, GError **error)
-{
- GDataGoogleServiceAuth *auth;
- GDataGoogleServicePrivate *priv;
- SoupSession *soup_session;
- SoupMessage *msg;
- const gchar *entry_edit_url;
- gboolean retval = FALSE;
-
- g_return_val_if_fail (service != NULL, FALSE);
- g_return_val_if_fail (GDATA_IS_GOOGLE_SERVICE(service), FALSE);
-
- if (!service_is_authenticated( GDATA_GOOGLE_SERVICE(service) )) {
- if (FALSE == gdata_google_service_authenticate(GDATA_GOOGLE_SERVICE(service), error))
- return FALSE;
- }
-
- entry_edit_url = gdata_entry_get_edit_link (entry);
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE (GDATA_GOOGLE_SERVICE (service));
- auth = (GDataGoogleServiceAuth *) priv->auth;
- soup_session = (SoupSession *)priv->soup_session;
-
- msg = soup_message_new (SOUP_METHOD_DELETE, entry_edit_url);
- soup_message_headers_append (msg->request_headers,
- "Authorization",
- (gchar *)g_strdup_printf ("GoogleLogin auth=%s",
- auth->token));
-
- /* Handle redirects ourself */
- send_and_handle_google_redirection (soup_session, msg);
-
- if (msg->status_code != 200) {
- g_set_error (error, SOUP_HTTP_ERROR,
- msg->status_code, "%s", msg->reason_phrase);
- } else {
- retval = TRUE;
- }
-
- g_object_unref (msg);
-
- return retval;
-}
-
-/**
- *
- * gdata_google_service_update_entry:
- * @service A GDataService Object
- * @feed_url Feed Url , this is the private url of the author which requires authentication
- * @entry A GDataEntry Object
- * updates the entry
- *
- **/
-static GDataEntry*
-gdata_google_service_update_entry (GDataService *service, GDataEntry *entry, GError **error)
-{
- const gchar *entry_edit_url;
-
- g_return_val_if_fail (service != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_GOOGLE_SERVICE (service), NULL);
-
- entry_edit_url = gdata_entry_get_edit_link (entry);
-
- return gdata_google_service_update_entry_with_link (service, entry, entry_edit_url, error);
-}
-
-/**
- *
- * gdata_google_update_entry_with_link:
- * @service A #GDataService Object
- * @edit_link url of the edit link of the entry
- * @entry A #GDataEntry Object
- * Updates the entry
- *
- **/
-static GDataEntry*
-gdata_google_service_update_entry_with_link (GDataService *service, GDataEntry *entry, const gchar *edit_link, GError **error)
-{
- GDataGoogleServiceAuth *auth;
- GDataGoogleServicePrivate *priv;
- SoupSession *soup_session;
- SoupMessage *msg;
- gchar *entry_xml;
- GDataEntry *updated_entry = NULL;
-
- g_return_val_if_fail (service != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_GOOGLE_SERVICE (service), NULL);
- g_return_val_if_fail (edit_link != NULL, NULL);
-
- if (!service_is_authenticated( GDATA_GOOGLE_SERVICE(service) )) {
- if (FALSE == gdata_google_service_authenticate(GDATA_GOOGLE_SERVICE(service), error))
- return NULL;
- }
-
- entry_xml = gdata_entry_generate_xml (entry);
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE (GDATA_GOOGLE_SERVICE(service));
- auth = (GDataGoogleServiceAuth *)priv->auth;
- soup_session = (SoupSession *)priv->soup_session;
-
- msg = soup_message_new (SOUP_METHOD_PUT, edit_link);
-
- soup_message_headers_append (msg->request_headers,
- "Authorization",
- (gchar *)g_strdup_printf ("GoogleLogin auth=%s",
- auth->token));
-
- soup_message_set_request (msg,
- "application/atom+xml",
- SOUP_MEMORY_COPY,
- entry_xml,
- strlen(entry_xml));
-
- /* Handle redirects ourself */
- send_and_handle_google_redirection (soup_session, msg);
-
- if (msg->status_code != 200) {
- g_set_error (error, SOUP_HTTP_ERROR,
- msg->status_code, "%s", msg->reason_phrase);
- g_object_unref (msg);
- return updated_entry;
- }
-
- if (msg->response_body->data && strlen (msg->response_body->data) > 0) {
- updated_entry = gdata_entry_new_from_xml (msg->response_body->data);
- }
-
- if (NULL == updated_entry) {
- g_set_error (error, GDATA_GOOGLE_ERROR,
- -1, "GData protocol error");
- }
-
- g_object_unref (msg);
- return updated_entry;
-}
-
-static void
-gdata_google_service_iface_init (GDataServiceIface *iface)
-{
- iface->set_proxy = gdata_google_service_set_proxy;
- iface->set_credentials = gdata_google_service_set_credentials;
- iface->get_feed = gdata_google_service_get_feed;
- iface->insert_entry = gdata_google_service_insert_entry;
- iface->delete_entry = gdata_google_service_delete_entry;
- iface->update_entry = gdata_google_service_update_entry;
- iface->update_entry_with_link = gdata_google_service_update_entry_with_link;
- return;
-}
-
-static void
-gdata_google_service_init (GDataGoogleService *instance)
-{
- GDataGoogleServicePrivate *priv;
- GDataGoogleService *self = instance;
-
- /* Private data set by g_type_class_add_private */
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(self);
- priv->dispose_has_run = FALSE;
-
- priv->name = NULL;
- priv->agent = NULL;
-
- priv->auth = g_new0(GDataGoogleServiceAuth,1);
- priv->auth->username = NULL;
- priv->auth->password = NULL;
- priv->auth->token = NULL;
-
- priv->soup_session = soup_session_sync_new();
-}
-
-static void gdata_google_service_dispose(GObject *obj)
-{
- GObjectClass *parent_class;
- GDataGoogleServiceClass *klass;
-
- GDataGoogleService *self = (GDataGoogleService *)obj;
- GDataGoogleServicePrivate *priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(self);
-
- if (priv->dispose_has_run) {
- /* Don't run dispose twice */
- return;
- }
- priv->dispose_has_run = TRUE;
-
- if (priv->soup_session) {
- g_object_unref (priv->soup_session);
- priv->soup_session = NULL;
- }
-
- /* Chain up to the parent class */
- klass = GDATA_GOOGLE_SERVICE_CLASS(g_type_class_peek(GDATA_TYPE_GOOGLE_SERVICE));
- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-
- parent_class->dispose(obj);
-}
-
-static void gdata_google_service_finalize(GObject *obj)
-{
- GDataGoogleServicePrivate *priv;
- GDataGoogleServiceAuth *auth;
- GDataGoogleService *self = GDATA_GOOGLE_SERVICE(obj);
- GObjectClass *parent_class;
- GDataGoogleServiceClass *klass;
-
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(self);
- auth = (GDataGoogleServiceAuth *)priv->auth;
-
- if (priv->name != NULL)
- g_free(priv->name);
-
- if (priv->agent != NULL)
- g_free(priv->agent);
-
- if (auth->username != NULL)
- g_free(auth->username);
-
- if (auth->password)
- g_free(auth->password);
-
- if (auth->token != NULL) {
- g_free(auth->token);
- }
- g_free(auth);
-
- /* Chain up to the parent class */
- klass = GDATA_GOOGLE_SERVICE_CLASS(g_type_class_peek(GDATA_TYPE_GOOGLE_SERVICE));
- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
- parent_class->finalize(obj);
-}
-
-static void gdata_google_service_get_property (GObject *obj,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GDataGoogleServicePrivate *priv;
-
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(obj);
-
- switch (property_id) {
- case PROP_NAME:
- g_value_set_string(value, priv->name);
- break;
- case PROP_AGENT:
- g_value_set_string(value, priv->name);
- break;
- default:
- /* Invalid Property */
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
- break;
- }
-}
-
-static void gdata_google_service_set_property (GObject *obj,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GDataGoogleServicePrivate *priv;
- GDataGoogleService *self = (GDataGoogleService *) obj;
-
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(self);
-
- switch (property_id) {
- case PROP_NAME:
- if (priv->name != NULL)
- g_free(priv->name);
- priv->name = g_value_dup_string(value);
- break;
- case PROP_AGENT:
- if (priv->agent != NULL)
- g_free(priv->agent);
- priv->agent = g_value_dup_string(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
- break;
- }
-}
-
-static void gdata_google_service_class_init (GDataGoogleServiceClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
- g_type_class_add_private(klass, sizeof (GDataGoogleServicePrivate));
-
- gobject_class->set_property = gdata_google_service_set_property;
- gobject_class->get_property = gdata_google_service_get_property;
- gobject_class->dispose = gdata_google_service_dispose;
- gobject_class->finalize = gdata_google_service_finalize;
-
- g_object_class_install_property(gobject_class, PROP_NAME,
- g_param_spec_string("name", "Name",
- "The name (e.g. 'cl') of the service",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property(gobject_class, PROP_AGENT,
- g_param_spec_string("agent", "Agent",
- "The agent (e.g 'evolution', 'tinymail') of the calling program",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
-
- return;
-}
-
-/*********API******* */
-
-/**
- *
- * gdata_google_service_new:
- * @service_name
- * @agent
- * Returns a new #GDataGoogleService Object
- *
- **/
-GDataGoogleService *
-gdata_google_service_new(const gchar *service_name, const gchar *agent)
-{
- return g_object_new(GDATA_TYPE_GOOGLE_SERVICE,
- "name", service_name,
- "agent",agent,
- NULL);
-}
-
-gboolean
-gdata_google_service_authenticate (GDataGoogleService *service, GError **error)
-{
- GDataGoogleServicePrivate *priv;
- GDataGoogleServiceAuth *auth;
- SoupMessage *msg;
- GHashTable *request_form;
- gchar *request_body;
- gchar *token = NULL;
-
- priv = GDATA_GOOGLE_SERVICE_GET_PRIVATE(service);
- auth = (GDataGoogleServiceAuth *)priv->auth;
-
- request_form = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (request_form, (gpointer) "Email", auth->username);
- g_hash_table_insert (request_form, (gpointer) "Passwd", auth->password);
- g_hash_table_insert (request_form, (gpointer) "service", priv->name);
- g_hash_table_insert (request_form, (gpointer) "source", priv->agent);
- g_hash_table_insert (request_form, (gpointer) "accountType", (gpointer) "HOSTED_OR_GOOGLE");
- request_body = soup_form_encode_hash (request_form);
- g_hash_table_destroy (request_form);
-
- msg = soup_message_new(SOUP_METHOD_POST, GOOGLE_CLIENT_LOGIN);
- soup_message_set_http_version(msg, SOUP_HTTP_1_0);
- soup_message_set_request (msg, "application/x-www-form-urlencoded",
- SOUP_MEMORY_TAKE,
- request_body, strlen(request_body));
-
- soup_session_send_message (priv->soup_session, msg);
-
- if (msg->status_code != 200) {
- g_set_error (error, SOUP_HTTP_ERROR,
- msg->status_code, "%s", msg->reason_phrase);
- g_object_unref(msg);
- return (NULL != token);
- }
- if (msg->response_body->data && strlen (msg->response_body->data) > 0) {
- gchar *auth_begin = NULL;
- gchar *auth_end = NULL;
-
- auth_begin = strstr(msg->response_body->data, "Auth=");
-
- if (!auth_begin) {
- return (NULL != token);
- }
-
- auth_end = strstr(auth_begin, "\n") - 5;
-
- if (auth_begin && strlen(auth_begin) > 5) {
- token = g_strndup(auth_begin + strlen("Auth="), auth_end - auth_begin);
- }
- }
-
- auth->token = token;
- if (NULL == token) {
- g_set_error (error, GDATA_GOOGLE_ERROR,
- -1, "GData protocol error");
- }
-
- return (NULL != token);
-}
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- * Ebby Wiselyn <ebbywiselyn@gmail.com>
- * Jason Willis <zenbrother@gmail.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef _GDATA_GOOGLE_SERVICE_H_
-#define _GDATA_GOOGLE_SERVICE_H_
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include "gdata-feed.h"
-#include "gdata-entry.h"
-
-G_BEGIN_DECLS
-
-#define GDATA_TYPE_GOOGLE_SERVICE (gdata_google_service_get_type())
-#define GDATA_GOOGLE_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GDATA_TYPE_GOOGLE_SERVICE, GDataGoogleService))
-#define GDATA_GOOGLE_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GDATA_TYPE_GOOGLE_SERVICE, GDataGoogleServiceClass))
-#define GDATA_IS_GOOGLE_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GDATA_TYPE_GOOGLE_SERVICE))
-#define GDATA_IS_GOOGLE_SERVICE_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE((klass), GDATA_TYPE_GOOGLE_SERVICE))
-#define GDATA_GOOGLE_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), GDATA_TYPE_GOOGLE_SERVICE, GDataGoogleServiceClass))
-
-#define GDATA_GOOGLE_ERROR gdata_google_error_quark ()
-
-typedef struct _GDataGoogleService GDataGoogleService;
-typedef struct _GDataGoogleServiceClass GDataGoogleServiceClass;
-typedef struct _GDataGoogleServicePrivate GDataGoogleServicePrivate;
-
-struct _GDataGoogleService {
- GObject parent;
-
- /* private */
-
-};
-
-struct _GDataGoogleServiceClass {
- GObjectClass parent_class;
-
- /* Public Methods - Inherited from GDATA_SERVICE_IFACE */
-};
-
-GType gdata_google_service_get_type(void);
-GQuark gdata_google_error_quark(void);
-
-/**API******/
-
-GDataGoogleService * gdata_google_service_new(const gchar *serviceName, const gchar *agent);
-gboolean gdata_google_service_authenticate (GDataGoogleService *service, GError **error);
-
-G_END_DECLS
-
-#endif
-
+++ /dev/null
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-
-privincludedir=@privincludedir@
-
-Name: libgdata-google
-Description: Client library for accessing google POA through SOAP interface
-Version: @VERSION@
-Requires: libsoup-2.4 >= @LIBSOUP_REQUIRED@
-Requires.private: libgdata-1.2
-Libs: -L${libdir} -lgdata-google-1.2
-Cflags: -I${privincludedir}/google/libgdata-google
+++ /dev/null
-lib_LTLIBRARIES = libgdata-1.2.la
-
-libgdata_1_2_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- -DG_LOG_DOMAIN=\"libgdata\" \
- -I$(top_srcdir) \
- -I$(top_builddir) \
- $(GDATA_CFLAGS)
-
-libgdata_1_2_la_SOURCES = \
- gdata-feed.c \
- gdata-feed.h \
- gdata-entry.c \
- gdata-entry.h \
- gdata-service-iface.c \
- gdata-service-iface.h
-
-libgdata_1_2_la_LIBADD = \
- $(GDATA_LIBS)
-
-libgdata_1_2_la_LDFLAGS = \
- -version-info $(LIBGDATA_CURRENT):$(LIBGDATA_REVISION):$(LIBGDATA_AGE) $(NO_UNDEFINED)
-
-libgdataincludedir = $(privincludedir)/google/libgdata
-
-libgdatainclude_HEADERS = \
- gdata-feed.h \
- gdata-entry.h \
- gdata-service-iface.h
-
-%-$(API_VERSION).pc: %.pc
- cp $< $@
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libgdata-$(API_VERSION).pc
-
-EXTRA_DIST = $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in)
-
-DISTCLEANFILES = $(pkgconfig_DATA)
-
-
--include $(top_srcdir)/git.mk
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- * Ebby Wiselyn <ebbyw@gnome.org>
- * Jason Willis <zenbrother@gmail.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include <config.h>
-
-/* LibXML2 includes */
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-
-#include <string.h>
-#include <gdata-entry.h>
-
-#define GDATA_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GDATA_TYPE_ENTRY, GDataEntryPrivate))
-
-G_DEFINE_TYPE (GDataEntry, gdata_entry, G_TYPE_OBJECT)
-
-struct _GDataEntryPrivate {
- GSList *authors;
- GSList *categories;
- GSList *links;
- GHashTable *field_table;
- GSList *attendees;
- gchar *location;
- gchar *content;
- gchar *title;
- gchar *reminder;
- gchar *status;
- gchar *visibility;
- gchar *start_time;
- gchar *end_time;
- gchar *send_notification;
- gchar *transparency;
- gchar *id;
-
- gboolean entry_needs_update;
- gboolean has_attendees;
- gchar *entry_xml;
-
- gboolean dispose_has_run;
- gboolean is_recurrent;
-
- /* Contacts Data */
-
- GSList *email_addresses;
- GSList *im_addresses;
- GSList *organizations;
- GSList *phone_numbers;
- GSList *postal_addresses;
- gboolean is_deleted;
-};
-
-static void destroy_authors (gpointer data, gpointer user_data)
-{
- GDataEntryAuthor *author = (GDataEntryAuthor *)data;
- if (author->email != NULL)
- g_free(author->email);
-
- if (author->name != NULL)
- g_free(author->name);
-
- if (author->uri != NULL)
- g_free(author->uri);
-
- g_free(author);
-}
-
-static void destroy_categories (gpointer data, gpointer user_data)
-{
- GDataEntryCategory *category = (GDataEntryCategory *)data;
- if (category->label != NULL)
- g_free(category->label);
-
- if (category->scheme != NULL)
- g_free(category->scheme);
-
- if (category->scheme_prefix != NULL)
- g_free(category->scheme_prefix);
-
- if (category->scheme_suffix != NULL)
- g_free(category->scheme_suffix);
-
- if (category->term != NULL)
- g_free(category->term);
-
- g_free(category);
-}
-
-static void destroy_links (gpointer data, gpointer user_data)
-{
- GDataEntryLink *link = (GDataEntryLink *)data;
- if (link->href != NULL)
- g_free(link->href);
-
- if (link->rel != NULL)
- g_free(link->rel);
-
- if (link->title != NULL)
- g_free(link->title);
-
- if (link->type != NULL)
- g_free(link->type);
-
- g_free(link);
-}
-
-static void destroy_email_address (gpointer data, gpointer user_data)
-{
- GDataEntryEmailAddress *email = data;
- g_free (email->address);
- g_free (email->label);
- g_free (email->rel);
- g_free (email);
-}
-
-static void destroy_im_address (gpointer data, gpointer user_data)
-{
- GDataEntryIMAddress *im = data;
- g_free (im->address);
- g_free (im->protocol);
- g_free (im->label);
- g_free (im->rel);
- g_free (im);
-}
-
-static void destroy_organization (gpointer data, gpointer user_data)
-{
- GDataEntryOrganization *org = data;
- g_free (org->name);
- g_free (org->title);
- g_free (org->label);
- g_free (org->rel);
- g_free (org);
-}
-
-static void destroy_phone_number (gpointer data, gpointer user_data)
-{
- GDataEntryPhoneNumber *phone = data;
- g_free (phone->number);
- g_free (phone->uri);
- g_free (phone->label);
- g_free (phone->rel);
- g_free (phone);
-}
-
-static void destroy_postal_address (gpointer data, gpointer user_data)
-{
- GDataEntryPostalAddress *address = data;
- g_free (address->address);
- g_free (address->label);
- g_free (address->rel);
- g_free (address);
-}
-
-static void gdata_entry_init (GDataEntry *instance)
-{
- GDataEntry *self = instance;
- GDataEntryPrivate *priv;
-
- /* Private data set by g_type_class_add_private */
- priv = GDATA_ENTRY_GET_PRIVATE(self);
- priv->dispose_has_run = FALSE;
- priv->authors = NULL;
- priv->links = NULL;
- priv->categories = NULL;
- priv->content = NULL;
- priv->title = NULL;
- priv->field_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- priv->entry_needs_update = FALSE;
- priv->entry_xml = NULL;
- priv->is_recurrent = FALSE;
-}
-
-static void gdata_entry_dispose (GObject *obj)
-{
- GObjectClass *parent_class;
- GDataEntryClass *klass;
- GDataEntry *self = GDATA_ENTRY(obj);
- GDataEntryPrivate *priv = GDATA_ENTRY_GET_PRIVATE(self);
-
- if (priv->dispose_has_run) {
- /* Don't run dispose twice */
- return;
- }
- priv->dispose_has_run = TRUE;
- /* Chain up to the parent class */
- klass = GDATA_ENTRY_CLASS(g_type_class_peek(GDATA_TYPE_ENTRY));
- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
- parent_class->dispose(obj);
-}
-
-static void gdata_entry_finalize (GObject *obj)
-{
- GDataEntryPrivate *priv;
- GDataEntry *self = GDATA_ENTRY(obj);
- GObjectClass *parent_class;
- GDataEntryClass *klass;
-
- priv = GDATA_ENTRY_GET_PRIVATE(self);
- if (priv->authors != NULL) {
- g_slist_foreach(priv->authors, (GFunc) destroy_authors, NULL);
- g_slist_free(priv->authors);
- }
- if (priv->links != NULL) {
- g_slist_foreach(priv->links, (GFunc) destroy_links, NULL);
- g_slist_free(priv->links);
- }
-
- if (priv->categories != NULL) {
- g_slist_foreach(priv->categories, (GFunc) destroy_categories, NULL);
- g_slist_free(priv->categories);
- }
-
- if (priv->email_addresses != NULL) {
- g_slist_foreach(priv->email_addresses, (GFunc) destroy_email_address, NULL);
- g_slist_free(priv->email_addresses);
- }
-
- if (priv->im_addresses != NULL) {
- g_slist_foreach(priv->im_addresses, (GFunc) destroy_im_address, NULL);
- g_slist_free(priv->im_addresses);
- }
-
- if (priv->organizations != NULL) {
- g_slist_foreach(priv->organizations, (GFunc) destroy_organization, NULL);
- g_slist_free(priv->organizations);
- }
-
- if (priv->phone_numbers != NULL) {
- g_slist_foreach(priv->phone_numbers, (GFunc) destroy_phone_number, NULL);
- g_slist_free(priv->phone_numbers);
- }
-
- if (priv->postal_addresses != NULL) {
- g_slist_foreach(priv->postal_addresses, (GFunc) destroy_postal_address, NULL);
- g_slist_free(priv->postal_addresses);
- }
-
- if (priv->field_table != NULL)
- g_hash_table_destroy(priv->field_table);
-
- if (priv->entry_xml != NULL)
- g_free(priv->entry_xml);
-
- /* Chain up to the parent class */
- klass = GDATA_ENTRY_CLASS(g_type_class_peek(GDATA_TYPE_ENTRY));
- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
- parent_class->finalize(obj);
-}
-
-static void gdata_entry_get_property (GObject *obj,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GDataEntryPrivate *priv;
-
- priv = GDATA_ENTRY_GET_PRIVATE(obj);
-}
-
-static void gdata_entry_set_property (GObject *obj,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GDataEntryPrivate *priv;
- GDataEntry *self = (GDataEntry *) obj;
-
- priv = GDATA_ENTRY_GET_PRIVATE(self);
-}
-
-static void gdata_entry_class_init (GDataEntryClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
- g_type_class_add_private(klass, sizeof (GDataEntryPrivate));
- gobject_class->set_property = gdata_entry_set_property;
- gobject_class->get_property = gdata_entry_get_property;
- gobject_class->dispose = gdata_entry_dispose;
- gobject_class->finalize = gdata_entry_finalize;
-}
-
-/*** API ***/
-static GDataEntryAuthor *
-xmlnode_to_author (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntryAuthor *author;
- xmlChar *value;
-
- author = g_new0(GDataEntryAuthor, 1);
- author->email = NULL;
- author->name = NULL;
- author->uri = NULL;
-
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if (!xmlStrcmp(cur->name, (xmlChar *)"email")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- author->email = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- if (!xmlStrcmp(cur->name, (xmlChar *)"name")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- author->name = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- if (!xmlStrcmp(cur->name, (xmlChar *)"uri")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- author->uri = g_strdup((gchar *)value);
- xmlFree(value);
- }
- cur = cur->next;
- }
-
- return author;
-}
-
-static GDataEntryLink *
-xmlnode_to_link (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntryLink *link;
- xmlChar *value;
-
- link = g_new0(GDataEntryLink, 1);
- link->href = NULL;
- link->rel = NULL;
- link->title = NULL;
- link->type = NULL;
-
- value = xmlGetProp(cur, (xmlChar *)"href");
- if (value) {
- link->href = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"rel");
- if (value) {
- link->rel = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"title");
- if (value) {
- link->title = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"type");
- if (value) {
- link->type = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- return link;
-}
-
-static GDataEntryCategory *
-xmlnode_to_category (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntryCategory *category;
- xmlChar *value;
-
- category = g_new0(GDataEntryCategory, 1);
- category->label = NULL;
- category->scheme = NULL;
- category->scheme_prefix = NULL;
- category->scheme_suffix = NULL;
- category->term = NULL;
-
- value = xmlGetProp(cur, (xmlChar *)"label");
- if (value) {
- category->label = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"scheme");
- if (value) {
- category->scheme = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"term");
- if (value) {
- category->term = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- return category;
-}
-
-static Attendee *
-xmlnode_to_attendee (xmlDocPtr doc, xmlNodePtr cur)
-{
- Attendee *attendee;
- xmlChar *value;
-
- attendee = g_new0 (Attendee, 1);
-
- value = xmlGetProp(cur, (xmlChar *)"email");
- if (value) {
- attendee->attendee_email = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"rel");
- if (value) {
- attendee->attendee_rel = g_strdup((gchar *)value);
- xmlFree (value);
- }
-
- value= xmlGetProp(cur, (xmlChar *)"valueString");
- if (value) {
- attendee->attendee_value = g_strdup((gchar *)value);
- xmlFree (value);
- }
-
- return attendee;
-}
-
-static GDataEntryEmailAddress *
-xmlnode_to_email_address (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntryEmailAddress *email;
- xmlChar *value;
-
- email = g_new0(GDataEntryEmailAddress, 1);
-
- value = xmlGetProp(cur, (xmlChar *)"address");
- if (value) {
- email->address = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"rel");
- if (value) {
- email->rel = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"label");
- if (value) {
- email->label = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"primary");
- if (value) {
- email->primary = TRUE;
- xmlFree(value);
- }
-
- return email;
-}
-
-static GDataEntryIMAddress *
-xmlnode_to_im_address (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntryIMAddress *im;
- xmlChar *value;
-
- im = g_new0(GDataEntryIMAddress, 1);
-
- value = xmlGetProp(cur, (xmlChar *)"address");
- if (value) {
- im->address = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"protocol");
- if (value) {
- im->protocol = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"rel");
- if (value) {
- im->rel = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"label");
- if (value) {
- im->label = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"primary");
- if (value) {
- im->primary = TRUE;
- xmlFree(value);
- }
-
- return im;
-}
-
-static GDataEntryOrganization *
-xmlnode_to_organization (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntryOrganization *org;
- xmlChar *value;
-
- org = g_new0(GDataEntryOrganization, 1);
-
- value = xmlGetProp(cur, (xmlChar *)"rel");
- if (value) {
- org->rel = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"label");
- if (value) {
- org->label = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"primary");
- if (value) {
- org->primary = TRUE;
- xmlFree(value);
- }
-
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if (!xmlStrcmp(cur->name, (xmlChar *)"orgName")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- org->name = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- if (!xmlStrcmp(cur->name, (xmlChar *)"orgTitle")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- org->title = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- cur = cur->next;
- }
-
- return org;
-}
-
-static GDataEntryPhoneNumber *
-xmlnode_to_phone_number (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntryPhoneNumber *phone;
- xmlChar *value;
-
- phone = g_new0(GDataEntryPhoneNumber, 1);
-
- value = xmlGetProp(cur, (xmlChar *)"uri");
- if (value) {
- phone->uri = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"rel");
- if (value) {
- phone->rel = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"label");
- if (value) {
- phone->label = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"primary");
- if (value) {
- phone->primary = TRUE;
- xmlFree(value);
- }
-
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- phone->number = g_strdup((gchar *)value);
- xmlFree(value);
-
- return phone;
-}
-
-static GDataEntryPostalAddress *
-xmlnode_to_postal_address (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntryPostalAddress *address;
- xmlChar *value;
-
- address = g_new0(GDataEntryPostalAddress, 1);
-
- value = xmlGetProp(cur, (xmlChar *)"rel");
- if (value) {
- address->rel = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"label");
- if (value) {
- address->label = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"primary");
- if (value) {
- address->primary = TRUE;
- xmlFree(value);
- }
-
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- address->address = g_strdup((gchar *)value);
- xmlFree(value);
-
- return address;
-}
-
-static xmlNodePtr
-author_to_xmlnode (GDataEntryAuthor *author)
-{
-
- xmlNodePtr author_node;
-
- author_node = xmlNewNode(NULL, (xmlChar *)"author");
- if (author->email)
- xmlNewChild (author_node, NULL, (xmlChar *)"email", (xmlChar *)author->email);
-
- if (author->name)
- xmlNewChild (author_node, NULL, (xmlChar *)"name", (xmlChar *)author->name);
-
- return author_node;
-}
-
-static xmlNodePtr
-link_to_xmlnode (GDataEntryLink *link)
-{
- xmlNodePtr link_node;
- link_node = xmlNewNode(NULL, (xmlChar *)"link");
-
- if (link->href) {
- xmlSetProp (link_node, (xmlChar *)"href", (xmlChar *)link->href);
- }
-
- if (link->rel) {
- xmlSetProp (link_node, (xmlChar *)"rel", (xmlChar *)link->rel);
- }
-
- if (link->title) {
- xmlSetProp (link_node, (xmlChar *)"title", (xmlChar *)link->title);
- }
-
- if (link->type) {
- xmlSetProp (link_node, (xmlChar *)"type", (xmlChar *)link->type);
- }
-
- return link_node;
-}
-
-static xmlNodePtr
-category_to_xmlnode (GDataEntryCategory *category)
-{
- xmlNodePtr category_node;
- category_node = xmlNewNode(NULL, (xmlChar *)"category");
-
- if (category->label) {
- xmlSetProp (category_node, (xmlChar *)"label", (xmlChar *)category->label);
- }
-
- if (category->scheme) {
- xmlSetProp (category_node, (xmlChar *)"scheme", (xmlChar *)category->scheme);
- }
-
- if (category->term) {
- xmlSetProp (category_node, (xmlChar *)"term", (xmlChar *)category->term);
- }
-
- return category_node;
-}
-
-static xmlNodePtr
-email_address_to_xmlnode (GDataEntryEmailAddress *email)
-{
-
- xmlNodePtr email_node;
-
- email_node = xmlNewNode(NULL, (xmlChar *)"email");
- xmlSetNs (email_node, xmlNewNs (email_node, NULL, (xmlChar *)"gd"));
- if (email->address)
- xmlSetProp (email_node, (xmlChar *)"address", (xmlChar *)email->address);
-
- if (email->rel)
- xmlSetProp (email_node, (xmlChar *)"rel", (xmlChar *)email->rel);
-
- if (email->label)
- xmlSetProp (email_node, (xmlChar *)"label", (xmlChar *)email->label);
-
- if (email->primary)
- xmlSetProp (email_node, (xmlChar *)"primary", (xmlChar *)"true");
-
- return email_node;
-}
-
-static xmlNodePtr
-im_address_to_xmlnode (GDataEntryIMAddress *im)
-{
-
- xmlNodePtr im_node;
-
- im_node = xmlNewNode(NULL, (xmlChar *)"im");
- xmlSetNs (im_node, xmlNewNs (im_node, NULL, (xmlChar *)"gd"));
- if (im->address)
- xmlSetProp (im_node, (xmlChar *)"address", (xmlChar *)im->address);
-
- if (im->protocol)
- xmlSetProp (im_node, (xmlChar *)"protocol", (xmlChar *)im->protocol);
-
- if (im->rel)
- xmlSetProp (im_node, (xmlChar *)"rel", (xmlChar *)im->rel);
-
- if (im->label)
- xmlSetProp (im_node, (xmlChar *)"label", (xmlChar *)im->label);
-
- if (im->primary)
- xmlSetProp (im_node, (xmlChar *)"primary", (xmlChar *)"true");
-
- return im_node;
-}
-
-static xmlNodePtr
-organization_to_xmlnode (GDataEntryOrganization *organization)
-{
-
- xmlNodePtr organization_node;
-
- organization_node = xmlNewNode(NULL, (xmlChar *)"organization");
- xmlSetNs (organization_node, xmlNewNs (organization_node, NULL, (xmlChar *)"gd"));
- if (organization->rel)
- xmlSetProp (organization_node, (xmlChar *)"rel", (xmlChar *)organization->rel);
-
- if (organization->label)
- xmlSetProp (organization_node, (xmlChar *)"label", (xmlChar *)organization->label);
-
- if (organization->primary)
- xmlSetProp (organization_node, (xmlChar *)"primary", (xmlChar *)"true");
-
- if (organization->name)
- xmlNewTextChild (organization_node, NULL, (xmlChar *)"orgName", (xmlChar *)organization->name);
-
- if (organization->title)
- xmlNewTextChild (organization_node, NULL, (xmlChar *)"orgTitle", (xmlChar *)organization->title);
-
- return organization_node;
-}
-
-static xmlNodePtr
-phone_number_to_xmlnode (GDataEntryPhoneNumber *number)
-{
-
- xmlNodePtr number_node;
-
- number_node = xmlNewNode(NULL, (xmlChar *)"phoneNumber");
- xmlSetNs (number_node, xmlNewNs (number_node, NULL, (xmlChar *)"gd"));
- if (number->uri)
- xmlSetProp (number_node, (xmlChar *)"uri", (xmlChar *)number->uri);
-
- if (number->rel)
- xmlSetProp (number_node, (xmlChar *)"rel", (xmlChar *)number->rel);
-
- if (number->label)
- xmlSetProp (number_node, (xmlChar *)"label", (xmlChar *)number->label);
-
- if (number->primary)
- xmlSetProp (number_node, (xmlChar *)"primary", (xmlChar *)"true");
-
- if (number->number)
- xmlNodeAddContent(number_node, (xmlChar *)number->number);
-
- return number_node;
-}
-
-static xmlNodePtr
-postal_address_to_xmlnode (GDataEntryPostalAddress *address)
-{
-
- xmlNodePtr address_node;
-
- address_node = xmlNewNode(NULL, (xmlChar *)"postalAddress");
- xmlSetNs (address_node, xmlNewNs (address_node, NULL, (xmlChar *)"gd"));
- if (address->rel)
- xmlSetProp (address_node, (xmlChar *)"rel", (xmlChar *)address->rel);
-
- if (address->label)
- xmlSetProp (address_node, (xmlChar *)"label", (xmlChar *)address->label);
-
- if (address->primary)
- xmlSetProp (address_node, (xmlChar *)"primary", (xmlChar *)"true");
-
- if (address->address)
- xmlNodeAddContent(address_node, (xmlChar *)address->address);
-
- return address_node;
-}
-
-/**
- * gdata_entry_new:
- * Creates a new #GDataEntry.
- **/
-GDataEntry *
-gdata_entry_new (void)
-{
- return g_object_new(GDATA_TYPE_ENTRY, NULL);
-}
-
-/**
- * gdata_entry_get_private:
- * @entry: A #GDataEntry object
- * Returns a #GDataEntryPrivate object
- **/
-GDataEntryPrivate *
-gdata_entry_get_private (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
-
- return priv;
-}
-/**
- * gdata_entry_new_from_xmlptr:
- * @doc: A xml document pointer
- * @ptr: A xml Node pointer
- **/
-GDataEntry *
-gdata_entry_new_from_xmlptr (xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataEntry *entry;
- GDataEntryPrivate *priv;
- xmlChar *value = NULL;
- xmlOutputBufferPtr buf;
- gchar *xmlString;
-
- g_return_val_if_fail(doc != NULL, NULL);
- g_return_val_if_fail(cur != NULL, NULL);
-
- if (xmlStrcmp(cur->name, (xmlChar *)"entry")) {
- return NULL;
- }
-
- entry = gdata_entry_new ();
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- buf = xmlAllocOutputBuffer (NULL);
-
- if (buf == NULL) {
- xmlString = NULL;
- }
- else {
- xmlNodeDumpOutput (buf, NULL, cur, 0, 1, NULL);
- xmlOutputBufferFlush (buf);
-
- if (buf->conv == NULL)
- xmlString = g_strdup ((gchar *)buf->buffer->content);
- else
- xmlString = g_strdup ((gchar *)buf->conv->content);
- xmlOutputBufferClose (buf);
- }
-
- priv->entry_xml = g_strdup (xmlString);
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
-
- if (!xmlStrcmp(cur->name, (xmlChar *)"author")) {
- priv->authors = g_slist_prepend(priv->authors, xmlnode_to_author(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"link")) {
- priv->links = g_slist_prepend(priv->links, xmlnode_to_link(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"category")) {
- priv->categories = g_slist_prepend(priv->categories, xmlnode_to_category(doc, cur));
- }
- else if (!xmlStrcmp (cur->name, (xmlChar *)"where")) {
- priv->location = (gchar *)xmlGetProp (cur, (xmlChar *)"valueString");
- }
- else if (!xmlStrcmp (cur->name, (xmlChar *)"eventStatus")) {
- priv->status = (gchar *)xmlGetProp (cur, (xmlChar *)"value");
- }
- else if (!xmlStrcmp (cur->name, (xmlChar *)"visibility")) {
- priv->visibility = (gchar *)xmlNodeListGetString (doc, cur->xmlChildrenNode, 1);
- }
- else if (!xmlStrcmp (cur->name, (xmlChar *)"when")) {
- priv->start_time = (gchar *)xmlGetProp (cur, (xmlChar *)"startTime");
- priv->end_time = (gchar *)xmlGetProp (cur, (xmlChar *)"endTime");
- }
- else if (!xmlStrcmp (cur->name, (xmlChar *)"recurrence")) {
- priv->is_recurrent = TRUE;
- }
-
- else if (!xmlStrcmp (cur->name, (xmlChar *)"who")) {
- priv->attendees = g_slist_prepend (priv->attendees, xmlnode_to_attendee (doc, cur));
- priv->has_attendees = TRUE;
- }
- else if (!xmlStrcmp (cur->name, (xmlChar *)"sendEventNotifications")) {
- priv->send_notification =(gchar *)xmlGetProp (cur, (xmlChar *)"value");
- }
- else if (!xmlStrcmp (cur->name, (xmlChar *)"comments")) {
- /*FIXME Call _comment_to_xml_node */
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"email")) {
- priv->email_addresses = g_slist_prepend(priv->email_addresses, xmlnode_to_email_address(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"im")) {
- priv->im_addresses = g_slist_prepend(priv->im_addresses, xmlnode_to_im_address(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"organization")) {
- priv->organizations = g_slist_prepend(priv->organizations, xmlnode_to_organization(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"phoneNumber")) {
- priv->phone_numbers = g_slist_prepend(priv->phone_numbers, xmlnode_to_phone_number(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"postalAddress")) {
- priv->postal_addresses = g_slist_prepend(priv->postal_addresses, xmlnode_to_postal_address(doc, cur));
- }
- else if (!xmlStrcmp (cur->name, (xmlChar *)"deleted")) {
- priv->is_deleted = TRUE;
- }
-
- else {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- if (!value)
- value = xmlGetProp (cur, (xmlChar *)"value");
-
- g_hash_table_insert(priv->field_table, g_strdup((gchar *)cur->name),
- g_strdup((gchar *)value));
- xmlFree(value);
- }
- cur = cur->next;
- }
-
- return entry;
-}
-
-/**
- * gdata_entries_new_from_xml:
- * @feed_xml: A xml tree.
- * @length: length of feed_xml
- * Returns the list of all the entries in a feed.
- **/
-/*Returns all the entries from the feed */
-GSList *
-gdata_entries_new_from_xml (const gchar *feed_xml, const gint length)
-{
- GSList *list;
- xmlNodePtr cur;
- xmlDocPtr doc;
-
- list = NULL;
-
- g_return_val_if_fail(feed_xml != NULL && *feed_xml != '\0', NULL);
-
- doc = xmlReadMemory (feed_xml, strlen(feed_xml), "feed.xml", NULL, 0);
- if (doc == NULL)
- return NULL;
-
- cur = xmlDocGetRootElement (doc);
- if (cur == NULL) {
- xmlFree (doc);
- }
-
- cur = cur->xmlChildrenNode;
- while (cur != NULL)
- {
- if (!xmlStrcmp (cur->name, (xmlChar *)"entry")) {
- list = g_slist_prepend (list, gdata_entry_new_from_xmlptr (doc, cur));
- }
- cur = cur->next;
- }
-
- /* Free them */
- xmlFreeDoc (doc);
- xmlFreeNode (cur);
-
- if (list == NULL)
- g_slist_free (list);
-
- return list;
-}
-
-/**
- * gdata_entry_new_from_xml:
- * @entry_xml: the xml tree
- * Returns a GDataEntry object:
- **/
-GDataEntry *
-gdata_entry_new_from_xml (const gchar *entry_xml)
-{
- GDataEntry *entry = NULL;
- xmlDocPtr doc;
- xmlNodePtr cur;
-
- g_return_val_if_fail (entry_xml != NULL && *entry_xml != '\0', NULL);
- doc = xmlReadMemory (entry_xml, strlen(entry_xml), "feed.xml", NULL, 0);
-
- if (doc == NULL)
- return NULL;
-
- cur = xmlDocGetRootElement (doc);
- if (cur == NULL)
- xmlFree (doc);
-
- while (cur != NULL) {
- if (!xmlStrcmp (cur->name,(xmlChar *)"entry"))
- entry = gdata_entry_new_from_xmlptr (doc, cur);
- cur = cur->next;
- }
- /*Free them */
- xmlFreeDoc (doc);
- xmlFreeNode (cur);
-
- if (!GDATA_IS_ENTRY(entry))
- return NULL;
-
- return entry;
-}
-
-/**
- *gdata_entry_generate_xml:
- *@entry: A GDataEntry Object
- *Returns the xml content:
- **/
-gchar *
-gdata_entry_generate_xml (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
- GSList *list;
- xmlChar *xmlString;
- xmlNsPtr ns;
- xmlNodePtr cur, cur_child, root;
- xmlDocPtr doc;
- gint xml_buffer_size;
-
- g_return_val_if_fail(entry !=NULL, NULL);
- g_return_val_if_fail(GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
-
- if (!(priv->entry_xml == NULL || priv->entry_needs_update == TRUE))
- return priv->entry_xml;
-
- /* Construct DOM tree */
- doc = xmlNewDoc ((xmlChar *)"1.0");
- root = xmlNewDocNode (doc, NULL, (xmlChar *)"entry", NULL);
-
- xmlSetProp (root, (xmlChar *)"xmlns", (xmlChar *)"http://www.w3.org/2005/Atom");
- ns = xmlNewNs (root, (xmlChar *)"http://schemas.google.com/g/2005", (xmlChar *)"gd");
- xmlDocSetRootElement (doc, root);
- cur = root;
-
- list = priv->categories;
- while (list) {
- cur_child = category_to_xmlnode(list->data);
- xmlAddChild(root, cur_child);
- list = g_slist_next(list);
- }
-
- list = priv->authors;
- while (list) {
- cur_child = author_to_xmlnode(list->data);
- xmlAddChild(root, cur_child);
- list = g_slist_next(list);
- }
-
- list = priv->links;
- while (list) {
- cur_child = link_to_xmlnode(list->data);
- xmlAddChild(root, cur_child);
- list = g_slist_next(list);
- }
-
- if (priv->status) {
- cur_child = xmlNewChild(root, NULL, (xmlChar *)"eventStatus", NULL);
- xmlSetNs (cur_child, xmlNewNs (cur_child, NULL, (xmlChar *)"gd"));
- xmlSetProp (cur_child, (xmlChar *)"value", (xmlChar *)priv->status);
- }
-
- if (priv->start_time || priv->end_time || priv->reminder) {
- cur_child = xmlNewChild(root, NULL, (xmlChar *)"when", NULL);
- xmlSetNs (cur_child, xmlNewNs (cur_child, NULL, (xmlChar *)"gd"));
- xmlSetProp (cur_child, (xmlChar *)"startTime", (xmlChar *)priv->start_time);
- xmlSetProp (cur_child, (xmlChar *)"endTime", (xmlChar *)priv->end_time);
-
- if (priv->reminder) {
- cur = cur_child;
- cur_child = xmlNewChild(cur, NULL, (xmlChar *)"reminder", (xmlChar *)"");
- xmlSetNs (cur_child, xmlNewNs (cur_child, NULL, (xmlChar *)"gd"));
- xmlSetProp (cur_child->xmlChildrenNode, (xmlChar *)"minutes", (xmlChar *)priv->reminder);
- }
- }
-
- if (priv->location ) {
- cur_child = xmlNewChild(root, NULL, (xmlChar *)"where", NULL);
- xmlSetNs (cur_child, xmlNewNs (cur_child, NULL, (xmlChar *)"gd"));
- xmlSetProp (cur_child, (xmlChar *)"valueString", (xmlChar *)priv->location);
- }
-
- if (priv->content) {
- cur_child = xmlNewChild(root, NULL, (xmlChar *)"content", (xmlChar *)priv->content);
- xmlSetProp (cur_child, (xmlChar *)"type", (xmlChar *)"text");
- }
-
- if (priv->title) {
- cur_child = xmlNewChild(root, NULL, (xmlChar *)"title", (xmlChar *)priv->title);
- xmlSetProp (cur_child, (xmlChar *)"type", (xmlChar *)"text");
- }
-
- list = priv->email_addresses;
- while (list) {
- cur_child = email_address_to_xmlnode(list->data);
- xmlAddChild(root, cur_child);
- list = g_slist_next(list);
- }
-
- list = priv->im_addresses;
- while (list) {
- cur_child = im_address_to_xmlnode(list->data);
- xmlAddChild(root, cur_child);
- list = g_slist_next(list);
- }
-
- list = priv->organizations;
- while (list) {
- cur_child = organization_to_xmlnode(list->data);
- xmlAddChild(root, cur_child);
- list = g_slist_next(list);
- }
-
- list = priv->phone_numbers;
- while (list) {
- cur_child = phone_number_to_xmlnode(list->data);
- xmlAddChild(root, cur_child);
- list = g_slist_next(list);
- }
-
- list = priv->postal_addresses;
- while (list) {
- cur_child = postal_address_to_xmlnode(list->data);
- xmlAddChild(root, cur_child);
- list = g_slist_next(list);
- }
-
- /*
- if (priv->field_table) {
- g_hash_table_foreach (priv->field_table,(GHFunc) _build_hash_table_entries, &root);
- }
- */
-
- xmlDocDumpMemory(doc, &xmlString, &xml_buffer_size);
- g_free (priv->entry_xml);
- priv->entry_xml = g_strdup((gchar *)xmlString);
-
- xmlFree(xmlString);
- xmlFreeDoc(doc);
-
- return priv->entry_xml;
-}
-
-/**
- * gdata_entry_get_id:
- * @entry: A GDataEntry object
- * Returns the id of the Entry:
- **/
-gchar *
-gdata_entry_get_id (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail(entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return g_hash_table_lookup (priv->field_table, "id");
-}
-
-/**
- * gdata_entry_get_visibility:
- * @entry: A GDataEntry object
- * Returns the visibility of the Entry:
- **/
-gchar *
-gdata_entry_get_visibility (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail(entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->visibility;
-}
-
-/**
- * gdata_entry_get_content:
- * @entry: A #GDataEntry object
- * Returns the content of the Entry/Event.
- **/
-gchar *
-gdata_entry_get_content (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry !=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return g_hash_table_lookup (priv->field_table, "content");
-}
-
-/**
- * gdata_entry_get_description:
- * @entry: A #GDataEntry object
- * Returns the description of the Entry.
- **/
-/* Returns the description of the entry */
-gchar *
-gdata_entry_get_description (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry !=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return NULL;
-}
-
-/**
- * gdata_entry_get_copyright:
- * @entry: A #GDataEntry object
- * Returns the copyright of the Entry
- **/
-gchar *
-gdata_entry_get_copyright (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry !=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return g_hash_table_lookup (priv->field_table, "copyright");
-}
-
-/**
- * gdata_entry_get_title:
- * @entry: A #GDataEntry object.
- * Returns the title of the Entry.
- **/
-gchar *
-gdata_entry_get_title (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry !=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return g_hash_table_lookup (priv->field_table, "title");
-}
-
-/**
- * gdata_entry_get_authors:
- * @entry: A #GDataEntry object.
- * Returns the list of authors of entry.
- **/
-GSList *
-gdata_entry_get_authors (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->authors;
-}
-
-/**
- * gdata_entry_get_links:
- * @entry: A #GDataEntry object.
- * Returns the list of links
- **/
-GSList *
-gdata_entry_get_links (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry !=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->links;
-}
-
-/**
- * gdata_entry_get_start_time:
- * @entry: A #GDataEntry object.
- * Returns the starting time of the Event.
- **/
-gchar *
-gdata_entry_get_start_time (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry!=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY(entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- return priv->start_time;
-}
-
-/**
- * gdata_entry_get_transparency:
- * @entry: A #GDataEntry object.
- * Returns the transparency of the Event.
- **/
-gchar *
-gdata_entry_get_transparency (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry!=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY(entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- return priv->transparency;
-}
-
-/**
- * gdata_entry_get_end_time:
- * @entry: A #GDataEntry object.
- * Returns the ending time of the Event.
- **/
-gchar *
-gdata_entry_get_end_time (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY(entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- return priv->end_time;
-}
-
-/**
- * gdata_entry_get_location:
- * @entry: A #GDataEntry object.
- * Returns the location of the Event.
- **/
-gchar *
-gdata_entry_get_location (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- return priv->location;
-}
-
-/**
- * gdata_entry_get_status:
- * @entry: A #GDataEntry object.
- * Returns the status of the Event.
- **/
-gchar *
-gdata_entry_get_status (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail(entry !=NULL, NULL);
- g_return_val_if_fail(GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- return priv->status;
-}
-
-/**
- * gdata_entry_get_categories:
- * @entry: A #GDataEntry object.
- * Returns the status of the Event.
- **/
-GSList *
-gdata_entry_get_categories (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail(entry !=NULL, NULL);
- g_return_val_if_fail(GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- return priv->categories;
-}
-
-/**
- * gdata_entry_get_edit_link:
- * @entry: A #GDataEntry object.
- * Returns the edit link of the entry
- **/
-gchar *
-gdata_entry_get_edit_link (GDataEntry *entry)
-{
- GSList *list;
- GDataEntryLink *link;
- gchar *edit_link = NULL;
-
- g_return_val_if_fail(GDATA_IS_ENTRY(entry), NULL);
- list = gdata_entry_get_links (entry);
-
- while (list) {
- link = list->data;
- if (!g_ascii_strcasecmp (link->rel, "edit")) {
- edit_link = g_strdup(link->href);
- }
- list = g_slist_next (list);
- }
-
- return edit_link;
-}
-
-/**
- * gdata_entry_get_email_addresses:
- * @entry: A #GDataEntry object.
- * Returns the list of emails of entry.
- **/
-GSList *
-gdata_entry_get_email_addresses (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->email_addresses;
-}
-
-/**
- * gdata_entry_get_primary_email_address:
- * @entry: A #GDataEntry object.
- * Returns the the primary email address.
- **/
-GDataEntryEmailAddress *
-gdata_entry_get_primary_email_address (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
- GSList *itr;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
-
- itr = priv->email_addresses;
- while (itr) {
- GDataEntryEmailAddress *email = itr->data;
- if (email->primary)
- return email;
- itr = itr->next;
- }
- return NULL;
-}
-
-/**
- * gdata_entry_get_im_addresses:
- * @entry: A #GDataEntry object.
- * Returns the list of im addresses of entry.
- **/
-GSList *
-gdata_entry_get_im_addresses (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->im_addresses;
-}
-
-/**
- * gdata_entry_get_primary_im_address:
- * @entry: A #GDataEntry object.
- * Returns the the primary im address.
- **/
-GDataEntryIMAddress *
-gdata_entry_get_primary_im_address (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
- GSList *itr;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
-
- itr = priv->im_addresses;
- while (itr) {
- GDataEntryIMAddress *im = itr->data;
- if (im->primary)
- return im;
- itr = itr->next;
- }
- return NULL;
-}
-
-/**
- * gdata_entry_get_organizations:
- * @entry: A #GDataEntry object.
- * Returns the list of organizations of entry.
- **/
-GSList *
-gdata_entry_get_organizations (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->organizations;
-}
-
-/**
- * gdata_entry_get_primary_organization:
- * @entry: A #GDataEntry object.
- * Returns the the primary organization.
- **/
-GDataEntryOrganization *
-gdata_entry_get_primary_organization (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
- GSList *itr;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
-
- itr = priv->organizations;
- while (itr) {
- GDataEntryOrganization *org = itr->data;
- if (org->primary) {
- g_slist_free (itr);
- return org;
- }
- itr = itr->next;
- }
- return NULL;
-}
-
-/**
- * gdata_entry_get_phone_numbers:
- * @entry: A #GDataEntry object.
- * Returns the list of phone numbers of entry.
- **/
-GSList *
-gdata_entry_get_phone_numbers (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->phone_numbers;
-}
-
-/**
- * gdata_entry_get_primary_phone_number:
- * @entry: A #GDataEntry object.
- * Returns the the primary phone number.
- **/
-GDataEntryPhoneNumber *
-gdata_entry_get_primary_phone_number (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
- GSList *itr;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
-
- itr = priv->phone_numbers;
- while (itr) {
- GDataEntryPhoneNumber *number = itr->data;
- if (number->primary)
- return number;
- itr = itr->next;
- }
- return NULL;
-}
-
-/**
- * gdata_entry_get_postal_addresses:
- * @entry: A #GDataEntry object.
- * Returns the list of postal addresses of entry.
- **/
-GSList *
-gdata_entry_get_postal_addresses (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->postal_addresses;
-}
-
-/**
- * gdata_entry_get_primary_postal_address:
- * @entry: A #GDataEntry object.
- * Returns the the primary postal address.
- **/
-GDataEntryPostalAddress *
-gdata_entry_get_primary_postal_address (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
- GSList *itr;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
-
- itr = priv->postal_addresses;
- while (itr) {
- GDataEntryPostalAddress *address = itr->data;
- if (address->primary)
- return address;
- itr = itr->next;
- }
- return NULL;
-}
-
-/**
- * gdata_entry_is_deleted:
- * @entry: A #GDataEntry object.
- * Returns whether this entry is marked (remotely) as deleted.
- **/
-gboolean
-gdata_entry_is_deleted (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail(entry !=NULL, TRUE);
- g_return_val_if_fail(GDATA_IS_ENTRY (entry), TRUE);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- return priv->is_deleted;
-}
-
-/**
- * gdata_entry_set_author:
- * @entry: A #GDataEntry object.
- * @author: A list of authors.
- * Sets the list of authors.
- **/
-void
-gdata_entry_set_author (GDataEntry *entry, GSList *author)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (author !=NULL);
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->authors = author;
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_id:
- * @entry: A #GDataEntry object.
- * @id: Id of the entry.
- * Sets the list of authors.
- **/
-void
-gdata_entry_set_id (GDataEntry *entry, gchar *id)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (id !=NULL);
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->id = g_strdup(id);
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_categories:
- * @entry: A GDataEntry object.
- * @categories: A list of categories.
- * Sets the list of categories of the Entry.
- **/
-void
-gdata_entry_set_categories (GDataEntry *entry, GSList *categories)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail(categories !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->categories = categories;
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_title:
- * @entry: A GDataEntry object.
- * @title: title of the event.
- * Sets the title of the Entry.
- **/
-void
-gdata_entry_set_title (GDataEntry *entry, const gchar *title)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail(title !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY (entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- priv->title = g_strdup(title);
- g_hash_table_insert (priv->field_table, g_strdup("title"), g_strdup(title));
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_content:
- * @entry: A GDataEntry object.
- * @content: The content of the event.
- * Sets the content of the Entry.
- **/
-void
-gdata_entry_set_content (GDataEntry *entry, const gchar *content)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail(content !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->content = g_strdup (content);
- priv->entry_needs_update = TRUE;
- g_hash_table_insert (priv->field_table, g_strdup("content"), g_strdup (content));
-}
-
-/**
- * gdata_entry_set_links:
- * @entry: A GDataEntry object.
- * @links: A list of links associated.
- * Sets the links of the Event.
- **/
-void
-gdata_entry_set_links (GDataEntry *entry, GSList *links)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail( links !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->links = links;
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_status:
- * @entry: A GDataEntry object.
- * @status: The status of the event.
- * Sets the status of the Event.
- **/
-void
-gdata_entry_set_status (GDataEntry *entry, const gchar *status)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail(status!=NULL);
- g_return_if_fail(GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->status = g_strdup (status);
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_sendNotification:
- * @entry: A GDataEntry object.
- * @sendNotification: Whether notification is required.
- * Sets whether notification should be sent by the Event.
- **/
-void
-gdata_entry_set_send_notification (GDataEntry *entry, const gchar *send_notification)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (send_notification!=NULL);
- g_return_if_fail (GDATA_IS_ENTRY (entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->send_notification = g_strdup(send_notification);
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_reminder:
- * @entry: A GDataEntry object.
- * @reminder: The reminder set.
- * Sets the reminder of the Event.
- **/
-void
-gdata_entry_set_reminder (GDataEntry *entry, const gchar *reminder)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail(reminder !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY (entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->reminder = g_strdup (reminder);
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_start_time:
- * @entry: A GDataEntry object.
- * @start_time: The starting time of the event.
- * Sets the starting time of the Event.
- **/
-void
-gdata_entry_set_start_time (GDataEntry *entry, const gchar *start_time)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail(start_time !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->start_time = g_strdup(start_time);
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_end_time:
- * @entry: A GDataEntry object.
- * @end_time: The end time of the event.
- * Sets the end time of the event.
- **/
-void
-gdata_entry_set_end_time (GDataEntry *entry, const gchar *end_time)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail(end_time !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY (entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->end_time = g_strdup(end_time);
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_transparency:
- * @entry: A GDataEntry object.
- * @transparency: Transparency of the Entry.
- * Sets the transparency of the entry.
- **/
-void
-gdata_entry_set_transparency (GDataEntry *entry, const gchar *transparency)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (transparency !=NULL);
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->transparency = g_strdup (transparency);
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_location:
- * @entry: A GDataEntry object.
- * @location: Location of the event.
- * Sets the location of the event.
- **/
-void
-gdata_entry_set_location (GDataEntry *entry, const gchar *location)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (location !=NULL);
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->location = g_strdup (location);
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_create_authors:
- * @entry: A GDataEntry object.
- * @name: The name of the author.
- * @email: The email of the author.
- * Sets the list of authors to the Entry.
- **/
-void
-gdata_entry_create_authors (GDataEntry *entry,
- const gchar *name,
- const gchar *email)
-{
- GDataEntryPrivate *priv;
- GDataEntryAuthor *author;
-
- g_return_if_fail(name !=NULL || email !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY(entry));
-
- author = g_new0 (GDataEntryAuthor, 1);
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
-
- author->name = g_strdup(name);
- author->email = g_strdup(email);
-
- priv->authors = g_slist_prepend(priv->authors, author);
- priv->entry_needs_update = TRUE;
-
-}
-
-/**
- * gdata_entry_create_categories:
- * @entry: A GDataEntry object.
- * @scheme:Scheme.
- * @label:Label.
- * @term: Term.
- * Sets the categories of the Event.
- **/
-void
-gdata_entry_create_categories (GDataEntry *entry,
- const gchar *scheme,
- const gchar *label ,
- const gchar *term)
-{
- GDataEntryPrivate *priv;
- GDataEntryCategory *category;
-
- g_return_if_fail(scheme !=NULL || label !=NULL || term !=NULL);
- g_return_if_fail(GDATA_IS_ENTRY (entry));
-
- category = g_new0(GDataEntryCategory, 1);
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
-
- category->scheme = g_strdup(scheme);
- category->label = g_strdup(label);
- category->term = g_strdup(term);
-
- priv->categories = g_slist_prepend(priv->categories, category);
- priv->entry_needs_update = TRUE;
-}
-
-gboolean
-gdata_entry_is_recurrent (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, 0);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), 0);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return priv->is_recurrent;
-}
-
-GSList *
-gdata_entry_get_attendee_list (GDataEntry *entry)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY(entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- return priv->attendees;
-}
-
-void
-gdata_entry_set_attendee_list (GDataEntry *entry, GSList *attendees)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (entry != NULL);
- g_return_if_fail (GDATA_IS_ENTRY(entry));
- g_return_if_fail (attendees != NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->attendees = attendees;
- priv->has_attendees = TRUE;
-}
-
-/**
- * gdata_entry_set_email_addresses:
- * @entry: A #GDataEntry object.
- * @emails: A list of emails.
- * Sets the list of emails.
- **/
-void
-gdata_entry_set_email_addresses (GDataEntry *entry, GSList *emails)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->email_addresses = emails;
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_im_addresses:
- * @entry: A #GDataEntry object.
- * @ims: A list of im addresses.
- * Sets the list of im addresses.
- **/
-void
-gdata_entry_set_im_addresses (GDataEntry *entry, GSList *ims)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->im_addresses = ims;
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_organizations:
- * @entry: A #GDataEntry object.
- * @orgs: A list of organizations.
- * Sets the list of organizations.
- **/
-void
-gdata_entry_set_organizations (GDataEntry *entry, GSList *orgs)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->organizations = orgs;
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_phone_numbers:
- * @entry: A #GDataEntry object.
- * @numbers: A list of phone numbers.
- * Sets the list of phone numbers.
- **/
-void
-gdata_entry_set_phone_numbers (GDataEntry *entry, GSList *numbers)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->phone_numbers = numbers;
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_set_postal_addresses:
- * @entry: A #GDataEntry object.
- * @addresses: A list of postal addresses.
- * Sets the list of postal addresses.
- **/
-void
-gdata_entry_set_postal_addresses (GDataEntry *entry, GSList *addresses)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (GDATA_IS_ENTRY(entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE(entry);
- priv->postal_addresses = addresses;
- priv->entry_needs_update = TRUE;
-}
-
-/**
- * gdata_entry_get_custom:
- * entry owns the returned pointer and is valid as long as the item is alive
- * and the value isn't changed by gdata_entry_set_custom or other method.
- * Do not use this method if there is direct method for your value!
- **/
-const gchar *
-gdata_entry_get_custom (GDataEntry *entry, const gchar *name)
-{
- GDataEntryPrivate *priv;
-
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- return g_hash_table_lookup (priv->field_table, name);
-}
-
-/**
- * gdata_entry_set_custom:
- * Sets the custom value.
- * Do not use this function when there exists direct method for your value!
- **/
-void
-gdata_entry_set_custom (GDataEntry *entry, const gchar *name, const gchar *value)
-{
- GDataEntryPrivate *priv;
-
- g_return_if_fail (entry != NULL);
- g_return_if_fail (name != NULL);
- g_return_if_fail (GDATA_IS_ENTRY (entry));
-
- priv = GDATA_ENTRY_GET_PRIVATE (entry);
- g_hash_table_insert (priv->field_table, g_strdup (name), g_strdup (value ? value : ""));
-}
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- * Ebby Wiselyn <ebbyw@gnome.org>
- * Jason Willis <zenbrother@gmail.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef _GDATA_ENTRY_H_
-#define _GDATA_ENTRY_H_
-
-#include <glib.h>
-#include <glib-object.h>
-
-/* LibXML2 includes */
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-
-G_BEGIN_DECLS
-
-#define GDATA_TYPE_ENTRY (gdata_entry_get_type())
-#define GDATA_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GDATA_TYPE_ENTRY, GDataEntry))
-#define GDATA_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GDATA_TYPE_ENTRY, GDataEntryClass))
-#define GDATA_IS_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GDATA_TYPE_ENTRY))
-#define GDATA_IS_ENTRY_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE((klass), GDATA_TYPE_ENTRY))
-#define GDATA_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDATA_TYPE_ENTRY, GDataEntryClass))
-
-typedef struct _GDataEntry GDataEntry;
-typedef struct _GDataEntryClass GDataEntryClass;
-typedef struct _GDataEntryPrivate GDataEntryPrivate;
-
-struct _GDataEntry {
-
- GObject parent;
-
- /* private */
- GDataEntryPrivate *priv;
-};
-
-struct _GDataEntryClass {
-
- GObjectClass parent_class;
- /* class members */
-
-};
-
-/* Should be moved under extensions */
-typedef struct _Attendee Attendee;
-struct _Attendee {
- gchar *attendee_email;
- gchar *attendee_rel;
- gchar *attendee_value;
- gchar *attendee_status;
- gchar *attendee_type;
-};
-
-typedef struct _GDataEntryAuthor GDataEntryAuthor;
-struct _GDataEntryAuthor {
- gchar *email;
- gchar *name;
- gchar *uri;
-};
-
-typedef struct _GDataEntryCategory GDataEntryCategory;
-struct _GDataEntryCategory {
- gchar *label;
- gchar *scheme;
- gchar *scheme_prefix;
- gchar *scheme_suffix;
- gchar *term;
-};
-
-typedef struct _GDataEntryLink GDataEntryLink;
-struct _GDataEntryLink {
- gchar *href;
- gint length;
- gchar *rel;
- gchar *title;
- gchar *type;
-};
-
-typedef struct _GDataEntryEmailAddress GDataEntryEmailAddress;
-struct _GDataEntryEmailAddress {
- gchar *address;
- gchar *label;
- gchar *rel;
- gboolean primary;
-};
-
-typedef struct _GDataEntryIMAddress GDataEntryIMAddress;
-struct _GDataEntryIMAddress {
- gchar *address;
- gchar *label;
- gchar *rel;
- gchar *protocol;
- gboolean primary;
-};
-
-typedef struct _GDataEntryOrganization GDataEntryOrganization;
-struct _GDataEntryOrganization {
- gchar *name;
- gchar *title;
- gchar *label;
- gchar *rel;
- gboolean primary;
-};
-
-typedef struct _GDataEntryPhoneNumber GDataEntryPhoneNumber;
-struct _GDataEntryPhoneNumber {
- gchar *number;
- gchar *uri;
- gchar *label;
- gchar *rel;
- gboolean primary;
-};
-
-typedef struct _GDataEntryPostalAddress GDataEntryPostalAddress;
-struct _GDataEntryPostalAddress {
- gchar *address;
- gchar *label;
- gchar *rel;
- gboolean primary;
-};
-
-GType gdata_entry_get_type(void);
-
-/***** API *****/
-
-GDataEntry * gdata_entry_new(void);
-
-GDataEntryPrivate * gdata_entry_get_private (GDataEntry *entry);
-
-GDataEntry * gdata_entry_new_from_xml(const gchar *entryXML);
-
-GDataEntry * gdata_entry_new_from_xmlptr (xmlDocPtr doc, xmlNodePtr cur);
-
-gchar * gdata_entry_generate_xml (GDataEntry *entry);
-
-gchar * gdata_entry_get_id(GDataEntry *entry);
-
-gchar * gdata_entry_get_content(GDataEntry *entry);
-
-gchar * gdata_entry_get_description (GDataEntry *entry);
-
-gchar * gdata_entry_get_copyright (GDataEntry *entry);
-
-gchar * gdata_entry_get_title (GDataEntry *entry);
-
-GSList * gdata_entry_get_authors (GDataEntry *entry);
-
-GSList * gdata_entry_get_links (GDataEntry *links);
-
-gchar * gdata_entry_get_start_time (GDataEntry *entry);
-
-gchar * gdata_entry_get_end_time (GDataEntry *entry);
-
-gchar * gdata_entry_get_location (GDataEntry *entry);
-
-gchar * gdata_entry_get_status (GDataEntry *entry);
-
-gchar * gdata_entry_get_edit_link (GDataEntry *entry);
-
-GSList * gdata_entry_get_categories (GDataEntry *entry);
-
-gchar * gdata_entry_get_start_date (GDataEntry *entry);
-
-gchar * gdata_entry_get_end_date (GDataEntry *entry);
-
-gchar * gdata_entry_get_visibility (GDataEntry *entry);
-
-gchar * gdata_entry_get_transparency (GDataEntry *entry);
-
-GSList * gdata_entry_get_attendee_list (GDataEntry *entry);
-
-GSList * gdata_entries_new_from_xml (const gchar *feedXML, const gint length);
-
-gboolean gdata_entry_is_recurrent (GDataEntry *entry);
-
-void gdata_entry_set_author (GDataEntry *entry, GSList *author);
-
-void gdata_entry_set_phone_numbers (GDataEntry *entry, GSList *phone_numbers);
-
-void gdata_entry_set_categories (GDataEntry *entry, GSList *categories);
-
-void gdata_entry_set_title (GDataEntry *entry, const gchar *title);
-
-void gdata_entry_set_content (GDataEntry *entry, const gchar *content);
-
-void gdata_entry_set_links (GDataEntry *entry, GSList *links);
-
-void gdata_entry_set_status (GDataEntry *entry, const gchar *status);
-
-void gdata_entry_set_send_notification (GDataEntry *entry, const gchar *sendNotification);
-
-void gdata_entry_set_reminder (GDataEntry *entry, const gchar *reminder);
-
-void gdata_entry_set_start_time (GDataEntry *entry, const gchar *start_time);
-
-void gdata_entry_set_end_time (GDataEntry *entry, const gchar *end_time);
-
-void gdata_entry_set_transparency (GDataEntry *entry, const gchar *transparency);
-
-void gdata_entry_set_location (GDataEntry *entry, const gchar *location);
-
-void gdata_entry_create_authors (GDataEntry *entry,const gchar *name, const gchar *email);
-
-void gdata_entry_create_categories (GDataEntry *entry, const gchar *scheme, const gchar *label , const gchar *term);
-
-void gdata_entry_set_id (GDataEntry *entry, gchar *id);
-
-void gdata_entry_set_email_addresses (GDataEntry *entry, GSList *emails);
-
-void gdata_entry_set_im_addresses (GDataEntry *entry, GSList *ims);
-
-void gdata_entry_set_organizations (GDataEntry *entry, GSList *orgs);
-
-void gdata_entry_set_postal_addresses (GDataEntry *entry, GSList *pas);
-
-void gdata_entry_set_attendee_list (GDataEntry *entry, GSList *attendee);
-
-gboolean gdata_entry_is_deleted (GDataEntry *entry);
-
-GSList * gdata_entry_get_email_addresses (GDataEntry *entry);
-
-GSList * gdata_entry_get_im_addresses (GDataEntry *entry);
-
-GSList * gdata_entry_get_organizations (GDataEntry *entry);
-
-GSList * gdata_entry_get_phone_numbers (GDataEntry *entry);
-
-GSList * gdata_entry_get_postal_addresses (GDataEntry *entry);
-
-GDataEntryEmailAddress * gdata_entry_get_primary_email_address (GDataEntry *entry);
-
-GDataEntryIMAddress * gdata_entry_get_primary_im_address (GDataEntry *entry);
-
-GDataEntryOrganization * gdata_entry_get_primary_organization (GDataEntry *entry);
-
-GDataEntryPhoneNumber * gdata_entry_get_primary_phone_number (GDataEntry *entry);
-
-GDataEntryPostalAddress * gdata_entry_get_primary_postal_address (GDataEntry *entry);
-
-const gchar *gdata_entry_get_custom (GDataEntry *entry, const gchar *name);
-void gdata_entry_set_custom (GDataEntry *entry, const gchar *name, const gchar *value);
-
-#endif
-
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- * Ebby Wiselyn <ebbywiselyn@gmail.com>
- * Jason Willis <zenbrother@gmail.com>
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include <config.h>
-
-#include <gdata-feed.h>
-#include <gdata-entry.h>
-
-/* LibXML2 includes */
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-
-#include <string.h>
-
-#define GDATA_FEED_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GDATA_TYPE_FEED, GDataFeedPrivate))
-
-G_DEFINE_TYPE (GDataFeed, gdata_feed, G_TYPE_OBJECT)
-
-struct _GDataFeedAuthor {
- gchar *email;
- gchar *name;
- gchar *uri;
-};
-typedef struct _GDataFeedAuthor GDataFeedAuthor;
-
-struct _GDataFeedCategory {
- gchar *label;
- gchar *scheme;
- gchar *scheme_prefix;
- gchar *scheme_suffix;
- gchar *term;
-};
-typedef struct _GDataFeedCategory GDataFeedCategory;
-
-struct _GDataFeedLink {
- gchar *href;
- gint length;
- gchar *rel;
- gchar *title;
- gchar *type;
-};
-typedef struct _GDataFeedLink GDataFeedLink;
-
-struct _GDataFeedPrivate {
-
- /* feed information */
- GSList *authors;
- GSList *categories;
- GSList *links;
- GSList *entries;
-
- gchar *content;
- gchar *contributor;
- gchar *id;
- gchar *link;
- gchar *published;
- gchar *rights;
- gchar *source;
- gchar *summary;
- gchar *title;
- gchar *updated;
- gchar *timezone;
-
- GHashTable *field_table;
- gchar *feedXML;
-
- gboolean dispose_has_run;
-};
-
-static void destroy_authors(gpointer data, gpointer user_data)
-{
- GDataFeedAuthor *author = (GDataFeedAuthor *)data;
- if (author->email != NULL)
- g_free(author->email);
-
- if (author->name != NULL)
- g_free(author->name);
-
- if (author->uri != NULL)
- g_free(author->uri);
-
- g_free(author);
-}
-
-static void destroy_categories(gpointer data, gpointer user_data)
-{
- GDataFeedCategory *category = (GDataFeedCategory *)data;
- if (category->label != NULL)
- g_free(category->label);
-
- if (category->scheme != NULL)
- g_free(category->scheme);
-
- if (category->scheme_prefix != NULL)
- g_free(category->scheme_prefix);
-
- if (category->scheme_suffix != NULL)
- g_free(category->scheme_suffix);
-
- if (category->term != NULL)
- g_free(category->term);
-
- g_free(category);
-}
-
-static void destroy_links(gpointer data, gpointer user_data)
-{
- GDataFeedLink *link = (GDataFeedLink *)data;
-
- if (link->href != NULL)
- g_free(link->href);
-
- if (link->rel != NULL)
- g_free(link->rel);
-
- if (link->title != NULL)
- g_free(link->title);
-
- if (link->type != NULL)
- g_free(link->type);
-
- g_free(link);
-}
-
-static void destroy_entries(gpointer data, gpointer user_data)
-{
- GDataEntry *entry = GDATA_ENTRY(data);
- g_object_unref(G_OBJECT(entry));
-}
-
-static void
-gdata_feed_init (GDataFeed *instance)
-{
- GDataFeed *self = instance;
- GDataFeedPrivate *priv;
-
- /* Private data set by g_type_class_add_private */
- priv = GDATA_FEED_GET_PRIVATE(self);
- priv->dispose_has_run = FALSE;
-
- priv->content = NULL;
- priv->contributor = NULL;
- priv->id = NULL;
- priv->link = NULL;
- priv->published = NULL;
- priv->rights = NULL;
- priv->source = NULL;
- priv->summary = NULL;
- priv->title = NULL;
- priv->updated = NULL;
- priv->timezone = NULL;
-
- priv->authors = NULL;
- priv->links = NULL;
- priv->categories = NULL;
- priv->entries = NULL;
-
- priv->field_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
- priv->feedXML = NULL;
-}
-
-static void
-gdata_feed_dispose(GObject *obj)
-{
- GObjectClass *parent_class;
- GDataFeedClass *klass;
-
- GDataFeed *self = GDATA_FEED(obj);
- GDataFeedPrivate *priv = GDATA_FEED_GET_PRIVATE(self);
-
- if (priv->dispose_has_run) {
- /* Don't run dispose twice */
- return;
- }
-
- priv->dispose_has_run = TRUE;
-
- /* Chain up to the parent class */
- klass = GDATA_FEED_CLASS(g_type_class_peek(GDATA_TYPE_FEED));
- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-
- parent_class->dispose(obj);
-}
-
-static void
-gdata_feed_finalize(GObject *obj)
-{
- GDataFeedPrivate *priv;
- GDataFeed *self = GDATA_FEED(obj);
-
- GObjectClass *parent_class;
- GDataFeedClass *klass;
-
- priv = GDATA_FEED_GET_PRIVATE(self);
- if (priv->entries != NULL) {
- g_slist_foreach(priv->entries, (GFunc)destroy_entries, NULL);
- g_slist_free(priv->entries);
- }
-
- if (priv->authors != NULL) {
- g_slist_foreach(priv->authors, (GFunc)destroy_authors, NULL);
- g_slist_free(priv->authors);
- }
-
- if (priv->links != NULL) {
- g_slist_foreach(priv->links, (GFunc)destroy_links, NULL);
- g_slist_free(priv->links);
- }
-
- if (priv->categories != NULL) {
- g_slist_foreach(priv->categories, (GFunc)destroy_categories, NULL);
- g_slist_free(priv->categories);
- }
-
- g_free (priv->updated);
- g_free (priv->timezone);
-
- if (priv->field_table != NULL)
- g_hash_table_destroy(priv->field_table);
-
- if (priv->feedXML != NULL)
- g_free(priv->feedXML);
-
- /* Chain up to the parent class */
- klass = GDATA_FEED_CLASS(g_type_class_peek(GDATA_TYPE_FEED));
- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
- parent_class->finalize(obj);
-}
-
-static void
-gdata_feed_get_property (GObject *obj,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GDataFeedPrivate *priv;
-
- priv = GDATA_FEED_GET_PRIVATE(obj);
-
-}
-
-static void
-gdata_feed_set_property (GObject *obj,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GDataFeedPrivate *priv;
- GDataFeed *self = (GDataFeed *) obj;
-
- priv = GDATA_FEED_GET_PRIVATE(self);
-
-}
-
-static GObject * gdata_feed_constructor(GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
-{
- GObject *obj;
-
- GObjectClass *parent_class;
- GDataFeedClass *klass;
-
- /* Chain up to the parent class */
- klass = GDATA_FEED_CLASS(g_type_class_peek(GDATA_TYPE_FEED));
- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-
- obj = parent_class->constructor(type, n_construct_properties, construct_properties);
-
- return obj;
-
-}
-
-static void
-gdata_feed_class_init (GDataFeedClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private(klass, sizeof (GDataFeedPrivate));
-
- gobject_class->set_property = gdata_feed_set_property;
- gobject_class->get_property = gdata_feed_get_property;
-
- gobject_class->dispose = gdata_feed_dispose;
- gobject_class->finalize = gdata_feed_finalize;
- gobject_class->constructor = gdata_feed_constructor;
-}
-
-/*** API ***/
- static GDataFeedAuthor *
-xmlnode_to_author(xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataFeedAuthor *author;
- xmlChar *value;
-
- author = g_new0(GDataFeedAuthor, 1);
- author->email = NULL;
- author->name = NULL;
- author->uri = NULL;
-
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if (!xmlStrcmp(cur->name, (xmlChar *)"email")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- author->email = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- if (!xmlStrcmp(cur->name, (xmlChar *)"name")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- author->name = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- if (!xmlStrcmp(cur->name, (xmlChar *)"uri")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- author->uri = g_strdup((gchar *)value);
- xmlFree(value);
- }
- cur = cur->next;
- }
-
- return author;
-}
-
-static GDataFeedLink *
-xmlnode_to_link(xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataFeedLink *link;
- xmlChar *value;
-
- link = g_new0(GDataFeedLink, 1);
- link->href = NULL;
- link->rel = NULL;
- link->title = NULL;
- link->type = NULL;
-
- value = xmlGetProp(cur, (xmlChar *)"href");
- if (value) {
- link->href = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"rel");
- if (value) {
- link->rel = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"title");
- if (value) {
- link->title = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"type");
- if (value) {
- link->type = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- return link;
-}
-
-static GDataFeedCategory *
-xmlnode_to_category(xmlDocPtr doc, xmlNodePtr cur)
-{
- GDataFeedCategory *category;
- xmlChar *value;
-
- category = g_new0(GDataFeedCategory, 1);
- category->label = NULL;
- category->scheme = NULL;
- category->scheme_prefix = NULL;
- category->scheme_suffix = NULL;
- category->term = NULL;
-
- value = xmlGetProp(cur, (xmlChar *)"label");
- if (value) {
- category->label = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"scheme");
- if (value) {
- category->scheme = g_strdup((gchar *)value);
- xmlFree(value);
- }
-
- value = xmlGetProp(cur, (xmlChar *)"term");
- if (value) {
- category->term = g_strdup((gchar *)value);
- xmlFree(value);
- }
- return category;
-}
-
-static xmlNodePtr
-link_to_xmlnode (GDataFeedLink *link)
-{
- xmlNodePtr cur;
- cur = xmlNewNode (NULL, (xmlChar *)"link");
-
- if (link->href) {
- xmlSetProp (cur, (xmlChar *)"href", (xmlChar *)link->href);
- }
- if (link->rel) {
- xmlSetProp (cur, (xmlChar *)"rel", (xmlChar *)link->rel);
- }
- if (link->title) {
- xmlSetProp (cur, (xmlChar *)"title", (xmlChar *)link->title);
- }
- if (link->type) {
- xmlSetProp (cur, (xmlChar *)"type", (xmlChar *)link->type);
- }
-
- return cur;
-}
-
-static xmlNodePtr
-author_to_xmlnode (GDataFeedAuthor *author)
-{
- xmlNodePtr cur;
- cur = xmlNewNode (NULL, (xmlChar *)"author");
-
- if (author->name)
- xmlNewChild (cur, NULL, (xmlChar *)"name", (xmlChar *)author->name);
-
- if (author->email)
- xmlNewChild (cur, NULL, (xmlChar *)"email", (xmlChar *)author->email);
-
- if (author->uri)
- xmlNewChild (cur, NULL, (xmlChar *)"uri", (xmlChar *)author->uri);
-
- return cur;
-}
-
-static xmlNodePtr
-category_to_xmlnode (GDataFeedCategory *category)
-{
- xmlNodePtr cur;
- cur = xmlNewNode (NULL, (xmlChar *)"category");
-
- if (category->label)
- xmlSetProp (cur, (xmlChar *)"label", (xmlChar *)category->label);
- if (category->scheme)
- xmlSetProp (cur, (xmlChar *)"scheme", (xmlChar *)category->scheme);
-
- return cur;
-}
-
-static xmlNodePtr
-entry_to_xmlnode (GDataEntry *entry)
-{
- xmlDocPtr doc;
- xmlNodePtr cur;
- gchar *xmlEntry;
-
- xmlEntry = gdata_entry_generate_xml (entry);
- doc = xmlReadMemory (xmlEntry, strlen (xmlEntry), "feed.xml", NULL, 0);
- cur = xmlDocGetRootElement (doc);
-
- return cur;
-}
-
-GDataFeed *
-gdata_feed_new(void)
-{
- return g_object_new(GDATA_TYPE_FEED, NULL);
-}
-
-GDataFeed *
-gdata_feed_new_from_xml(const gchar * feedXML, const gint length)
-{
- GDataFeed *feed;
- GDataFeedPrivate *priv;
-
- xmlDocPtr doc;
- xmlNodePtr cur;
-
- xmlChar *value;
- gint value_size;
-
- g_return_val_if_fail(feedXML != NULL && *feedXML != '\0', NULL);
- doc = xmlReadMemory(feedXML, length,
- "feed.xml",
- NULL,
- 0);
-
- if (doc == NULL)
- return NULL;
-
- cur = xmlDocGetRootElement(doc);
- if (cur == NULL) {
- /* Empty */
- xmlFreeDoc(doc);
- return NULL;
- }
-
- if (xmlStrcmp(cur->name, (xmlChar *)"feed")) {
- xmlFreeDoc(doc);
- return NULL;
- }
-
- feed = g_object_new(GDATA_TYPE_FEED, NULL);
- priv = GDATA_FEED_GET_PRIVATE(feed);
-
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
-
- if (!xmlStrcmp(cur->name, (xmlChar *)"author")) {
- priv->authors = g_slist_prepend(priv->authors, xmlnode_to_author(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"link")) {
- priv->links = g_slist_prepend(priv->links, xmlnode_to_link(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"category")) {
- priv->categories = g_slist_prepend(priv->categories, xmlnode_to_category(doc, cur));
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"updated")) {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- priv->updated = g_strdup ((gchar *)value);
- xmlFree(value);
- } else if (!xmlStrcmp(cur->name, (xmlChar *)"timezone")) {
- value = xmlGetProp (cur, (xmlChar *)"value");
- g_free (priv->timezone);
- priv->timezone = g_strdup ((gchar *)value);
- xmlFree (value);
- }
- else if (!xmlStrcmp(cur->name, (xmlChar *)"entry")) {
- priv->entries = g_slist_prepend(priv->entries, gdata_entry_new_from_xmlptr(doc,cur));
- }
- else {
- value = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- g_hash_table_insert(priv->field_table, g_strdup((gchar *)cur->name),
- g_strdup((gchar *)value));
- xmlFree(value);
- }
- cur = cur->next;
- }
-
- xmlDocDumpFormatMemory(doc, &value, &value_size, 1);
- priv->feedXML = g_strdup(feedXML);
-
- xmlFree(value);
- xmlFreeDoc(doc);
-
- return feed;
-}
-
-gchar *
-gdata_feed_generate_xml(GDataFeed *feed)
-{
- GDataFeedPrivate *priv;
- xmlDocPtr doc;
- xmlNodePtr cur;
- xmlNodePtr root;
- xmlNsPtr ns_os, ns_gd, ns_gcal;
- xmlChar *xmlString;
- gint xml_buffer_size;
- GSList *list;
-
- g_return_val_if_fail(feed != NULL, NULL);
- g_return_val_if_fail(GDATA_IS_FEED(feed), NULL);
-
- priv = GDATA_FEED_GET_PRIVATE(feed);
-
- if (!priv->feedXML) {
- doc = xmlNewDoc ((xmlChar *)"1.0");
- root = xmlNewDocNode (doc, NULL, (xmlChar *)"feed", NULL);
-
- xmlSetProp (root, (xmlChar *)"xmlns", (xmlChar *)"http://www.w3.org/2005/Atom");
- ns_os = xmlNewNs (root, (xmlChar *)"http://a9.com/-/spec/opensearchrss/1.0/", (xmlChar *)"openSearch");
- ns_gd = xmlNewNs (root, (xmlChar *)"http://schemas.google.com/g/2005", (xmlChar *)"gd");
- ns_gcal = xmlNewNs (root, (xmlChar *)"http://schemas.google.com/gcal/2005", (xmlChar *)"gCal");
-
- if (priv->id) {
- cur = xmlNewChild (root, NULL, (xmlChar *)"id", NULL);
- xmlNodeSetContent (cur, (xmlChar *)priv->id);
- }
-
- list = priv->categories;
- while (list) {
- cur = category_to_xmlnode (list->data);
- xmlAddChild (root, cur);
- list = g_slist_next (list);
- }
-
- list = priv->links;
- while (list) {
- cur = link_to_xmlnode (list->data);
- xmlAddChild (root, cur);
- list = g_slist_next (list);
- }
-
- list = priv->authors;
- while (list) {
- cur = author_to_xmlnode (list->data);
- xmlAddChild (root, cur);
- list = g_slist_next (list);
- }
-
- list = priv->entries;
- while (list) {
- cur = entry_to_xmlnode (list->data);
- xmlAddChild (root, cur);
- list = g_slist_next (list);
- }
- xmlDocDumpMemory (doc, &xmlString, &xml_buffer_size);
- priv->feedXML = g_strdup ((gchar *)xmlString);
- xmlFree (xmlString);
- xmlFreeDoc (doc);
- return priv->feedXML;
- }
- else {
- return priv->feedXML;
- }
-}
-
-gchar * gdata_feed_get_updated (GDataFeed *feed)
-{
- GDataFeedPrivate *priv;
- priv = GDATA_FEED_GET_PRIVATE (feed);
-
- g_return_val_if_fail (feed !=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_FEED(feed), NULL);
-
- return priv->updated;
-}
-
-GSList *
-gdata_feed_get_entries (GDataFeed *feed)
-{
- GDataFeedPrivate *priv;
- priv = GDATA_FEED_GET_PRIVATE (feed);
-
- g_return_val_if_fail (feed !=NULL, NULL);
- g_return_val_if_fail (GDATA_IS_FEED(feed), NULL);
-
- return priv->entries;
-}
-
-/**
- * gdata_feed_get_timezone:
- * Returned pointer owns the feed, its value is like 'Indian/Christmas'
- **/
-const gchar *
-gdata_feed_get_timezone (GDataFeed *feed)
-{
- GDataFeedPrivate *priv;
-
- g_return_val_if_fail (feed != NULL, NULL);
- g_return_val_if_fail (GDATA_IS_FEED (feed), NULL);
-
- priv = GDATA_FEED_GET_PRIVATE (feed);
-
- return priv->timezone;
-}
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- * Ebby Wiselyn <ebbywiselyn@gmail.com>
- * Jason Willis <zenbrother@gmail.com>
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef _GDATA_FEED_H_
-#define _GDATA_FEED_H_
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define GDATA_TYPE_FEED (gdata_feed_get_type())
-#define GDATA_FEED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GDATA_TYPE_FEED, GDataFeed))
-#define GDATA_FEED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GDATA_TYPE_FEED, GDataFeedClass))
-#define GDATA_IS_FEED(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GDATA_TYPE_FEED))
-#define GDATA_IS_FEED_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE((klass), GDATA_TYPE_FEED))
-#define GDATA_FEED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDATA_TYPE_FEED, GDataFeedClass))
-
-typedef struct _GDataFeed GDataFeed;
-typedef struct _GDataFeedClass GDataFeedClass;
-typedef struct _GDataFeedPrivate GDataFeedPrivate;
-
-struct _GDataFeed {
-
- GObject parent;
-
- /* private */
- GDataFeedPrivate *priv;
-};
-
-struct _GDataFeedClass {
-
- GObjectClass parent_class;
- /* class members */
-
-};
-
-GType gdata_feed_get_type(void);
-
-/*** API ***/
-
-GDataFeed * gdata_feed_new(void);
-
-GDataFeed * gdata_feed_new_from_xml(const gchar *feedXML, const gint length);
-
-gchar * gdata_feed_generate_xml(GDataFeed *feed);
-
-gchar * gdata_feed_get_updated (GDataFeed *feed);
-
-GSList * gdata_feed_get_entries (GDataFeed *feed);
-
-const gchar *gdata_feed_get_timezone (GDataFeed *feed);
-
-#endif
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- * Ebby Wiselyn <ebbywiselyn@gmail.com>
- * Jason Willis <zenbrother@gmail.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include <config.h>
-#include <gdata-service-iface.h>
-
-void
-gdata_service_set_proxy (GDataService *self, SoupURI *proxy)
-{
- GDATA_SERVICE_GET_IFACE(self)->set_proxy(self, proxy);
-}
-
-void
-gdata_service_set_credentials (GDataService *self, const gchar *username, const gchar *password)
-{
- GDATA_SERVICE_GET_IFACE(self)->set_credentials(self, username, password);
-}
-
-GDataFeed*
-gdata_service_get_feed (GDataService *self, const gchar * feedURL, GError **error)
-{
- return GDATA_SERVICE_GET_IFACE(self)->get_feed(self, feedURL, error);
-}
-
-GDataEntry*
-gdata_service_insert_entry (GDataService *self, const gchar *feed_postURL, GDataEntry *entry, GError **error)
-{
- return GDATA_SERVICE_GET_IFACE(self)->insert_entry(self, feed_postURL, entry, error);
-}
-
-GDataEntry*
-gdata_service_get_entry (GDataService *self, const gchar *entry_getURL, GError **error)
-{
- return GDATA_SERVICE_GET_IFACE(self)->get_entry(self, entry_getURL, error);
-}
-
-GDataEntry*
-gdata_service_update_entry (GDataService *self, GDataEntry *entry, GError **error)
-{
- return GDATA_SERVICE_GET_IFACE(self)->update_entry(self, entry, error);
-}
-
-GDataEntry*
-gdata_service_update_entry_with_link (GDataService *self, GDataEntry *entry, gchar *link, GError **error)
-{
- return GDATA_SERVICE_GET_IFACE(self)->update_entry_with_link(self, entry, link, error);
-}
-
-gboolean
-gdata_service_delete_entry (GDataService *self, GDataEntry *entry, GError **error)
-{
- return GDATA_SERVICE_GET_IFACE(self)->delete_entry (self, entry, error);
-}
-
-static void
-gdata_service_base_init (gpointer g_class)
-{
- static gboolean initialized = FALSE;
-
- if (!initialized) {
- /* create interface signals here. */
- initialized = TRUE;
- }
-}
-
-GType
-gdata_service_get_type (void)
-{
- static volatile gsize define_type_id__volatile = 0;
-
- if (g_once_init_enter (&define_type_id__volatile)) {
- static const GTypeInfo info =
- {
- sizeof (GDataServiceIface),
- gdata_service_base_init, /* base_init */
- NULL, /* base_finalize */
- NULL, /* class_init */
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL /* instance_init */
- };
- GType type = g_type_register_static (G_TYPE_INTERFACE, "GDataService", &info, 0);
-
- g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
-
- g_once_init_leave (&define_type_id__volatile, type);
- }
-
- return define_type_id__volatile;
-}
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors :
- * Ebby Wiselyn <ebbywiselyn@gmail.com>
- * Jason Willis <zenbrother@gmail.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * 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 this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef _GDATA_SERVICE_H_
-#define _GDATA_SERVICE_H_
-
-#include <glib.h>
-#include <glib-object.h>
-#include <libsoup/soup.h>
-
-#include "gdata-feed.h"
-#include "gdata-entry.h"
-
-G_BEGIN_DECLS
-
-#define GDATA_TYPE_SERVICE (gdata_service_get_type())
-#define GDATA_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GDATA_TYPE_SERVICE, GDataService))
-#define GDATA_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GDATA_TYPE_SERVICE, GDataServiceClass))
-#define GDATA_IS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GDATA_TYPE_SERVICE))
-#define GDATA_IS_SERVICE_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE((klass), GDATA_TYPE_SERVICE))
-#define GDATA_SERVICE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), GDATA_TYPE_SERVICE, GDataServiceIface))
-
-typedef struct _GDataService GDataService;
-typedef struct _GDataServiceIface GDataServiceIface;
-
-struct _GDataServiceIface {
-
- GTypeInterface parent;
-
- /* Public Methods */
- void (*set_proxy) (GDataService *self, SoupURI *proxy);
- void (*set_credentials)(GDataService *self, const gchar *username, const gchar *password);
- GDataFeed * (*get_feed) (GDataService *self, const gchar *feed_getURL, GError **error);
- GDataEntry* (*insert_entry)(GDataService *self, const gchar *feed_postURL, GDataEntry *entry, GError **error);
- GDataEntry* (*get_entry) (GDataService *self, const gchar *entry_getURL, GError **error);
- GDataEntry* (*update_entry)(GDataService *self, GDataEntry *entry, GError **error);
- GDataEntry* (*update_entry_with_link)(GDataService *self, GDataEntry *entry, const gchar *link, GError **error);
- gboolean (*delete_entry)(GDataService *self, GDataEntry *entry, GError **error);
-};
-
-GType gdata_service_get_type(void);
-
-/* Function Prototypes */
-void gdata_service_set_proxy (GDataService *self, SoupURI *proxy);
-void gdata_service_set_credentials(GDataService *self, const gchar *username, const gchar *password);
-
-GDataFeed* gdata_service_get_feed(GDataService *self, const gchar *feed_getURL, GError **error);
-
-GDataEntry* gdata_service_insert_entry(GDataService *self, const gchar *feed_postURL, GDataEntry *entry, GError **error);
-
-GDataEntry* gdata_service_get_entry(GDataService *self, const gchar *entry_getURL, GError **error);
-
-GDataEntry* gdata_service_update_entry(GDataService *self, GDataEntry *entry, GError **error);
-
-GDataEntry* gdata_service_update_entry_with_link(GDataService *self, GDataEntry *entry, gchar *link, GError **error);
-
-gboolean gdata_service_delete_entry(GDataService *self, GDataEntry *entry, GError **error);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-datarootdir=@datarootdir@
-datadir=@datadir@
-
-privincludedir=@privincludedir@
-
-Name: libgdata
-Description: Client library for accessing google POA through SOAP interface
-Version: @VERSION@
-Requires: libsoup-2.4 >= @LIBSOUP_REQUIRED@
-Libs: -L${libdir} -lgdata-1.2
-Cflags: -I${privincludedir}/google/libgdata