[gthumb: 3/22] [picasaweb] read the album list
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb: 3/22] [picasaweb] read the album list
- Date: Sat, 30 Jan 2010 23:19:31 +0000 (UTC)
commit a52a67ac522268f607d0f7ca4cc359cdc57edbab
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Jan 24 18:06:37 2010 +0100
[picasaweb] read the album list
extensions/picasaweb/Makefile.am | 6 +-
extensions/picasaweb/data/ui/Makefile.am | 8 +-
.../picasaweb/data/ui/export-to-picasaweb.ui | 59 ++--
.../data/ui/picasa-web-account-manager.ui | 134 ++++++++
.../data/ui/picasa-web-account-properties.ui | 143 ++++++++
extensions/picasaweb/data/ui/picasaweb-account.ui | 358 --------------------
extensions/picasaweb/dlg-export-to-picasaweb.c | 356 +++++++++++---------
extensions/picasaweb/google-connection.c | 258 +++++++++++++-
extensions/picasaweb/google-connection.h | 40 ++-
.../picasaweb/gth-account-properties-dialog.c | 114 ++++++-
.../picasaweb/gth-account-properties-dialog.h | 3 +-
extensions/picasaweb/picasa-web-album.c | 284 ++++++++++++++++
extensions/picasaweb/picasa-web-album.h | 85 +++++
extensions/picasaweb/picasa-web-service.c | 292 ++++++++++++++++-
extensions/picasaweb/picasa-web-service.h | 34 ++-
15 files changed, 1562 insertions(+), 612 deletions(-)
---
diff --git a/extensions/picasaweb/Makefile.am b/extensions/picasaweb/Makefile.am
index 4a86d7a..d91c56b 100644
--- a/extensions/picasaweb/Makefile.am
+++ b/extensions/picasaweb/Makefile.am
@@ -19,13 +19,15 @@ libpicasaweb_la_SOURCES = \
gth-account-properties-dialog.c \
gth-account-properties-dialog.h \
main.c \
+ picasa-web-album.c \
+ picasa-web-album.h \
picasa-web-service.c \
picasa-web-service.h \
preferences.h
-libpicasaweb_la_CPPFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(GNOME_KEYRING_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
+libpicasaweb_la_CFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(GNOME_KEYRING_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
libpicasaweb_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
-libpicasaweb_la_LIBADD = $(GTHUMB_LIBS)
+libpicasaweb_la_LIBADD = $(GTHUMB_LIBS)
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 c5ff2c3..c8d5702 100644
--- a/extensions/picasaweb/data/ui/Makefile.am
+++ b/extensions/picasaweb/data/ui/Makefile.am
@@ -1,7 +1,9 @@
uidir = $(pkgdatadir)/ui
-ui_DATA = \
- export-to-picasaweb.ui \
- picasaweb-account.ui
+ui_DATA = \
+ export-to-picasaweb.ui \
+ picasa-web-account-manager.ui \
+ picasa-web-account-properties.ui \
+ picasa-web-album-properties.ui
EXTRA_DIST = $(ui_DATA)
-include $(top_srcdir)/git.mk
diff --git a/extensions/picasaweb/data/ui/export-to-picasaweb.ui b/extensions/picasaweb/data/ui/export-to-picasaweb.ui
index 9ee5b76..2c7e1c1 100644
--- a/extensions/picasaweb/data/ui/export-to-picasaweb.ui
+++ b/extensions/picasaweb/data/ui/export-to-picasaweb.ui
@@ -2,6 +2,34 @@
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
+ <object class="GtkListStore" id="account_liststore">
+ <columns>
+ <!-- column-name account -->
+ <column type="gchararray"/>
+ <!-- column-name type -->
+ <column type="gint"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ <!-- column-name icon -->
+ <column type="gchararray"/>
+ <!-- column-name sensitive -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="album_liststore">
+ <columns>
+ <!-- column-name album -->
+ <column type="GObject"/>
+ <!-- column-name type -->
+ <column type="gint"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ <!-- column-name icon -->
+ <column type="gchararray"/>
+ <!-- column-name sensitive -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
<object class="GtkDialog" id="export_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Upload to Picasa Web Albums</property>
@@ -59,6 +87,7 @@
</child>
</object>
<packing>
+ <property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
@@ -74,6 +103,7 @@
<property name="use_underline">True</property>
</object>
<packing>
+ <property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
@@ -161,7 +191,6 @@
</child>
</object>
<packing>
- <property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
@@ -232,34 +261,6 @@
<property name="visible">True</property>
<property name="stock">gtk-goto-top</property>
</object>
- <object class="GtkListStore" id="album_liststore">
- <columns>
- <!-- column-name album data -->
- <column type="gpointer"/>
- <!-- column-name type -->
- <column type="gint"/>
- <!-- column-name name -->
- <column type="gchararray"/>
- <!-- column-name icon name -->
- <column type="gchararray"/>
- <!-- column-name sensitive -->
- <column type="gboolean"/>
- </columns>
- </object>
- <object class="GtkListStore" id="account_liststore">
- <columns>
- <!-- column-name account data -->
- <column type="gpointer"/>
- <!-- column-name type -->
- <column type="gint"/>
- <!-- column-name name -->
- <column type="gchararray"/>
- <!-- column-name icon name -->
- <column type="gchararray"/>
- <!-- column-name sensitive -->
- <column type="gboolean"/>
- </columns>
- </object>
<object class="GtkDialog" id="choose_account_dialog">
<property name="border_width">5</property>
<property name="type_hint">normal</property>
diff --git a/extensions/picasaweb/data/ui/picasa-web-account-manager.ui b/extensions/picasaweb/data/ui/picasa-web-account-manager.ui
new file mode 100644
index 0000000..ea42ea6
--- /dev/null
+++ b/extensions/picasaweb/data/ui/picasa-web-account-manager.ui
@@ -0,0 +1,134 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkListStore" id="accounts_liststore">
+ <columns>
+ <!-- column-name account -->
+ <column type="gpointer"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkVBox" id="account_manager">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Accounts:</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="account_treeview">
+ <property name="width_request">300</property>
+ <property name="height_request">150</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">accounts_liststore</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">1</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="button6">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button7">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-properties</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button8">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child>
+ <object class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="stock">gtk-delete</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/extensions/picasaweb/data/ui/picasa-web-account-properties.ui b/extensions/picasaweb/data/ui/picasa-web-account-properties.ui
new file mode 100644
index 0000000..de138f3
--- /dev/null
+++ b/extensions/picasaweb/data/ui/picasa-web-account-properties.ui
@@ -0,0 +1,143 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkListStore" id="accounts_liststore">
+ <columns>
+ <!-- column-name account -->
+ <column type="gpointer"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkVBox" id="account_properties">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_E-Mail:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">email_entry</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="email_entry">
+ <property name="width_request">300</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="password_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="challange_box">
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="challenge_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Type the characters you see in the picture below. Letters are not case-sensitive.</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="challenge_image">
+ <property name="visible">True</property>
+ <property name="ypad">12</property>
+ <property name="stock">gtk-missing-image</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="challenge_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="top_padding">5</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">_Password:</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/extensions/picasaweb/dlg-export-to-picasaweb.c b/extensions/picasaweb/dlg-export-to-picasaweb.c
index 4b237ff..599ba53 100644
--- a/extensions/picasaweb/dlg-export-to-picasaweb.c
+++ b/extensions/picasaweb/dlg-export-to-picasaweb.c
@@ -29,6 +29,7 @@
#include "dlg-export-to-picasaweb.h"
#include "gth-account-chooser-dialog.h"
#include "gth-account-properties-dialog.h"
+#include "picasa-web-album.h"
#include "picasa-web-service.h"
@@ -68,6 +69,7 @@ typedef struct {
GList *accounts;
char *email;
char *password;
+ char *challange;
GList *albums;
GoogleConnection *conn;
PicasaWebService *picasaweb;
@@ -79,10 +81,15 @@ static void
export_dialog_destroy_cb (GtkWidget *widget,
DialogData *data)
{
+ picasa_web_accounts_save_to_file (data->albums);
+ if (data->conn != NULL)
+ gth_task_completed (GTH_TASK (data->conn), NULL);
+
_g_object_unref (data->cancellable);
_g_object_unref (data->picasaweb);
_g_object_unref (data->conn);
_g_object_list_unref (data->albums);
+ g_free (data->challange);
g_free (data->password);
g_free (data->email);
_g_string_list_free (data->accounts);
@@ -103,6 +110,7 @@ export_dialog_response_cb (GtkDialog *dialog,
show_help_dialog (GTK_WINDOW (data->browser), "export-to-picasaweb");
break;
+ case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_CANCEL:
gtk_widget_destroy (data->dialog);
break;
@@ -119,7 +127,66 @@ export_dialog_response_cb (GtkDialog *dialog,
static void
show_export_dialog (DialogData *data)
{
- /* FIXME: update widgets data */
+ GtkTreeIter iter;
+ int current_account;
+ int idx;
+ GList *scan;
+
+ /* Accounts */
+
+ gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("account_liststore")));
+
+ current_account = 0;
+ 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_DATA_COLUMN, account,
+ ACCOUNT_TYPE_COLUMN, ITEM_TYPE_ENTRY,
+ ACCOUNT_NAME_COLUMN, account,
+ ACCOUNT_SENSITIVE_COLUMN, TRUE,
+ -1);
+ }
+
+ 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_TYPE_COLUMN, ITEM_TYPE_SEPARATOR,
+ ACCOUNT_SENSITIVE_COLUMN, TRUE,
+ -1);
+
+ 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, NULL,
+ ACCOUNT_TYPE_COLUMN, ITEM_TYPE_COMMAND,
+ ACCOUNT_ICON_COLUMN, GTK_STOCK_EDIT,
+ ACCOUNT_NAME_COLUMN, _("Edit Accounts..."),
+ ACCOUNT_SENSITIVE_COLUMN, TRUE,
+ -1);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), current_account);
+
+ /* Albums */
+
+ gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("album_liststore")));
+
+ for (scan = data->albums; scan; scan = scan->next) {
+ PicasaWebAlbum *album = scan->data;
+
+ 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_TYPE_COLUMN, ITEM_TYPE_ENTRY,
+ ALBUM_NAME_COLUMN, album->title,
+ ALBUM_SENSITIVE_COLUMN, TRUE,
+ -1);
+ }
+
+ gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), data->albums != NULL);
+
+ /**/
gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (data->browser));
gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
@@ -149,17 +216,43 @@ list_albums_ready_cb (GObject *source_object,
static void
+get_album_list (DialogData *data)
+{
+ if (data->picasaweb == NULL)
+ data->picasaweb = picasa_web_service_new (data->conn);
+ picasa_web_service_list_albums (data->picasaweb,
+ "default",
+ data->cancellable,
+ list_albums_ready_cb,
+ data);
+}
+
+
+#ifdef HAVE_GNOME_KEYRING
+static void
+store_password_done_cb (GnomeKeyringResult result,
+ gpointer user_data)
+{
+ get_album_list ((DialogData *) user_data);
+}
+#endif
+
+
+static void challange_account_dialog (DialogData *data);
+
+
+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;
+ GError *error = NULL;
if (! google_connection_connect_finish (conn, result, &error)) {
if (g_error_matches (error, GOOGLE_CONNECTION_ERROR, GOOGLE_CONNECTION_ERROR_CAPTCHA_REQUIRED)) {
- /* FIXME: request to insert the captcha text */
+ challange_account_dialog (data);
}
else {
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not connect to the server"), &error);
@@ -168,13 +261,27 @@ connection_ready_cb (GObject *source_object,
return;
}
- if (data->picasaweb == NULL)
- data->picasaweb = picasa_web_service_new (conn);
- picasa_web_service_list_albums (data->picasaweb,
- "default",
- data->cancellable,
- list_albums_ready_cb,
- data);
+ if (! g_list_find_custom (data->accounts, data->email, (GCompareFunc) strcmp))
+ data->accounts = g_list_append (data->accounts, g_strdup (data->email));
+
+#ifdef HAVE_GNOME_KEYRING
+ if (gnome_keyring_is_available ()) {
+ gnome_keyring_store_password (GNOME_KEYRING_NETWORK_PASSWORD,
+ GNOME_KEYRING_SESSION,
+ _("Picasa Web Album"),
+ data->password,
+ store_password_done_cb,
+ data,
+ NULL,
+ "user", data->email,
+ "server", "picasaweb.google.com",
+ "protocol", "http",
+ NULL);
+ return;
+ }
+#endif
+
+ get_album_list (data);
}
@@ -187,24 +294,78 @@ connect_to_server (DialogData *data)
gth_progress_dialog_add_task (GTH_PROGRESS_DIALOG (data->progress_dialog), GTH_TASK (data->conn));
}
+#ifdef HAVE_GNOME_KEYRING
+ if (data->password == NULL) {
+ if (gnome_keyring_is_available ()) {
+ gnome_keyring_find_password_sync (GNOME_KEYRING_NETWORK_PASSWORD,
+ &data->password,
+ "user", data->email,
+ "server", "picasaweb.google.com",
+ "protocol", "http",
+ NULL);
+ }
+ }
+#endif
+
google_connection_connect (data->conn,
data->email,
data->password,
- NULL,
+ data->challange,
data->cancellable,
connection_ready_cb,
data);
}
-#ifdef HAVE_GNOME_KEYRING
static void
-store_password_done_cb (GnomeKeyringResult result,
- gpointer user_data)
+challange_account_dialog_response_cb (GtkDialog *dialog,
+ int response_id,
+ gpointer user_data)
{
- connect_to_server ((DialogData *) user_data);
+ DialogData *data = user_data;
+
+ switch (response_id) {
+ case GTK_RESPONSE_HELP:
+ show_help_dialog (GTK_WINDOW (dialog), "challange-picasaweb-account");
+ 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 (gth_account_properties_dialog_get_email (GTH_ACCOUNT_PROPERTIES_DIALOG (dialog)));
+ data->password = g_strdup (gth_account_properties_dialog_get_password (GTH_ACCOUNT_PROPERTIES_DIALOG (dialog)));
+ data->challange = g_strdup (gth_account_properties_dialog_get_challange (GTH_ACCOUNT_PROPERTIES_DIALOG (dialog)));
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ connect_to_server (data);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void
+challange_account_dialog (DialogData *data)
+{
+ GtkWidget *dialog;
+
+ dialog = gth_account_properties_dialog_new (data->email, data->password, google_connection_get_challange_url (data->conn));
+ 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));
}
-#endif
static void
@@ -219,35 +380,21 @@ new_account_dialog_response_cb (GtkDialog *dialog,
show_help_dialog (GTK_WINDOW (dialog), "new-picasaweb-account");
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 (gth_account_properties_dialog_get_email (GTH_ACCOUNT_PROPERTIES_DIALOG (dialog)));
- data->password = g_strdup (gth_account_properties_dialog_get_password (GTH_ACCOUNT_PROPERTIES_DIALOG (dialog)));
- data->accounts = g_list_append (data->accounts, g_strdup (data->email));
-#ifdef HAVE_GNOME_KEYRING
- if (gnome_keyring_is_available ())
- gnome_keyring_store_password (GNOME_KEYRING_NETWORK_PASSWORD,
- GNOME_KEYRING_SESSION,
- _("Picasa Web Album"),
- data->password,
- store_password_done_cb,
- data,
- NULL,
- "user", data->email,
- "server", "picasaweb.google.com",
- "protocol", "http",
- NULL);
- else
-#endif
- connect_to_server (data);
- }
+ g_free (data->email);
+ g_free (data->password);
+ g_free (data->challange);
+ data->email = g_strdup (gth_account_properties_dialog_get_email (GTH_ACCOUNT_PROPERTIES_DIALOG (dialog)));
+ data->password = g_strdup (gth_account_properties_dialog_get_password (GTH_ACCOUNT_PROPERTIES_DIALOG (dialog)));
+ data->challange = NULL;
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ connect_to_server (data);
break;
default:
@@ -261,12 +408,13 @@ new_account_dialog (DialogData *data)
{
GtkWidget *dialog;
- dialog = gth_account_properties_dialog_new (NULL, NULL);
+ dialog = gth_account_properties_dialog_new (NULL, NULL, NULL);
g_signal_connect (dialog,
"response",
G_CALLBACK (new_account_dialog_response_cb),
data);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("New 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));
@@ -289,6 +437,8 @@ account_chooser_dialog_response_cb (GtkDialog *dialog,
case GTK_RESPONSE_OK:
g_free (data->password);
data->password = NULL;
+ g_free (data->challange);
+ data->challange = NULL;
g_free (data->email);
data->email = g_strdup (gth_account_chooser_dialog_get_active (GTH_ACCOUNT_CHOOSER_DIALOG (dialog)));
if (data->email != NULL) {
@@ -321,70 +471,10 @@ account_combobox_row_separator_func (GtkTreeModel *model,
}
-static gboolean
-album_combobox_row_separator_func (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer data)
-{
- int item_type;
-
- gtk_tree_model_get (model, iter, ALBUM_TYPE_COLUMN, &item_type, -1);
-
- return item_type == ITEM_TYPE_SEPARATOR;
-}
-
-
-static GList *
-picasaweb_accounts_read_from_file (void)
-{
- GList *accounts = NULL;
- char *filename;
- char *buffer;
- gsize len;
- GError *error;
- DomDocument *doc;
-
- filename = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", "picasaweb.xml", NULL);
- g_file_get_contents (filename, &buffer, &len, &error);
-
- doc = dom_document_new ();
- if (dom_document_load (doc, buffer, len, &error)) {
- 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));
- }
- }
-
- accounts = g_list_reverse (accounts);
- }
- }
-
- g_object_unref (doc);
- g_free (buffer);
- g_free (filename);
-
- return accounts;
-}
-
-
void
dlg_export_to_picasaweb (GthBrowser *browser)
{
- DialogData *data;
- GtkTreeIter iter;
+ DialogData *data;
data = g_new0 (DialogData, 1);
data->browser = browser;
@@ -398,70 +488,6 @@ dlg_export_to_picasaweb (GthBrowser *browser)
account_combobox_row_separator_func,
data,
NULL);
- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")),
- album_combobox_row_separator_func,
- data,
- NULL);
-
- /* Account */
-
- data->accounts = picasaweb_accounts_read_from_file ();
-
- /*
- 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, NULL,
- ACCOUNT_TYPE_COLUMN, ITEM_TYPE_ENTRY,
- ACCOUNT_NAME_COLUMN, "",
- ACCOUNT_SENSITIVE_COLUMN, FALSE,
- -1);
-
- 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_TYPE_COLUMN, ITEM_TYPE_SEPARATOR,
- ACCOUNT_SENSITIVE_COLUMN, TRUE,
- -1);
-
- 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, NULL,
- ACCOUNT_TYPE_COLUMN, ITEM_TYPE_COMMAND,
- ACCOUNT_ICON_COLUMN, GTK_STOCK_EDIT,
- ACCOUNT_NAME_COLUMN, _("Edit Accounts..."),
- ACCOUNT_SENSITIVE_COLUMN, TRUE,
- -1);
-
- gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), 0);
- */
-
- /* Album */
-
- /*
- 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, NULL,
- ALBUM_TYPE_COLUMN, ITEM_TYPE_ENTRY,
- ALBUM_NAME_COLUMN, _("(Empty)"),
- ALBUM_SENSITIVE_COLUMN, FALSE,
- -1);
-
- 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_TYPE_COLUMN, ITEM_TYPE_SEPARATOR,
- ALBUM_SENSITIVE_COLUMN, TRUE,
- -1);
-
- 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, NULL,
- ALBUM_TYPE_COLUMN, ITEM_TYPE_COMMAND,
- ALBUM_ICON_COLUMN, GTK_STOCK_EDIT,
- ALBUM_NAME_COLUMN, _("Edit Albums..."),
- ALBUM_SENSITIVE_COLUMN, TRUE,
- -1);
-
- gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")), 0);
- */
/* Set the signals handlers. */
diff --git a/extensions/picasaweb/google-connection.c b/extensions/picasaweb/google-connection.c
index 3a2a7bd..db78092 100644
--- a/extensions/picasaweb/google-connection.c
+++ b/extensions/picasaweb/google-connection.c
@@ -27,6 +27,10 @@
#include "google-connection.h"
+#define SOUP_LOG_LEVEL SOUP_LOGGER_LOG_BODY /* FIXME: set to SOUP_LOGGER_LOG_NONE when done */
+#define GTHUMB_SOURCE ("GNOME-" PACKAGE "-" VERSION)
+
+
GQuark
google_connection_error_quark (void)
{
@@ -39,10 +43,17 @@ google_connection_error_quark (void)
}
+/* -- GoogleConnection -- */
+
+
struct _GoogleConnectionPrivate
{
- char *service;
- char *token;
+ char *service;
+ SoupSession *session;
+ char *token;
+ char *challange_url;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *result;
};
@@ -55,8 +66,13 @@ google_connection_finalize (GObject *object)
GoogleConnection *self;
self = GOOGLE_CONNECTION (object);
- g_free (self->priv->service);
+
+ _g_object_unref (self->priv->result);
+ _g_object_unref (self->priv->cancellable);
+ g_free (self->priv->challange_url);
g_free (self->priv->token);
+ _g_object_unref (self->priv->session);
+ g_free (self->priv->service);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -99,7 +115,12 @@ google_connection_init (GoogleConnection *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GOOGLE_TYPE_CONNECTION, GoogleConnectionPrivate);
self->priv->service = NULL;
+ self->priv->session = NULL;
self->priv->token = NULL;
+ self->priv->challange_url = NULL;
+ self->priv->cancellable = NULL;
+ self->priv->result = NULL;
+
}
@@ -144,15 +165,218 @@ google_connection_new (const char *service)
void
-google_connection_connect (GoogleConnection *conn,
- const char *email,
- const char *password,
- const char *challange,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- /* FIXME */
+google_connection_send_message (GoogleConnection *self,
+ SoupMessage *msg,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ gpointer source_tag,
+ SoupSessionCallback soup_session_cb,
+ gpointer soup_session_cb_data)
+{
+ char *value;
+
+ _g_object_unref (self->priv->cancellable);
+ self->priv->cancellable = _g_object_ref (cancellable);
+
+ _g_object_unref (self->priv->result);
+ self->priv->result = g_simple_async_result_new (G_OBJECT (soup_session_cb_data),
+ callback,
+ user_data,
+ source_tag);
+
+ value = g_strconcat ("GoogleLogin auth=", self->priv->token, NULL);
+ soup_message_headers_replace (msg->request_headers, "Authorization", value);
+ g_free (value);
+
+ soup_message_headers_replace (msg->request_headers, "GData-Version", "2");
+
+ soup_session_queue_message (self->priv->session,
+ msg,
+ soup_session_cb,
+ soup_session_cb_data);
+}
+
+
+GSimpleAsyncResult *
+google_connection_get_result (GoogleConnection *self)
+{
+ return self->priv->result;
+}
+
+
+static GHashTable *
+get_keys_from_message_body (SoupBuffer *body)
+{
+ GHashTable *keys;
+ char **lines;
+ int i;
+
+ keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ lines = g_strsplit (body->data, "\n", -1);
+ for (i = 0; lines[i] != NULL; i++) {
+ char **pair;
+
+ pair = g_strsplit (lines[i], "=", 2);
+ if ((pair[0] != NULL) && (pair[1] != NULL))
+ g_hash_table_insert (keys, g_strdup (pair[0]), g_strdup (pair[1]));
+
+ g_strfreev (pair);
+ }
+
+ g_strfreev (lines);
+
+ return keys;
+}
+
+
+static void
+connect_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ GoogleConnection *self = user_data;
+ SoupBuffer *body;
+ GHashTable *keys;
+
+ body = soup_message_body_flatten (msg->response_body);
+ keys = get_keys_from_message_body (body);
+
+ g_free (self->priv->token);
+ self->priv->token = NULL;
+
+ if (msg->status_code == 403) {
+ char *error_name;
+ GError *error;
+ int error_code;
+ char *error_message;
+
+ error_name = g_hash_table_lookup (keys, "Error");
+ error_code = GOOGLE_CONNECTION_ERROR_UNKNOWN;
+ error_message = "The error is unknown or unspecified; the request contained invalid input or was malformed.";
+
+ if (error_name == NULL) {
+ /* void */
+ }
+ else if (strcmp (error_name, "BadAuthentication") == 0) {
+ error_code = GOOGLE_CONNECTION_ERROR_BAD_AUTHENTICATION;
+ error_message = "The login request used a username or password that is not recognized.";
+ }
+ else if (strcmp (error_name, "NotVerified") == 0) {
+ error_code = GOOGLE_CONNECTION_ERROR_NOT_VERIFIED;
+ error_message = "The account email address has not been verified. The user will need to access their Google account directly to resolve the issue before logging in using a non-Google application.";
+ }
+ else if (strcmp (error_name, "TermsNotAgreed") == 0) {
+ error_code = GOOGLE_CONNECTION_ERROR_TERMS_NOT_AGREED;
+ error_message = "The user has not agreed to terms. The user will need to access their Google account directly to resolve the issue before logging in using a non-Google application.";
+ }
+ else if (strcmp (error_name, "CaptchaRequired") == 0) {
+ error_code = GOOGLE_CONNECTION_ERROR_CAPTCHA_REQUIRED;
+ error_message = "A CAPTCHA is required.";
+ }
+ else if (strcmp (error_name, "AccountDeleted") == 0) {
+ error_code = GOOGLE_CONNECTION_ERROR_ACCOUNT_DELETED;
+ error_message = "The user account has been deleted.";
+ }
+ else if (strcmp (error_name, "AccountDisabled") == 0) {
+ error_code = GOOGLE_CONNECTION_ERROR_ACCOUNT_DISABLED;
+ error_message = "The user account has been disabled.";
+ }
+ else if (strcmp (error_name, "ServiceDisabled") == 0) {
+ error_code = GOOGLE_CONNECTION_ERROR_SERVICE_DISABLED;
+ error_message = "The user's access to the specified service has been disabled.";
+ }
+ else if (strcmp (error_name, "ServiceUnavailable") == 0) {
+ error_code = GOOGLE_CONNECTION_ERROR_SERVICE_UNAVAILABLE;
+ error_message = "The service is not available; try again later.";
+ }
+
+ error = g_error_new_literal (GOOGLE_CONNECTION_ERROR, error_code, error_message);
+ if (error_code == GOOGLE_CONNECTION_ERROR_CAPTCHA_REQUIRED) {
+ g_free (self->priv->challange_url);
+ self->priv->token = g_strdup (g_hash_table_lookup (keys, "CaptchaToken"));
+ self->priv->challange_url = g_strdup (g_hash_table_lookup (keys, "CaptchaUrl"));
+ }
+
+ g_simple_async_result_set_from_error (self->priv->result, error);
+ g_error_free (error);
+ }
+ else if (msg->status_code == 200) {
+ self->priv->token = g_strdup (g_hash_table_lookup (keys, "Auth"));
+ g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
+ }
+ else {
+ g_simple_async_result_set_error (self->priv->result,
+ SOUP_HTTP_ERROR,
+ msg->status_code,
+ "%s",
+ soup_status_get_phrase (msg->status_code));
+ g_simple_async_result_complete_in_idle (self->priv->result);
+ }
+
+ g_simple_async_result_complete_in_idle (self->priv->result);
+
+ g_hash_table_destroy (keys);
+ soup_buffer_free (body);
+}
+
+
+void
+google_connection_connect (GoogleConnection *self,
+ const char *email,
+ const char *password,
+ const char *challange,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SoupMessage *msg;
+ GHashTable *data_set;
+
+ g_return_if_fail (email != NULL);
+ g_return_if_fail (password != NULL);
+
+ if (self->priv->session == NULL) {
+ SoupLogger *logger;
+
+ self->priv->session = soup_session_async_new_with_options (
+#ifdef HAVE_LIBSOUP_GNOME
+ SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_GNOME,
+#endif
+ NULL);
+
+ logger = soup_logger_new (SOUP_LOG_LEVEL, -1);
+ soup_session_add_feature (self->priv->session, SOUP_SESSION_FEATURE (logger));
+
+ g_object_unref (logger);
+ }
+
+ _g_object_unref (self->priv->cancellable);
+ self->priv->cancellable = _g_object_ref (cancellable);
+
+ _g_object_unref (self->priv->result);
+ self->priv->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ google_connection_connect);
+
+ data_set = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (data_set, "accountType", "HOSTED_OR_GOOGLE");
+ g_hash_table_insert (data_set, "service", self->priv->service);
+ g_hash_table_insert (data_set, "Email", (char *) email);
+ g_hash_table_insert (data_set, "Passwd", (char *) password);
+ g_hash_table_insert (data_set, "source", GTHUMB_SOURCE);
+ if (self->priv->token != NULL)
+ g_hash_table_insert (data_set, "logintoken", self->priv->token);
+ if (challange != NULL)
+ g_hash_table_insert (data_set, "logincaptcha", (char *) challange);
+ msg = soup_form_request_new_from_hash ("POST",
+ "https://www.google.com/accounts/ClientLogin",
+ data_set);
+ soup_session_queue_message (self->priv->session, msg, connect_cb, self);
+
+ g_object_unref (msg);
+ g_hash_table_destroy (data_set);
}
@@ -161,13 +385,15 @@ google_connection_connect_finish (GoogleConnection *conn,
GAsyncResult *result,
GError **error)
{
- /* FIXME */
- return FALSE;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return FALSE;
+ else
+ return TRUE;
}
const char *
-google_connection_get_token (GoogleConnection*conn)
+google_connection_get_challange_url (GoogleConnection *self)
{
- return conn->priv->token;
+ return self->priv->challange_url;
}
diff --git a/extensions/picasaweb/google-connection.h b/extensions/picasaweb/google-connection.h
index 4227379..948f0d9 100644
--- a/extensions/picasaweb/google-connection.h
+++ b/extensions/picasaweb/google-connection.h
@@ -24,6 +24,11 @@
#define GOOGLE_CONNECTION_H
#include <glib-object.h>
+#ifdef HAVE_LIBSOUP_GNOME
+#include <libsoup/soup-gnome.h>
+#else
+#include <libsoup/soup.h>
+#endif /* HAVE_LIBSOUP_GNOME */
#include <gthumb.h>
#define GOOGLE_SERVICE_PICASA_WEB_ALBUM "lh2"
@@ -65,18 +70,27 @@ struct _GoogleConnectionClass
GthTaskClass __parent_class;
};
-GType google_connection_get_type (void) G_GNUC_CONST;
-GoogleConnection * google_connection_new (const char *service);
-void google_connection_connect (GoogleConnection *conn,
- const char *email,
- const char *password,
- const char *challange,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean google_connection_connect_finish (GoogleConnection *conn,
- GAsyncResult *result,
- GError **error);
-const char * google_connection_get_token (GoogleConnection *conn);
+GType google_connection_get_type (void) G_GNUC_CONST;
+GoogleConnection * google_connection_new (const char *service);
+void google_connection_send_message (GoogleConnection *self,
+ SoupMessage *msg,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ gpointer source_tag,
+ SoupSessionCallback soup_session_cb,
+ gpointer soup_session_cb_data);
+GSimpleAsyncResult * google_connection_get_result (GoogleConnection *self);
+void google_connection_connect (GoogleConnection *self,
+ const char *email,
+ const char *password,
+ const char *challange,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean google_connection_connect_finish (GoogleConnection *self,
+ GAsyncResult *result,
+ GError **error);
+const char * google_connection_get_challange_url (GoogleConnection *self);
#endif /* GOOGLE_CONNECTION_H */
diff --git a/extensions/picasaweb/gth-account-properties-dialog.c b/extensions/picasaweb/gth-account-properties-dialog.c
index c8c4ad4..0ed1924 100644
--- a/extensions/picasaweb/gth-account-properties-dialog.c
+++ b/extensions/picasaweb/gth-account-properties-dialog.c
@@ -25,13 +25,18 @@
#include "gth-account-properties-dialog.h"
+#define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
+
+
static gpointer parent_class = NULL;
struct _GthAccountPropertiesDialogPrivate {
- char *email;
- char *password;
- char *challange;
+ GtkBuilder *builder;
+ char *email;
+ char *password;
+ char *challange_url;
+ GCancellable *cancellable;
};
@@ -41,9 +46,11 @@ gth_account_properties_dialog_finalize (GObject *object)
GthAccountPropertiesDialog *self;
self = GTH_ACCOUNT_PROPERTIES_DIALOG (object);
+ _g_object_unref (self->priv->builder);
g_free (self->priv->email);
g_free (self->priv->password);
- g_free (self->priv->challange);
+ g_free (self->priv->challange_url);
+ g_object_unref (self->priv->cancellable);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -65,10 +72,32 @@ gth_account_properties_dialog_class_init (GthAccountPropertiesDialogClass *klass
static void
gth_account_properties_dialog_init (GthAccountPropertiesDialog *self)
{
+ GtkWidget *content;
+
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_ACCOUNT_PROPERTIES_DIALOG, GthAccountPropertiesDialogPrivate);
self->priv->email = NULL;
self->priv->password = NULL;
- self->priv->challange = NULL;
+ self->priv->challange_url = NULL;
+ self->priv->cancellable = g_cancellable_new ();
+ self->priv->builder = _gtk_builder_new_from_file ("picasa-web-account-properties.ui", "picasaweb");
+
+ gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
+ gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
+ gtk_container_set_border_width (GTK_CONTAINER (self), 5);
+
+ content = _gtk_builder_get_widget (self->priv->builder, "account_properties");
+ gtk_container_set_border_width (GTK_CONTAINER (content), 0);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
+
+ gtk_entry_set_visibility (GTK_ENTRY (GET_WIDGET ("password_entry")), FALSE);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (self),
+ GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
}
@@ -100,15 +129,78 @@ gth_account_properties_dialog_get_type (void)
}
+static void
+image_buffer_ready_cb (void *buffer,
+ gsize count,
+ GError *error,
+ gpointer user_data)
+{
+ GthAccountPropertiesDialog *self = user_data;
+ GInputStream *stream;
+ GdkPixbuf *pixbuf;
+
+ if (error != NULL) {
+ /* FIXME: show the error dialog */
+ return;
+ }
+
+ stream = g_memory_input_stream_new_from_data (buffer, count, NULL);
+ pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
+ if (pixbuf != NULL) {
+ gtk_widget_show (GET_WIDGET ("challange_box"));
+ gtk_image_set_from_pixbuf (GTK_IMAGE (GET_WIDGET ("challenge_image")), pixbuf);
+ g_object_unref (pixbuf);
+ }
+
+ g_object_unref (stream);
+}
+
+
+static void
+gth_account_properties_dialog_construct (GthAccountPropertiesDialog *self,
+ const char *email,
+ const char *password,
+ const char *challange_url)
+{
+ if (email != NULL) {
+ self->priv->email = g_strdup (email);
+ gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("email_entry")), self->priv->email);
+ }
+
+ if (password != NULL) {
+ self->priv->password = g_strdup (password);
+ gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("password_entry")), self->priv->password);
+ }
+
+ if (challange_url != NULL) {
+ char *url;
+ GFile *file;
+
+ self->priv->challange_url = g_strdup (challange_url);
+
+ url = g_strconcat ("http://www.google.com/accounts/", challange_url, NULL);
+ file = g_file_new_for_uri (url);
+ g_load_file_async (file,
+ G_PRIORITY_DEFAULT,
+ self->priv->cancellable,
+ image_buffer_ready_cb,
+ self);
+
+ g_object_unref (file);
+ g_free (url);
+ }
+}
+
+
GtkWidget *
gth_account_properties_dialog_new (const char *email,
- const char *password)
+ const char *password,
+ const char *challange_url)
{
GthAccountPropertiesDialog *self;
self = g_object_new (GTH_TYPE_ACCOUNT_PROPERTIES_DIALOG, NULL);
- self->priv->email = g_strdup (email);
- self->priv->password = g_strdup (password);
+ gth_account_properties_dialog_construct (self, email, password, challange_url);
return (GtkWidget *) self;
}
@@ -117,19 +209,19 @@ gth_account_properties_dialog_new (const char *email,
const char *
gth_account_properties_dialog_get_email (GthAccountPropertiesDialog *self)
{
- return self->priv->email;
+ return gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("email_entry")));
}
const char *
gth_account_properties_dialog_get_password (GthAccountPropertiesDialog *self)
{
- return self->priv->password;
+ return gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("password_entry")));
}
const char *
gth_account_properties_dialog_get_challange (GthAccountPropertiesDialog *self)
{
- return self->priv->challange;
+ return gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("challenge_entry")));
}
diff --git a/extensions/picasaweb/gth-account-properties-dialog.h b/extensions/picasaweb/gth-account-properties-dialog.h
index 9be0ada..571fa92 100644
--- a/extensions/picasaweb/gth-account-properties-dialog.h
+++ b/extensions/picasaweb/gth-account-properties-dialog.h
@@ -50,7 +50,8 @@ struct _GthAccountPropertiesDialogClass {
GType gth_account_properties_dialog_get_type (void);
GtkWidget * gth_account_properties_dialog_new (const char *email,
- const char *password);
+ const char *password,
+ const char *challange);
const char * gth_account_properties_dialog_get_email (GthAccountPropertiesDialog *self);
const char * gth_account_properties_dialog_get_password (GthAccountPropertiesDialog *self);
const char * gth_account_properties_dialog_get_challange (GthAccountPropertiesDialog *self);
diff --git a/extensions/picasaweb/picasa-web-album.c b/extensions/picasaweb/picasa-web-album.c
new file mode 100644
index 0000000..e135782
--- /dev/null
+++ b/extensions/picasaweb/picasa-web-album.c
@@ -0,0 +1,284 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2010 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gthumb.h>
+#include "picasa-web-album.h"
+
+
+static gpointer picasa_web_album_parent_class = NULL;
+
+
+static void
+picasa_web_album_finalize (GObject *obj)
+{
+ PicasaWebAlbum *self;
+
+ self = PICASA_WEB_ALBUM (obj);
+
+ g_free (self->id);
+ g_free (self->title);
+ g_free (self->summary);
+ g_free (self->edit_url);
+
+ G_OBJECT_CLASS (picasa_web_album_parent_class)->finalize (obj);
+}
+
+
+static void
+picasa_web_album_class_init (PicasaWebAlbumClass *klass)
+{
+ picasa_web_album_parent_class = g_type_class_peek_parent (klass);
+ G_OBJECT_CLASS (klass)->finalize = picasa_web_album_finalize;
+}
+
+
+static DomElement*
+picasa_web_album_create_element (DomDomizable *base,
+ DomDocument *doc)
+{
+ PicasaWebAlbum *self;
+ DomElement *element;
+ char *value;
+
+ self = PICASA_WEB_ALBUM (base);
+
+ element = dom_document_create_element (doc, "entry",
+ "xmlns", "http://www.w3.org/2005/Atom",
+ "xmlns:media", "http://search.yahoo.com/mrss/",
+ "xmlns:gphoto", "http://schemas.google.com/photos/2007",
+ NULL);
+ if (self->id != NULL)
+ dom_element_append_child (element, dom_document_create_element_with_text (doc, self->id, "id", NULL));
+ if (self->title != NULL)
+ dom_element_append_child (element, dom_document_create_element_with_text (doc, self->title, "title", "type", "text", NULL));
+ if (self->summary != NULL)
+ dom_element_append_child (element, dom_document_create_element_with_text (doc, self->summary, "summary", "type", "text", NULL));
+
+ switch (self->access) {
+ case PICASA_WEB_ACCESS_ALL:
+ value = "all";
+ break;
+ case PICASA_WEB_ACCESS_PRIVATE:
+ value = "private";
+ break;
+ case PICASA_WEB_ACCESS_PUBLIC:
+ value = "public";
+ break;
+ case PICASA_WEB_ACCESS_VISIBLE:
+ value = "visible";
+ break;
+ }
+ dom_element_append_child (element, dom_document_create_element_with_text (doc, value, "gphoto:access", NULL));
+
+ dom_element_append_child (element,
+ dom_document_create_element (doc, "category",
+ "scheme", "http://schemas.google.com/g/2005#kind",
+ "term", "http://schemas.google.com/photos/2007#album",
+ NULL));
+
+ return element;
+}
+
+
+static void
+picasa_web_album_load_from_element (DomDomizable *base,
+ DomElement *element)
+{
+ PicasaWebAlbum *self;
+ DomElement *node;
+
+ self = PICASA_WEB_ALBUM (base);
+
+ picasa_web_album_set_id (self, NULL);
+ picasa_web_album_set_title (self, NULL);
+ picasa_web_album_set_summary (self, NULL);
+ picasa_web_album_set_edit_url (self, NULL);
+ picasa_web_album_set_access (self, NULL);
+ self->n_photos = 0;
+
+ picasa_web_album_set_etag (self, dom_element_get_attribute (element, "gd:etag"));
+ for (node = element->first_child; node; node = node->next_sibling) {
+ if (g_strcmp0 (node->tag_name, "gphoto:id") == 0) {
+ picasa_web_album_set_id (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "title") == 0) {
+ picasa_web_album_set_title (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "summary") == 0) {
+ picasa_web_album_set_summary (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "link") == 0) {
+ if (g_strcmp0 (dom_element_get_attribute (node, "rel"), "edit") == 0)
+ picasa_web_album_set_edit_url (self, dom_element_get_attribute (node, "href"));
+ }
+ else if (g_strcmp0 (node->tag_name, "gphoto:access") == 0) {
+ picasa_web_album_set_access (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "gphoto:numphotos") == 0) {
+ picasa_web_album_set_n_photos (self, dom_element_get_inner_text (node));
+ }
+ }
+}
+
+
+static void
+picasa_web_album_dom_domizable_interface_init (DomDomizableIface *iface)
+{
+ iface->create_element = picasa_web_album_create_element;
+ iface->load_from_element = picasa_web_album_load_from_element;
+}
+
+
+static void
+picasa_web_album_instance_init (PicasaWebAlbum *self)
+{
+}
+
+
+GType
+picasa_web_album_get_type (void)
+{
+ static GType picasa_web_album_type_id = 0;
+
+ if (picasa_web_album_type_id == 0) {
+ static const GTypeInfo g_define_type_info = {
+ sizeof (PicasaWebAlbumClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) picasa_web_album_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (PicasaWebAlbum),
+ 0,
+ (GInstanceInitFunc) picasa_web_album_instance_init,
+ NULL
+ };
+ static const GInterfaceInfo dom_domizable_info = {
+ (GInterfaceInitFunc) picasa_web_album_dom_domizable_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ picasa_web_album_type_id = g_type_register_static (G_TYPE_OBJECT,
+ "PicasaWebAlbum",
+ &g_define_type_info,
+ 0);
+ g_type_add_interface_static (picasa_web_album_type_id, DOM_TYPE_DOMIZABLE, &dom_domizable_info);
+ }
+
+ return picasa_web_album_type_id;
+}
+
+
+PicasaWebAlbum *
+picasa_web_album_new (void)
+{
+ return g_object_new (PICASA_WEB_TYPE_ALBUM, NULL);
+}
+
+
+void
+picasa_web_album_set_etag (PicasaWebAlbum *self,
+ const char *value)
+{
+ g_free (self->etag);
+ self->etag = NULL;
+ if (value != NULL)
+ self->etag = g_strdup (value);
+}
+
+
+void
+picasa_web_album_set_id (PicasaWebAlbum *self,
+ const char *value)
+{
+ g_free (self->id);
+ self->id = NULL;
+ if (value != NULL)
+ self->id = g_strdup (value);
+}
+
+
+void
+picasa_web_album_set_title (PicasaWebAlbum *self,
+ const char *value)
+{
+ g_free (self->title);
+ self->title = NULL;
+ if (value != NULL)
+ self->title = g_strdup (value);
+}
+
+
+void
+picasa_web_album_set_summary (PicasaWebAlbum *self,
+ const char *value)
+{
+ g_free (self->summary);
+ self->summary = NULL;
+ if (value != NULL)
+ self->summary = g_strdup (value);
+}
+
+
+void
+picasa_web_album_set_edit_url (PicasaWebAlbum *self,
+ const char *value)
+{
+ g_free (self->edit_url);
+ self->edit_url = NULL;
+ if (value != NULL)
+ self->edit_url = g_strdup (value);
+}
+
+
+void
+picasa_web_album_set_access (PicasaWebAlbum *self,
+ const char *value)
+{
+ if (value == NULL)
+ self->access = PICASA_WEB_ACCESS_PRIVATE;
+ else if (strcmp (value, "all"))
+ self->access = PICASA_WEB_ACCESS_ALL;
+ else if (strcmp (value, "private"))
+ self->access = PICASA_WEB_ACCESS_PRIVATE;
+ else if (strcmp (value, "public"))
+ self->access = PICASA_WEB_ACCESS_PUBLIC;
+ else if (strcmp (value, "visible"))
+ self->access = PICASA_WEB_ACCESS_VISIBLE;
+ else
+ self->access = PICASA_WEB_ACCESS_PRIVATE;
+}
+
+
+void
+picasa_web_album_set_n_photos (PicasaWebAlbum *self,
+ const char *value)
+{
+ if (value != NULL)
+ self->n_photos = atoi (value);
+ else
+ self->n_photos = 0;
+}
diff --git a/extensions/picasaweb/picasa-web-album.h b/extensions/picasaweb/picasa-web-album.h
new file mode 100644
index 0000000..d4afe7b
--- /dev/null
+++ b/extensions/picasaweb/picasa-web-album.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2010 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PICASA_WEB_ALBUM_H
+#define PICASA_WEB_ALBUM_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PICASA_WEB_TYPE_ALBUM (picasa_web_album_get_type ())
+#define PICASA_WEB_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PICASA_WEB_TYPE_ALBUM, PicasaWebAlbum))
+#define PICASA_WEB_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PICASA_WEB_TYPE_ALBUM, PicasaWebAlbumClass))
+#define PICASA_WEB_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PICASA_WEB_TYPE_ALBUM))
+#define PICASA_WEB_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PICASA_WEB_TYPE_ALBUM))
+#define PICASA_WEB_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PICASA_WEB_TYPE_ALBUM, PicasaWebAlbumClass))
+
+typedef struct _PicasaWebAlbum PicasaWebAlbum;
+typedef struct _PicasaWebAlbumClass PicasaWebAlbumClass;
+typedef struct _PicasaWebAlbumPrivate PicasaWebAlbumPrivate;
+
+typedef enum {
+ PICASA_WEB_ACCESS_ALL,
+ PICASA_WEB_ACCESS_PRIVATE,
+ PICASA_WEB_ACCESS_PUBLIC,
+ PICASA_WEB_ACCESS_VISIBLE
+} PicasaWebAccess;
+
+struct _PicasaWebAlbum {
+ GObject parent_instance;
+ PicasaWebAlbumPrivate *priv;
+
+ char *etag;
+ char *id;
+ char *title;
+ char *summary;
+ char *edit_url;
+ PicasaWebAccess access;
+ int n_photos;
+};
+
+struct _PicasaWebAlbumClass {
+ GObjectClass parent_class;
+};
+
+GType picasa_web_album_get_type (void);
+PicasaWebAlbum * picasa_web_album_new (void);
+void picasa_web_album_set_etag (PicasaWebAlbum *self,
+ const char *value);
+void picasa_web_album_set_id (PicasaWebAlbum *self,
+ const char *value);
+void picasa_web_album_set_title (PicasaWebAlbum *self,
+ const char *value);
+void picasa_web_album_set_summary (PicasaWebAlbum *self,
+ const char *value);
+void picasa_web_album_set_edit_url (PicasaWebAlbum *self,
+ const char *value);
+void picasa_web_album_set_access (PicasaWebAlbum *self,
+ const char *value);
+void picasa_web_album_set_n_photos (PicasaWebAlbum *self,
+ const char *value);
+
+G_END_DECLS
+
+#endif /* PICASA_WEB_ALBUM_H */
diff --git a/extensions/picasaweb/picasa-web-service.c b/extensions/picasaweb/picasa-web-service.c
index 5173fed..4f23058 100644
--- a/extensions/picasaweb/picasa-web-service.c
+++ b/extensions/picasaweb/picasa-web-service.c
@@ -24,12 +24,14 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gthumb.h>
+#include "picasa-web-album.h"
#include "picasa-web-service.h"
struct _PicasaWebServicePrivate
{
GoogleConnection *conn;
+ char *user_id;
};
@@ -43,6 +45,7 @@ picasa_web_service_finalize (GObject *object)
self = PICASA_WEB_SERVICE (object);
_g_object_unref (self->priv->conn);
+ g_free (self->priv->user_id);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -66,6 +69,7 @@ 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_id = g_strdup ("default");
}
@@ -109,14 +113,108 @@ picasa_web_service_new (GoogleConnection *conn)
}
+/* -- picasa_web_service_list_albums -- */
+
+
+static void
+list_albums_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ PicasaWebService *self = user_data;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc;
+ GError *error = NULL;
+
+ result = google_connection_get_result (self->priv->conn);
+
+ if (msg->status_code != 200) {
+ g_simple_async_result_set_error (result,
+ SOUP_HTTP_ERROR,
+ msg->status_code,
+ "%s",
+ soup_status_get_phrase (msg->status_code));
+ g_simple_async_result_complete_in_idle (result);
+ return;
+ }
+
+ body = soup_message_body_flatten (msg->response_body);
+ doc = dom_document_new ();
+ if (dom_document_load (doc, body->data, body->length, &error)) {
+ DomElement *feed_node;
+ GList *albums = NULL;
+
+ feed_node = DOM_ELEMENT (doc)->first_child;
+ while ((feed_node != NULL) && g_strcmp0 (feed_node->tag_name, "feed") != 0)
+ feed_node = feed_node->next_sibling;
+
+ if (feed_node != NULL) {
+ DomElement *node;
+ PicasaWebAlbum *album = NULL;
+
+ for (node = feed_node->first_child;
+ node != NULL;
+ node = node->next_sibling)
+ {
+ if (g_strcmp0 (node->tag_name, "id") == 0) { /* get the user id */
+ char *user_id;
+
+ user_id = strrchr (dom_element_get_inner_text (node), '/');
+ if (user_id != NULL) {
+ g_free (self->priv->user_id);
+ self->priv->user_id = g_strdup (user_id + 1);
+ }
+ }
+ else if (g_strcmp0 (node->tag_name, "entry") == 0) { /* read the album data */
+ if (album != NULL)
+ albums = g_list_prepend (albums, album);
+ album = picasa_web_album_new ();
+ dom_domizable_load_from_element (DOM_DOMIZABLE (album), node);
+ }
+ }
+ if (album != NULL)
+ albums = g_list_prepend (albums, album);
+ }
+ albums = g_list_reverse (albums);
+ g_simple_async_result_set_op_res_gpointer (result, albums, (GDestroyNotify) _g_object_list_unref);
+ }
+ else {
+ g_simple_async_result_set_from_error (result, error);
+ g_error_free (error);
+ }
+ g_simple_async_result_complete_in_idle (result);
+
+ g_object_unref (doc);
+ soup_buffer_free (body);
+}
+
+
void
-picasa_web_service_list_albums (PicasaWebService *service,
+picasa_web_service_list_albums (PicasaWebService *self,
const char *user_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- /* FIXME */
+ char *url;
+ SoupMessage *msg;
+
+ g_return_if_fail (user_id != NULL);
+
+ url = g_strconcat ("http://picasaweb.google.com/data/feed/api/user/", user_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);
+
+ g_object_unref (msg);
+ g_free (url);
}
@@ -125,6 +223,192 @@ picasa_web_service_list_albums_finish (PicasaWebService *service,
GAsyncResult *result,
GError **error)
{
- /* FIXME */
- return NULL;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+ else
+ return g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+}
+
+
+/* -- picasa_web_service_create_album -- */
+
+
+static void
+create_album_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ PicasaWebService *self = user_data;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc;
+ GError *error = NULL;
+
+ result = google_connection_get_result (self->priv->conn);
+
+ if (msg->status_code != 201) {
+ g_simple_async_result_set_error (result,
+ SOUP_HTTP_ERROR,
+ msg->status_code,
+ "%s",
+ soup_status_get_phrase (msg->status_code));
+ g_simple_async_result_complete_in_idle (result);
+ return;
+ }
+
+ body = soup_message_body_flatten (msg->response_body);
+ doc = dom_document_new ();
+ if (dom_document_load (doc, body->data, body->length, &error)) {
+ PicasaWebAlbum *album;
+
+ album = picasa_web_album_new ();
+ dom_domizable_load_from_element (DOM_DOMIZABLE (album), DOM_ELEMENT (doc)->first_child);
+ g_simple_async_result_set_op_res_gpointer (result, album, (GDestroyNotify) _g_object_list_unref);
+ }
+ else {
+ g_simple_async_result_set_from_error (result, error);
+ g_error_free (error);
+ }
+ g_simple_async_result_complete_in_idle (result);
+
+ g_object_unref (doc);
+ soup_buffer_free (body);
+}
+
+
+void
+picasa_web_service_create_album (PicasaWebService *self,
+ PicasaWebAlbum *album,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DomDocument *doc;
+ DomElement *entry;
+ char *buffer;
+ gsize len;
+ char *url;
+ SoupMessage *msg;
+
+ g_return_if_fail (self->priv->user_id != NULL);
+
+ 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);
+ msg = soup_message_new ("POST", url);
+ soup_message_set_response (msg, "text/xml", 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);
+
+ g_object_unref (msg);
+ g_free (url);
+ g_object_unref (doc);
+}
+
+
+PicasaWebAlbum *
+picasa_web_service_create_album_finish (PicasaWebService *service,
+ GAsyncResult *result,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+ else
+ return g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+}
+
+
+/* utilities */
+
+
+GList *
+picasa_web_accounts_load_from_file (void)
+{
+ GList *accounts = NULL;
+ char *filename;
+ char *buffer;
+ gsize len;
+ DomDocument *doc;
+
+ filename = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", "picasaweb.xml", NULL);
+ if (! g_file_get_contents (filename, &buffer, &len, NULL)) {
+ g_free (filename);
+ 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));
+ }
+ }
+
+ accounts = g_list_reverse (accounts);
+ }
+ }
+
+ g_object_unref (doc);
+ g_free (buffer);
+ g_free (filename);
+
+ return accounts;
+}
+
+
+void
+picasa_web_accounts_save_to_file (GList *accounts)
+{
+ DomDocument *doc;
+ DomElement *root;
+ GList *scan;
+ char *buffer;
+ gsize len;
+ char *filename;
+ 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)
+ dom_element_append_child (root,
+ dom_document_create_element (doc, "account",
+ "email", (char *) scan->data,
+ NULL));
+
+ gth_user_dir_make_dir_for_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", "picasaweb.xml", NULL);
+ filename = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", "picasaweb.xml", NULL);
+ file = g_file_new_for_path (filename);
+ buffer = dom_document_dump (doc, &len);
+ g_write_file (file, FALSE, 0, buffer, len, NULL, NULL);
+
+ g_free (buffer);
+ g_object_unref (file);
+ g_free (filename);
+ g_object_unref (doc);
}
diff --git a/extensions/picasaweb/picasa-web-service.h b/extensions/picasaweb/picasa-web-service.h
index 2a774e4..d99e5b8 100644
--- a/extensions/picasaweb/picasa-web-service.h
+++ b/extensions/picasaweb/picasa-web-service.h
@@ -25,6 +25,7 @@
#include <glib-object.h>
#include "google-connection.h"
+#include "picasa-web-album.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))
@@ -48,15 +49,28 @@ struct _PicasaWebServiceClass
GObjectClass __parent_class;
};
-GType picasa_web_service_get_type (void) G_GNUC_CONST;
-PicasaWebService * picasa_web_service_new (GoogleConnection *conn);
-void picasa_web_service_list_albums (PicasaWebService *service,
- const char *user_id,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GList * picasa_web_service_list_albums_finish (PicasaWebService *service,
- GAsyncResult *result,
- GError **error);
+GType picasa_web_service_get_type (void) G_GNUC_CONST;
+PicasaWebService * picasa_web_service_new (GoogleConnection *conn);
+void picasa_web_service_list_albums (PicasaWebService *service,
+ const char *user_id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GList * picasa_web_service_list_albums_finish (PicasaWebService *service,
+ GAsyncResult *result,
+ GError **error);
+void picasa_web_service_create_album (PicasaWebService *service,
+ PicasaWebAlbum *album,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+PicasaWebAlbum * picasa_web_service_create_album_finish (PicasaWebService *service,
+ GAsyncResult *result,
+ GError **error);
+
+/* utilities */
+
+GList * picasa_web_accounts_load_from_file (void);
+void picasa_web_accounts_save_to_file (GList *accounts);
#endif /* PICASA_WEB_SERVICE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]