[gthumb] picasaweb: use the oauth2 authentication process



commit fac9f435a899d9de9e0fa2d71f6e6a5675a9365c
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Dec 16 19:06:02 2012 +0100

    picasaweb: use the oauth2 authentication process

 extensions/facebook/facebook-service.c             |   19 +-
 extensions/oauth/oauth2-ask-authorization-dialog.c |   27 +-
 extensions/oauth/oauth2-ask-authorization-dialog.h |    4 +-
 extensions/oauth/web-service.c                     |   13 +
 extensions/oauth/web-service.h                     |   10 +-
 extensions/picasaweb/Makefile.am                   |   14 +-
 extensions/picasaweb/data/ui/Makefile.am           |    3 -
 .../picasaweb/data/ui/export-to-picasaweb.ui       |   28 +-
 .../data/ui/picasa-web-account-chooser.ui          |   77 --
 .../data/ui/picasa-web-account-manager.ui          |  136 ----
 .../data/ui/picasa-web-account-properties.ui       |  202 -----
 extensions/picasaweb/dlg-export-to-picasaweb.c     |  708 ++++--------------
 extensions/picasaweb/dlg-import-from-picasaweb.c   |  730 ++++--------------
 extensions/picasaweb/google-connection.c           |  392 ----------
 extensions/picasaweb/google-connection.h           |   97 ---
 .../picasaweb/picasa-account-chooser-dialog.c      |  165 ----
 .../picasaweb/picasa-account-chooser-dialog.h      |   59 --
 .../picasaweb/picasa-account-manager-dialog.c      |  240 ------
 .../picasaweb/picasa-account-manager-dialog.h      |   58 --
 .../picasaweb/picasa-account-properties-dialog.c   |  221 ------
 .../picasaweb/picasa-account-properties-dialog.h   |   66 --
 extensions/picasaweb/picasa-web-service.c          |  801 +++++++++++++++-----
 extensions/picasaweb/picasa-web-service.h          |   26 +-
 extensions/picasaweb/picasa-web-user.c             |  201 -----
 extensions/picasaweb/picasa-web-user.h             |   74 --
 po/POTFILES.in                                     |   13 -
 26 files changed, 981 insertions(+), 3403 deletions(-)
