aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2009-07-17 18:08:18 +0800
committerMilan Crha <mcrha@redhat.com>2009-07-17 18:08:18 +0800
commit143695d07f3f23a82b5cb8f7f60ae777e91a3b6c (patch)
treec48ca8b0a17877d29b970a426690856e10c0b79a
parent52c6958571696c8fcce89e021669725be982bcfc (diff)
downloadgsoc2013-evolution-143695d07f3f23a82b5cb8f7f60ae777e91a3b6c.tar.gz
gsoc2013-evolution-143695d07f3f23a82b5cb8f7f60ae777e91a3b6c.tar.zst
gsoc2013-evolution-143695d07f3f23a82b5cb8f7f60ae777e91a3b6c.zip
Bug #583374 - Use CalDAV as Google's calendar backend
-rw-r--r--plugins/google-account-setup/google-source.c166
1 files changed, 103 insertions, 63 deletions
diff --git a/plugins/google-account-setup/google-source.c b/plugins/google-account-setup/google-source.c
index e0655ce6aa..c3cfde8ff2 100644
--- a/plugins/google-account-setup/google-source.c
+++ b/plugins/google-account-setup/google-source.c
@@ -52,6 +52,7 @@
#define CALENDAR_LOCATION "://www.google.com/calendar/feeds/"
#define CALENDAR_DEFAULT_PATH "/private/full"
#define URL_GET_SUBSCRIBED_CALENDARS "://www.google.com/calendar/feeds/default/allcalendars/full"
+#define CALENDAR_CALDAV_URI "caldav://%s@www.google.com/calendar/dav/%s/events"
#define d(x)
@@ -97,6 +98,22 @@ e_plugin_lib_enable (EPluginLib *ep, gint enable)
/********************************************************************************************************************/
+static gchar *
+decode_at_back (const gchar *user)
+{
+ gchar *res, *at;
+
+ g_return_val_if_fail (user != NULL, NULL);
+
+ res = g_strdup (user);
+ while (at = strstr (res, "%40"), at != NULL) {
+ *at = '@';
+ memmove (at + 1, at + 3, strlen (at + 3) + 1);
+ }
+
+ return res;
+}
+
static gboolean
is_email (const gchar *address)
{
@@ -118,7 +135,9 @@ sanitize_user_mail (const gchar *user)
if (!user)
return NULL;
- if (!is_email (user)) {
+ if (strstr (user, "%40") != NULL) {
+ return g_strdup (user);
+ } else if (!is_email (user)) {
return g_strconcat (user, "%40gmail.com", NULL);
} else {
gchar *tmp = g_malloc0 (sizeof (gchar) * (1 + strlen (user) + 2));
@@ -190,12 +209,47 @@ is_default_uri (const gchar *given_uri, const gchar *username)
return res;
}
+static void
+update_source_uris (ESource *source, const gchar *uri)
+{
+ gchar *abs_uri, *tmp, *user_sanitized, *slash;
+ const gchar *user, *feeds;
+
+ g_return_if_fail (source != NULL);
+ g_return_if_fail (uri != NULL);
+
+ /* this also changes an absolute uri */
+ e_source_set_relative_uri (source, uri);
+
+ user = e_source_get_property (source, "username");
+ g_return_if_fail (user != NULL);
+
+ feeds = strstr (uri, "/feeds/");
+ g_return_if_fail (feeds != NULL);
+ feeds += 7;
+
+ user_sanitized = sanitize_user_mail (user);
+ /* no "%40" in the URL path for caldav, really */
+ tmp = decode_at_back (feeds);
+
+ slash = strchr (tmp, '/');
+ if (slash)
+ *slash = '\0';
+
+ abs_uri = g_strdup_printf (CALENDAR_CALDAV_URI, user_sanitized, tmp);
+ e_source_set_absolute_uri (source, abs_uri);
+
+ g_free (abs_uri);
+ g_free (tmp);
+ g_free (user_sanitized);
+}
+
static void init_combo_values (GtkComboBox *combo, const gchar *deftitle, const gchar *defuri);
static void
user_changed (GtkEntry *editable, ESource *source)
{
- gchar *uri;
+ gchar *uri, *eml;
const gchar *user, *ssl;
/* two reasons why set readonly to FALSE:
@@ -203,18 +257,38 @@ user_changed (GtkEntry *editable, ESource *source)
b) we are going to set default uri, which should be always writeable */
e_source_set_readonly (source, FALSE);
- ssl = e_source_get_property (source, "ssl");
user = gtk_entry_get_text (GTK_ENTRY (editable));
+
+ if (user && *user) {
+ /* store the non-encoded email in the "username" property */
+ if (strstr (user, "@") == NULL && strstr (user, "%40") == NULL)
+ eml = g_strconcat (user, "@gmail.com", NULL);
+ else
+ eml = decode_at_back (user);
+ } else {
+ eml = NULL;
+ }
+
+ /* set username first, as it's used in update_source_uris */
+ e_source_set_property (source, "username", eml);
+
+ ssl = e_source_get_property (source, "ssl");
uri = construct_default_uri (user, !ssl || g_str_equal (ssl, "1"));
- e_source_set_relative_uri (source, uri);
+ update_source_uris (source, uri);
g_free (uri);
- e_source_set_property (source, "username", user);
- e_source_set_property (source, "protocol", "google");
- e_source_set_property (source, "auth-domain", "google");
+ /* "setup-username" is used to this plugin only, to keep what user wrote,
+ not what uses the backend */
+ e_source_set_property (source, "setup-username", user);
e_source_set_property (source, "auth", (user && *user) ? "1" : NULL);
e_source_set_property (source, "googlename", NULL);
+ /* delete obsolete properties */
+ e_source_set_property (source, "protocol", NULL);
+ e_source_set_property (source, "auth-domain", NULL);
+
+ g_free (eml);
+
/* we changed user, thus reset the chosen calendar combo too, because
other user means other calendars subscribed */
init_combo_values (GTK_COMBO_BOX (g_object_get_data (G_OBJECT (editable), "CalendarCombo")), _("Default"), NULL);
@@ -361,11 +435,13 @@ cal_combo_changed (GtkComboBox *combo, ESource *source)
/* first set readonly to FALSE, otherwise if TRUE, then e_source_set_readonly does nothing */
e_source_set_readonly (source, FALSE);
- e_source_set_relative_uri (source, uri);
+ update_source_uris (source, uri);
e_source_set_readonly (source, readonly);
e_source_set_property (source, "googlename", title);
- e_source_set_property (source, "protocol", "google");
- e_source_set_property (source, "auth-domain", "google");
+
+ /* delete obsolete properties */
+ e_source_set_property (source, "protocol", NULL);
+ e_source_set_property (source, "auth-domain", NULL);
g_free (title);
g_free (uri);
@@ -393,7 +469,7 @@ retrieve_list_clicked (GtkButton *button, GtkComboBox *combo)
ESource *source;
GDataGoogleService *service;
GDataFeed *feed;
- gchar *password, *tmp;
+ gchar *user, *password, *tmp;
const gchar *username, *ssl;
gchar *get_subscribed_url;
GError *error = NULL;
@@ -410,17 +486,20 @@ retrieve_list_clicked (GtkButton *button, GtkComboBox *combo)
username = e_source_get_property (source, "username");
g_return_if_fail (username != NULL && *username != '\0');
- tmp = g_strdup_printf (_("Enter password for user %s to access list of subscribed calendars."), username);
+ user = decode_at_back (username);
+ tmp = g_strdup_printf (_("Enter password for user %s to access list of subscribed calendars."), user);
password = e_passwords_ask_password (_("Enter password"), "Calendar", "", tmp,
E_PASSWORDS_REMEMBER_NEVER | E_PASSWORDS_REPROMPT | E_PASSWORDS_SECRET | E_PASSWORDS_DISABLE_REMEMBER,
NULL, parent);
g_free (tmp);
- if (!password)
+ if (!password) {
+ g_free (user);
return;
+ }
service = gdata_google_service_new ("cl", "evolution-client-0.0.1");
- gdata_service_set_credentials (GDATA_SERVICE (service), username, password);
+ gdata_service_set_credentials (GDATA_SERVICE (service), user, password);
/* privacy... maybe... */
memset (password, 0, strlen (password));
g_free (password);
@@ -478,7 +557,7 @@ retrieve_list_clicked (GtkButton *button, GtkComboBox *combo)
if (color)
gdk_color_parse (color, &gdkcolor);
- if (default_idx == -1 && is_default_uri (uri, username)) {
+ if (default_idx == -1 && is_default_uri (uri, user)) {
/* have the default uri always NULL and first in the combo */
uri = NULL;
gtk_list_store_insert (store, &iter, 0);
@@ -524,6 +603,7 @@ retrieve_list_clicked (GtkButton *button, GtkComboBox *combo)
}
g_object_unref (service);
+ g_free (user);
}
static void
@@ -538,20 +618,6 @@ retrieve_list_sensitize (GtkEntry *username_entry,
gtk_widget_set_sensitive (button, sensitive);
}
-static void
-ssl_toggled (GtkToggleButton *check, ESource *source)
-{
- g_return_if_fail (check != NULL);
- g_return_if_fail (source != NULL);
-
- if (gtk_toggle_button_get_active (check))
- e_source_set_property (source, "ssl", "1");
- else
- e_source_set_property (source, "ssl", "0");
-
- user_changed (GTK_ENTRY (g_object_get_data (G_OBJECT (check), "username")), source);
-}
-
GtkWidget *
plugin_google (EPlugin *epl,
EConfigHookItemFactoryData *data)
@@ -561,7 +627,6 @@ plugin_google (EPlugin *epl,
ESourceGroup *group;
EUri *euri;
GtkWidget *parent;
- GtkWidget *cssl;
GtkWidget *widget;
GtkWidget *luser;
GtkWidget *user;
@@ -569,8 +634,6 @@ plugin_google (EPlugin *epl,
GtkWidget *combo;
gchar *uri;
const gchar *username;
- const gchar *ssl_prop;
- gboolean ssl_enabled;
gint row;
GtkCellRenderer *renderer;
GtkListStore *store;
@@ -595,37 +658,17 @@ plugin_google (EPlugin *epl,
e_uri_free (euri);
- username = e_source_get_property (source, "username");
-
- ssl_prop = e_source_get_property (source, "ssl");
- if (!ssl_prop || g_str_equal (ssl_prop, "1")) {
- ssl_enabled = TRUE;
- } else {
- ssl_enabled = FALSE;
- }
+ username = e_source_get_property (source, "setup-username");
+ if (!username)
+ username = e_source_get_property (source, "username");
- if (!ssl_prop) {
- e_source_set_property (source, "ssl", "1");
- } else if (ssl_enabled) {
- const gchar *rel_uri = e_source_peek_relative_uri (source);
-
- if (rel_uri && g_str_has_prefix (rel_uri, "http://")) {
- ssl_enabled = FALSE;
- e_source_set_property (source, "ssl", "0");
- }
- }
+ /* google's CalDAV requires SSL, thus forcing it here, and no setup for it */
+ e_source_set_property (source, "ssl", "1");
/* Build up the UI */
parent = data->parent;
row = GTK_TABLE (parent)->nrows;
- cssl = gtk_check_button_new_with_mnemonic (_("Use _SSL"));
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cssl), ssl_enabled);
- gtk_widget_show (cssl);
- gtk_table_attach (GTK_TABLE (parent),
- cssl, 1, 2,
- row + 3, row + 4,
- GTK_FILL, 0, 0, 0);
luser = gtk_label_new_with_mnemonic (_("User_name:"));
gtk_widget_show (luser);
gtk_misc_set_alignment (GTK_MISC (luser), 0.0, 0.5);
@@ -679,9 +722,6 @@ plugin_google (EPlugin *epl,
gtk_table_attach (GTK_TABLE (parent), hbox, 1, 2, row + 2, row + 3, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- g_object_set_data (G_OBJECT (cssl), "username", user);
- g_signal_connect (cssl, "toggled", G_CALLBACK (ssl_toggled), source);
-
g_signal_connect (G_OBJECT (user),
"changed",
G_CALLBACK (user_changed),
@@ -690,7 +730,7 @@ plugin_google (EPlugin *epl,
label = gtk_label_new_with_mnemonic (_("Cal_endar:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_widget_show (label);
- gtk_table_attach (GTK_TABLE (parent), label, 0, 1, row + 4, row + 5, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (parent), label, 0, 1, row + 3, row + 4, GTK_FILL | GTK_EXPAND, 0, 0, 0);
store = gtk_list_store_new (
NUM_COLUMNS,
@@ -727,10 +767,10 @@ plugin_google (EPlugin *epl,
g_signal_connect (user, "changed", G_CALLBACK (retrieve_list_sensitize), label);
g_object_set_data (G_OBJECT (label), "ESource", source);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_widget_set_sensitive (label, FALSE);
+ gtk_widget_set_sensitive (label, username && *username);
gtk_widget_show_all (hbox);
- gtk_table_attach (GTK_TABLE (parent), hbox, 1, 2, row + 4, row + 5, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (parent), hbox, 1, 2, row + 3, row + 4, GTK_FILL | GTK_EXPAND, 0, 0, 0);
return widget;
}