---
diff --git a/extensions/facebook/facebook-service.c b/extensions/facebook/facebook-service.c
index c5ae554..16b76d4 100644
--- a/extensions/facebook/facebook-service.c
+++ b/extensions/facebook/facebook-service.c
@@ -127,7 +127,7 @@ _facebook_service_add_access_token (FacebookService *self,
 
 
 static char *
-get_access_type_name (WebAuthorizationType access_type)
+get_access_type_name (WebAuthorization access_type)
 {
 	char *name = NULL;
 
@@ -146,7 +146,7 @@ get_access_type_name (WebAuthorizationType access_type)
 
 
 static char *
-facebook_utils_get_authorization_url (WebAuthorizationType access_type)
+facebook_utils_get_authorization_url (WebAuthorization access_type)
 {
 	GHashTable *data_set;
 	GString    *link;
@@ -213,10 +213,20 @@ facebook_utils_parse_response (SoupMessage  *msg,
 		obj = json_node_get_object (*node);
 		if (json_object_has_member (obj, "error")) {
 			JsonObject *error_obj;
+			int         error_code;
 
 			error_obj = json_object_get_object_member (obj, "error");
+			switch (json_object_get_int_member (error_obj, "code")) {
+			case FACEBOOK_SERVICE_ERROR_TOKEN_EXPIRED:
+				error_code = WEB_SERVICE_ERROR_TOKEN_EXPIRED;
+				break;
+			default:
+				error_code = WEB_SERVICE_ERROR_GENERIC;
+				break;
+			}
+
 			*error = g_error_new (WEB_SERVICE_ERROR,
-					      json_object_get_int_member (error_obj, "code"),
+					      error_code,
 					      "%s",
 					      json_object_get_string_member (error_obj, "message"));
 
@@ -333,7 +343,8 @@ facebook_service_get_user_info (WebService          *base,
 	SoupMessage     *msg;
 
 	account = web_service_get_current_account (WEB_SERVICE (self));
-	_facebook_service_set_access_token (self, account->token_secret);
+	if (account != NULL)
+		_facebook_service_set_access_token (self, account->token_secret);
 
 	data_set = g_hash_table_new (g_str_hash, g_str_equal);
 	_facebook_service_add_access_token (self, data_set);
diff --git a/extensions/oauth/oauth2-ask-authorization-dialog.c b/extensions/oauth/oauth2-ask-authorization-dialog.c
index 21cb092..e4bb2f2 100644
--- a/extensions/oauth/oauth2-ask-authorization-dialog.c
+++ b/extensions/oauth/oauth2-ask-authorization-dialog.c
@@ -33,6 +33,7 @@ G_DEFINE_TYPE (OAuth2AskAuthorizationDialog, oauth2_ask_authorization_dialog, GT
 
 /* Signals */
 enum {
+	LOADED,
 	REDIRECTED,
 	LAST_SIGNAL
 };
@@ -51,6 +52,15 @@ oauth2_ask_authorization_dialog_class_init (OAuth2AskAuthorizationDialogClass *k
 {
 	g_type_class_add_private (klass, sizeof (OAuth2AskAuthorizationDialogPrivate));
 
+	oauth2_ask_authorization_dialog_signals[LOADED] =
+		g_signal_new ("loaded",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (OAuth2AskAuthorizationDialogClass, loaded),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
 	oauth2_ask_authorization_dialog_signals[REDIRECTED] =
 		g_signal_new ("redirected",
 			      G_TYPE_FROM_CLASS (klass),
@@ -70,8 +80,16 @@ webkit_view_load_changed_cb (WebKitWebView   *web_view,
 {
 	OAuth2AskAuthorizationDialog *self = user_data;
 
-	if (load_event == WEBKIT_LOAD_REDIRECTED)
+	switch (load_event) {
+	case WEBKIT_LOAD_REDIRECTED:
 		g_signal_emit (self, oauth2_ask_authorization_dialog_signals[REDIRECTED], 0);
+		break;
+	case WEBKIT_LOAD_FINISHED:
+		g_signal_emit (self, oauth2_ask_authorization_dialog_signals[LOADED], 0);
+		break;
+	default:
+		break;
+	}
 }
 
 
@@ -133,3 +151,10 @@ oauth2_ask_authorization_dialog_get_uri (OAuth2AskAuthorizationDialog *self)
 {
 	return webkit_web_view_get_uri (WEBKIT_WEB_VIEW (self->priv->view));
 }
+
+
+const char *
+oauth2_ask_authorization_dialog_get_title (OAuth2AskAuthorizationDialog *self)
+{
+	return webkit_web_view_get_title (WEBKIT_WEB_VIEW (self->priv->view));
+}
diff --git a/extensions/oauth/oauth2-ask-authorization-dialog.h b/extensions/oauth/oauth2-ask-authorization-dialog.h
index 31067ba..2d4f1c5 100644
--- a/extensions/oauth/oauth2-ask-authorization-dialog.h
+++ b/extensions/oauth/oauth2-ask-authorization-dialog.h
@@ -48,13 +48,15 @@ struct _OAuth2AskAuthorizationDialogClass {
 
 	/*< signals >*/
 
-	void  (*redirected)  (OAuth2AskAuthorizationDialog *self);
+	void  (*loaded)		(OAuth2AskAuthorizationDialog *self);
+	void  (*redirected)	(OAuth2AskAuthorizationDialog *self);
 };
 
 GType          oauth2_ask_authorization_dialog_get_type     (void);
 GtkWidget *    oauth2_ask_authorization_dialog_new          (const char                   *url);
 GtkWidget *    oauth2_ask_authorization_dialog_get_view     (OAuth2AskAuthorizationDialog *self);
 const char *   oauth2_ask_authorization_dialog_get_uri      (OAuth2AskAuthorizationDialog *self);
+const char *   oauth2_ask_authorization_dialog_get_title    (OAuth2AskAuthorizationDialog *self);
 
 G_END_DECLS
 
diff --git a/extensions/oauth/web-service.c b/extensions/oauth/web-service.c
index dfac32c..0c7aba4 100644
--- a/extensions/oauth/web-service.c
+++ b/extensions/oauth/web-service.c
@@ -87,6 +87,7 @@ struct _WebServicePrivate
 	OAuthAccount       *account;
 	GtkWidget          *browser;
 	GtkWidget          *dialog;
+	GtkWidget          *auth_dialog;
 };
 
 
@@ -307,6 +308,7 @@ web_service_init (WebService *self)
 	self->priv->cancellable = NULL;
 	self->priv->browser = NULL;
 	self->priv->dialog = NULL;
+	self->priv->auth_dialog = NULL;
 }
 
 
@@ -702,6 +704,7 @@ web_service_account_ready (WebService *self)
 void
 web_service_ask_authorization (WebService *self)
 {
+	web_service_set_current_account (self, NULL);
 	WEB_SERVICE_GET_CLASS (self)->ask_authorization (self);
 }
 
@@ -835,6 +838,9 @@ void
 _web_service_set_auth_dialog (WebService *self,
 			      GtkDialog  *dialog)
 {
+	self->priv->auth_dialog = GTK_WIDGET (dialog);
+	g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer *) &self->priv->auth_dialog);
+
 	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 	if (gtk_widget_get_visible (self->priv->dialog))
 		gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self->priv->dialog));
@@ -850,3 +856,10 @@ _web_service_set_auth_dialog (WebService *self,
 			  G_CALLBACK (ask_authorization_dialog_response_cb),
 			  self);
 }
+
+
+GtkWidget *
+_web_service_get_auth_dialog (WebService *self)
+{
+	return self->priv->auth_dialog;
+}
diff --git a/extensions/oauth/web-service.h b/extensions/oauth/web-service.h
index 8526555..d2c0559 100644
--- a/extensions/oauth/web-service.h
+++ b/extensions/oauth/web-service.h
@@ -27,14 +27,17 @@
 #include "oauth.h"
 
 #define WEB_SERVICE_ERROR web_service_error_quark()
-#define WEB_SERVICE_ERROR_TOKEN_EXPIRED 1
-
 GQuark web_service_error_quark (void);
 
 typedef enum {
+	WEB_SERVICE_ERROR_GENERIC,
+	WEB_SERVICE_ERROR_TOKEN_EXPIRED
+} WebSericeError;
+
+typedef enum {
 	WEB_AUTHORIZATION_READ,
 	WEB_AUTHORIZATION_WRITE
-} WebAuthorizationType;
+} WebAuthorization;
 
 #define WEB_TYPE_SERVICE         (web_service_get_type ())
 #define WEB_SERVICE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), WEB_TYPE_SERVICE, WebService))
@@ -106,6 +109,7 @@ GSimpleAsyncResult *
 SoupMessage *	_web_service_get_message	(WebService		 *self);
 void            _web_service_set_auth_dialog	(WebService		 *self,
 						 GtkDialog               *dialog);
+GtkWidget *     _web_service_get_auth_dialog    (WebService		 *self);
 
 #endif /* WEB_SERVICE_H */
 
diff --git a/extensions/picasaweb/Makefile.am b/extensions/picasaweb/Makefile.am
index 33ce52a..bba1644 100644
--- a/extensions/picasaweb/Makefile.am
+++ b/extensions/picasaweb/Makefile.am
@@ -14,15 +14,7 @@ libpicasaweb_la_SOURCES = 			\
 	dlg-export-to-picasaweb.h		\
 	dlg-import-from-picasaweb.c		\
 	dlg-import-from-picasaweb.h		\
-	google-connection.c			\
-	google-connection.h			\
 	main.c					\
-	picasa-account-chooser-dialog.c		\
-	picasa-account-chooser-dialog.h		\
-	picasa-account-manager-dialog.c		\
-	picasa-account-manager-dialog.h		\
-	picasa-account-properties-dialog.c	\
-	picasa-account-properties-dialog.h	\
 	picasa-album-properties-dialog.c	\
 	picasa-album-properties-dialog.h	\
 	picasa-web-album.c			\
@@ -32,13 +24,11 @@ libpicasaweb_la_SOURCES = 			\
 	picasa-web-service.c			\
 	picasa-web-service.h			\
 	picasa-web-types.h			\
-	picasa-web-user.c			\
-	picasa-web-user.h			\
 	preferences.h
 
-libpicasaweb_la_CFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(LIBSECRET_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
+libpicasaweb_la_CFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(LIBSECRET_CFLAGS) $(JSON_GLIB_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
 libpicasaweb_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
-libpicasaweb_la_LIBADD = $(GTHUMB_LIBS) $(LIBSOUP_LIBS) $(LIBSECRET_LIBS) ../importer/libimporter.la ../export_tools/libexport_tools.la
+libpicasaweb_la_LIBADD = $(GTHUMB_LIBS) $(LIBSOUP_LIBS) $(LIBSECRET_LIBS) $(JSON_GLIB_LIBS) ../importer/libimporter.la ../export_tools/libexport_tools.la
 libpicasaweb_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
 
 extensioninidir = $(extensiondir)
diff --git a/extensions/picasaweb/data/ui/Makefile.am b/extensions/picasaweb/data/ui/Makefile.am
index 5630740..7224618 100644
--- a/extensions/picasaweb/data/ui/Makefile.am
+++ b/extensions/picasaweb/data/ui/Makefile.am
@@ -2,9 +2,6 @@ uidir = $(pkgdatadir)/ui
 ui_DATA = 					\
 	export-to-picasaweb.ui			\
 	import-from-picasaweb.ui		\
-	picasa-web-account-chooser.ui		\
-	picasa-web-account-manager.ui		\
-	picasa-web-account-properties.ui	\
 	picasa-web-album-properties.ui		\
 	picasa-web-export-completed.ui
 EXTRA_DIST = $(ui_DATA)
diff --git a/extensions/picasaweb/data/ui/export-to-picasaweb.ui b/extensions/picasaweb/data/ui/export-to-picasaweb.ui
index b6becd3..e8c0844 100644
--- a/extensions/picasaweb/data/ui/export-to-picasaweb.ui
+++ b/extensions/picasaweb/data/ui/export-to-picasaweb.ui
@@ -3,12 +3,10 @@
   <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkListStore" id="account_liststore">
     <columns>
-      <!-- column-name email -->
-      <column type="gchararray"/>
+      <!-- column-name account -->
+      <column type="GObject"/>
       <!-- column-name name -->
       <column type="gchararray"/>
-      <!-- column-name icon -->
-      <column type="gchararray"/>
     </columns>
   </object>
   <object class="GtkListStore" id="album_liststore">
@@ -45,11 +43,9 @@
             <child>
               <object class="GtkButton" id="close_button">
                 <property name="label">gtk-cancel</property>
-                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="use_stock">True</property>
               </object>
               <packing>
@@ -61,11 +57,9 @@
             <child>
               <object class="GtkButton" id="upload_button">
                 <property name="label" translatable="yes">_Upload</property>
-                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="image">upload_image</property>
                 <property name="use_underline">True</property>
               </object>
@@ -78,11 +72,9 @@
             <child>
               <object class="GtkButton" id="button1">
                 <property name="label">gtk-help</property>
-                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="use_stock">True</property>
               </object>
               <packing>
@@ -178,12 +170,6 @@
                                 <property name="can_focus">False</property>
                                 <property name="model">account_liststore</property>
                                 <child>
-                                  <object class="GtkCellRendererPixbuf" id="cellrenderertext1"/>
-                                  <attributes>
-                                    <attribute name="icon-name">2</attribute>
-                                  </attributes>
-                                </child>
-                                <child>
                                   <object class="GtkCellRendererText" id="cellrenderertext3"/>
                                   <attributes>
                                     <attribute name="text">1</attribute>
@@ -198,16 +184,14 @@
                             </child>
                             <child>
                               <object class="GtkButton" id="edit_accounts_button">
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
-                                <property name="use_action_appearance">False</property>
                                 <child>
                                   <object class="GtkImage" id="image2">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="stock">gtk-edit</property>
+                                    <property name="icon_name">view-list-symbolic</property>
                                   </object>
                                 </child>
                               </object>
@@ -368,16 +352,14 @@
                             <property name="spacing">6</property>
                             <child>
                               <object class="GtkButton" id="add_album_button">
-                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
-                                <property name="use_action_appearance">False</property>
                                 <child>
                                   <object class="GtkImage" id="image1">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="stock">gtk-add</property>
+                                    <property name="icon_name">list-add-symbolic</property>
                                   </object>
                                 </child>
                               </object>
@@ -416,11 +398,9 @@
                     <child>
                       <object class="GtkCheckButton" id="resize_checkbutton">
                         <property name="label" translatable="yes">_Resize if larger than:</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="xalign">0</property>
                         <property name="draw_indicator">True</property>
diff --git a/extensions/picasaweb/dlg-export-to-picasaweb.c b/extensions/picasaweb/dlg-export-to-picasaweb.c
index f6bf142..0de6238 100644
--- a/extensions/picasaweb/dlg-export-to-picasaweb.c
+++ b/extensions/picasaweb/dlg-export-to-picasaweb.c
@@ -21,18 +21,12 @@
 
 #include <config.h>
 #include <gtk/gtk.h>
-#ifdef HAVE_LIBSECRET
-#include <libsecret/secret.h>
-#endif /* HAVE_LIBSECRET */
 #include <gthumb.h>
+#include <extensions/oauth/oauth.h>
 #include "dlg-export-to-picasaweb.h"
-#include "picasa-account-chooser-dialog.h"
-#include "picasa-account-manager-dialog.h"
-#include "picasa-account-properties-dialog.h"
 #include "picasa-album-properties-dialog.h"
 #include "picasa-web-album.h"
 #include "picasa-web-service.h"
-#include "picasa-web-user.h"
 #include "preferences.h"
 
 
@@ -41,9 +35,8 @@
 
 
 enum {
-	ACCOUNT_EMAIL_COLUMN,
-	ACCOUNT_NAME_COLUMN,
-	ACCOUNT_ICON_COLUMN
+	ACCOUNT_DATA_COLUMN,
+	ACCOUNT_NAME_COLUMN
 };
 
 
@@ -66,14 +59,8 @@ typedef struct {
 	GtkWidget        *dialog;
 	GtkWidget        *list_view;
 	GtkWidget        *progress_dialog;
-	GList            *accounts;
-	PicasaWebUser    *user;
-	char             *email;
-	char             *password;
-	char             *challange;
+	PicasaWebService *service;
 	GList            *albums;
-	GoogleConnection *conn;
-	PicasaWebService *picasaweb;
 	PicasaWebAlbum   *album;
 	GCancellable     *cancellable;
 } DialogData;
@@ -84,18 +71,11 @@ destroy_dialog (DialogData *data)
 {
 	if (data->dialog != NULL)
 		gtk_widget_destroy (data->dialog);
-	if (data->conn != NULL)
-		gth_task_completed (GTH_TASK (data->conn), NULL);
+	gth_task_completed (GTH_TASK (data->service), NULL);
 	_g_object_unref (data->cancellable);
 	_g_object_unref (data->album);
-	_g_object_unref (data->picasaweb);
-	_g_object_unref (data->conn);
+	_g_object_unref (data->service);
 	_g_object_list_unref (data->albums);
-	g_free (data->challange);
-	g_free (data->password);
-	g_free (data->email);
-	_g_object_unref (data->user);
-	_g_string_list_free (data->accounts);
 	_g_object_unref (data->builder);
 	_g_object_list_unref (data->file_list);
 	_g_object_unref (data->location);
@@ -120,10 +100,12 @@ completed_messagedialog_response_cb (GtkDialog *dialog,
 
 	case _OPEN_IN_BROWSER_RESPONSE:
 		{
-			GdkScreen *screen;
-			char      *url = NULL;
-			GError    *error = NULL;
+			OAuthAccount *account;
+			GdkScreen    *screen;
+			char         *url = NULL;
+			GError       *error = NULL;
 
+			account = web_service_get_current_account (WEB_SERVICE (data->service));
 			screen = gtk_widget_get_screen (GTK_WIDGET (dialog));
 			gtk_widget_destroy (GTK_WIDGET (dialog));
 
@@ -131,14 +113,13 @@ completed_messagedialog_response_cb (GtkDialog *dialog,
 				if (data->album->alternate_url != NULL)
 					url = g_strdup (data->album->alternate_url);
 				else
-					url = g_strconcat ("http://picasaweb.google.com/";, data->user->id, "/", data->album->id, NULL);
+					url = g_strconcat ("http://picasaweb.google.com/";, account->id, "/", data->album->id, NULL);
 			}
 			else
-				url = g_strconcat ("http://picasaweb.google.com/";, data->user->id, NULL);
+				url = g_strconcat ("http://picasaweb.google.com/";, account->id, NULL);
 
 			if ((url != NULL) && ! gtk_show_uri (screen, url, 0, &error)) {
-				if (data->conn != NULL)
-					gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
+				gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
 				_gtk_error_dialog_from_gerror_run (GTK_WINDOW (data->browser), _("Could not connect to the server"), error);
 				g_clear_error (&error);
 			}
@@ -160,7 +141,7 @@ export_completed_with_success (DialogData *data)
 	GtkBuilder *builder;
 	GtkWidget  *dialog;
 
-	gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
+	gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
 
 	builder = _gtk_builder_new_from_file ("picasa-web-export-completed.ui", "picasaweb");
 	dialog = _gtk_builder_get_widget (builder, "completed_messagedialog");
@@ -190,8 +171,7 @@ post_photos_ready_cb (GObject      *source_object,
 	GError           *error = NULL;
 
 	if (! picasa_web_service_post_photos_finish (picasaweb, result, &error)) {
-		if (data->conn != NULL)
-			gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
+		gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
 		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not upload the files"), error);
 		g_clear_error (&error);
 		return;
@@ -209,13 +189,8 @@ export_dialog_response_cb (GtkDialog *dialog,
 	DialogData *data = user_data;
 
 	switch (response_id) {
-	case GTK_RESPONSE_HELP:
-		show_help_dialog (GTK_WINDOW (data->browser), "gthumb-export-social");
-		break;
-
 	case GTK_RESPONSE_DELETE_EVENT:
 	case GTK_RESPONSE_CANCEL:
-		picasa_web_accounts_save_to_file (data->accounts, data->email);
 		gth_file_list_cancel (GTH_FILE_LIST (data->list_view), (DataFunc) destroy_dialog, data);
 		break;
 
@@ -228,7 +203,9 @@ export_dialog_response_cb (GtkDialog *dialog,
 			int           max_height;
 
 			if (! gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (GET_WIDGET ("albums_treeview"))), &tree_model, &iter)) {
-				gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), FALSE);
+				gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
+								   GTK_RESPONSE_OK,
+								   FALSE);
 				return;
 			}
 
@@ -238,7 +215,7 @@ export_dialog_response_cb (GtkDialog *dialog,
 					    -1);
 
 			gtk_widget_hide (data->dialog);
-			gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
+			gth_task_dialog (GTH_TASK (data->service), FALSE, NULL);
 
 			file_list = gth_file_data_list_to_file_list (data->file_list);
 
@@ -252,7 +229,7 @@ export_dialog_response_cb (GtkDialog *dialog,
 			g_settings_set_int (data->settings, PREF_PICASAWEB_RESIZE_WIDTH, max_width);
 			g_settings_set_int (data->settings, PREF_PICASAWEB_RESIZE_HEIGHT, max_height);
 
-			picasa_web_service_post_photos (data->picasaweb,
+			picasa_web_service_post_photos (data->service,
 							data->album,
 							file_list,
 							max_width,
@@ -272,42 +249,13 @@ export_dialog_response_cb (GtkDialog *dialog,
 
 
 static void
-update_account_list (DialogData *data)
-{
-	GtkTreeIter  iter;
-	int          current_account;
-	int          idx;
-	GList       *scan;
-
-	current_account = 0;
-	gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("account_liststore")));
-	for (scan = data->accounts, idx = 0; scan; scan = scan->next, idx++) {
-		char *account = scan->data;
-
-		if (g_strcmp0 (account, data->email) == 0)
-			current_account = idx;
-
-		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter);
-		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
-				    ACCOUNT_EMAIL_COLUMN, account,
-				    ACCOUNT_NAME_COLUMN, account,
-				    -1);
-	}
-
-	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), current_account);
-}
-
-
-static void
 update_album_list (DialogData *data)
 {
 	GtkTreeIter  iter;
 	GList       *scan;
 	char        *free_space;
 
-	g_return_if_fail (data->user != NULL);
-
-	free_space = g_format_size (data->user->quota_limit - data->user->quota_current);
+	free_space = g_format_size (picasa_web_service_get_free_space (PICASA_WEB_SERVICE (data->service)));
 	gtk_label_set_text (GTK_LABEL (GET_WIDGET ("free_space_label")), free_space);
 	g_free (free_space);
 
@@ -338,389 +286,9 @@ update_album_list (DialogData *data)
 		g_free (n_photos_remaining);
 	}
 
-	gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), FALSE);
-}
-
-
-static void
-show_export_dialog (DialogData *data)
-{
-	update_account_list (data);
-	update_album_list (data);
-	gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-
-	gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (data->browser));
-	gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
-	gtk_window_present (GTK_WINDOW (data->dialog));
-}
-
-
-static void
-list_albums_ready_cb (GObject      *source_object,
-		      GAsyncResult *result,
-		      gpointer      user_data)
-{
-	DialogData       *data = user_data;
-	PicasaWebService *picasaweb = PICASA_WEB_SERVICE (source_object);
-	GError           *error = NULL;
-
-	_g_object_list_unref (data->albums);
-	data->albums = picasa_web_service_list_albums_finish (picasaweb, result, &error);
-	if (error != NULL) {
-		if (data->conn != NULL)
-			gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the album list"), error);
-		g_clear_error (&error);
-		gtk_dialog_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_DELETE_EVENT);
-		return;
-	}
-
-	_g_object_unref (data->user);
-	data->user = g_object_ref (picasa_web_service_get_user (picasaweb));
-	show_export_dialog (data);
-}
-
-
-static void
-get_album_list (DialogData *data)
-{
-	char *user_id;
-
-	gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
-
-	if (data->picasaweb == NULL)
-		data->picasaweb = picasa_web_service_new (data->conn);
-	user_id = google_utils_get_user_id_from_email (data->email);
-	picasa_web_service_list_albums (data->picasaweb,
-					user_id,
-				        data->cancellable,
-				        list_albums_ready_cb,
-				        data);
-
-	g_free (user_id);
-}
-
-
-#ifdef HAVE_LIBSECRET
-static void
-password_store_ready_cb (GObject      *source_object,
-			 GAsyncResult *result,
-			 gpointer      user_data)
-{
-	DialogData *data = user_data;
-
-	secret_password_store_finish (result, NULL);
-	get_album_list (data);
-}
-#endif
-
-
-static void account_properties_dialog (DialogData *data,
-			               const char *email,
-			               GError     *error);
-static void challange_account_dialog  (DialogData *data,
-	        		       GError     *error);
-
-
-static void
-connection_ready_cb (GObject      *source_object,
-		     GAsyncResult *result,
-		     gpointer      user_data)
-{
-	DialogData       *data = user_data;
-	GoogleConnection *conn = GOOGLE_CONNECTION (source_object);
-	GError           *error = NULL;
-
-	if (! google_connection_connect_finish (conn, result, &error)) {
-		if (g_error_matches (error, GOOGLE_CONNECTION_ERROR, GOOGLE_CONNECTION_ERROR_CAPTCHA_REQUIRED)) {
-			challange_account_dialog (data, error);
-			g_clear_error (&error);
-		}
-		else if (g_error_matches (error, GOOGLE_CONNECTION_ERROR, GOOGLE_CONNECTION_ERROR_BAD_AUTHENTICATION)) {
-			account_properties_dialog (data, data->email, error);
-			g_clear_error (&error);
-		}
-		else {
-			if (data->conn != NULL)
-				gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-			_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not connect to the server"), error);
-			g_clear_error (&error);
-			gtk_dialog_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_DELETE_EVENT);
-		}
-		return;
-	}
-
-	if (! g_list_find_custom (data->accounts, data->email, (GCompareFunc) strcmp))
-		data->accounts = g_list_append (data->accounts, g_strdup (data->email));
-
-#ifdef HAVE_LIBSECRET
-	secret_password_store (SECRET_SCHEMA_COMPAT_NETWORK,
-			       NULL,
-			       _("Picasa Web Album"),
-			       data->password,
-			       data->cancellable,
-			       password_store_ready_cb,
-			       data,
-			       "user", data->email,
-			       "server", "picasaweb.google.com",
-			       "protocol", "http",
-			       NULL);
-#else
-	get_album_list (data);
-#endif
-}
-
-
-static void connect_to_server (DialogData *data);
-static void auto_select_account (DialogData *data);
-
-
-static void
-account_properties_dialog_response_cb (GtkDialog *dialog,
-				       int        response_id,
-				       gpointer   user_data)
-{
-	DialogData *data = user_data;
-
-	switch (response_id) {
-	case GTK_RESPONSE_HELP:
-		show_help_dialog (GTK_WINDOW (dialog), "picasaweb-account-properties");
-		break;
-
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		gtk_dialog_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_DELETE_EVENT);
-		break;
-
-	case GTK_RESPONSE_OK:
-		g_free (data->email);
-		g_free (data->password);
-		g_free (data->challange);
-		data->email = g_strdup (picasa_account_properties_dialog_get_email (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		data->password = g_strdup (picasa_account_properties_dialog_get_password (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		data->challange = NULL;
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		connect_to_server (data);
-		break;
-
-	case PICASA_ACCOUNT_PROPERTIES_RESPONSE_CHOOSE:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		g_free (data->email);
-		data->email = NULL;
-		auto_select_account (data);
-		break;
-
-	default:
-		break;
-	}
-}
-
-
-static void
-account_properties_dialog (DialogData *data,
-			   const char *email,
-			   GError     *error)
-{
-	GtkWidget *dialog;
-
-	if (data->conn != NULL)
-		gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-
-	dialog = picasa_account_properties_dialog_new (email, NULL, NULL);
-	picasa_account_properties_dialog_set_error (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog), error);
-	if ((error != NULL) && (data->accounts != NULL) && (data->accounts->next != NULL))
-		picasa_account_properties_dialog_can_choose (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog), TRUE);
-
-	g_signal_connect (dialog,
-			  "delete-event",
-			  G_CALLBACK (gtk_true),
-			  NULL);
-	g_signal_connect (dialog,
-			  "response",
-			  G_CALLBACK (account_properties_dialog_response_cb),
-			  data);
-
-	gtk_window_set_title (GTK_WINDOW (dialog), _("Account"));
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-	gtk_window_present (GTK_WINDOW (dialog));
-}
-
-
-static void
-connect_to_server_step2 (DialogData *data)
-{
-	if ((data->password == NULL) || g_str_equal (data->password, "")) {
-		gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-		account_properties_dialog (data, data->email, NULL);
-	}
-	else {
-		gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
-		google_connection_connect (data->conn,
-					   data->email,
-					   data->password,
-					   data->challange,
-					   data->cancellable,
-					   connection_ready_cb,
-					   data);
-	}
-}
-
-
-#ifdef HAVE_LIBSECRET
-static void
-password_lookup_ready_cb (GObject      *source_object,
-			  GAsyncResult *result,
-			  gpointer      user_data)
-{
-	DialogData *data = user_data;
-	char       *string;
-
-	string = secret_password_lookup_finish (result, NULL);
-	if (string != NULL) {
-		data->password = g_strdup (string);
-		g_free (string);
-	}
-
-	connect_to_server_step2 (data);
-}
-#endif
-
-
-static void
-connect_to_server (DialogData *data)
-{
-	if (data->conn == NULL) {
-		data->conn = google_connection_new (GOOGLE_SERVICE_PICASA_WEB_ALBUM);
-		data->progress_dialog = gth_progress_dialog_new (GTK_WINDOW (data->browser));
-		gth_progress_dialog_add_task (GTH_PROGRESS_DIALOG (data->progress_dialog), GTH_TASK (data->conn));
-	}
-
-#ifdef HAVE_LIBSECRET
-	if (data->password == NULL) {
-		secret_password_lookup (SECRET_SCHEMA_COMPAT_NETWORK,
-				        data->cancellable,
-				        password_lookup_ready_cb,
-				        data,
-				        "user", data->email,
-				        "server", "picasaweb.google.com",
-				        "protocol", "http",
-				        NULL);
-		return;
-	}
-#endif
-
-	connect_to_server_step2 (data);
-}
-
-
-static void
-challange_account_dialog_response_cb (GtkDialog *dialog,
-				      int        response_id,
-				      gpointer   user_data)
-{
-	DialogData *data = user_data;
-
-	switch (response_id) {
-	case GTK_RESPONSE_HELP:
-		show_help_dialog (GTK_WINDOW (dialog), "picasaweb-account-challange");
-		break;
-
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		gtk_dialog_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_DELETE_EVENT);
-		break;
-
-	case GTK_RESPONSE_OK:
-		g_free (data->email);
-		g_free (data->password);
-		data->email = g_strdup (picasa_account_properties_dialog_get_email (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		data->password = g_strdup (picasa_account_properties_dialog_get_password (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		data->challange = g_strdup (picasa_account_properties_dialog_get_challange (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		connect_to_server (data);
-		break;
-
-	case PICASA_ACCOUNT_PROPERTIES_RESPONSE_CHOOSE:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		g_free (data->email);
-		data->email = NULL;
-		auto_select_account (data);
-		break;
-
-	default:
-		break;
-	}
-}
-
-
-static void
-challange_account_dialog (DialogData *data,
-			  GError     *error)
-{
-	GtkWidget *dialog;
-
-	if (data->conn != NULL)
-		gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-
-	dialog = picasa_account_properties_dialog_new (data->email, data->password, google_connection_get_challange_url (data->conn));
-	picasa_account_properties_dialog_set_error (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog), error);
-	if ((error != NULL) && (data->accounts != NULL) && (data->accounts->next != NULL))
-		picasa_account_properties_dialog_can_choose (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog), TRUE);
-
-	g_signal_connect (dialog,
-			  "delete-event",
-			  G_CALLBACK (gtk_true),
-			  NULL);
-	g_signal_connect (dialog,
-			  "response",
-			  G_CALLBACK (challange_account_dialog_response_cb),
-			  data);
-
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-	gtk_window_present (GTK_WINDOW (dialog));
-}
-
-
-static void
-account_chooser_dialog_response_cb (GtkDialog *dialog,
-				    int        response_id,
-				    gpointer   user_data)
-{
-	DialogData *data = user_data;
-
-	switch (response_id) {
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		gtk_dialog_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_DELETE_EVENT);
-		break;
-
-	case GTK_RESPONSE_OK:
-		g_free (data->password);
-		data->password = NULL;
-		g_free (data->challange);
-		data->challange = NULL;
-		g_free (data->email);
-		data->email = picasa_account_chooser_dialog_get_active (PICASA_ACCOUNT_CHOOSER_DIALOG (dialog));
-		if (data->email != NULL) {
-			gtk_widget_destroy (GTK_WIDGET (dialog));
-			connect_to_server (data);
-		}
-
-		break;
-
-	case PICASA_ACCOUNT_CHOOSER_RESPONSE_NEW:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		account_properties_dialog (data, NULL, NULL);
-		break;
-
-	default:
-		break;
-	}
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
+					   GTK_RESPONSE_OK,
+					   FALSE);
 }
 
 
@@ -736,8 +304,7 @@ create_album_ready_cb (GObject      *source_object,
 
 	album = picasa_web_service_create_album_finish (picasaweb, result, &error);
 	if (error != NULL) {
-		if (data->conn != NULL)
-			gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
+		gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
 		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not create the album"), error);
 		g_clear_error (&error);
 		return;
@@ -768,7 +335,7 @@ new_album_dialog_response_cb (GtkDialog *dialog,
 			album = picasa_web_album_new ();
 			picasa_web_album_set_title (album, picasa_album_properties_dialog_get_name (PICASA_ALBUM_PROPERTIES_DIALOG (dialog)));
 			album->access = picasa_album_properties_dialog_get_access (PICASA_ALBUM_PROPERTIES_DIALOG (dialog));
-			picasa_web_service_create_album (data->picasaweb,
+			picasa_web_service_create_album (data->service,
 							 album,
 							 data->cancellable,
 							 create_album_ready_cb,
@@ -812,100 +379,12 @@ add_album_button_clicked_cb (GtkButton *button,
 
 
 static void
-auto_select_account (DialogData *data)
-{
-	gtk_widget_hide (data->dialog);
-	if (data->conn != NULL)
-		gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
-
-	if (data->accounts != NULL) {
-		if (data->email != NULL) {
-			connect_to_server (data);
-		}
-		else if (data->accounts->next == NULL) {
-			data->email = g_strdup ((char *)data->accounts->data);
-			connect_to_server (data);
-		}
-		else {
-			GtkWidget *dialog;
-
-			if (data->conn != NULL)
-				gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-			dialog = picasa_account_chooser_dialog_new (data->accounts, data->email);
-			g_signal_connect (dialog,
-					  "delete-event",
-					  G_CALLBACK (gtk_true),
-					  NULL);
-			g_signal_connect (dialog,
-					  "response",
-					  G_CALLBACK (account_chooser_dialog_response_cb),
-					  data);
-
-			gtk_window_set_title (GTK_WINDOW (dialog), _("Choose Account"));
-			gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
-			gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-			gtk_window_present (GTK_WINDOW (dialog));
-		}
-	}
-	else
-		account_properties_dialog (data, NULL, NULL);
-}
-
-
-static void
-account_manager_dialog_response_cb (GtkDialog *dialog,
-			            int        response_id,
-			            gpointer   user_data)
-{
-	DialogData *data = user_data;
-
-	switch (response_id) {
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		break;
-
-	case GTK_RESPONSE_OK:
-		_g_string_list_free (data->accounts);
-		data->accounts = picasa_account_manager_dialog_get_accounts (PICASA_ACCOUNT_MANAGER_DIALOG (dialog));
-		if (! g_list_find_custom (data->accounts, data->email, (GCompareFunc) strcmp)) {
-			g_free (data->email);
-			data->email = NULL;
-			auto_select_account (data);
-		}
-		else
-			update_account_list (data);
-		picasa_web_accounts_save_to_file (data->accounts, data->email);
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		break;
-
-	default:
-		break;
-	}
-}
-
-
-static void
 edit_accounts_button_clicked_cb (GtkButton *button,
 			         gpointer   user_data)
 {
 	DialogData *data = user_data;
-	GtkWidget  *dialog;
-
-	dialog = picasa_account_manager_dialog_new (data->accounts);
-	g_signal_connect (dialog,
-			  "delete-event",
-			  G_CALLBACK (gtk_true),
-			  NULL);
-	g_signal_connect (dialog,
-			  "response",
-			  G_CALLBACK (account_manager_dialog_response_cb),
-			  data);
 
-	gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Accounts"));
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->dialog));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-	gtk_window_present (GTK_WINDOW (dialog));
+	web_service_edit_accounts (WEB_SERVICE (data->service), GTK_WINDOW (data->dialog));
 }
 
 
@@ -913,29 +392,22 @@ static void
 account_combobox_changed_cb (GtkComboBox *widget,
 			     gpointer     user_data)
 {
-	DialogData  *data = user_data;
-	GtkTreeIter  iter;
-	char        *email;
+	DialogData   *data = user_data;
+	GtkTreeIter   iter;
+	OAuthAccount *account;
 
 	if (! gtk_combo_box_get_active_iter (widget, &iter))
 		return;
 
 	gtk_tree_model_get (gtk_combo_box_get_model (widget),
 			    &iter,
-			    ACCOUNT_EMAIL_COLUMN, &email,
+			    ACCOUNT_DATA_COLUMN, &account,
 			    -1);
 
-	if (g_strcmp0 (email, data->email) != 0) {
-		g_free (data->email);
-		g_free (data->password);
-		g_free (data->challange);
-		data->email = email;
-		data->password = NULL;
-		data->challange = NULL;
-		auto_select_account (data);
-	}
-	else
-		g_free (email);
+	if (oauth_account_cmp (account, web_service_get_current_account (WEB_SERVICE (data->service))) != 0)
+		web_service_connect (WEB_SERVICE (data->service), account);
+
+	g_object_unref (account);
 }
 
 
@@ -947,14 +419,17 @@ albums_treeview_selection_changed_cb (GtkTreeSelection *treeselection,
 	gboolean    selected;
 
 	selected = gtk_tree_selection_get_selected (treeselection, NULL, NULL);
-	gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), selected);
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
+					   GTK_RESPONSE_OK,
+					   selected);
 }
 
 
 static void
 update_sensitivity (DialogData *data)
 {
-	gtk_widget_set_sensitive (GET_WIDGET ("resize_combobox"), gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("resize_checkbutton"))));
+	gtk_widget_set_sensitive (GET_WIDGET ("resize_combobox"),
+				  gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("resize_checkbutton"))));
 }
 
 
@@ -966,6 +441,86 @@ resize_checkbutton_toggled_cb (GtkToggleButton *button,
 }
 
 
+static void
+list_albums_ready_cb (GObject      *source_object,
+		      GAsyncResult *result,
+		      gpointer      user_data)
+{
+	DialogData       *data = user_data;
+	PicasaWebService *picasaweb = PICASA_WEB_SERVICE (source_object);
+	GError           *error = NULL;
+
+	_g_object_list_unref (data->albums);
+	data->albums = picasa_web_service_list_albums_finish (picasaweb, result, &error);
+	if (error != NULL) {
+		gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
+		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the album list"), error);
+		g_clear_error (&error);
+		gtk_dialog_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_DELETE_EVENT);
+		return;
+	}
+
+	update_album_list (data);
+
+	gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
+	gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (data->browser));
+	gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
+	gtk_window_present (GTK_WINDOW (data->dialog));
+}
+
+
+static void
+update_account_list (DialogData *data)
+{
+	int           current_account_idx;
+	OAuthAccount *current_account;
+	int           idx;
+	GList        *scan;
+	GtkTreeIter   iter;
+
+	gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("account_liststore")));
+
+	current_account_idx = 0;
+	current_account = web_service_get_current_account (WEB_SERVICE (data->service));
+	for (scan = web_service_get_accounts (WEB_SERVICE (data->service)), idx = 0; scan; scan = scan->next, idx++) {
+		OAuthAccount *account = scan->data;
+
+		if ((current_account != NULL) && (g_strcmp0 (current_account->id, account->id) == 0))
+			current_account_idx = idx;
+
+		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter);
+		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
+				    ACCOUNT_DATA_COLUMN, account,
+				    ACCOUNT_NAME_COLUMN, account->name,
+				    -1);
+	}
+	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), current_account_idx);
+}
+
+
+static void
+service_account_ready_cb (WebService *service,
+			  gpointer    user_data)
+{
+	DialogData *data = user_data;
+
+	update_account_list (data);
+	picasa_web_service_list_albums (data->service,
+				        data->cancellable,
+				        list_albums_ready_cb,
+				        data);
+}
+
+
+static void
+service_accounts_changed_cb (WebService *service,
+			     gpointer    user_data)
+{
+	DialogData *data = user_data;
+	update_account_list (data);
+}
+
+
 void
 dlg_export_to_picasaweb (GthBrowser *browser,
 		         GList      *file_list)
@@ -1036,8 +591,7 @@ dlg_export_to_picasaweb (GthBrowser *browser,
 	if (data->file_list == NULL) {
 		GError *error;
 
-		if (data->conn != NULL)
-			gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
+		gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
 
 		error = g_error_new_literal (GTH_ERROR, GTH_ERROR_GENERIC, _("No valid file selected."));
 		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not export the files"), error);
@@ -1111,6 +665,20 @@ dlg_export_to_picasaweb (GthBrowser *browser,
 
 	update_sensitivity (data);
 
-	data->accounts = picasa_web_accounts_load_from_file (&data->email);
-	auto_select_account (data);
+	data->service = picasa_web_service_new (data->cancellable,
+						GTK_WIDGET (data->browser),
+						data->dialog);
+	g_signal_connect (data->service,
+			  "account-ready",
+			  G_CALLBACK (service_account_ready_cb),
+			  data);
+	g_signal_connect (data->service,
+			  "accounts-changed",
+			  G_CALLBACK (service_accounts_changed_cb),
+			  data);
+
+	data->progress_dialog = gth_progress_dialog_new (GTK_WINDOW (data->browser));
+	gth_progress_dialog_add_task (GTH_PROGRESS_DIALOG (data->progress_dialog), GTH_TASK (data->service));
+
+	web_service_autoconnect (WEB_SERVICE (data->service));
 }
diff --git a/extensions/picasaweb/dlg-import-from-picasaweb.c b/extensions/picasaweb/dlg-import-from-picasaweb.c
index 8989b9a..24ded51 100644
--- a/extensions/picasaweb/dlg-import-from-picasaweb.c
+++ b/extensions/picasaweb/dlg-import-from-picasaweb.c
@@ -20,29 +20,21 @@
  */
 
 #include <config.h>
-#define GDK_PIXBUF_ENABLE_BACKEND
-#include <gtk/gtk.h>
-#ifdef HAVE_LIBSECRET
-#include <libsecret/secret.h>
-#endif /* HAVE_LIBSECRET */
 #include <gthumb.h>
+#include <extensions/oauth/oauth.h>
 #include <extensions/importer/importer.h>
 #include "dlg-import-from-picasaweb.h"
-#include "picasa-account-chooser-dialog.h"
-#include "picasa-account-manager-dialog.h"
-#include "picasa-account-properties-dialog.h"
 #include "picasa-album-properties-dialog.h"
 #include "picasa-web-album.h"
 #include "picasa-web-photo.h"
 #include "picasa-web-service.h"
-#include "picasa-web-user.h"
 
 
 #define GET_WIDGET(x) (_gtk_builder_get_widget (data->builder, (x)))
 
 
 enum {
-	ACCOUNT_EMAIL_COLUMN,
+	ACCOUNT_DATA_COLUMN,
 	ACCOUNT_NAME_COLUMN,
 	ACCOUNT_ICON_COLUMN
 };
@@ -58,22 +50,15 @@ enum {
 
 typedef struct {
 	GthBrowser       *browser;
-	GthFileData      *location;
 	GtkBuilder       *builder;
 	GtkWidget        *dialog;
 	GtkWidget        *preferences_dialog;
 	GtkWidget        *progress_dialog;
 	GtkWidget        *file_list;
-	GList            *accounts;
-	PicasaWebUser    *user;
-	char             *email;
-	char             *password;
-	char             *challange;
 	GList            *albums;
 	PicasaWebAlbum   *album;
 	GList            *photos;
-	GoogleConnection *conn;
-	PicasaWebService *picasaweb;
+	PicasaWebService *service;
 	GCancellable     *cancellable;
 } DialogData;
 
@@ -82,21 +67,13 @@ static void
 import_dialog_destroy_cb (GtkWidget  *widget,
 			  DialogData *data)
 {
-	if (data->conn != NULL)
-		gth_task_completed (GTH_TASK (data->conn), NULL);
+	gth_task_completed (GTH_TASK (data->service), NULL);
 	_g_object_unref (data->cancellable);
-	_g_object_unref (data->picasaweb);
-	_g_object_unref (data->conn);
+	_g_object_unref (data->service);
 	_g_object_list_unref (data->albums);
 	_g_object_unref (data->album);
 	_g_object_list_unref (data->photos);
-	g_free (data->challange);
-	g_free (data->password);
-	g_free (data->email);
-	_g_object_unref (data->user);
-	_g_string_list_free (data->accounts);
 	_g_object_unref (data->builder);
-	_g_object_unref (data->location);
 	g_free (data);
 }
 
@@ -129,13 +106,8 @@ import_dialog_response_cb (GtkDialog *dialog,
 	DialogData *data = user_data;
 
 	switch (response_id) {
-	case GTK_RESPONSE_HELP:
-		show_help_dialog (GTK_WINDOW (data->browser), "export-to-picasaweb");
-		break;
-
 	case GTK_RESPONSE_DELETE_EVENT:
 	case GTK_RESPONSE_CANCEL:
-		picasa_web_accounts_save_to_file (data->accounts, data->email);
 		gth_file_list_cancel (GTH_FILE_LIST (data->file_list), (DataFunc) gtk_widget_destroy, data->dialog);
 		break;
 
@@ -146,7 +118,9 @@ import_dialog_response_cb (GtkDialog *dialog,
 			GList          *file_list;
 
 			if (! gtk_combo_box_get_active_iter (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")), &iter)) {
-				gtk_widget_set_sensitive (GET_WIDGET ("download_button"), FALSE);
+				gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
+								   GTK_RESPONSE_OK,
+								   FALSE);
 				return;
 			}
 
@@ -223,535 +197,12 @@ import_dialog_response_cb (GtkDialog *dialog,
 
 
 static void
-update_account_list (DialogData *data)
-{
-	GtkTreeIter  iter;
-	int          current_account;
-	int          idx;
-	GList       *scan;
-
-	current_account = 0;
-	gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("account_liststore")));
-	for (scan = data->accounts, idx = 0; scan; scan = scan->next, idx++) {
-		char *account = scan->data;
-
-		if (g_strcmp0 (account, data->email) == 0)
-			current_account = idx;
-
-		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter);
-		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
-				    ACCOUNT_EMAIL_COLUMN, account,
-				    ACCOUNT_NAME_COLUMN, account,
-				    -1);
-	}
-
-	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), current_account);
-}
-
-
-static void
-update_album_list (DialogData *data)
-{
-	GtkTreeIter  iter;
-	GList       *scan;
-
-	g_return_if_fail (data->user != NULL);
-
-	gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("album_liststore")));
-	for (scan = data->albums; scan; scan = scan->next) {
-		PicasaWebAlbum *album = scan->data;
-		char           *used_bytes;
-
-		used_bytes = g_format_size (album->used_bytes);
-
-		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter);
-		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter,
-				    ALBUM_DATA_COLUMN, album,
-				    ALBUM_ICON_COLUMN, "file-catalog",
-				    ALBUM_NAME_COLUMN, album->title,
-				    ALBUM_SIZE_COLUMN, used_bytes,
-				    -1);
-
-		g_free (used_bytes);
-	}
-
-	gtk_widget_set_sensitive (GET_WIDGET ("download_button"), FALSE);
-	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")), -1);
-}
-
-
-static void
-show_import_dialog (DialogData *data)
-{
-	update_account_list (data);
-	update_album_list (data);
-	gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-
-	gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (data->browser));
-	gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
-	gtk_window_present (GTK_WINDOW (data->dialog));
-}
-
-
-static void
-list_albums_ready_cb (GObject      *source_object,
-		      GAsyncResult *result,
-		      gpointer      user_data)
-{
-	DialogData       *data = user_data;
-	PicasaWebService *picasaweb = PICASA_WEB_SERVICE (source_object);
-	GError           *error = NULL;
-
-	_g_object_list_unref (data->albums);
-	data->albums = picasa_web_service_list_albums_finish (picasaweb, result, &error);
-	if (error != NULL) {
-		if (data->conn != NULL)
-			gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the album list"), error);
-		g_clear_error (&error);
-		gtk_widget_destroy (data->dialog);
-		return;
-	}
-
-	_g_object_unref (data->user);
-	data->user = g_object_ref (picasa_web_service_get_user (picasaweb));
-	show_import_dialog (data);
-}
-
-
-static void
-get_album_list (DialogData *data)
-{
-	char *user_id;
-
-	gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
-
-	if (data->picasaweb == NULL)
-		data->picasaweb = picasa_web_service_new (data->conn);
-	user_id = google_utils_get_user_id_from_email (data->email);
-	picasa_web_service_list_albums (data->picasaweb,
-					user_id,
-				        data->cancellable,
-				        list_albums_ready_cb,
-				        data);
-
-	g_free (user_id);
-}
-
-
-#ifdef HAVE_LIBSECRET
-static void
-password_store_ready_cb (GObject      *source_object,
-			 GAsyncResult *result,
-			 gpointer      user_data)
-{
-	DialogData *data = user_data;
-
-	secret_password_store_finish (result, NULL);
-	get_album_list (data);
-}
-#endif
-
-
-static void account_properties_dialog (DialogData *data,
-			               const char *email,
-			               GError     *error);
-static void challange_account_dialog  (DialogData *data,
-	               	       	       GError     *error);
-
-
-static void
-connection_ready_cb (GObject      *source_object,
-		     GAsyncResult *result,
-		     gpointer      user_data)
-{
-	DialogData       *data = user_data;
-	GoogleConnection *conn = GOOGLE_CONNECTION (source_object);
-	GError           *error = NULL;
-
-	if (! google_connection_connect_finish (conn, result, &error)) {
-		if (g_error_matches (error, GOOGLE_CONNECTION_ERROR, GOOGLE_CONNECTION_ERROR_CAPTCHA_REQUIRED)) {
-			challange_account_dialog (data, error);
-			g_clear_error (&error);
-		}
-		else if (g_error_matches (error, GOOGLE_CONNECTION_ERROR, GOOGLE_CONNECTION_ERROR_BAD_AUTHENTICATION)) {
-			account_properties_dialog (data, data->email, error);
-			g_clear_error (&error);
-		}
-		else {
-			if (data->conn != NULL)
-				gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-			_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not connect to the server"), error);
-			g_clear_error (&error);
-			gtk_widget_destroy (data->dialog);
-		}
-		return;
-	}
-
-	if (! g_list_find_custom (data->accounts, data->email, (GCompareFunc) strcmp))
-		data->accounts = g_list_append (data->accounts, g_strdup (data->email));
-
-#ifdef HAVE_LIBSECRET
-	secret_password_store (SECRET_SCHEMA_COMPAT_NETWORK,
-			       NULL,
-			       _("Picasa Web Album"),
-			       data->password,
-			       data->cancellable,
-			       password_store_ready_cb,
-			       data,
-			       "user", data->email,
-			       "server", "picasaweb.google.com",
-			       "protocol", "http",
-			       NULL);
-#else
-	get_album_list (data);
-#endif
-}
-
-
-static void connect_to_server (DialogData *data);
-static void auto_select_account (DialogData *data);
-
-
-static void
-account_properties_dialog_response_cb (GtkDialog *dialog,
-				       int        response_id,
-				       gpointer   user_data)
-{
-	DialogData *data = user_data;
-
-	switch (response_id) {
-	case GTK_RESPONSE_HELP:
-		show_help_dialog (GTK_WINDOW (dialog), "picasaweb-account-properties");
-		break;
-
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		gtk_widget_destroy (data->dialog);
-		break;
-
-	case GTK_RESPONSE_OK:
-		g_free (data->email);
-		g_free (data->password);
-		g_free (data->challange);
-		data->email = g_strdup (picasa_account_properties_dialog_get_email (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		data->password = g_strdup (picasa_account_properties_dialog_get_password (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		data->challange = NULL;
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		connect_to_server (data);
-		break;
-
-	case PICASA_ACCOUNT_PROPERTIES_RESPONSE_CHOOSE:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		g_free (data->email);
-		data->email = NULL;
-		auto_select_account (data);
-		break;
-
-	default:
-		break;
-	}
-}
-
-
-static void
-account_properties_dialog (DialogData *data,
-			   const char *email,
-			   GError     *error)
-{
-	GtkWidget *dialog;
-
-	if (data->conn != NULL)
-		gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-
-	dialog = picasa_account_properties_dialog_new (email, NULL, NULL);
-	picasa_account_properties_dialog_set_error (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog), error);
-	if ((error != NULL) && (data->accounts != NULL) && (data->accounts->next != NULL))
-		picasa_account_properties_dialog_can_choose (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog), TRUE);
-
-	g_signal_connect (dialog,
-			  "delete-event",
-			  G_CALLBACK (gtk_true),
-			  NULL);
-	g_signal_connect (dialog,
-			  "response",
-			  G_CALLBACK (account_properties_dialog_response_cb),
-			  data);
-
-	gtk_window_set_title (GTK_WINDOW (dialog), _("Account"));
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-	gtk_window_present (GTK_WINDOW (dialog));
-}
-
-
-static void
-connect_to_server_step2 (DialogData *data)
-{
-	if ((data->password == NULL) || g_str_equal (data->password, "")) {
-		gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-		account_properties_dialog (data, data->email, NULL);
-	}
-	else {
-		gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
-		google_connection_connect (data->conn,
-					   data->email,
-					   data->password,
-					   data->challange,
-					   data->cancellable,
-					   connection_ready_cb,
-					   data);
-	}
-}
-
-
-#ifdef HAVE_LIBSECRET
-static void
-password_lookup_ready_cb (GObject      *source_object,
-			  GAsyncResult *result,
-			  gpointer      user_data)
-{
-	DialogData *data = user_data;
-	char       *string;
-
-	string = secret_password_lookup_finish (result, NULL);
-	if (string != NULL) {
-		data->password = g_strdup (string);
-		g_free (string);
-	}
-
-	connect_to_server_step2 (data);
-}
-#endif
-
-
-static void
-connect_to_server (DialogData *data)
-{
-	if (data->conn == NULL) {
-		data->conn = google_connection_new (GOOGLE_SERVICE_PICASA_WEB_ALBUM);
-		data->progress_dialog = gth_progress_dialog_new (GTK_WINDOW (data->browser));
-		gth_progress_dialog_add_task (GTH_PROGRESS_DIALOG (data->progress_dialog), GTH_TASK (data->conn));
-	}
-
-#ifdef HAVE_LIBSECRET
-	if (data->password == NULL) {
-		secret_password_lookup (SECRET_SCHEMA_COMPAT_NETWORK,
-					data->cancellable,
-					password_lookup_ready_cb,
-					data,
-					"user", data->email,
-					"server", "picasaweb.google.com",
-					"protocol", "http",
-					NULL);
-		return;
-	}
-#endif
-
-	connect_to_server_step2 (data);
-}
-
-
-static void
-challange_account_dialog_response_cb (GtkDialog *dialog,
-				      int        response_id,
-				      gpointer   user_data)
-{
-	DialogData *data = user_data;
-
-	switch (response_id) {
-	case GTK_RESPONSE_HELP:
-		show_help_dialog (GTK_WINDOW (dialog), "picasaweb-account-challange");
-		break;
-
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		gtk_widget_destroy (data->dialog);
-		break;
-
-	case GTK_RESPONSE_OK:
-		g_free (data->email);
-		g_free (data->password);
-		data->email = g_strdup (picasa_account_properties_dialog_get_email (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		data->password = g_strdup (picasa_account_properties_dialog_get_password (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		data->challange = g_strdup (picasa_account_properties_dialog_get_challange (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog)));
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		connect_to_server (data);
-		break;
-
-	case PICASA_ACCOUNT_PROPERTIES_RESPONSE_CHOOSE:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		g_free (data->email);
-		data->email = NULL;
-		auto_select_account (data);
-		break;
-
-	default:
-		break;
-	}
-}
-
-
-static void
-challange_account_dialog (DialogData *data,
-			  GError     *error)
-{
-	GtkWidget *dialog;
-
-	dialog = picasa_account_properties_dialog_new (data->email, data->password, google_connection_get_challange_url (data->conn));
-	picasa_account_properties_dialog_set_error (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog), error);
-	if ((error != NULL) && (data->accounts != NULL) && (data->accounts->next != NULL))
-		picasa_account_properties_dialog_can_choose (PICASA_ACCOUNT_PROPERTIES_DIALOG (dialog), TRUE);
-
-	g_signal_connect (dialog,
-			  "delete-event",
-			  G_CALLBACK (gtk_true),
-			  NULL);
-	g_signal_connect (dialog,
-			  "response",
-			  G_CALLBACK (challange_account_dialog_response_cb),
-			  data);
-
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-	gtk_window_present (GTK_WINDOW (dialog));
-}
-
-
-static void
-account_chooser_dialog_response_cb (GtkDialog *dialog,
-				    int        response_id,
-				    gpointer   user_data)
-{
-	DialogData *data = user_data;
-
-	switch (response_id) {
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		gtk_widget_destroy (data->dialog);
-		break;
-
-	case GTK_RESPONSE_OK:
-		g_free (data->password);
-		data->password = NULL;
-		g_free (data->challange);
-		data->challange = NULL;
-		g_free (data->email);
-		data->email = picasa_account_chooser_dialog_get_active (PICASA_ACCOUNT_CHOOSER_DIALOG (dialog));
-		if (data->email != NULL) {
-			gtk_widget_destroy (GTK_WIDGET (dialog));
-			connect_to_server (data);
-		}
-
-		break;
-
-	case PICASA_ACCOUNT_CHOOSER_RESPONSE_NEW:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		account_properties_dialog (data, NULL, NULL);
-		break;
-
-	default:
-		break;
-	}
-}
-
-
-static void
-auto_select_account (DialogData *data)
-{
-	gtk_widget_hide (data->dialog);
-
-	if (data->accounts != NULL) {
-		if (data->email != NULL) {
-			connect_to_server (data);
-		}
-		else if (data->accounts->next == NULL) {
-			data->email = g_strdup ((char *)data->accounts->data);
-			connect_to_server (data);
-		}
-		else {
-			GtkWidget *dialog;
-
-			if (data->conn != NULL)
-				gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
-			dialog = picasa_account_chooser_dialog_new (data->accounts, data->email);
-			g_signal_connect (dialog,
-					  "delete-event",
-					  G_CALLBACK (gtk_true),
-					  NULL);
-			g_signal_connect (dialog,
-					  "response",
-					  G_CALLBACK (account_chooser_dialog_response_cb),
-					  data);
-
-			gtk_window_set_title (GTK_WINDOW (dialog), _("Choose Account"));
-			gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
-			gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-			gtk_window_present (GTK_WINDOW (dialog));
-		}
-	}
-	else
-		account_properties_dialog (data, NULL, NULL);
-}
-
-
-static void
-account_manager_dialog_response_cb (GtkDialog *dialog,
-			            int        response_id,
-			            gpointer   user_data)
-{
-	DialogData *data = user_data;
-
-	switch (response_id) {
-	case GTK_RESPONSE_DELETE_EVENT:
-	case GTK_RESPONSE_CANCEL:
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		break;
-
-	case GTK_RESPONSE_OK:
-		_g_string_list_free (data->accounts);
-		data->accounts = picasa_account_manager_dialog_get_accounts (PICASA_ACCOUNT_MANAGER_DIALOG (dialog));
-		if (! g_list_find_custom (data->accounts, data->email, (GCompareFunc) strcmp)) {
-			g_free (data->email);
-			data->email = NULL;
-			auto_select_account (data);
-		}
-		else
-			update_account_list (data);
-		picasa_web_accounts_save_to_file (data->accounts, data->email);
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		break;
-
-	default:
-		break;
-	}
-}
-
-
-static void
 edit_accounts_button_clicked_cb (GtkButton *button,
 			         gpointer   user_data)
 {
 	DialogData *data = user_data;
-	GtkWidget  *dialog;
 
-	dialog = picasa_account_manager_dialog_new (data->accounts);
-	g_signal_connect (dialog,
-			  "delete-event",
-			  G_CALLBACK (gtk_true),
-			  NULL);
-	g_signal_connect (dialog,
-			  "response",
-			  G_CALLBACK (account_manager_dialog_response_cb),
-			  data);
-
-	gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Accounts"));
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->dialog));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-	gtk_window_present (GTK_WINDOW (dialog));
+	web_service_edit_accounts (WEB_SERVICE (data->service), GTK_WINDOW (data->dialog));
 }
 
 
@@ -759,29 +210,22 @@ static void
 account_combobox_changed_cb (GtkComboBox *widget,
 			     gpointer     user_data)
 {
-	DialogData  *data = user_data;
-	GtkTreeIter  iter;
-	char        *email;
+	DialogData   *data = user_data;
+	GtkTreeIter   iter;
+	OAuthAccount *account;
 
 	if (! gtk_combo_box_get_active_iter (widget, &iter))
 		return;
 
 	gtk_tree_model_get (gtk_combo_box_get_model (widget),
 			    &iter,
-			    ACCOUNT_EMAIL_COLUMN, &email,
+			    ACCOUNT_DATA_COLUMN, &account,
 			    -1);
 
-	if (g_strcmp0 (email, data->email) != 0) {
-		g_free (data->email);
-		g_free (data->password);
-		g_free (data->challange);
-		data->email = email;
-		data->password = NULL;
-		data->challange = NULL;
-		auto_select_account (data);
-	}
-	else
-		g_free (email);
+	if (oauth_account_cmp (account, web_service_get_current_account (WEB_SERVICE (data->service))) != 0)
+		web_service_connect (WEB_SERVICE (data->service), account);
+
+	g_object_unref (account);
 }
 
 
@@ -826,13 +270,11 @@ list_photos_ready_cb (GObject      *source_object,
 	GList            *list;
 	GList            *scan;
 
-	if (data->conn != NULL)
-		gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
+	gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
 	_g_object_list_unref (data->photos);
 	data->photos = picasa_web_service_list_albums_finish (picasaweb, result, &error);
 	if (error != NULL) {
-		if (data->conn != NULL)
-			gth_task_dialog (GTH_TASK (data->conn), TRUE, NULL);
+		gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
 		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the photo list"), error);
 		g_clear_error (&error);
 		gtk_widget_destroy (data->dialog);
@@ -879,8 +321,8 @@ album_combobox_changed_cb (GtkComboBox *widget,
 
 	gth_import_preferences_dialog_set_event (GTH_IMPORT_PREFERENCES_DIALOG (data->preferences_dialog), data->album->title);
 
-	gth_task_dialog (GTH_TASK (data->conn), FALSE, NULL);
-	picasa_web_service_list_photos (data->picasaweb,
+	gth_task_dialog (GTH_TASK (data->service), FALSE, NULL);
+	picasa_web_service_list_photos (data->service,
 					data->album,
 					data->cancellable,
 					list_photos_ready_cb,
@@ -979,6 +421,117 @@ file_list_selection_changed_cb (GtkIconView *iconview,
 }
 
 
+static void
+update_album_list (DialogData *data)
+{
+	GtkTreeIter  iter;
+	GList       *scan;
+
+	gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("album_liststore")));
+	for (scan = data->albums; scan; scan = scan->next) {
+		PicasaWebAlbum *album = scan->data;
+		char           *used_bytes;
+
+		used_bytes = g_format_size (album->used_bytes);
+
+		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter);
+		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter,
+				    ALBUM_DATA_COLUMN, album,
+				    ALBUM_ICON_COLUMN, "file-catalog",
+				    ALBUM_NAME_COLUMN, album->title,
+				    ALBUM_SIZE_COLUMN, used_bytes,
+				    -1);
+
+		g_free (used_bytes);
+	}
+
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
+					   GTK_RESPONSE_OK,
+					   FALSE);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")), -1);
+}
+
+
+static void
+list_albums_ready_cb (GObject      *source_object,
+		      GAsyncResult *result,
+		      gpointer      user_data)
+{
+	DialogData       *data = user_data;
+	PicasaWebService *picasaweb = PICASA_WEB_SERVICE (source_object);
+	GError           *error = NULL;
+
+	_g_object_list_unref (data->albums);
+	data->albums = picasa_web_service_list_albums_finish (picasaweb, result, &error);
+	if (error != NULL) {
+		gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
+		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the album list"), error);
+		g_clear_error (&error);
+		gtk_widget_destroy (data->dialog);
+		return;
+	}
+
+	update_album_list (data);
+	gth_task_dialog (GTH_TASK (data->service), TRUE, NULL);
+
+	gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (data->browser));
+	gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
+	gtk_window_present (GTK_WINDOW (data->dialog));
+}
+
+
+static void
+update_account_list (DialogData *data)
+{
+	int           current_account_idx;
+	OAuthAccount *current_account;
+	int           idx;
+	GList        *scan;
+	GtkTreeIter   iter;
+
+	gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("account_liststore")));
+
+	current_account_idx = 0;
+	current_account = web_service_get_current_account (WEB_SERVICE (data->service));
+	for (scan = web_service_get_accounts (WEB_SERVICE (data->service)), idx = 0; scan; scan = scan->next, idx++) {
+		OAuthAccount *account = scan->data;
+
+		if ((current_account != NULL) && (g_strcmp0 (current_account->username, account->username) == 0))
+			current_account_idx = idx;
+
+		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter);
+		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("account_liststore")), &iter,
+				    ACCOUNT_DATA_COLUMN, account,
+				    ACCOUNT_NAME_COLUMN, account->username,
+				    -1);
+	}
+	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), current_account_idx);
+}
+
+
+static void
+service_account_ready_cb (WebService *service,
+			  gpointer    user_data)
+{
+	DialogData *data = user_data;
+
+	update_account_list (data);
+	picasa_web_service_list_albums (data->service,
+				        data->cancellable,
+				        list_albums_ready_cb,
+				        data);
+}
+
+
+static void
+service_accounts_changed_cb (WebService *service,
+			     gpointer    user_data)
+{
+	DialogData *data = user_data;
+	update_account_list (data);
+}
+
+
 void
 dlg_import_from_picasaweb (GthBrowser *browser)
 {
@@ -987,7 +540,6 @@ dlg_import_from_picasaweb (GthBrowser *browser)
 
 	data = g_new0 (DialogData, 1);
 	data->browser = browser;
-	data->location = gth_file_data_dup (gth_browser_get_location_data (browser));
 	data->builder = _gtk_builder_new_from_file ("import-from-picasaweb.ui", "picasaweb");
 	data->dialog = _gtk_builder_get_widget (data->builder, "import_dialog");
 	data->cancellable = g_cancellable_new ();
@@ -1082,6 +634,20 @@ dlg_import_from_picasaweb (GthBrowser *browser)
 	update_selection_status (data);
 	gth_import_preferences_dialog_set_event (GTH_IMPORT_PREFERENCES_DIALOG (data->preferences_dialog), "");
 
-	data->accounts = picasa_web_accounts_load_from_file (&data->email);
-	auto_select_account (data);
+	data->service = picasa_web_service_new (data->cancellable,
+						GTK_WIDGET (data->browser),
+						data->dialog);
+	g_signal_connect (data->service,
+			  "account-ready",
+			  G_CALLBACK (service_account_ready_cb),
+			  data);
+	g_signal_connect (data->service,
+			  "accounts-changed",
+			  G_CALLBACK (service_accounts_changed_cb),
+			  data);
+
+	data->progress_dialog = gth_progress_dialog_new (GTK_WINDOW (data->browser));
+	gth_progress_dialog_add_task (GTH_PROGRESS_DIALOG (data->progress_dialog), GTH_TASK (data->service));
+
+	web_service_autoconnect (WEB_SERVICE (data->service));
 }
diff --git a/extensions/picasaweb/picasa-web-service.c b/extensions/picasaweb/picasa-web-service.c
index 61a57cd..1127f02 100644
--- a/extensions/picasaweb/picasa-web-service.c
+++ b/extensions/picasaweb/picasa-web-service.c
@@ -3,7 +3,7 @@
 /*
  *  GThumb
  *
- *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *  Copyright (C) 2010-2012 Free Software Foundation, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -22,13 +22,28 @@
 #include <config.h>
 #include <glib.h>
 #include <glib/gi18n.h>
+#include <json-glib/json-glib.h>
 #include <gthumb.h>
+#include <extensions/oauth/oauth.h>
 #include "picasa-web-album.h"
 #include "picasa-web-photo.h"
 #include "picasa-web-service.h"
 
 
-G_DEFINE_TYPE (PicasaWebService, picasa_web_service, G_TYPE_OBJECT)
+#define ATOM_ENTRY_MIME_TYPE "application/atom+xml; charset=UTF-8; type=entry"
+/*#define PICASA_WEB_API_VERSION "1.0"
+#define PICASA_WEB_AUTHENTICATION_RESPONSE_CHOOSE_ACCOUNT 2
+#define PICASA_WEB_HTTP_SERVER "https://www.picasa_web.com";
+#define PICASA_WEB_MAX_IMAGE_SIZE 2048
+#define PICASA_WEB_MIN_IMAGE_SIZE 720 FIXME */
+#define PICASA_WEB_REDIRECT_URI "urn:ietf:wg:oauth:2.0:oob"
+#define PICASA_WEB_REDIRECT_TITLE "Success code="
+#define PICASA_WEB_SERVICE_ERROR_TOKEN_EXPIRED 190
+#define GTHUMB_PICASA_WEB_CLIENT_ID "499958842898.apps.googleusercontent.com"
+#define GTHUMB_PICASA_WEB_CLIENT_SECRET "-DdIqzDxVRc_Wkobuf-2g-of"
+
+
+/* -- post_photos_data -- */
 
 
 typedef struct {
@@ -40,9 +55,9 @@ typedef struct {
         GAsyncReadyCallback  callback;
         gpointer             user_data;
 	GList               *current;
-	goffset              total_size;
-	goffset              uploaded_size;
-	goffset              wrote_body_data_size;
+	guint64              total_size;
+	guint64              uploaded_size;
+	guint64              wrote_body_data_size;
 	int                  n_files;
 	int                  uploaded_files;
 } PostPhotosData;
@@ -60,38 +75,511 @@ post_photos_data_free (PostPhotosData *post_photos)
 }
 
 
-struct _PicasaWebServicePrivate
-{
-	GoogleConnection *conn;
-	PicasaWebUser    *user;
-	PostPhotosData   *post_photos;
+/* -- picasa_web_service -- */
+
+
+G_DEFINE_TYPE (PicasaWebService, picasa_web_service, WEB_TYPE_SERVICE)
+
+
+struct _PicasaWebServicePrivate {
+	char                    *access_token;
+	char                    *refresh_token;
+	guint64         	 quota_limit;
+	guint64       		 quota_used;
+	PostPhotosData		*post_photos;
 };
 
 
 static void
 picasa_web_service_finalize (GObject *object)
 {
-	PicasaWebService *self;
-
-	self = PICASA_WEB_SERVICE (object);
+	PicasaWebService *self = PICASA_WEB_SERVICE (object);
 
-	_g_object_unref (self->priv->conn);
-	_g_object_unref (self->priv->user);
 	post_photos_data_free (self->priv->post_photos);
+	g_free (self->priv->access_token);
+	g_free (self->priv->refresh_token);
 
 	G_OBJECT_CLASS (picasa_web_service_parent_class)->finalize (object);
 }
 
 
+/* -- connection utilities -- */
+
+
+static void
+_picasa_web_service_add_headers (PicasaWebService *self,
+				 SoupMessage      *msg)
+{
+	if (self->priv->access_token != NULL) {
+		char *value;
+
+		value = g_strconcat ("Bearer ", self->priv->access_token, NULL);
+		soup_message_headers_replace (msg->request_headers, "Authorization", value);
+		g_free (value);
+	}
+
+	soup_message_headers_replace (msg->request_headers, "GData-Version", "2");
+}
+
+
+static gboolean
+picasa_web_utils_parse_json_response (SoupMessage  *msg,
+				      JsonNode    **node,
+				      GError      **error)
+{
+	JsonParser *parser;
+	SoupBuffer *body;
+
+	g_return_val_if_fail (msg != NULL, FALSE);
+	g_return_val_if_fail (node != NULL, FALSE);
+
+	*node = NULL;
+
+	if ((msg->status_code != 200) && (msg->status_code != 400)) {
+		*error = g_error_new (SOUP_HTTP_ERROR,
+				      msg->status_code,
+				      "%s",
+				      soup_status_get_phrase (msg->status_code));
+		return FALSE;
+	}
+
+	body = soup_message_body_flatten (msg->response_body);
+	parser = json_parser_new ();
+	if (json_parser_load_from_data (parser, body->data, body->length, error)) {
+		JsonObject *obj;
+
+		*node = json_node_copy (json_parser_get_root (parser));
+
+		obj = json_node_get_object (*node);
+		if (json_object_has_member (obj, "error")) {
+			JsonObject *error_obj;
+
+			error_obj = json_object_get_object_member (obj, "error");
+			*error = g_error_new (WEB_SERVICE_ERROR,
+					      json_object_get_int_member (error_obj, "code"),
+					      "%s",
+					      json_object_get_string_member (error_obj, "message"));
+
+			json_node_free (*node);
+			*node = NULL;
+		}
+	}
+
+	g_object_unref (parser);
+	soup_buffer_free (body);
+
+	return *node != NULL;
+}
+
+
+/* -- _picasa_web_service_get_refresh_token -- */
+
+static void
+_picasa_web_service_get_refresh_token_ready_cb (SoupSession *session,
+						SoupMessage *msg,
+						gpointer     user_data)
+{
+	PicasaWebService   *self = user_data;
+	GSimpleAsyncResult *result;
+	GError             *error = NULL;
+	JsonNode           *node;
+
+	result = _web_service_get_result (WEB_SERVICE (self));
+
+	if (picasa_web_utils_parse_json_response (msg, &node, &error)) {
+		JsonObject *obj;
+
+		obj = json_node_get_object (node);
+		_g_strset (&self->priv->access_token, json_object_get_string_member (obj, "access_token"));
+		_g_strset (&self->priv->refresh_token, json_object_get_string_member (obj, "refresh_token"));
+	}
+	else
+		g_simple_async_result_set_from_error (result, error);
+
+	g_simple_async_result_complete_in_idle (result);
+}
+
+
+static void
+_picasa_web_service_get_refresh_token (PicasaWebService    *self,
+				       const char          *authorization_code,
+				       GCancellable        *cancellable,
+				       GAsyncReadyCallback  callback,
+				       gpointer             user_data)
+{
+	GHashTable  *data_set;
+	SoupMessage *msg;
+
+	data_set = g_hash_table_new (g_str_hash, g_str_equal);
+	g_hash_table_insert (data_set, "code", (gpointer) authorization_code);
+	g_hash_table_insert (data_set, "client_id", GTHUMB_PICASA_WEB_CLIENT_ID);
+	g_hash_table_insert (data_set, "client_secret", GTHUMB_PICASA_WEB_CLIENT_SECRET);
+	g_hash_table_insert (data_set, "redirect_uri", PICASA_WEB_REDIRECT_URI);
+	g_hash_table_insert (data_set, "grant_type", "authorization_code");
+	msg = soup_form_request_new_from_hash ("POST", "https://accounts.google.com/o/oauth2/token";, data_set);
+	_picasa_web_service_add_headers (self, msg);
+	_web_service_send_message (WEB_SERVICE (self),
+				   msg,
+				   cancellable,
+				   callback,
+				   user_data,
+				   _picasa_web_service_get_refresh_token,
+				   _picasa_web_service_get_refresh_token_ready_cb,
+				   self);
+
+	g_hash_table_destroy (data_set);
+}
+
+
+static gboolean
+_picasa_web_service_get_refresh_token_finish (PicasaWebService  *service,
+					      GAsyncResult      *result,
+					      GError           **error)
+{
+	return ! g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+}
+
+
+/* -- picasa_web_service_ask_authorization -- */
+
+
+static void
+refresh_token_ready_cb (GObject      *source_object,
+		        GAsyncResult *result,
+		        gpointer      user_data)
+{
+	PicasaWebService *self = user_data;
+	GError           *error = NULL;
+	GtkWidget        *dialog;
+	gboolean          success;
+
+	dialog = _web_service_get_auth_dialog (WEB_SERVICE (self));
+	success = _picasa_web_service_get_refresh_token_finish (self, result, &error);
+	gtk_dialog_response (GTK_DIALOG (dialog), success ? GTK_RESPONSE_OK : GTK_RESPONSE_CANCEL);
+}
+
+
+static void
+ask_authorization_dialog_loaded_cb (OAuth2AskAuthorizationDialog *dialog,
+				    gpointer                      user_data)
+{
+	PicasaWebService *self = user_data;
+	const char       *title;
+
+	title = oauth2_ask_authorization_dialog_get_title (dialog);
+	if (title == NULL)
+		return;
+
+	if (g_str_has_prefix (title, PICASA_WEB_REDIRECT_TITLE)) {
+		const char *authorization_code;
+
+		authorization_code = title + strlen (PICASA_WEB_REDIRECT_TITLE);
+		_picasa_web_service_get_refresh_token (self,
+						       authorization_code,
+						       gth_task_get_cancellable (GTH_TASK (self)),
+						       refresh_token_ready_cb,
+						       self);
+	}
+}
+
+
+static char *
+picasa_web_service_get_authorization_url (PicasaWebService *self)
+{
+	GHashTable *data_set;
+	GString    *link;
+	GList      *keys;
+	GList      *scan;
+
+	data_set = g_hash_table_new (g_str_hash, g_str_equal);
+	g_hash_table_insert (data_set, "response_type", "code");
+	g_hash_table_insert (data_set, "client_id", GTHUMB_PICASA_WEB_CLIENT_ID);
+	g_hash_table_insert (data_set, "redirect_uri", PICASA_WEB_REDIRECT_URI);
+	g_hash_table_insert (data_set, "scope", "https://picasaweb.google.com/data/ https://www.googleapis.com/auth/userinfo.profile";);
+
+	link = g_string_new ("https://accounts.google.com/o/oauth2/auth?";);
+	keys = g_hash_table_get_keys (data_set);
+	for (scan = keys; scan; scan = scan->next) {
+		char *key = scan->data;
+		char *encoded;
+
+		if (scan != keys)
+			g_string_append (link, "&");
+		g_string_append (link, key);
+		g_string_append (link, "=");
+		encoded = soup_uri_encode (g_hash_table_lookup (data_set, key), NULL);
+		g_string_append (link, encoded);
+
+		g_free (encoded);
+	}
+
+	g_list_free (keys);
+	g_hash_table_destroy (data_set);
+
+	return g_string_free (link, FALSE);
+}
+
+
+static void
+picasa_web_service_ask_authorization (WebService *base)
+{
+	PicasaWebService *self = PICASA_WEB_SERVICE (base);
+	GtkWidget        *dialog;
+
+	_g_strset (&self->priv->refresh_token, NULL);
+	_g_strset (&self->priv->access_token, NULL);
+
+	gth_task_dialog (GTH_TASK (self), TRUE, NULL);
+
+	dialog = oauth2_ask_authorization_dialog_new (picasa_web_service_get_authorization_url (self));
+	gtk_window_set_default_size (GTK_WINDOW (dialog), 680, 580);
+	_web_service_set_auth_dialog (WEB_SERVICE (self), GTK_DIALOG (dialog));
+
+	g_signal_connect (OAUTH2_ASK_AUTHORIZATION_DIALOG (dialog),
+			  "loaded",
+			  G_CALLBACK (ask_authorization_dialog_loaded_cb),
+			  self);
+
+	gtk_widget_show (dialog);
+}
+
+
+/* -- _picasa_web_service_get_access_token -- */
+
+
+static void
+_picasa_web_service_get_access_token_ready_cb (SoupSession *session,
+					       SoupMessage *msg,
+					       gpointer     user_data)
+{
+	PicasaWebService   *self = user_data;
+	GSimpleAsyncResult *result;
+	GError             *error = NULL;
+	JsonNode           *node;
+
+	result = _web_service_get_result (WEB_SERVICE (self));
+
+	if (picasa_web_utils_parse_json_response (msg, &node, &error)) {
+		JsonObject   *obj;
+		OAuthAccount *account;
+
+		obj = json_node_get_object (node);
+		account = web_service_get_current_account (WEB_SERVICE (self));
+		if (account != NULL)
+			g_object_set (account,
+				      "token", json_object_get_string_member (obj, "access_token"),
+				      NULL);
+		else
+			_g_strset (&self->priv->access_token, json_object_get_string_member (obj, "access_token"));
+	}
+	else
+		g_simple_async_result_set_from_error (result, error);
+
+	g_simple_async_result_complete_in_idle (result);
+}
+
+
+static void
+_picasa_web_service_get_access_token (PicasaWebService    *self,
+				      const char          *refresh_token,
+				      GCancellable        *cancellable,
+				      GAsyncReadyCallback  callback,
+				      gpointer             user_data)
+{
+	GHashTable  *data_set;
+	SoupMessage *msg;
+
+	_g_strset (&self->priv->access_token, NULL);
+
+	data_set = g_hash_table_new (g_str_hash, g_str_equal);
+	g_hash_table_insert (data_set, "refresh_token", (gpointer) refresh_token);
+	g_hash_table_insert (data_set, "client_id", GTHUMB_PICASA_WEB_CLIENT_ID);
+	g_hash_table_insert (data_set, "client_secret", GTHUMB_PICASA_WEB_CLIENT_SECRET);
+	g_hash_table_insert (data_set, "grant_type", "refresh_token");
+	msg = soup_form_request_new_from_hash ("POST", "https://accounts.google.com/o/oauth2/token";, data_set);
+	_picasa_web_service_add_headers (self, msg);
+	_web_service_send_message (WEB_SERVICE (self),
+				   msg,
+				   cancellable,
+				   callback,
+				   user_data,
+				   _picasa_web_service_get_access_token,
+				   _picasa_web_service_get_access_token_ready_cb,
+				   self);
+
+	g_hash_table_destroy (data_set);
+}
+
+
+static gboolean
+_picasa_web_service_get_access_token_finish (PicasaWebService  *service,
+					     GAsyncResult      *result,
+					     GError           **error)
+{
+	return ! g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+}
+
+
+/* -- picasa_web_service_get_user_info -- */
+
+
+static void
+picasa_web_service_get_user_info_ready_cb (SoupSession *session,
+				           SoupMessage *msg,
+				           gpointer     user_data)
+{
+	PicasaWebService   *self = user_data;
+	GSimpleAsyncResult *result;
+	GError             *error = NULL;
+	JsonNode           *node;
+
+	result = _web_service_get_result (WEB_SERVICE (self));
+
+	if (picasa_web_utils_parse_json_response (msg, &node, &error)) {
+		OAuthAccount *account;
+
+		account = (OAuthAccount *) json_gobject_deserialize (OAUTH_TYPE_ACCOUNT, node);
+		g_object_set (account,
+			      "token", self->priv->access_token,
+			      "token-secret", self->priv->refresh_token,
+			      NULL);
+		web_service_set_current_account (WEB_SERVICE (self), account);
+
+		g_simple_async_result_set_op_res_gpointer (result,
+							   g_object_ref (account),
+							   (GDestroyNotify) g_object_unref);
+
+		_g_object_unref (account);
+		json_node_free (node);
+	}
+	else
+		g_simple_async_result_set_from_error (result, error);
+
+	g_simple_async_result_complete_in_idle (result);
+}
+
+
+typedef struct {
+	PicasaWebService    *service;
+	GCancellable        *cancellable;
+	GAsyncReadyCallback  callback;
+	gpointer	     user_data;
+} AccessTokenData;
+
+
+static void
+access_token_data_free (AccessTokenData *data)
+{
+	_g_object_unref (data->cancellable);
+	g_free (data);
+}
+
+
+static void
+picasa_web_service_get_user_info (WebService          *base,
+				  GCancellable        *cancellable,
+				  GAsyncReadyCallback  callback,
+				  gpointer	       user_data);
+
+
+static void
+access_token_ready_cb (GObject      *source_object,
+		       GAsyncResult *result,
+		       gpointer      user_data)
+{
+	AccessTokenData  *data = user_data;
+	PicasaWebService *self = data->service;
+	GError           *error = NULL;
+
+	if (! _picasa_web_service_get_access_token_finish (self, result, &error)) {
+		GSimpleAsyncResult *result;
+
+		result = g_simple_async_result_new (G_OBJECT (self),
+						    data->callback,
+						    data->user_data,
+						    picasa_web_service_get_user_info);
+		g_simple_async_result_take_error (result, error);
+		g_simple_async_result_complete_in_idle (result);
+
+		access_token_data_free (data);
+		return;
+	}
+
+	/* call get_user_info again, now that we have the access token */
+	picasa_web_service_get_user_info (WEB_SERVICE (self),
+					  data->cancellable,
+					  data->callback,
+					  data->user_data);
+
+	access_token_data_free (data);
+}
+
+
+static void
+picasa_web_service_get_user_info (WebService          *base,
+				  GCancellable        *cancellable,
+				  GAsyncReadyCallback  callback,
+				  gpointer	       user_data)
+{
+	PicasaWebService *self = PICASA_WEB_SERVICE (base);
+	OAuthAccount     *account;
+	GHashTable       *data_set;
+	SoupMessage      *msg;
+
+	account = web_service_get_current_account (WEB_SERVICE (self));
+	if (account != NULL) {
+		_g_strset (&self->priv->refresh_token, account->token_secret);
+		_g_strset (&self->priv->access_token, account->token);
+	}
+
+	data_set = g_hash_table_new (g_str_hash, g_str_equal);
+	if (self->priv->access_token != NULL) {
+		msg = soup_form_request_new_from_hash ("GET", "https://www.googleapis.com/oauth2/v2/userinfo";, data_set);
+		_picasa_web_service_add_headers (self, msg);
+		_web_service_send_message (WEB_SERVICE (self),
+					   msg,
+					   cancellable,
+					   callback,
+					   user_data,
+					   picasa_web_service_get_user_info,
+					   picasa_web_service_get_user_info_ready_cb,
+					   self);
+	}
+	else {
+		/* Get the access token from the refresh token */
+
+		AccessTokenData *data;
+
+		data = g_new0 (AccessTokenData, 1);
+		data->service = self;
+		data->cancellable = _g_object_ref (cancellable);
+		data->callback = callback;
+		data->user_data = user_data;
+		_picasa_web_service_get_access_token (self,
+						      self->priv->refresh_token,
+						      cancellable,
+						      access_token_ready_cb,
+						      data);
+	}
+
+	g_hash_table_destroy (data_set);
+}
+
+
 static void
 picasa_web_service_class_init (PicasaWebServiceClass *klass)
 {
-	GObjectClass *object_class;
+	GObjectClass    *object_class;
+	WebServiceClass *service_class;
 
 	g_type_class_add_private (klass, sizeof (PicasaWebServicePrivate));
 
 	object_class = (GObjectClass*) klass;
 	object_class->finalize = picasa_web_service_finalize;
+
+	service_class = (WebServiceClass*) klass;
+	service_class->ask_authorization = picasa_web_service_ask_authorization;
+	service_class->get_user_info = picasa_web_service_get_user_info;
 }
 
 
@@ -99,28 +587,37 @@ static void
 picasa_web_service_init (PicasaWebService *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, PICASA_TYPE_WEB_SERVICE, PicasaWebServicePrivate);
-	self->priv->conn = NULL;
-	self->priv->user = NULL;
+	self->priv->refresh_token = NULL;
+	self->priv->access_token = NULL;
+	self->priv->quota_limit = 0;
+	self->priv->quota_used = 0;
 	self->priv->post_photos = NULL;
 }
 
 
 PicasaWebService *
-picasa_web_service_new (GoogleConnection *conn)
+picasa_web_service_new (GCancellable	*cancellable,
+		        GtkWidget	*browser,
+		        GtkWidget	*dialog)
 {
-	PicasaWebService *self;
-
-	self = (PicasaWebService *) g_object_new (PICASA_TYPE_WEB_SERVICE, NULL);
-	self->priv->conn = g_object_ref (conn);
-
-	return self;
+	return g_object_new (PICASA_TYPE_WEB_SERVICE,
+			     "service-name", "picasaweb",
+			     "service-address", "picasaweb.google.com",
+			     "service-protocol", "https",
+			     "cancellable", cancellable,
+			     "browser", browser,
+			     "dialog", dialog,
+			     NULL);
 }
 
 
-PicasaWebUser *
-picasa_web_service_get_user (PicasaWebService *self)
+guint64
+picasa_web_service_get_free_space (PicasaWebService *self)
 {
-	return self->priv->user;
+	if (self->priv->quota_limit >= self->priv->quota_used)
+		return (guint64) (self->priv->quota_limit - self->priv->quota_used);
+	else
+		return 0;
 }
 
 
@@ -138,7 +635,7 @@ list_albums_ready_cb (SoupSession *session,
 	DomDocument        *doc;
 	GError             *error = NULL;
 
-	result = google_connection_get_result (self->priv->conn);
+	result = _web_service_get_result (WEB_SERVICE (self));
 
 	if (msg->status_code != 200) {
 		g_simple_async_result_set_error (result,
@@ -164,9 +661,6 @@ list_albums_ready_cb (SoupSession *session,
 			DomElement     *node;
 			PicasaWebAlbum *album;
 
-			self->priv->user = picasa_web_user_new ();
-			dom_domizable_load_from_element (DOM_DOMIZABLE (self->priv->user), feed_node);
-
 			album = NULL;
 			for (node = feed_node->first_child;
 			     node != NULL;
@@ -178,6 +672,12 @@ list_albums_ready_cb (SoupSession *session,
 					album = picasa_web_album_new ();
 					dom_domizable_load_from_element (DOM_DOMIZABLE (album), node);
 				}
+				else if (g_strcmp0 (node->tag_name, "gphoto:quotalimit") == 0) {
+					self->priv->quota_limit = g_ascii_strtoull (dom_element_get_inner_text (node), NULL, 10);
+				}
+				else if (g_strcmp0 (node->tag_name, "gphoto:quotacurrent") == 0) {
+					self->priv->quota_used = g_ascii_strtoull (dom_element_get_inner_text (node), NULL, 10);
+				}
 			}
 			if (album != NULL)
 				albums = g_list_prepend (albums, album);
@@ -198,28 +698,30 @@ list_albums_ready_cb (SoupSession *session,
 
 void
 picasa_web_service_list_albums (PicasaWebService    *self,
-			        const char          *user_id,
 			        GCancellable        *cancellable,
 			        GAsyncReadyCallback  callback,
 			        gpointer             user_data)
 {
-	char        *url;
-	SoupMessage *msg;
+	OAuthAccount *account;
+	SoupMessage  *msg;
+	char         *url;
 
-	g_return_if_fail (user_id != NULL);
+	account = web_service_get_current_account (WEB_SERVICE (self));
+	g_return_if_fail (account != NULL);
 
-	gth_task_progress (GTH_TASK (self->priv->conn), _("Getting the album list"), NULL, TRUE, 0.0);
+	gth_task_progress (GTH_TASK (self), _("Getting the album list"), NULL, TRUE, 0.0);
 
-	url = g_strconcat ("http://picasaweb.google.com/data/feed/api/user/";, user_id, NULL);
+	url = g_strconcat ("https://picasaweb.google.com/data/feed/api/user/";, account->id, NULL);
 	msg = soup_message_new ("GET", url);
-	google_connection_send_message (self->priv->conn,
-					msg,
-					cancellable,
-					callback,
-					user_data,
-					picasa_web_service_list_albums,
-					list_albums_ready_cb,
-					self);
+	_picasa_web_service_add_headers (self, msg);
+	_web_service_send_message (WEB_SERVICE (self),
+				   msg,
+				   cancellable,
+				   callback,
+				   user_data,
+				   picasa_web_service_list_albums,
+				   list_albums_ready_cb,
+				   self);
 
 	g_free (url);
 }
@@ -251,7 +753,7 @@ create_album_ready_cb (SoupSession *session,
 	DomDocument        *doc;
 	GError             *error = NULL;
 
-	result = google_connection_get_result (self->priv->conn);
+	result = _web_service_get_result (WEB_SERVICE (self));
 
 	if (msg->status_code != 201) {
 		g_simple_async_result_set_error (result,
@@ -290,36 +792,36 @@ picasa_web_service_create_album (PicasaWebService     *self,
 				 GAsyncReadyCallback   callback,
 				 gpointer              user_data)
 {
-	DomDocument *doc;
-	DomElement  *entry;
-	char        *buffer;
-	gsize        len;
-	char        *url;
-	SoupMessage *msg;
+	OAuthAccount *account;
+	DomDocument  *doc;
+	DomElement   *entry;
+	char         *buffer;
+	gsize         len;
+	char         *url;
+	SoupMessage  *msg;
 
-	g_return_if_fail (self->priv->user != NULL);
+	account = web_service_get_current_account (WEB_SERVICE (self));
+	g_return_if_fail (account != NULL);
 
-	gth_task_progress (GTH_TASK (self->priv->conn), _("Creating the new album"), NULL, TRUE, 0.0);
+	gth_task_progress (GTH_TASK (self), _("Creating the new album"), NULL, TRUE, 0.0);
 
 	doc = dom_document_new ();
 	entry = dom_domizable_create_element (DOM_DOMIZABLE (album), doc);
-	dom_element_set_attribute (entry, "xmlns", "http://www.w3.org/2005/Atom";);
-	dom_element_set_attribute (entry, "xmlns:media", "http://search.yahoo.com/mrss/";);
-	dom_element_set_attribute (entry, "xmlns:gphoto", "http://schemas.google.com/photos/2007";);
 	dom_element_append_child (DOM_ELEMENT (doc), entry);
 	buffer = dom_document_dump (doc, &len);
 
-	url = g_strconcat ("http://picasaweb.google.com/data/feed/api/user/";, self->priv->user->id, NULL);
+	url = g_strconcat ("https://picasaweb.google.com/data/feed/api/user/";, account->id, NULL);
 	msg = soup_message_new ("POST", url);
 	soup_message_set_request (msg, ATOM_ENTRY_MIME_TYPE, SOUP_MEMORY_TAKE, buffer, len);
-	google_connection_send_message (self->priv->conn,
-					msg,
-					cancellable,
-					callback,
-					user_data,
-					picasa_web_service_create_album,
-					create_album_ready_cb,
-					self);
+	_picasa_web_service_add_headers (self, msg);
+	_web_service_send_message (WEB_SERVICE (self),
+				   msg,
+				   cancellable,
+				   callback,
+				   user_data,
+				   picasa_web_service_create_album,
+				   create_album_ready_cb,
+				   self);
 
 	g_free (url);
 	g_object_unref (doc);
@@ -347,7 +849,7 @@ post_photos_done (PicasaWebService *self,
 {
 	GSimpleAsyncResult *result;
 
-	result = google_connection_get_result (self->priv->conn);
+	result = _web_service_get_result (WEB_SERVICE (self));
 	if (error == NULL) {
 		g_simple_async_result_set_op_res_gboolean (result, TRUE);
 	}
@@ -380,7 +882,9 @@ post_photo_ready_cb (SoupSession *session,
 	if (msg->status_code != 201) {
 		GError *error;
 
-		error = g_error_new_literal (SOUP_HTTP_ERROR, msg->status_code, soup_status_get_phrase (msg->status_code));
+		error = g_error_new_literal (SOUP_HTTP_ERROR,
+					     msg->status_code,
+					     soup_status_get_phrase (msg->status_code));
 		post_photos_done (self, error);
 		g_error_free (error);
 
@@ -413,7 +917,7 @@ upload_photo_wrote_body_data_cb (SoupMessage *msg,
 	/* Translators: %s is a filename */
 	details = g_strdup_printf (_("Uploading '%s'"), g_file_info_get_display_name (file_data->info));
 	current_file_fraction = (double) self->priv->post_photos->wrote_body_data_size / msg->request_body->length;
-	gth_task_progress (GTH_TASK (self->priv->conn),
+	gth_task_progress (GTH_TASK (self),
 			   NULL,
 			   details,
 			   FALSE,
@@ -430,6 +934,7 @@ post_photo_file_buffer_ready_cb (void     **buffer,
 				 gpointer   user_data)
 {
 	PicasaWebService   *self = user_data;
+	OAuthAccount       *account;
 	GthFileData        *file_data;
 	SoupMultipart      *multipart;
 	const char         *filename;
@@ -451,6 +956,7 @@ post_photo_file_buffer_ready_cb (void     **buffer,
 		return;
 	}
 
+	account = web_service_get_current_account (WEB_SERVICE (self));
 	file_data = self->priv->post_photos->current->data;
 	multipart = soup_multipart_new ("multipart/related");
 
@@ -543,8 +1049,8 @@ post_photo_file_buffer_ready_cb (void     **buffer,
 	/* send the file */
 
 	self->priv->post_photos->wrote_body_data_size = 0;
-	url = g_strconcat ("http://picasaweb.google.com/data/feed/api/user/";,
-			   self->priv->user->id,
+	url = g_strconcat ("https://picasaweb.google.com/data/feed/api/user/";,
+			   account->id,
 			   "/albumid/",
 			   self->priv->post_photos->album->id,
 			   NULL);
@@ -554,14 +1060,15 @@ post_photo_file_buffer_ready_cb (void     **buffer,
 			  (GCallback) upload_photo_wrote_body_data_cb,
 			  self);
 
-	google_connection_send_message (self->priv->conn,
-					msg,
-					self->priv->post_photos->cancellable,
-					self->priv->post_photos->callback,
-					self->priv->post_photos->user_data,
-					picasa_web_service_post_photos,
-					post_photo_ready_cb,
-					self);
+	_picasa_web_service_add_headers (self, msg);
+	_web_service_send_message (WEB_SERVICE (self),
+				   msg,
+				   self->priv->post_photos->cancellable,
+				   self->priv->post_photos->callback,
+				   self->priv->post_photos->user_data,
+				   picasa_web_service_post_photos,
+				   post_photo_ready_cb,
+				   self);
 
 	g_free (url);
 	soup_multipart_free (multipart);
@@ -628,7 +1135,11 @@ picasa_web_service_post_photos (PicasaWebService    *self,
 	g_return_if_fail (album != NULL);
 	g_return_if_fail (self->priv->post_photos == NULL);
 
-	gth_task_progress (GTH_TASK (self->priv->conn), _("Uploading the files to the server"), NULL, TRUE, 0.0);
+	gth_task_progress (GTH_TASK (self),
+			   _("Uploading the files to the server"),
+			   NULL,
+			   TRUE,
+			   0.0);
 
 	self->priv->post_photos = g_new0 (PostPhotosData, 1);
 	self->priv->post_photos->album = g_object_ref (album);
@@ -673,7 +1184,7 @@ list_photos_ready_cb (SoupSession *session,
 	DomDocument        *doc;
 	GError             *error = NULL;
 
-	result = google_connection_get_result (self->priv->conn);
+	result = _web_service_get_result (WEB_SERVICE (self));
 
 	if (msg->status_code != 200) {
 		g_simple_async_result_set_error (result,
@@ -699,9 +1210,6 @@ list_photos_ready_cb (SoupSession *session,
 			DomElement     *node;
 			PicasaWebPhoto *photo;
 
-			self->priv->user = picasa_web_user_new ();
-			dom_domizable_load_from_element (DOM_DOMIZABLE (self->priv->user), feed_node);
-
 			photo = NULL;
 			for (node = feed_node->first_child;
 			     node != NULL;
@@ -738,27 +1246,35 @@ picasa_web_service_list_photos (PicasaWebService    *self,
 				GAsyncReadyCallback  callback,
 				gpointer             user_data)
 {
-	char        *url;
-	SoupMessage *msg;
+	OAuthAccount *account;
+	char         *url;
+	SoupMessage  *msg;
 
+	account = web_service_get_current_account (WEB_SERVICE (self));
+	g_return_if_fail (account != NULL);
 	g_return_if_fail (album != NULL);
 
-	gth_task_progress (GTH_TASK (self->priv->conn), _("Getting the photo list"), NULL, TRUE, 0.0);
+	gth_task_progress (GTH_TASK (self),
+			   _("Getting the photo list"),
+			   NULL,
+			   TRUE,
+			   0.0);
 
-	url = g_strconcat ("http://picasaweb.google.com/data/feed/api/user/";,
-			   self->priv->user->id,
+	url = g_strconcat ("https://picasaweb.google.com/data/feed/api/user/";,
+			   account->id,
 			   "/albumid/",
 			   album->id,
 			   NULL);
 	msg = soup_message_new ("GET", url);
-	google_connection_send_message (self->priv->conn,
-					msg,
-					cancellable,
-					callback,
-					user_data,
-					picasa_web_service_list_photos,
-					list_photos_ready_cb,
-					self);
+	_picasa_web_service_add_headers (self, msg);
+	_web_service_send_message (WEB_SERVICE (self),
+				   msg,
+				   cancellable,
+				   callback,
+				   user_data,
+				   picasa_web_service_list_photos,
+				   list_photos_ready_cb,
+				   self);
 
 	g_free (url);
 }
@@ -774,92 +1290,3 @@ picasa_web_service_list_photos_finish (PicasaWebService  *self,
 	else
 		return _g_object_list_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
 }
-
-
-/* utilities */
-
-
-GList *
-picasa_web_accounts_load_from_file (char **_default)
-{
-	GList       *accounts = NULL;
-	GFile       *file;
-	char        *buffer;
-	gsize        len;
-	DomDocument *doc;
-
-	file = gth_user_dir_get_file_for_read (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", "picasaweb.xml", NULL);
-	if (! _g_file_load_in_buffer (file, (void **) &buffer, &len, NULL, NULL)) {
-		g_object_unref (file);
-		return NULL;
-	}
-
-	doc = dom_document_new ();
-	if (dom_document_load (doc, buffer, len, NULL)) {
-		DomElement *node;
-
-		node = DOM_ELEMENT (doc)->first_child;
-		if ((node != NULL) && (g_strcmp0 (node->tag_name, "accounts") == 0)) {
-			DomElement *child;
-
-			for (child = node->first_child;
-			     child != NULL;
-			     child = child->next_sibling)
-			{
-				if (strcmp (child->tag_name, "account") == 0) {
-					const char *value;
-
-					value = dom_element_get_attribute (child, "email");
-					if (value != NULL)
-						accounts = g_list_prepend (accounts, g_strdup (value));
-					if ((_default != NULL)  && (g_strcmp0 (dom_element_get_attribute (child, "default"), "1") == 0))
-						*_default = g_strdup (value);
-				}
-			}
-
-			accounts = g_list_reverse (accounts);
-		}
-	}
-
-	g_object_unref (doc);
-	g_free (buffer);
-	g_object_unref (file);
-
-	return accounts;
-}
-
-
-void
-picasa_web_accounts_save_to_file (GList      *accounts,
-				  const char *_default)
-{
-	DomDocument *doc;
-	DomElement  *root;
-	GList       *scan;
-	char        *buffer;
-	gsize        len;
-	GFile       *file;
-
-	doc = dom_document_new ();
-	root = dom_document_create_element (doc, "accounts", NULL);
-	dom_element_append_child (DOM_ELEMENT (doc), root);
-	for (scan = accounts; scan; scan = scan->next) {
-		const char *email = scan->data;
-		DomElement *node;
-
-		node = dom_document_create_element (doc, "account",
-						    "email", email,
-						    NULL);
-		if (g_strcmp0 (email, _default) == 0)
-			dom_element_set_attribute (node, "default", "1");
-		dom_element_append_child (root, node);
-	}
-
-	file = gth_user_dir_get_file_for_write (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", "picasaweb.xml", NULL);
-	buffer = dom_document_dump (doc, &len);
-	_g_file_write (file, FALSE, G_FILE_CREATE_PRIVATE | G_FILE_CREATE_REPLACE_DESTINATION, buffer, len, NULL, NULL);
-
-	g_free (buffer);
-	g_object_unref (file);
-	g_object_unref (doc);
-}
diff --git a/extensions/picasaweb/picasa-web-service.h b/extensions/picasaweb/picasa-web-service.h
index 8f1b48f..a2c59ea 100644
--- a/extensions/picasaweb/picasa-web-service.h
+++ b/extensions/picasaweb/picasa-web-service.h
@@ -3,7 +3,7 @@
 /*
  *  GThumb
  *
- *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *  Copyright (C) 2010-2012 Free Software Foundation, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -22,10 +22,11 @@
 #ifndef PICASA_WEB_SERVICE_H
 #define PICASA_WEB_SERVICE_H
 
-#include <glib-object.h>
-#include "google-connection.h"
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include <extensions/oauth/oauth.h>
 #include "picasa-web-album.h"
-#include "picasa-web-user.h"
+#include "picasa-web-types.h"
 
 #define PICASA_TYPE_WEB_SERVICE         (picasa_web_service_get_type ())
 #define PICASA_WEB_SERVICE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), PICASA_TYPE_WEB_SERVICE, PicasaWebService))
@@ -40,20 +41,21 @@ typedef struct _PicasaWebServiceClass    PicasaWebServiceClass;
 
 struct _PicasaWebService
 {
-	GObject __parent;
+	WebService __parent;
 	PicasaWebServicePrivate *priv;
 };
 
 struct _PicasaWebServiceClass
 {
-	GObjectClass __parent_class;
+	WebServiceClass __parent_class;
 };
 
 GType                picasa_web_service_get_type            (void) G_GNUC_CONST;
-PicasaWebService *   picasa_web_service_new                 (GoogleConnection     *conn);
-PicasaWebUser *      picasa_web_service_get_user            (PicasaWebService     *self);
+PicasaWebService *   picasa_web_service_new                 (GCancellable         *cancellable,
+							     GtkWidget            *browser,
+							     GtkWidget            *dialog);
+guint64              picasa_web_service_get_free_space      (PicasaWebService     *self);
 void                 picasa_web_service_list_albums         (PicasaWebService     *self,
-						             const char           *user_id,
 						             GCancellable         *cancellable,
 						             GAsyncReadyCallback   callback,
 						             gpointer              user_data);
@@ -88,10 +90,4 @@ GList *              picasa_web_service_list_photos_finish  (PicasaWebService
 							     GAsyncResult         *result,
 							     GError              **error);
 
-/* utilities */
-
-GList *              picasa_web_accounts_load_from_file    (char       **_default);
-void                 picasa_web_accounts_save_to_file      (GList       *accounts,
-							    const char  *_default);
-
 #endif /* PICASA_WEB_SERVICE_H */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 53bb25f..d372a8f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -536,24 +536,13 @@ extensions/picasaweb/callbacks.c
 extensions/picasaweb/callbacks.h
 [type: gettext/glade]extensions/picasaweb/data/ui/export-to-picasaweb.ui
 [type: gettext/glade]extensions/picasaweb/data/ui/import-from-picasaweb.ui
-[type: gettext/glade]extensions/picasaweb/data/ui/picasa-web-account-chooser.ui
-[type: gettext/glade]extensions/picasaweb/data/ui/picasa-web-account-manager.ui
-[type: gettext/glade]extensions/picasaweb/data/ui/picasa-web-account-properties.ui
 [type: gettext/glade]extensions/picasaweb/data/ui/picasa-web-album-properties.ui
 [type: gettext/glade]extensions/picasaweb/data/ui/picasa-web-export-completed.ui
 extensions/picasaweb/dlg-export-to-picasaweb.c
 extensions/picasaweb/dlg-export-to-picasaweb.h
 extensions/picasaweb/dlg-import-from-picasaweb.c
 extensions/picasaweb/dlg-import-from-picasaweb.h
-extensions/picasaweb/google-connection.c
-extensions/picasaweb/google-connection.h
 extensions/picasaweb/main.c
-extensions/picasaweb/picasa-account-chooser-dialog.c
-extensions/picasaweb/picasa-account-chooser-dialog.h
-extensions/picasaweb/picasa-account-manager-dialog.c
-extensions/picasaweb/picasa-account-manager-dialog.h
-extensions/picasaweb/picasa-account-properties-dialog.c
-extensions/picasaweb/picasa-account-properties-dialog.h
 extensions/picasaweb/picasa-album-properties-dialog.c
 extensions/picasaweb/picasa-album-properties-dialog.h
 extensions/picasaweb/picasa-web-album.c
@@ -564,8 +553,6 @@ extensions/picasaweb/picasa-web-photo.h
 extensions/picasaweb/picasa-web-service.c
 extensions/picasaweb/picasa-web-service.h
 extensions/picasaweb/picasa-web-types.h
-extensions/picasaweb/picasa-web-user.c
-extensions/picasaweb/picasa-web-user.h
 extensions/picasaweb/preferences.h
 extensions/raw_files/main.c
 [type: gettext/ini]extensions/raw_files/raw_files.extension.in.in



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]