[gthumb] [photobucket] big batch of changes
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] [photobucket] big batch of changes
- Date: Wed, 19 May 2010 18:53:37 +0000 (UTC)
commit 719df0cc80e2e7d7a4baade43a75c93e5bb7ae8a
Author: Paolo Bacchilega <paobac src gnome org>
Date: Tue May 18 21:02:51 2010 +0200
[photobucket] big batch of changes
Completed the authentication/authorization process; Started work
on the export dialog.
data/icons/hicolor/16x16/actions/Makefile.am | 1 +
data/icons/hicolor/16x16/actions/photobucket.png | Bin 0 -> 703 bytes
extensions/oauth/oauth-account.c | 6 +-
extensions/oauth/oauth-account.h | 25 +-
extensions/oauth/oauth-authentication.c | 37 +-
extensions/oauth/oauth-authentication.h | 4 +-
extensions/oauth/oauth-connection.c | 44 +-
extensions/oauth/oauth-connection.h | 50 +-
extensions/photobucket/Makefile.am | 12 +-
extensions/photobucket/callbacks.c | 6 +-
extensions/photobucket/data/ui/Makefile.am | 3 +-
.../photobucket/data/ui/export-to-photobucket.ui | 225 ++----
.../data/ui/photobucket-album-properties.ui | 163 ++++
extensions/photobucket/dlg-export-to-photobucket.c | 366 ++++----
extensions/photobucket/photobucket-account.c | 209 +++++
extensions/photobucket/photobucket-account.h | 74 ++
.../photobucket-album-properties-dialog.c | 142 +++
.../photobucket-album-properties-dialog.h | 58 ++
extensions/photobucket/photobucket-album.c | 149 +++
extensions/photobucket/photobucket-album.h | 60 ++
extensions/photobucket/photobucket-consumer.c | 155 ++--
extensions/photobucket/photobucket-consumer.h | 6 +
extensions/photobucket/photobucket-photo.c | 231 +++++
extensions/photobucket/photobucket-photo.h | 81 ++
extensions/photobucket/photobucket-service.c | 989 ++++++++++++++++++++
extensions/photobucket/photobucket-service.h | 107 +++
gthumb/gsignature.c | 29 +-
gthumb/gsignature.h | 6 +
tests/Makefile.am | 6 +-
tests/gsignature-test.c | 38 +-
tests/oauth-test.c | 133 +++
31 files changed, 2931 insertions(+), 484 deletions(-)
---
diff --git a/data/icons/hicolor/16x16/actions/Makefile.am b/data/icons/hicolor/16x16/actions/Makefile.am
index e435660..286c79c 100644
--- a/data/icons/hicolor/16x16/actions/Makefile.am
+++ b/data/icons/hicolor/16x16/actions/Makefile.am
@@ -12,6 +12,7 @@ icons_DATA = \
file-search.png \
flickr.png \
histogram.png \
+ photobucket.png \
picasaweb.png \
tool-adjust-colors.png \
tool-crop.png \
diff --git a/data/icons/hicolor/16x16/actions/photobucket.png b/data/icons/hicolor/16x16/actions/photobucket.png
new file mode 100644
index 0000000..ea19560
Binary files /dev/null and b/data/icons/hicolor/16x16/actions/photobucket.png differ
diff --git a/extensions/oauth/oauth-account.c b/extensions/oauth/oauth-account.c
index 905f907..90a449f 100644
--- a/extensions/oauth/oauth-account.c
+++ b/extensions/oauth/oauth-account.c
@@ -56,7 +56,7 @@ oauth_account_class_init (OAuthAccountClass *klass)
}
-static DomElement*
+DomElement*
oauth_account_create_element (DomDomizable *base,
DomDocument *doc)
{
@@ -88,9 +88,9 @@ oauth_account_create_element (DomDomizable *base,
}
-static void
+void
oauth_account_load_from_element (DomDomizable *base,
- DomElement *element)
+ DomElement *element)
{
OAuthAccount *self;
diff --git a/extensions/oauth/oauth-account.h b/extensions/oauth/oauth-account.h
index 1592d15..3fb6b36 100644
--- a/extensions/oauth/oauth-account.h
+++ b/extensions/oauth/oauth-account.h
@@ -25,6 +25,7 @@
#include <glib.h>
#include <glib-object.h>
+#include <gthumb.h>
G_BEGIN_DECLS
@@ -53,16 +54,20 @@ struct _OAuthAccountClass {
GObjectClass parent_class;
};
-GType oauth_account_get_type (void);
-OAuthAccount * oauth_account_new (void);
-void oauth_account_set_username (OAuthAccount *self,
- const char *value);
-void oauth_account_set_token (OAuthAccount *self,
- const char *value);
-void oauth_account_set_token_secret (OAuthAccount *self,
- const char *value);
-int oauth_account_cmp (OAuthAccount *a,
- OAuthAccount *b);
+GType oauth_account_get_type (void);
+OAuthAccount * oauth_account_new (void);
+void oauth_account_set_username (OAuthAccount *self,
+ const char *value);
+void oauth_account_set_token (OAuthAccount *self,
+ const char *value);
+void oauth_account_set_token_secret (OAuthAccount *self,
+ const char *value);
+int oauth_account_cmp (OAuthAccount *a,
+ OAuthAccount *b);
+DomElement * oauth_account_create_element (DomDomizable *base,
+ DomDocument *doc);
+void oauth_account_load_from_element (DomDomizable *base,
+ DomElement *element);
G_END_DECLS
diff --git a/extensions/oauth/oauth-authentication.c b/extensions/oauth/oauth-authentication.c
index 5326821..7e1ab99 100644
--- a/extensions/oauth/oauth-authentication.c
+++ b/extensions/oauth/oauth-authentication.c
@@ -146,6 +146,7 @@ oauth_authentication_get_type (void)
OAuthAuthentication *
oauth_authentication_new (OAuthConnection *conn,
+ GType account_type,
GCancellable *cancellable,
GtkWidget *browser,
GtkWidget *dialog)
@@ -157,7 +158,7 @@ oauth_authentication_new (OAuthConnection *conn,
self = (OAuthAuthentication *) g_object_new (OAUTH_TYPE_AUTHENTICATION, NULL);
self->priv->conn = g_object_ref (conn);
self->priv->cancellable = _g_object_ref (cancellable);
- self->priv->accounts = oauth_accounts_load_from_file (self->priv->conn->consumer->name);
+ self->priv->accounts = oauth_accounts_load_from_file (self->priv->conn->consumer->name, account_type);
self->priv->account = oauth_accounts_find_default (self->priv->accounts);
self->priv->browser = browser;
self->priv->dialog = dialog;
@@ -244,7 +245,9 @@ check_token_ready_cb (GObject *source_object,
show_authentication_error_dialog (self, &error);
return;
}
- oauth_accounts_save_to_file (self->priv->conn->consumer->name, self->priv->accounts, self->priv->account);
+ oauth_accounts_save_to_file (self->priv->conn->consumer->name,
+ self->priv->accounts,
+ self->priv->account);
g_signal_emit (self, oauth_authentication_signals[READY], 0);
}
@@ -261,6 +264,7 @@ connect_to_server_step2 (OAuthAuthentication *self)
self->priv->account->token,
self->priv->account->token_secret);
oauth_connection_check_token (self->priv->conn,
+ self->priv->account,
self->priv->cancellable,
check_token_ready_cb,
self);
@@ -357,7 +361,7 @@ get_access_token_ready_cb (GObject *source_object,
GError *error = NULL;
OAuthAccount *account;
- account = oauth_connection_get_access_token_finish (OAUTH_CONNECTION (source_object), res, &error);
+ account = oauth_connection_get_access_token_finish (self->priv->conn, res, &error);
if (error != NULL) {
show_authentication_error_dialog (self, &error);
return;
@@ -541,7 +545,7 @@ get_request_token_ready_cb (GObject *source_object,
OAuthAuthentication *self = user_data;
GError *error = NULL;
- if (! oauth_connection_get_request_token_finish (OAUTH_CONNECTION (source_object), res, &error))
+ if (! oauth_connection_get_request_token_finish (self->priv->conn, res, &error))
show_authentication_error_dialog (self, &error);
else
ask_authorization (self);
@@ -720,16 +724,23 @@ oauth_authentication_edit_accounts (OAuthAuthentication *self,
GList *
-oauth_accounts_load_from_file (const char *service_name)
+oauth_accounts_load_from_file (const char *service_name,
+ GType account_type)
{
GList *accounts = NULL;
char *filename;
+ char *path;
char *buffer;
gsize len;
+ GError *error = NULL;
DomDocument *doc;
- filename = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", service_name, ".xml", NULL);
- if (! g_file_get_contents (filename, &buffer, &len, NULL)) {
+ filename = g_strconcat (service_name, ".xml", NULL);
+ path = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", filename, NULL);
+ if (! g_file_get_contents (path, &buffer, &len, &error)) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
+ g_free (path);
g_free (filename);
return NULL;
}
@@ -749,7 +760,7 @@ oauth_accounts_load_from_file (const char *service_name)
if (strcmp (child->tag_name, "account") == 0) {
OAuthAccount *account;
- account = oauth_account_new ();
+ account = g_object_new (account_type, NULL);
dom_domizable_load_from_element (DOM_DOMIZABLE (account), child);
accounts = g_list_prepend (accounts, account);
@@ -762,6 +773,7 @@ oauth_accounts_load_from_file (const char *service_name)
g_object_unref (doc);
g_free (buffer);
+ g_free (path);
g_free (filename);
return accounts;
@@ -795,6 +807,7 @@ oauth_accounts_save_to_file (const char *service_name,
char *buffer;
gsize len;
char *filename;
+ char *path;
GFile *file;
doc = dom_document_new ();
@@ -812,14 +825,16 @@ oauth_accounts_save_to_file (const char *service_name,
dom_element_append_child (root, node);
}
- gth_user_dir_make_dir_for_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", service_name, ".xml", NULL);
- filename = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", service_name, ".xml", NULL);
- file = g_file_new_for_path (filename);
+ filename = g_strconcat (service_name, ".xml", NULL);
+ gth_user_dir_make_dir_for_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", filename, NULL);
+ path = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, "accounts", filename, NULL);
+ file = g_file_new_for_path (path);
buffer = dom_document_dump (doc, &len);
g_write_file (file, FALSE, G_FILE_CREATE_PRIVATE | G_FILE_CREATE_REPLACE_DESTINATION, buffer, len, NULL, NULL);
g_free (buffer);
g_object_unref (file);
+ g_free (path);
g_free (filename);
g_object_unref (doc);
}
diff --git a/extensions/oauth/oauth-authentication.h b/extensions/oauth/oauth-authentication.h
index ee1ddab..69c6d2f 100644
--- a/extensions/oauth/oauth-authentication.h
+++ b/extensions/oauth/oauth-authentication.h
@@ -57,6 +57,7 @@ struct _OAuthAuthenticationClass {
GType oauth_authentication_get_type (void);
OAuthAuthentication * oauth_authentication_new (OAuthConnection *conn,
+ GType account_type,
GCancellable *cancellable,
GtkWidget *browser,
GtkWidget *dialog);
@@ -70,7 +71,8 @@ void oauth_authentication_edit_accounts (OAuthAuthentication
/* utilities */
-GList * oauth_accounts_load_from_file (const char *service_name);
+GList * oauth_accounts_load_from_file (const char *service_name,
+ GType account_type);
OAuthAccount * oauth_accounts_find_default (GList *accounts);
void oauth_accounts_save_to_file (const char *service_name,
GList *accounts,
diff --git a/extensions/oauth/oauth-connection.c b/extensions/oauth/oauth-connection.c
index 4f27afd..996a581 100644
--- a/extensions/oauth/oauth-connection.c
+++ b/extensions/oauth/oauth-connection.c
@@ -203,7 +203,7 @@ oauth_connection_send_message (OAuthConnection *self,
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),
+ self->priv->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
source_tag);
@@ -317,12 +317,13 @@ oauth_connection_add_signature (OAuthConnection *self,
/* Calculate the signature value */
signature_key = g_string_new ("");
- g_string_append (signature_key, self->consumer->consumer_key);
+ g_string_append (signature_key, self->consumer->consumer_secret);
g_string_append (signature_key, "&");
- if (self->priv->token != NULL)
- g_string_append (signature_key, self->priv->token);
+ if (self->priv->token_secret != NULL)
+ g_string_append (signature_key, self->priv->token_secret);
g_free (self->priv->signature);
self->priv->signature = g_compute_signature_for_string (G_CHECKSUM_SHA1,
+ G_SIGNATURE_ENC_BASE64,
signature_key->str,
signature_key->len,
base_string->str,
@@ -506,12 +507,19 @@ oauth_connection_get_token_secret (OAuthConnection *self)
/* -- oauth_connection_check_token -- */
+typedef struct {
+ OAuthConnection *conn;
+ OAuthAccount *account;
+} CheckTokenData;
+
+
static void
check_token_ready_cb (SoupSession *session,
SoupMessage *msg,
gpointer user_data)
{
- OAuthConnection *self = user_data;
+ CheckTokenData *check_token_data = user_data;
+ OAuthConnection *self = check_token_data->conn;
SoupBuffer *body;
if (msg->status_code != 200) {
@@ -525,27 +533,40 @@ check_token_ready_cb (SoupSession *session,
}
body = soup_message_body_flatten (msg->response_body);
- self->consumer->check_token_response (self, msg, body, self->priv->result);
+ self->consumer->check_token_response (self, msg, body, self->priv->result, check_token_data->account);
g_simple_async_result_complete_in_idle (self->priv->result);
soup_buffer_free (body);
+ g_free (check_token_data);
}
void
oauth_connection_check_token (OAuthConnection *self,
+ OAuthAccount *account,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GHashTable *data_set;
- SoupMessage *msg;
+ CheckTokenData *check_token_data;
+ GHashTable *data_set;
+ char *url;
+ SoupMessage *msg;
+
+ check_token_data = g_new0 (CheckTokenData, 1);
+ check_token_data->conn = self;
+ check_token_data->account = account;
gth_task_progress (GTH_TASK (self), _("Connecting to the server"), _("Getting account information"), TRUE, 0.0);
data_set = g_hash_table_new (g_str_hash, g_str_equal);
- oauth_connection_add_signature (self, "POST", self->consumer->check_token_url, data_set);
- msg = soup_form_request_new_from_hash ("POST", self->consumer->check_token_url, data_set);
+
+ url = self->consumer->get_check_token_url (self, account, TRUE);
+ oauth_connection_add_signature (self, "GET", url, data_set);
+ g_free (url);
+
+ url = self->consumer->get_check_token_url (self, account, FALSE);
+ msg = soup_form_request_new_from_hash ("GET", url, data_set);
oauth_connection_send_message (self,
msg,
cancellable,
@@ -553,8 +574,9 @@ oauth_connection_check_token (OAuthConnection *self,
user_data,
oauth_connection_check_token,
check_token_ready_cb,
- self);
+ check_token_data);
+ g_free (url);
g_hash_table_destroy (data_set);
}
diff --git a/extensions/oauth/oauth-connection.h b/extensions/oauth/oauth-connection.h
index b684a58..5b5ab6b 100644
--- a/extensions/oauth/oauth-connection.h
+++ b/extensions/oauth/oauth-connection.h
@@ -98,6 +98,7 @@ void oauth_connection_set_token (OAuthConnection
const char * oauth_connection_get_token (OAuthConnection *self);
const char * oauth_connection_get_token_secret (OAuthConnection *self);
void oauth_connection_check_token (OAuthConnection *self,
+ OAuthAccount *account,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -107,31 +108,34 @@ gboolean oauth_connection_check_token_finish (OAuthConnection
/* -- OAuthConsumer -- */
-typedef void (*OAuthResponseFunc) (OAuthConnection *self,
- SoupMessage *msg,
- SoupBuffer *body,
- GSimpleAsyncResult *result);
-typedef char * (*OAuthLoginLinkFunc) (OAuthConnection *self);
-
+typedef void (*OAuthResponseFunc) (OAuthConnection *self,
+ SoupMessage *msg,
+ SoupBuffer *body,
+ GSimpleAsyncResult *result);
+typedef void (*OAuthAccountResponseFunc) (OAuthConnection *self,
+ SoupMessage *msg,
+ SoupBuffer *body,
+ GSimpleAsyncResult *result,
+ OAuthAccount *account);
+typedef char * (*OAuthStringFunc) (OAuthConnection *self);
+typedef char * (*OAuthUrlFunc) (OAuthConnection *self,
+ OAuthAccount *account,
+ gboolean for_signature);
struct _OAuthConsumer {
- const char *display_name;
- const char *name;
- const char *url;
- const char *protocol;
- const char *consumer_key;
- const char *consumer_secret;
-
- const char *request_token_url;
- OAuthResponseFunc get_request_token_response;
-
- OAuthLoginLinkFunc get_login_link;
-
- const char *access_token_url;
- OAuthResponseFunc get_access_token_response;
-
- const char *check_token_url;
- OAuthResponseFunc check_token_response;
+ const char *display_name;
+ const char *name;
+ const char *url;
+ const char *protocol;
+ const char *consumer_key;
+ const char *consumer_secret;
+ const char *request_token_url;
+ OAuthResponseFunc get_request_token_response;
+ OAuthStringFunc get_login_link;
+ const char *access_token_url;
+ OAuthResponseFunc get_access_token_response;
+ OAuthUrlFunc get_check_token_url;
+ OAuthAccountResponseFunc check_token_response;
};
#endif /* OAUTH_CONNECTION_H */
diff --git a/extensions/photobucket/Makefile.am b/extensions/photobucket/Makefile.am
index 616c74b..638896f 100644
--- a/extensions/photobucket/Makefile.am
+++ b/extensions/photobucket/Makefile.am
@@ -13,8 +13,18 @@ libphotobucket_la_SOURCES = \
dlg-export-to-photobucket.c \
dlg-export-to-photobucket.h \
main.c \
+ photobucket-account.c \
+ photobucket-account.h \
+ photobucket-album.c \
+ photobucket-album.h \
+ photobucket-album-properties-dialog.c \
+ photobucket-album-properties-dialog.h \
photobucket-consumer.c \
- photobucket-consumer.h
+ photobucket-consumer.h \
+ photobucket-photo.c \
+ photobucket-photo.h \
+ photobucket-service.c \
+ photobucket-service.h
libphotobucket_la_CFLAGS = $(GTHUMB_CFLAGS) $(LIBSOUP_CFLAGS) $(GNOME_KEYRING_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
libphotobucket_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
diff --git a/extensions/photobucket/callbacks.c b/extensions/photobucket/callbacks.c
index 1180c90..a53d7d6 100644
--- a/extensions/photobucket/callbacks.c
+++ b/extensions/photobucket/callbacks.c
@@ -47,8 +47,8 @@ static const char *ui_info =
static GtkActionEntry action_entries[] = {
{ "File_Export_PhotoBucket", "photobucket",
- N_("PhotoBucket..."), NULL,
- N_("Upload photos to PhotoBucket"),
+ N_("Photobucket..."), NULL,
+ N_("Upload photos to Photobucket"),
G_CALLBACK (gth_browser_activate_action_export_photobucket) },
};
@@ -66,7 +66,7 @@ browser_data_free (BrowserData *data)
void
-fl__gth_browser_construct_cb (GthBrowser *browser)
+pb__gth_browser_construct_cb (GthBrowser *browser)
{
BrowserData *data;
GError *error = NULL;
diff --git a/extensions/photobucket/data/ui/Makefile.am b/extensions/photobucket/data/ui/Makefile.am
index e95fff4..89536cc 100644
--- a/extensions/photobucket/data/ui/Makefile.am
+++ b/extensions/photobucket/data/ui/Makefile.am
@@ -1,7 +1,8 @@
uidir = $(pkgdatadir)/ui
ui_DATA = \
export-to-photobucket.ui \
- photobucket-export-completed.ui
+ photobucket-album-properties.ui \
+ photobucket-export-completed.ui
EXTRA_DIST = $(ui_DATA)
diff --git a/extensions/photobucket/data/ui/export-to-photobucket.ui b/extensions/photobucket/data/ui/export-to-photobucket.ui
index e9e12e5..8010dd9 100644
--- a/extensions/photobucket/data/ui/export-to-photobucket.ui
+++ b/extensions/photobucket/data/ui/export-to-photobucket.ui
@@ -2,8 +2,33 @@
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
+ <object class="GtkListStore" id="album_liststore">
+ <columns>
+ <!-- column-name data -->
+ <column type="GObject"/>
+ <!-- column-name icon -->
+ <column type="gchararray"/>
+ <!-- column-name title -->
+ <column type="gchararray"/>
+ <!-- column-name n_photos -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="account_liststore">
+ <columns>
+ <!-- column-name account -->
+ <column type="GObject"/>
+ <!-- column-name username -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkImage" id="upload_image">
+ <property name="visible">True</property>
+ <property name="stock">gtk-goto-top</property>
+ </object>
<object class="GtkDialog" id="export_dialog">
<property name="border_width">5</property>
+ <property name="title" translatable="yes">Export to Flickr</property>
<property name="type_hint">dialog</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
@@ -43,7 +68,7 @@
<child>
<object class="GtkTable" id="table2">
<property name="visible">True</property>
- <property name="n_rows">5</property>
+ <property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">5</property>
@@ -118,7 +143,7 @@
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
- <object class="GtkLabel" id="label4">
+ <object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">Free space:</property>
<attributes>
@@ -158,114 +183,54 @@
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Ph_otoset:</property>
+ <property name="label" translatable="yes">A_lbum:</property>
<property name="use_underline">True</property>
- <property name="mnemonic_widget">photoset_comboboxentry</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBoxEntry" id="photoset_comboboxentry">
- <property name="visible">True</property>
- <property name="model">photoset_liststore</property>
- <property name="text_column">2</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext2"/>
- <attributes>
- <attribute name="text">3</attribute>
- </attributes>
- </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="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Privacy:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">privacy_combobox</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
- <object class="GtkComboBox" id="privacy_combobox">
+ <object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
- <property name="model">privacy_liststore</property>
- <property name="active">0</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkCellRendererText" id="cellrenderertext5"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
+ <object class="GtkComboBox" id="album_combobox">
+ <property name="visible">True</property>
+ <property name="model">album_liststore</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
</child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="hidden_checkbutton">
- <property name="label" translatable="yes">Hi_de from public searches</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Safety:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">safety_combobox</property>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="safety_combobox">
- <property name="visible">True</property>
- <property name="model">safety_liststore</property>
- <property name="active">0</property>
<child>
- <object class="GtkCellRendererText" id="cellrenderertext3"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
+ <object class="GtkButton" id="add_album_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes">Add a new album</property>
+ <property name="use_action_appearance">False</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="fill">False</property>
+ <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">3</property>
- <property name="bottom_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
</packing>
</child>
</object>
@@ -348,80 +313,4 @@
<action-widget response="-11">button1</action-widget>
</action-widgets>
</object>
- <object class="GtkImage" id="upload_image">
- <property name="visible">True</property>
- <property name="stock">gtk-goto-top</property>
- </object>
- <object class="GtkListStore" id="account_liststore">
- <columns>
- <!-- column-name account -->
- <column type="GObject"/>
- <!-- column-name username -->
- <column type="gchararray"/>
- </columns>
- </object>
- <object class="GtkListStore" id="safety_liststore">
- <columns>
- <!-- column-name value -->
- <column type="gint"/>
- <!-- column-name name -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0">0</col>
- <col id="1" translatable="yes">Safe content</col>
- </row>
- <row>
- <col id="0">1</col>
- <col id="1" translatable="yes">Moderate content</col>
- </row>
- <row>
- <col id="0">2</col>
- <col id="1" translatable="yes">Restricted content</col>
- </row>
- </data>
- </object>
- <object class="GtkListStore" id="privacy_liststore">
- <columns>
- <!-- column-name value -->
- <column type="gint"/>
- <!-- column-name name -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0">0</col>
- <col id="1" translatable="yes">Public photos</col>
- </row>
- <row>
- <col id="0">1</col>
- <col id="1" translatable="yes">Private photos, visible to family and friends</col>
- </row>
- <row>
- <col id="0">2</col>
- <col id="1" translatable="yes">Private photos, visible to friends</col>
- </row>
- <row>
- <col id="0">3</col>
- <col id="1" translatable="yes">Private photos, visible to family</col>
- </row>
- <row>
- <col id="0">4</col>
- <col id="1" translatable="yes">Private photos</col>
- </row>
- </data>
- </object>
- <object class="GtkListStore" id="photoset_liststore">
- <columns>
- <!-- column-name data -->
- <column type="GObject"/>
- <!-- column-name icon -->
- <column type="gchararray"/>
- <!-- column-name title -->
- <column type="gchararray"/>
- <!-- column-name n_photos -->
- <column type="gchararray"/>
- </columns>
- </object>
</interface>
diff --git a/extensions/photobucket/data/ui/photobucket-album-properties.ui b/extensions/photobucket/data/ui/photobucket-album-properties.ui
new file mode 100644
index 0000000..410c2ac
--- /dev/null
+++ b/extensions/photobucket/data/ui/photobucket-album-properties.ui
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="2.18"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkVBox" id="album_properties">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">4</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">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">name_entry</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name_entry">
+ <property name="width_request">300</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â??</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Visibility:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkComboBox" id="visibility_combobox">
+ <property name="visible">True</property>
+ <property name="model">visibility_liststore</property>
+ <property name="active">0</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="description_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â??</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">D_escription:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">description_entry</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="location_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="invisible_char_set">True</property>
+ </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="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Location:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">location_entry</property>
+ </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="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkListStore" id="visibility_liststore">
+ <columns>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ <!-- column-name value -->
+ <column type="gint"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">Public photos</col>
+ <col id="1">0</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Private photos, visible to friends</col>
+ <col id="1">3</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Private</col>
+ <col id="1">4</col>
+ </row>
+ </data>
+ </object>
+</interface>
diff --git a/extensions/photobucket/dlg-export-to-photobucket.c b/extensions/photobucket/dlg-export-to-photobucket.c
index 5a6753f..6f28f1b 100644
--- a/extensions/photobucket/dlg-export-to-photobucket.c
+++ b/extensions/photobucket/dlg-export-to-photobucket.c
@@ -23,8 +23,12 @@
#include <config.h>
#include <gtk/gtk.h>
#include <gthumb.h>
+#include <extensions/oauth/oauth-authentication.h>
#include "dlg-export-to-photobucket.h"
+#include "photobucket-account.h"
+#include "photobucket-album-properties-dialog.h"
#include "photobucket-consumer.h"
+#include "photobucket-service.h"
#define GET_WIDGET(x) (_gtk_builder_get_widget (data->builder, (x)))
@@ -54,8 +58,8 @@ typedef struct {
GtkWidget *progress_dialog;
OAuthConnection *conn;
OAuthAuthentication *auth;
- PhotobucktService *service;
- PhotobucketUser *user;
+ PhotobucketService *service;
+ PhotobucketAccount *account;
GList *albums;
PhotobucketAlbum *album;
GList *photos_ids;
@@ -73,7 +77,7 @@ export_dialog_destroy_cb (GtkWidget *widget,
_g_string_list_free (data->photos_ids);
_g_object_unref (data->album);
_g_object_list_unref (data->albums);
- _g_object_unref (data->user);
+ _g_object_unref (data->account);
_g_object_unref (data->auth);
_g_object_unref (data->conn);
_g_object_unref (data->builder);
@@ -99,11 +103,12 @@ completed_messagedialog_response_cb (GtkDialog *dialog,
case _OPEN_IN_BROWSER_RESPONSE:
{
- char *url = NULL;
- GError *error = NULL;
+ /*char *url = NULL;
+ GError *error = NULL;*/
gtk_widget_destroy (GTK_WIDGET (dialog));
+ /* FIXME
if (data->album == NULL) {
GString *ids;
GList *scan;
@@ -128,9 +133,11 @@ completed_messagedialog_response_cb (GtkDialog *dialog,
gth_task_dialog (GTH_TASK (data->conn), TRUE);
_gtk_error_dialog_from_gerror_run (GTK_WINDOW (data->browser), _("Could not connect to the server"), &error);
}
+ */
+
gtk_widget_destroy (data->dialog);
- g_free (url);
+ /*g_free (url);*/
}
break;
@@ -163,103 +170,21 @@ export_completed_with_success (DialogData *data)
static void
-add_photos_to_album_ready_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- DialogData *data = user_data;
- GError *error = NULL;
-
- if (! photobucket_service_add_photos_to_set_finish (PHOTOBUCKET_SERVICE (source_object), result, &error)) {
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not create the album"), &error);
- gtk_widget_destroy (data->dialog);
- return;
- }
-
- export_completed_with_success (data);
-}
-
-
-static void
-add_photos_to_album (DialogData *data)
-{
- photobucket_service_add_photos_to_set (data->service,
- data->album,
- data->photos_ids,
- data->cancellable,
- add_photos_to_album_ready_cb,
- data);
-}
-
-
-static void
-create_album_ready_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
+upload_photos_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
DialogData *data = user_data;
GError *error = NULL;
- char *primary;
- primary = g_strdup (data->album->primary);
- g_object_unref (data->album);
- data->album = photobucket_service_create_album_finish (PHOTOBUCKET_SERVICE (source_object), result, &error);
- if (error != NULL) {
- _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not create the album"), &error);
- gtk_widget_destroy (data->dialog);
- }
- else {
- photobucket_album_set_primary (data->album, primary);
- add_photos_to_album (data);
- }
-
- g_free (primary);
-}
-
-
-static void
-post_photos_ready_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- DialogData *data = user_data;
- GError *error = NULL;
-
- data->photos_ids = photobucket_service_post_photos_finish (PHOTOBUCKET_SERVICE (source_object), result, &error);
+ data->photos_ids = photobucket_service_upload_photos_finish (PHOTOBUCKET_SERVICE (source_object), result, &error);
if (error != NULL) {
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not upload the files"), &error);
gtk_widget_destroy (data->dialog);
return;
}
- if (data->album == NULL) {
- export_completed_with_success (data);
- return;
- }
-
- /* create the album if it doesn't exists */
-
- if (data->album->id == NULL) {
- char *first_id;
-
- first_id = data->photos_ids->data;
- photobucket_album_set_primary (data->album, first_id);
- photobucket_service_create_album (data->service,
- data->album,
- data->cancellable,
- create_album_ready_cb,
- data);
- }
- else
- add_photos_to_album (data);
-}
-
-
-static int
-find_album_by_title (PhotobucketAlbum *album,
- const char *name)
-{
- return g_strcmp0 (album->title, name);
+ export_completed_with_success (data);
}
@@ -282,39 +207,29 @@ export_dialog_response_cb (GtkDialog *dialog,
case GTK_RESPONSE_OK:
{
- char *album_title;
- GList *file_list;
+ GtkTreeIter iter;
+ GList *file_list;
gtk_widget_hide (data->dialog);
gth_task_dialog (GTH_TASK (data->conn), FALSE);
data->album = NULL;
- album_title = gtk_combo_box_get_active_text (GTK_COMBO_BOX (GET_WIDGET ("album_comboboxentry")));
- if ((album_title != NULL) && (g_strcmp0 (album_title, "") != 0)) {
- GList *link;
-
- link = g_list_find_custom (data->albums, album_title, (GCompareFunc) find_album_by_title);
- if (link != NULL)
- data->album = g_object_ref (link->data);
-
- if (data->album == NULL) {
- data->album = photobucket_album_new ();
- photobucket_album_set_title (data->album, album_title);
- }
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")), &iter)) {
+ gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (GET_WIDGET ("album_combobox"))),
+ &iter,
+ ALBUM_DATA_COLUMN, &data->album,
+ -1);
}
file_list = gth_file_data_list_to_file_list (data->file_list);
- photobucket_service_post_photos (data->service,
- gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("privacy_combobox"))),
- gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("safety_combobox"))),
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("hidden_checkbutton"))),
- file_list,
- data->cancellable,
- post_photos_ready_cb,
- data);
+ photobucket_service_upload_photos (data->service,
+ data->album,
+ file_list,
+ data->cancellable,
+ upload_photos_ready_cb,
+ data);
_g_object_list_unref (file_list);
- g_free (album_title);
}
break;
@@ -327,19 +242,19 @@ export_dialog_response_cb (GtkDialog *dialog,
static void
update_account_list (DialogData *data)
{
- int current_account_idx;
- PhotobucketAccount *current_account;
- int idx;
- GList *scan;
- GtkTreeIter iter;
- char *free_space;
+ int current_account_idx;
+ OAuthAccount *current_account;
+ int idx;
+ GList *scan;
+ GtkTreeIter iter;
+ char *free_space;
gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("account_liststore")));
current_account_idx = 0;
- current_account = photobucket_authentication_get_account (data->auth);
- for (scan = photobucket_authentication_get_accounts (data->auth), idx = 0; scan; scan = scan->next, idx++) {
- PhotobucketAccount *account = scan->data;
+ current_account = oauth_authentication_get_account (data->auth);
+ for (scan = oauth_authentication_get_accounts (data->auth), 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;
@@ -352,59 +267,64 @@ update_account_list (DialogData *data)
}
gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("account_combobox")), current_account_idx);
- free_space = g_format_size_for_display (data->user->max_bandwidth - data->user->used_bandwidth);
+ free_space = g_format_size_for_display ((data->account->megabytes_allowed - data->account->megabytes_used) * (1024 * 1024));
gtk_label_set_text (GTK_LABEL (GET_WIDGET ("free_space_label")), free_space);
g_free (free_space);
}
static void
-authentication_accounts_changed_cb (PhotobucketAuthentication *auth,
- gpointer user_data)
+authentication_accounts_changed_cb (OAuthAuthentication *auth,
+ gpointer user_data)
{
update_account_list ((DialogData *) user_data);
}
static void
-album_list_ready_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
+update_album_list (DialogData *data)
{
- DialogData *data = user_data;
- GError *error = NULL;
- GList *scan;
-
- _g_object_list_unref (data->albums);
- data->albums = photobucket_service_list_albums_finish (PHOTOBUCKET_SERVICE (source_object), res, &error);
- if (error != NULL) {
- if (data->conn != NULL)
- gth_task_dialog (GTH_TASK (data->conn), TRUE);
- _gtk_error_dialog_from_gerror_run (GTK_WINDOW (data->browser), _("Could not connect to the server"), &error);
- gtk_widget_destroy (data->dialog);
- return;
- }
+ GList *scan;
gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("album_liststore")));
for (scan = data->albums; scan; scan = scan->next) {
PhotobucketAlbum *album = scan->data;
- char *n_photos;
+ char *size;
GtkTreeIter iter;
- n_photos = g_strdup_printf ("(%d)", album->n_photos);
+ size = g_strdup_printf ("(%d)", album->photo_count); /* FIXME: show video_count as well */
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_TITLE_COLUMN, album->title,
- ALBUM_N_PHOTOS_COLUMN, n_photos,
+ ALBUM_TITLE_COLUMN, album->name,
+ ALBUM_N_PHOTOS_COLUMN, size,
-1);
- g_free (n_photos);
+ g_free (size);
}
+}
+
+
+static void
+album_list_ready_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ GError *error = NULL;
- gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), TRUE);
+ _g_object_list_unref (data->albums);
+ data->albums = photobucket_service_get_albums_finish (data->service, res, &error);
+ if (error != NULL) {
+ if (data->conn != NULL)
+ gth_task_dialog (GTH_TASK (data->conn), TRUE);
+ _gtk_error_dialog_from_gerror_run (GTK_WINDOW (data->browser), _("Could not connect to the server"), &error);
+ gtk_widget_destroy (data->dialog);
+ return;
+ }
+ update_album_list (data);
gth_task_dialog (GTH_TASK (data->conn), TRUE);
@@ -418,15 +338,15 @@ static void
authentication_ready_cb (OAuthAuthentication *auth,
DialogData *data)
{
- _g_object_unref (data->user);
- data->user = g_object_ref (user);
+ _g_object_unref (data->account);
+ data->account = g_object_ref (oauth_authentication_get_account (auth));
update_account_list (data);
- photobucket_service_list_albums (data->service,
- NULL,
- data->cancellable,
- album_list_ready_cb,
- data);
+ photobucket_service_get_albums (data->service,
+ data->account,
+ data->cancellable,
+ album_list_ready_cb,
+ data);
}
@@ -461,6 +381,95 @@ account_combobox_changed_cb (GtkComboBox *widget,
}
+static void
+album_combobox_changed_cb (GtkComboBox *widget,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ GtkTreeIter iter;
+
+ gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), gtk_combo_box_get_active_iter (widget, &iter));
+}
+
+
+static void
+create_album_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ PhotobucketAlbum *album;
+ GError *error = NULL;
+
+ album = photobucket_service_create_album_finish (data->service, result, &error);
+ if (error != NULL) {
+ if (data->conn != NULL)
+ gth_task_dialog (GTH_TASK (data->conn), TRUE);
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not create the album"), &error);
+ return;
+ }
+
+ data->albums = g_list_append (data->albums, album);
+ update_album_list (data);
+}
+
+
+static void
+new_album_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:
+ {
+ PhotobucketAlbum *album;
+
+ album = photobucket_album_new ();
+ photobucket_album_set_name (album, photobucket_album_properties_dialog_get_name (PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG (dialog)));
+ photobucket_service_create_album (data->service,
+ album,
+ data->cancellable,
+ create_album_ready_cb,
+ data);
+
+ g_object_unref (album);
+ }
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void
+add_album_button_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ GtkWidget *dialog;
+
+ dialog = photobucket_album_properties_dialog_new (g_file_info_get_edit_name (data->location->info));
+ g_signal_connect (dialog,
+ "response",
+ G_CALLBACK (new_album_dialog_response_cb),
+ data);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("New Album"));
+ 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));
+}
+
+
void
dlg_export_to_photobucket (GthBrowser *browser,
GList *file_list)
@@ -481,6 +490,31 @@ dlg_export_to_photobucket (GthBrowser *browser,
data->dialog = _gtk_builder_get_widget (data->builder, "export_dialog");
data->cancellable = g_cancellable_new ();
+ {
+ GtkCellLayout *cell_layout;
+ GtkCellRenderer *renderer;
+
+ cell_layout = GTK_CELL_LAYOUT (GET_WIDGET ("album_combobox"));
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (cell_layout, renderer, FALSE);
+ gtk_cell_layout_set_attributes (cell_layout, renderer,
+ "icon-name", ALBUM_ICON_COLUMN,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (cell_layout, renderer, TRUE);
+ gtk_cell_layout_set_attributes (cell_layout, renderer,
+ "text", ALBUM_TITLE_COLUMN,
+ NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (cell_layout, renderer, FALSE);
+ gtk_cell_layout_set_attributes (cell_layout, renderer,
+ "text", ALBUM_N_PHOTOS_COLUMN,
+ NULL);
+ }
+
data->file_list = NULL;
n_total = 0;
total_size = 0;
@@ -519,7 +553,7 @@ dlg_export_to_photobucket (GthBrowser *browser,
/* Set the widget data */
- list_view = gth_file_list_new (GTH_FILE_LIST_TYPE_NO_SELECTION);
+ list_view = gth_file_list_new (GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
gth_file_list_set_thumb_size (GTH_FILE_LIST (list_view), 112);
gth_file_view_set_spacing (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (list_view))), 0);
gth_file_list_enable_thumbs (GTH_FILE_LIST (list_view), TRUE);
@@ -532,7 +566,7 @@ dlg_export_to_photobucket (GthBrowser *browser,
gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (GET_WIDGET ("album_comboboxentry")))), g_file_info_get_edit_name (data->location->info));
gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), FALSE);
- title = g_strdup_printf (_("Export to %s"), photobucket_consumer->display_name);
+ title = g_strdup_printf (_("Export to %s"), photobucket_consumer.display_name);
gtk_window_set_title (GTK_WINDOW (data->dialog), title);
g_free (title);
@@ -554,10 +588,18 @@ dlg_export_to_photobucket (GthBrowser *browser,
"changed",
G_CALLBACK (account_combobox_changed_cb),
data);
+ g_signal_connect (GET_WIDGET ("add_album_button"),
+ "clicked",
+ G_CALLBACK (add_album_button_clicked_cb),
+ data);
+ g_signal_connect (GET_WIDGET ("album_combobox"),
+ "changed",
+ G_CALLBACK (album_combobox_changed_cb),
+ data);
- data->conn = oauth_connection_new (photobucket_consumer);
- data->service = photobucket_service_new (data->conn);
+ data->conn = oauth_connection_new (&photobucket_consumer);
data->auth = oauth_authentication_new (data->conn,
+ PHOTOBUCKET_TYPE_ACCOUNT,
data->cancellable,
GTK_WIDGET (data->browser),
data->dialog);
@@ -570,6 +612,8 @@ dlg_export_to_photobucket (GthBrowser *browser,
G_CALLBACK (authentication_accounts_changed_cb),
data);
+ data->service = photobucket_service_new (data->conn);
+
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));
diff --git a/extensions/photobucket/photobucket-account.c b/extensions/photobucket/photobucket-account.c
new file mode 100644
index 0000000..bc3e0ef
--- /dev/null
+++ b/extensions/photobucket/photobucket-account.c
@@ -0,0 +1,209 @@
+/* -*- 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 "photobucket-account.h"
+
+
+static gpointer photobucket_account_parent_class = NULL;
+
+
+static void
+photobucket_account_finalize (GObject *obj)
+{
+ PhotobucketAccount *self;
+
+ self = PHOTOBUCKET_ACCOUNT (obj);
+
+ g_free (self->subdomain);
+ g_free (self->home_url);
+ g_free (self->album_url);
+
+ G_OBJECT_CLASS (photobucket_account_parent_class)->finalize (obj);
+}
+
+
+static void
+photobucket_account_class_init (PhotobucketAccountClass *klass)
+{
+ photobucket_account_parent_class = g_type_class_peek_parent (klass);
+ G_OBJECT_CLASS (klass)->finalize = photobucket_account_finalize;
+}
+
+
+static DomElement*
+photobucket_account_create_element (DomDomizable *base,
+ DomDocument *doc)
+{
+ PhotobucketAccount *self;
+ DomElement *element;
+
+ self = PHOTOBUCKET_ACCOUNT (base);
+ element = oauth_account_create_element (DOM_DOMIZABLE (self), doc);
+ if (self->subdomain != NULL)
+ dom_element_set_attribute (element, "subdomain", self->subdomain);
+
+ return element;
+}
+
+
+static void
+photobucket_account_load_from_element (DomDomizable *base,
+ DomElement *element)
+{
+ PhotobucketAccount *self;
+
+ self = PHOTOBUCKET_ACCOUNT (base);
+
+ if (g_str_equal (element->tag_name, "content")) {
+ DomElement *node;
+
+ for (node = element->first_child; node; node = node->next_sibling) {
+ if (g_str_equal (node->tag_name, "album_url")) {
+ photobucket_account_set_album_url (self, dom_element_get_inner_text (node));
+ }
+ else if (g_str_equal (node->tag_name, "megabytes_used")) {
+ photobucket_account_set_megabytes_used (self, dom_element_get_inner_text (node));
+ }
+ else if (g_str_equal (node->tag_name, "megabytes_allowed")) {
+ photobucket_account_set_megabytes_allowed (self, dom_element_get_inner_text (node));
+ }
+ else if (g_str_equal (node->tag_name, "public")) {
+ photobucket_account_set_is_public (self, dom_element_get_inner_text (node));
+ }
+ }
+ }
+ else if (g_str_equal (element->tag_name, "account")) {
+ oauth_account_load_from_element (DOM_DOMIZABLE (self), element);
+ photobucket_account_set_subdomain (self, dom_element_get_attribute (element, "subdomain"));
+ }
+}
+
+
+static void
+photobucket_account_dom_domizable_interface_init (DomDomizableIface *iface)
+{
+ iface->create_element = photobucket_account_create_element;
+ iface->load_from_element = photobucket_account_load_from_element;
+}
+
+
+static void
+photobucket_account_instance_init (PhotobucketAccount *self)
+{
+ self->subdomain = NULL;
+ self->home_url = NULL;
+ self->album_url = NULL;
+}
+
+
+GType
+photobucket_account_get_type (void)
+{
+ static GType photobucket_account_type_id = 0;
+
+ if (photobucket_account_type_id == 0) {
+ static const GTypeInfo g_define_type_info = {
+ sizeof (PhotobucketAccountClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) photobucket_account_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (PhotobucketAccount),
+ 0,
+ (GInstanceInitFunc) photobucket_account_instance_init,
+ NULL
+ };
+ static const GInterfaceInfo dom_domizable_info = {
+ (GInterfaceInitFunc) photobucket_account_dom_domizable_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ photobucket_account_type_id = g_type_register_static (OAUTH_TYPE_ACCOUNT,
+ "PhotobucketAccount",
+ &g_define_type_info,
+ 0);
+ g_type_add_interface_static (photobucket_account_type_id, DOM_TYPE_DOMIZABLE, &dom_domizable_info);
+ }
+
+ return photobucket_account_type_id;
+}
+
+
+OAuthAccount *
+photobucket_account_new (void)
+{
+ return g_object_new (PHOTOBUCKET_TYPE_ACCOUNT, NULL);
+}
+
+
+void
+photobucket_account_set_subdomain (PhotobucketAccount *self,
+ const char *value)
+{
+ _g_strset (&self->subdomain, value);
+}
+
+
+void
+photobucket_account_set_home_url (PhotobucketAccount *self,
+ const char *value)
+{
+ _g_strset (&self->home_url, value);
+}
+
+
+void
+photobucket_account_set_album_url (PhotobucketAccount *self,
+ const char *value)
+{
+ _g_strset (&self->album_url, value);
+}
+
+
+void
+photobucket_account_set_megabytes_used (PhotobucketAccount *self,
+ const char *value)
+{
+ self->megabytes_used = g_ascii_strtoull (value, NULL, 10);
+}
+
+
+void
+photobucket_account_set_megabytes_allowed (PhotobucketAccount *self,
+ const char *value)
+{
+ self->megabytes_allowed = g_ascii_strtoull (value, NULL, 10);
+}
+
+
+void
+photobucket_account_set_is_public (PhotobucketAccount *self,
+ const char *value)
+{
+ self->is_public = g_str_equal (value, "1");
+}
diff --git a/extensions/photobucket/photobucket-account.h b/extensions/photobucket/photobucket-account.h
new file mode 100644
index 0000000..68230ec
--- /dev/null
+++ b/extensions/photobucket/photobucket-account.h
@@ -0,0 +1,74 @@
+/* -*- 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 PHOTOBUCKET_ACCOUNT_H
+#define PHOTOBUCKET_ACCOUNT_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <extensions/oauth/oauth-account.h>
+
+G_BEGIN_DECLS
+
+#define PHOTOBUCKET_TYPE_ACCOUNT (photobucket_account_get_type ())
+#define PHOTOBUCKET_ACCOUNT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PHOTOBUCKET_TYPE_ACCOUNT, PhotobucketAccount))
+#define PHOTOBUCKET_ACCOUNT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PHOTOBUCKET_TYPE_ACCOUNT, PhotobucketAccountClass))
+#define PHOTOBUCKET_IS_ACCOUNT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PHOTOBUCKET_TYPE_ACCOUNT))
+#define PHOTOBUCKET_IS_ACCOUNT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PHOTOBUCKET_TYPE_ACCOUNT))
+#define PHOTOBUCKET_ACCOUNT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PHOTOBUCKET_TYPE_ACCOUNT, PhotobucketAccountClass))
+
+typedef struct _PhotobucketAccount PhotobucketAccount;
+typedef struct _PhotobucketAccountClass PhotobucketAccountClass;
+
+struct _PhotobucketAccount {
+ OAuthAccount parent_instance;
+
+ char *subdomain;
+ char *home_url;
+ char *album_url;
+ goffset megabytes_used;
+ goffset megabytes_allowed;
+ gboolean is_public;
+};
+
+struct _PhotobucketAccountClass {
+ OAuthAccountClass parent_class;
+};
+
+GType photobucket_account_get_type (void);
+OAuthAccount * photobucket_account_new (void);
+void photobucket_account_set_subdomain (PhotobucketAccount *self,
+ const char *value);
+void photobucket_account_set_home_url (PhotobucketAccount *self,
+ const char *value);
+void photobucket_account_set_album_url (PhotobucketAccount *self,
+ const char *value);
+void photobucket_account_set_megabytes_used (PhotobucketAccount *self,
+ const char *value);
+void photobucket_account_set_megabytes_allowed (PhotobucketAccount *self,
+ const char *value);
+void photobucket_account_set_is_public (PhotobucketAccount *self,
+ const char *value);
+
+G_END_DECLS
+
+#endif /* PHOTOBUCKET_ACCOUNT_H */
diff --git a/extensions/photobucket/photobucket-album-properties-dialog.c b/extensions/photobucket/photobucket-album-properties-dialog.c
new file mode 100644
index 0000000..34012b1
--- /dev/null
+++ b/extensions/photobucket/photobucket-album-properties-dialog.c
@@ -0,0 +1,142 @@
+/* -*- 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 <glib/gi18n.h>
+#include "photobucket-album-properties-dialog.h"
+
+
+#define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
+
+
+static gpointer parent_class = NULL;
+
+
+struct _PhotobucketAlbumPropertiesDialogPrivate {
+ GtkBuilder *builder;
+};
+
+
+static void
+photobucket_album_properties_dialog_finalize (GObject *object)
+{
+ PhotobucketAlbumPropertiesDialog *self;
+
+ self = PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG (object);
+ _g_object_unref (self->priv->builder);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+photobucket_album_properties_dialog_class_init (PhotobucketAlbumPropertiesDialogClass *klass)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (PhotobucketAlbumPropertiesDialogPrivate));
+
+ object_class = (GObjectClass*) klass;
+ object_class->finalize = photobucket_album_properties_dialog_finalize;
+}
+
+
+static void
+photobucket_album_properties_dialog_init (PhotobucketAlbumPropertiesDialog *self)
+{
+ GtkWidget *content;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG, PhotobucketAlbumPropertiesDialogPrivate);
+ self->priv->builder = _gtk_builder_new_from_file ("photobucket-album-properties.ui", "photobucket");
+
+ 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, "album_properties");
+ gtk_container_set_border_width (GTK_CONTAINER (content), 5);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (self),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
+}
+
+
+GType
+photobucket_album_properties_dialog_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ static const GTypeInfo g_define_type_info = {
+ sizeof (PhotobucketAlbumPropertiesDialogClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) photobucket_album_properties_dialog_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (PhotobucketAlbumPropertiesDialog),
+ 0,
+ (GInstanceInitFunc) photobucket_album_properties_dialog_init,
+ NULL
+ };
+ type = g_type_register_static (GTK_TYPE_DIALOG,
+ "PhotobucketAlbumPropertiesDialog",
+ &g_define_type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+static void
+photobucket_album_properties_dialog_construct (PhotobucketAlbumPropertiesDialog *self,
+ const char *name)
+{
+ if (name != NULL)
+ gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("name_entry")), name);
+}
+
+
+GtkWidget *
+photobucket_album_properties_dialog_new (const char *name)
+{
+ PhotobucketAlbumPropertiesDialog *self;
+
+ self = g_object_new (PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG, NULL);
+ photobucket_album_properties_dialog_construct (self, name);
+
+ return (GtkWidget *) self;
+}
+
+
+const char *
+photobucket_album_properties_dialog_get_name (PhotobucketAlbumPropertiesDialog *self)
+{
+ return gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("name_entry")));
+}
diff --git a/extensions/photobucket/photobucket-album-properties-dialog.h b/extensions/photobucket/photobucket-album-properties-dialog.h
new file mode 100644
index 0000000..51944df
--- /dev/null
+++ b/extensions/photobucket/photobucket-album-properties-dialog.h
@@ -0,0 +1,58 @@
+/* -*- 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 PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG_H
+#define PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG_H
+
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include "photobucket-album.h"
+
+G_BEGIN_DECLS
+
+#define PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG (photobucket_album_properties_dialog_get_type ())
+#define PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG, PhotobucketAlbumPropertiesDialog))
+#define PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG, PhotobucketAlbumPropertiesDialogClass))
+#define PHOTOBUCKET_IS_ALBUM_PROPERTIES_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG))
+#define PHOTOBUCKET_IS_ALBUM_PROPERTIES_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG))
+#define PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG, PhotobucketAlbumPropertiesDialogClass))
+
+typedef struct _PhotobucketAlbumPropertiesDialog PhotobucketAlbumPropertiesDialog;
+typedef struct _PhotobucketAlbumPropertiesDialogClass PhotobucketAlbumPropertiesDialogClass;
+typedef struct _PhotobucketAlbumPropertiesDialogPrivate PhotobucketAlbumPropertiesDialogPrivate;
+
+struct _PhotobucketAlbumPropertiesDialog {
+ GtkDialog parent_instance;
+ PhotobucketAlbumPropertiesDialogPrivate *priv;
+};
+
+struct _PhotobucketAlbumPropertiesDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType photobucket_album_properties_dialog_get_type (void);
+GtkWidget * photobucket_album_properties_dialog_new (const char *name);
+const char * photobucket_album_properties_dialog_get_name (PhotobucketAlbumPropertiesDialog *self);
+
+G_END_DECLS
+
+#endif /* PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG_H */
diff --git a/extensions/photobucket/photobucket-album.c b/extensions/photobucket/photobucket-album.c
new file mode 100644
index 0000000..778854f
--- /dev/null
+++ b/extensions/photobucket/photobucket-album.c
@@ -0,0 +1,149 @@
+/* -*- 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 "photobucket-album.h"
+
+
+static gpointer photobucket_album_parent_class = NULL;
+
+
+static void
+photobucket_album_finalize (GObject *obj)
+{
+ PhotobucketAlbum *self;
+
+ self = PHOTOBUCKET_ALBUM (obj);
+
+ g_free (self->name);
+
+ G_OBJECT_CLASS (photobucket_album_parent_class)->finalize (obj);
+}
+
+
+static void
+photobucket_album_class_init (PhotobucketAlbumClass *klass)
+{
+ photobucket_album_parent_class = g_type_class_peek_parent (klass);
+ G_OBJECT_CLASS (klass)->finalize = photobucket_album_finalize;
+}
+
+
+static DomElement*
+photobucket_album_create_element (DomDomizable *base,
+ DomDocument *doc)
+{
+ PhotobucketAlbum *self;
+ DomElement *element;
+
+ self = PHOTOBUCKET_ALBUM (base);
+
+ element = dom_document_create_element (doc, "photoset", NULL);
+ if (self->name != NULL)
+ dom_element_append_child (element, dom_document_create_element_with_text (doc, self->name, "name", NULL));
+
+ return element;
+}
+
+
+static void
+photobucket_album_load_from_element (DomDomizable *base,
+ DomElement *element)
+{
+ PhotobucketAlbum *self;
+
+ self = PHOTOBUCKET_ALBUM (base);
+
+ photobucket_album_set_name (self, dom_element_get_attribute (element, "name"));
+ self->photo_count = atoi (dom_element_get_attribute (element, "photo_count"));
+ self->video_count = atoi (dom_element_get_attribute (element, "video_count"));
+}
+
+
+static void
+photobucket_album_dom_domizable_interface_init (DomDomizableIface *iface)
+{
+ iface->create_element = photobucket_album_create_element;
+ iface->load_from_element = photobucket_album_load_from_element;
+}
+
+
+static void
+photobucket_album_instance_init (PhotobucketAlbum *self)
+{
+ self->name = NULL;
+ self->photo_count = 0;
+ self->video_count = 0;
+}
+
+
+GType
+photobucket_album_get_type (void)
+{
+ static GType photobucket_album_type_id = 0;
+
+ if (photobucket_album_type_id == 0) {
+ static const GTypeInfo g_define_type_info = {
+ sizeof (PhotobucketAlbumClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) photobucket_album_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (PhotobucketAlbum),
+ 0,
+ (GInstanceInitFunc) photobucket_album_instance_init,
+ NULL
+ };
+ static const GInterfaceInfo dom_domizable_info = {
+ (GInterfaceInitFunc) photobucket_album_dom_domizable_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ photobucket_album_type_id = g_type_register_static (G_TYPE_OBJECT,
+ "PhotobucketAlbum",
+ &g_define_type_info,
+ 0);
+ g_type_add_interface_static (photobucket_album_type_id, DOM_TYPE_DOMIZABLE, &dom_domizable_info);
+ }
+
+ return photobucket_album_type_id;
+}
+
+
+PhotobucketAlbum *
+photobucket_album_new (void)
+{
+ return g_object_new (PHOTOBUCKET_TYPE_ALBUM, NULL);
+}
+
+
+void
+photobucket_album_set_name (PhotobucketAlbum *self,
+ const char *value)
+{
+ _g_strset (&self->name, value);
+}
diff --git a/extensions/photobucket/photobucket-album.h b/extensions/photobucket/photobucket-album.h
new file mode 100644
index 0000000..19803cd
--- /dev/null
+++ b/extensions/photobucket/photobucket-album.h
@@ -0,0 +1,60 @@
+/* -*- 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 PHOTOBUCKET_ALBUM_H
+#define PHOTOBUCKET_ALBUM_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PHOTOBUCKET_TYPE_ALBUM (photobucket_album_get_type ())
+#define PHOTOBUCKET_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PHOTOBUCKET_TYPE_ALBUM, PhotobucketAlbum))
+#define PHOTOBUCKET_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PHOTOBUCKET_TYPE_ALBUM, PhotobucketAlbumClass))
+#define PHOTOBUCKET_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PHOTOBUCKET_TYPE_ALBUM))
+#define PHOTOBUCKET_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PHOTOBUCKET_TYPE_ALBUM))
+#define PHOTOBUCKET_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PHOTOBUCKET_TYPE_ALBUM, PhotobucketAlbumClass))
+
+typedef struct _PhotobucketAlbum PhotobucketAlbum;
+typedef struct _PhotobucketAlbumClass PhotobucketAlbumClass;
+
+struct _PhotobucketAlbum {
+ GObject parent_instance;
+
+ char *name;
+ int photo_count;
+ int video_count;
+};
+
+struct _PhotobucketAlbumClass {
+ GObjectClass parent_class;
+};
+
+GType photobucket_album_get_type (void);
+PhotobucketAlbum * photobucket_album_new (void);
+void photobucket_album_set_name (PhotobucketAlbum *self,
+ const char *value);
+
+G_END_DECLS
+
+#endif /* PHOTOBUCKET_ALBUM_H */
diff --git a/extensions/photobucket/photobucket-consumer.c b/extensions/photobucket/photobucket-consumer.c
index efa9fe3..2490e20 100644
--- a/extensions/photobucket/photobucket-consumer.c
+++ b/extensions/photobucket/photobucket-consumer.c
@@ -24,13 +24,15 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gthumb.h>
+#include "photobucket-account.h"
#include "photobucket-consumer.h"
-static gboolean
-photobucket_utils_parse_response (SoupBuffer *body,
- DomDocument **doc_p,
- GError **error)
+gboolean
+photobucket_utils_parse_response (SoupBuffer *body,
+ DomDocument **doc_p,
+ GSimpleAsyncResult *result,
+ GError **error)
{
DomDocument *doc;
DomElement *node;
@@ -61,8 +63,8 @@ photobucket_utils_parse_response (SoupBuffer *body,
}
if (status == NULL) {
- error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 999, _("Unknown error"));
- g_simple_async_result_set_from_error (self->priv->result, error);
+ *error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 999, _("Unknown error"));
+ g_simple_async_result_set_from_error (result, *error);
}
else if (strcmp (status, "Exception") == 0) {
*error = g_error_new_literal (OAUTH_CONNECTION_ERROR,
@@ -70,8 +72,10 @@ photobucket_utils_parse_response (SoupBuffer *body,
(message != NULL) ? message : _("Unknown error"));
}
- g_object_unref (doc);
- return FALSE;
+ if (*error != NULL) {
+ g_object_unref (doc);
+ return FALSE;
+ }
}
}
@@ -87,40 +91,25 @@ photobucket_login_request_response (OAuthConnection *self,
SoupBuffer *body,
GSimpleAsyncResult *result)
{
- DomDocument *doc = NULL;
- GError *error = NULL;
-
- if (photobucket_utils_parse_response (body, &doc, &error)) {
- /*OAuthAccount *account;
- char *username;*/
-
- /* FIXME: set the connection token and token_secret from the response */
-
- /*account = oauth_account_new ();
- oauth_account_set_username (account, username);
- oauth_account_set_token (account, oauth_connection_get_token (self));
- oauth_account_set_token_secret (account, oauth_connection_get_token_secret (self));*/
-
- char *token;
- char *token_secret;
-
- token = NULL;
- token_secret = NULL;
-
- /* FIXME: parse the body and set the token */
- /*oauth_connection_set_token (self, token, token_secret);*/
-
- if ((token == NULL) || (token_secret == NULL)) {
- error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 0, _("Unknown error"));
- g_simple_async_result_set_from_error (result, error);
- }
- else
- g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
-
- g_object_unref (doc);
+ GHashTable *values;
+ char *token;
+ char *token_secret;
+
+ values = soup_form_decode (body->data);
+ token = g_hash_table_lookup (values, "oauth_token");
+ token_secret = g_hash_table_lookup (values, "oauth_token_secret");
+ if ((token != NULL) && (token_secret != NULL)) {
+ oauth_connection_set_token (self, token, token_secret);
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
}
- else
+ else {
+ GError *error;
+
+ error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 0, _("Unknown error"));
g_simple_async_result_set_from_error (result, error);
+ }
+
+ g_hash_table_destroy (values);
}
@@ -145,33 +134,49 @@ photobucket_get_access_token_response (OAuthConnection *self,
SoupBuffer *body,
GSimpleAsyncResult *result)
{
- DomDocument *doc = NULL;
- GError *error = NULL;
+ GHashTable *values;
+ char *username;
+ char *token;
+ char *token_secret;
+
+ values = soup_form_decode (body->data);
- if (photobucket_utils_parse_response (body, &doc, &error)) {
- OAuthAccount *account = NULL;
- char *username;
+ username = g_hash_table_lookup (values, "username");
+ token = g_hash_table_lookup (values, "oauth_token");
+ token_secret = g_hash_table_lookup (values, "oauth_token_secret");
+ if ((username != NULL) && (token != NULL) && (token_secret != NULL)) {
+ OAuthAccount *account;
- /* FIXME: parse the body and set the account */
+ oauth_connection_set_token (self, token, token_secret);
- /*account = oauth_account_new ();
+ account = photobucket_account_new ();
oauth_account_set_username (account, username);
- oauth_account_set_token (account, oauth_connection_get_token (self));
- oauth_account_set_token_secret (account, oauth_connection_get_token_secret (self));*/
+ oauth_account_set_token (account, token);
+ oauth_account_set_token_secret (account, token_secret);
+ photobucket_account_set_subdomain (PHOTOBUCKET_ACCOUNT (account), g_hash_table_lookup (values, "subdomain"));
+ photobucket_account_set_home_url (PHOTOBUCKET_ACCOUNT (account), g_hash_table_lookup (values, "homeurl"));
+ g_simple_async_result_set_op_res_gpointer (result, account, g_object_unref);
+ }
+ else {
+ GError *error;
+
+ error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 0, _("Unknown error"));
+ g_simple_async_result_set_from_error (result, error);
+ }
- /*oauth_connection_set_token (self, token, token_secret);*/
+ g_hash_table_destroy (values);
+}
- if (account == NULL) {
- error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 0, _("Unknown error"));
- g_simple_async_result_set_from_error (result, error);
- }
- else
- g_simple_async_result_set_op_res_gpointer (self->priv->result, account, g_object_unref);
- g_object_unref (doc);
- }
+static char *
+photobucket_get_check_token_url (OAuthConnection *self,
+ OAuthAccount *account,
+ gboolean for_signature)
+{
+ if (for_signature)
+ return g_strconcat ("http://api.photobucket.com/user/", account->username, NULL);
else
- g_simple_async_result_set_from_error (result, error);
+ return g_strconcat ("http://", PHOTOBUCKET_ACCOUNT (account)->subdomain, "/user/", account->username, NULL);
}
@@ -179,14 +184,30 @@ static void
photobucket_check_token_response (OAuthConnection *self,
SoupMessage *msg,
SoupBuffer *body,
- GSimpleAsyncResult *result)
+ GSimpleAsyncResult *result,
+ OAuthAccount *account)
{
DomDocument *doc = NULL;
GError *error = NULL;
- if (photobucket_utils_parse_response (body, &doc, &error)) {
- /* FIXME: add other user info to the account */
- g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
+ if (photobucket_utils_parse_response (body, &doc, result, &error)) {
+ DomElement *node;
+
+ for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
+ if (g_strcmp0 (node->tag_name, "response") == 0) {
+ DomElement *child;
+
+ for (child = DOM_ELEMENT (node)->first_child; child; child = child->next_sibling) {
+ if (g_strcmp0 (child->tag_name, "content") == 0) {
+ dom_domizable_load_from_element (DOM_DOMIZABLE (account), child);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
g_object_unref (doc);
}
else
@@ -195,17 +216,17 @@ photobucket_check_token_response (OAuthConnection *self,
OAuthConsumer photobucket_consumer = {
- "PhotoBucket",
+ "Photobucket",
"photobucket",
"http://www.photobucket.com",
"http",
- "8960706ee7f4151e893b11837e9c24ce",
- "1ff8d1e45c873423",
+ "149829931",
+ "b4e542229836cc59b66489c6d2d8ca04",
"http://api.photobucket.com/login/request",
photobucket_login_request_response,
phoyobucket_get_login_link,
"http://api.photobucket.com/login/access",
photobucket_get_access_token_response,
- "http://api.photobucket.com/user/",
+ photobucket_get_check_token_url,
photobucket_check_token_response
};
diff --git a/extensions/photobucket/photobucket-consumer.h b/extensions/photobucket/photobucket-consumer.h
index 25a2515..8cbebb6 100644
--- a/extensions/photobucket/photobucket-consumer.h
+++ b/extensions/photobucket/photobucket-consumer.h
@@ -23,8 +23,14 @@
#ifndef PHOTOBUCKET_CONSUMER_H
#define PHOTOBUCKET_CONSUMER_H
+#include <gthumb.h>
#include <extensions/oauth/oauth-connection.h>
extern OAuthConsumer photobucket_consumer;
+gboolean photobucket_utils_parse_response (SoupBuffer *body,
+ DomDocument **doc_p,
+ GSimpleAsyncResult *result,
+ GError **error);
+
#endif /* PHOTOBUCKET_CONSUMER_H */
diff --git a/extensions/photobucket/photobucket-photo.c b/extensions/photobucket/photobucket-photo.c
new file mode 100644
index 0000000..054d298
--- /dev/null
+++ b/extensions/photobucket/photobucket-photo.c
@@ -0,0 +1,231 @@
+/* -*- 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 "photobucket-photo.h"
+
+
+static gpointer photobucket_photo_parent_class = NULL;
+
+
+static void
+photobucket_photo_finalize (GObject *obj)
+{
+ PhotobucketPhoto *self;
+
+ self = PHOTOBUCKET_PHOTO (obj);
+
+ g_free (self->name);
+ g_free (self->browse_url);
+ g_free (self->url);
+ g_free (self->thumb_url);
+ g_free (self->description);
+ g_free (self->title);
+
+ G_OBJECT_CLASS (photobucket_photo_parent_class)->finalize (obj);
+}
+
+
+static void
+photobucket_photo_class_init (PhotobucketPhotoClass *klass)
+{
+ photobucket_photo_parent_class = g_type_class_peek_parent (klass);
+ G_OBJECT_CLASS (klass)->finalize = photobucket_photo_finalize;
+}
+
+
+static DomElement*
+photobucket_photo_create_element (DomDomizable *base,
+ DomDocument *doc)
+{
+ PhotobucketPhoto *self;
+ DomElement *element;
+
+ self = PHOTOBUCKET_PHOTO (base);
+
+ element = dom_document_create_element (doc, "photo", NULL);
+ if (self->name != NULL)
+ dom_element_set_attribute (element, "name", self->name);
+
+ return element;
+}
+
+
+static void
+photobucket_photo_load_from_element (DomDomizable *base,
+ DomElement *element)
+{
+ PhotobucketPhoto *self;
+ DomElement *node;
+
+ if ((element == NULL) || (g_strcmp0 (element->tag_name, "photo") != 0))
+ return;
+
+ self = PHOTOBUCKET_PHOTO (base);
+
+ photobucket_photo_set_name (self, dom_element_get_attribute (element, "name"));
+ photobucket_photo_set_is_public (self, dom_element_get_attribute (element, "public"));
+
+ for (node = element->first_child; node; node = node->next_sibling) {
+ if (g_strcmp0 (node->tag_name, "browse_url") == 0) {
+ photobucket_photo_set_browse_url (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "url") == 0) {
+ photobucket_photo_set_url (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "thumb_url") == 0) {
+ photobucket_photo_set_thumb_url (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "description") == 0) {
+ photobucket_photo_set_description (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "title") == 0) {
+ photobucket_photo_set_title (self, dom_element_get_inner_text (node));
+ }
+ else if (g_strcmp0 (node->tag_name, "is_sponsored") == 0) {
+ photobucket_photo_set_is_sponsored (self, dom_element_get_inner_text (node));
+ }
+ }
+}
+
+
+static void
+photobucket_photo_dom_domizable_interface_init (DomDomizableIface *iface)
+{
+ iface->create_element = photobucket_photo_create_element;
+ iface->load_from_element = photobucket_photo_load_from_element;
+}
+
+
+static void
+photobucket_photo_instance_init (PhotobucketPhoto *self)
+{
+}
+
+
+GType
+photobucket_photo_get_type (void)
+{
+ static GType photobucket_photo_type_id = 0;
+
+ if (photobucket_photo_type_id == 0) {
+ static const GTypeInfo g_define_type_info = {
+ sizeof (PhotobucketPhotoClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) photobucket_photo_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (PhotobucketPhoto),
+ 0,
+ (GInstanceInitFunc) photobucket_photo_instance_init,
+ NULL
+ };
+ static const GInterfaceInfo dom_domizable_info = {
+ (GInterfaceInitFunc) photobucket_photo_dom_domizable_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ photobucket_photo_type_id = g_type_register_static (G_TYPE_OBJECT,
+ "PhotobucketPhoto",
+ &g_define_type_info,
+ 0);
+ g_type_add_interface_static (photobucket_photo_type_id, DOM_TYPE_DOMIZABLE, &dom_domizable_info);
+ }
+
+ return photobucket_photo_type_id;
+}
+
+
+PhotobucketPhoto *
+photobucket_photo_new (void)
+{
+ return g_object_new (PHOTOBUCKET_TYPE_PHOTO, NULL);
+}
+
+
+void
+photobucket_photo_set_name (PhotobucketPhoto *self,
+ const char *value)
+{
+ _g_strset (&self->name, value);
+}
+
+
+void
+photobucket_photo_set_is_public (PhotobucketPhoto *self,
+ const char *value)
+{
+ self->is_public = (g_strcmp0 (value, "1") == 0);
+}
+
+
+void
+photobucket_photo_set_browse_url (PhotobucketPhoto *self,
+ const char *value)
+{
+ _g_strset (&self->name, value);
+}
+
+
+void
+photobucket_photo_set_url (PhotobucketPhoto *self,
+ const char *value)
+{
+ _g_strset (&self->name, value);
+}
+
+
+void
+photobucket_photo_set_thumb_url (PhotobucketPhoto *self,
+ const char *value)
+{
+ _g_strset (&self->name, value);
+}
+
+
+void
+photobucket_photo_set_description (PhotobucketPhoto *self,
+ const char *value)
+{
+ _g_strset (&self->name, value);
+}
+
+
+void
+photobucket_photo_set_title (PhotobucketPhoto *self,
+ const char *value)
+{
+ _g_strset (&self->name, value);
+}
+
+
+void
+photobucket_photo_set_is_sponsored (PhotobucketPhoto *self,
+ const char *value)
+{
+ self->is_sponsored = (g_strcmp0 (value, "1") == 0);
+}
diff --git a/extensions/photobucket/photobucket-photo.h b/extensions/photobucket/photobucket-photo.h
new file mode 100644
index 0000000..2919131
--- /dev/null
+++ b/extensions/photobucket/photobucket-photo.h
@@ -0,0 +1,81 @@
+/* -*- 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 PHOTOBUCKET_PHOTO_H
+#define PHOTOBUCKET_PHOTO_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PHOTOBUCKET_TYPE_PHOTO (photobucket_photo_get_type ())
+#define PHOTOBUCKET_PHOTO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PHOTOBUCKET_TYPE_PHOTO, PhotobucketPhoto))
+#define PHOTOBUCKET_PHOTO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PHOTOBUCKET_TYPE_PHOTO, PhotobucketPhotoClass))
+#define PHOTOBUCKET_IS_PHOTO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PHOTOBUCKET_TYPE_PHOTO))
+#define PHOTOBUCKET_IS_PHOTO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PHOTOBUCKET_TYPE_PHOTO))
+#define PHOTOBUCKET_PHOTO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PHOTOBUCKET_TYPE_PHOTO, PhotobucketPhotoClass))
+
+typedef struct _PhotobucketPhoto PhotobucketPhoto;
+typedef struct _PhotobucketPhotoClass PhotobucketPhotoClass;
+typedef struct _PhotobucketPhotoPrivate PhotobucketPhotoPrivate;
+
+struct _PhotobucketPhoto {
+ GObject parent_instance;
+ PhotobucketPhotoPrivate *priv;
+
+ char *name;
+ gboolean is_public;
+ char *browse_url;
+ char *url;
+ char *thumb_url;
+ char *description;
+ char *title;
+ gboolean is_sponsored;
+};
+
+struct _PhotobucketPhotoClass {
+ GObjectClass parent_class;
+};
+
+GType photobucket_photo_get_type (void);
+PhotobucketPhoto * photobucket_photo_new (void);
+void photobucket_photo_set_name (PhotobucketPhoto *self,
+ const char *value);
+void photobucket_photo_set_is_public (PhotobucketPhoto *self,
+ const char *value);
+void photobucket_photo_set_browse_url (PhotobucketPhoto *self,
+ const char *value);
+void photobucket_photo_set_url (PhotobucketPhoto *self,
+ const char *value);
+void photobucket_photo_set_thumb_url (PhotobucketPhoto *self,
+ const char *value);
+void photobucket_photo_set_description (PhotobucketPhoto *self,
+ const char *value);
+void photobucket_photo_set_title (PhotobucketPhoto *self,
+ const char *value);
+void photobucket_photo_set_is_sponsored (PhotobucketPhoto *self,
+ const char *value);
+
+G_END_DECLS
+
+#endif /* PHOTOBUCKET_PHOTO_H */
diff --git a/extensions/photobucket/photobucket-service.c b/extensions/photobucket/photobucket-service.c
new file mode 100644
index 0000000..d67ea50
--- /dev/null
+++ b/extensions/photobucket/photobucket-service.c
@@ -0,0 +1,989 @@
+/* -*- 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 <glib.h>
+#include <glib/gi18n.h>
+#include <gthumb.h>
+#include "photobucket-album.h"
+#include "photobucket-consumer.h"
+#include "photobucket-photo.h"
+#include "photobucket-service.h"
+
+
+typedef struct {
+ PhotobucketAlbum *album;
+ GList *file_list;
+ GCancellable *cancellable;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ GList *current;
+ goffset total_size;
+ goffset uploaded_size;
+ int n_files;
+ int uploaded_files;
+ GList *ids;
+} PostPhotosData;
+
+
+static void
+post_photos_data_free (PostPhotosData *post_photos)
+{
+ if (post_photos == NULL)
+ return;
+ _g_string_list_free (post_photos->ids);
+ _g_object_unref (post_photos->cancellable);
+ _g_object_list_unref (post_photos->file_list);
+ g_free (post_photos);
+}
+
+
+struct _PhotobucketServicePrivate
+{
+ OAuthConnection *conn;
+ PostPhotosData *post_photos;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+photobucket_service_finalize (GObject *object)
+{
+ PhotobucketService *self;
+
+ self = PHOTOBUCKET_SERVICE (object);
+
+ _g_object_unref (self->priv->conn);
+ post_photos_data_free (self->priv->post_photos);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+photobucket_service_class_init (PhotobucketServiceClass *klass)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (PhotobucketServicePrivate));
+
+ object_class = (GObjectClass*) klass;
+ object_class->finalize = photobucket_service_finalize;
+}
+
+
+static void
+photobucket_service_init (PhotobucketService *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, PHOTOBUCKET_TYPE_SERVICE, PhotobucketServicePrivate);
+ self->priv->conn = NULL;
+ self->priv->post_photos = NULL;
+}
+
+
+GType
+photobucket_service_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (PhotobucketServiceClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) photobucket_service_class_init,
+ NULL,
+ NULL,
+ sizeof (PhotobucketService),
+ 0,
+ (GInstanceInitFunc) photobucket_service_init
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "PhotobucketService",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+PhotobucketService *
+photobucket_service_new (OAuthConnection *conn)
+{
+ PhotobucketService *self;
+
+ self = (PhotobucketService *) g_object_new (PHOTOBUCKET_TYPE_SERVICE, NULL);
+ self->priv->conn = g_object_ref (conn);
+
+ return self;
+}
+
+
+#if 0
+
+
+/* -- photobucket_service_get_user_info -- */
+
+
+static void
+get_logged_in_user_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ PhotobucketService *self = user_data;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc = NULL;
+ GError *error = NULL;
+
+ result = oauth_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);
+ if (photobucket_utils_parse_response (body, &doc, result, &error)) {
+ DomElement *root;
+ char *uid = NULL;
+
+ root = DOM_ELEMENT (doc)->first_child;
+ if (g_strcmp0 (root->tag_name, "users_getLoggedInUser_response") == 0)
+ uid = g_strdup (dom_element_get_inner_text (root));
+
+ if (uid == NULL) {
+ error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 0, _("Unknown error"));
+ g_simple_async_result_set_from_error (result, error);
+ }
+ else
+ g_simple_async_result_set_op_res_gpointer (result, uid, g_free);
+
+ g_object_unref (doc);
+ }
+ else
+ g_simple_async_result_set_from_error (result, error);
+
+ g_simple_async_result_complete_in_idle (result);
+
+ soup_buffer_free (body);
+}
+
+
+void
+photobucket_service_get_logged_in_user (PhotobucketService *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GHashTable *data_set;
+ SoupMessage *msg;
+
+ gth_task_progress (GTH_TASK (self->priv->conn), _("Connecting to the server"), _("Getting account information"), TRUE, 0.0);
+
+ data_set = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (data_set, "method", "photobucket.users.getLoggedInUser");
+ oauth_connection_add_signature (self->priv->conn, "photobucket.users.getLoggedInUser", );
+ msg = soup_form_request_new_from_hash ("POST", PHOTOBUCKET_HTTPS_REST_SERVER, data_set);
+ oauth_connection_send_message (self->priv->conn,
+ msg,
+ cancellable,
+ callback,
+ user_data,
+ photobucket_service_get_logged_in_user,
+ get_logged_in_user_ready_cb,
+ self);
+
+ g_hash_table_destroy (data_set);
+}
+
+
+char *
+photobucket_service_get_logged_in_user_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+ else
+ return g_strdup (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+}
+
+
+/* -- photobucket_service_get_user_info -- */
+
+
+static void
+get_user_info_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ PhotobucketService *self = user_data;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc = NULL;
+ GError *error = NULL;
+
+ result = oauth_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);
+ if (photobucket_utils_parse_response (body, &doc, &error)) {
+ DomElement *node;
+ PhotobucketUser *user = NULL;
+
+ for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
+ if (g_strcmp0 (node->tag_name, "users_getInfo_response") == 0) {
+ DomElement *child;
+
+ for (child = node->first_child; child; child = child->next_sibling) {
+ if (g_strcmp0 (child->tag_name, "user") == 0) {
+ user = photobucket_user_new ();
+ dom_domizable_load_from_element (DOM_DOMIZABLE (user), child);
+ g_simple_async_result_set_op_res_gpointer (result, user, (GDestroyNotify) g_object_unref);
+ }
+ }
+ }
+ }
+
+ if (user == NULL) {
+ error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 0, _("Unknown error"));
+ g_simple_async_result_set_from_error (result, error);
+ }
+
+ g_object_unref (doc);
+ }
+ else
+ g_simple_async_result_set_from_error (result, error);
+
+ g_simple_async_result_complete_in_idle (result);
+
+ soup_buffer_free (body);
+}
+
+
+void
+photobucket_service_get_user_info (PhotobucketService *self,
+ const char *fields,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GHashTable *data_set;
+ SoupMessage *msg;
+
+ gth_task_progress (GTH_TASK (self->priv->conn), _("Connecting to the server"), _("Getting account information"), TRUE, 0.0);
+
+ data_set = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (data_set, "method", "photobucket.users.getInfo");
+ g_hash_table_insert (data_set, "uids", (char *) oauth_connection_get_user_id (self->priv->conn));
+ g_hash_table_insert (data_set, "fields", (char *) fields);
+ oauth_connection_add_api_sig (self->priv->conn, data_set);
+ msg = soup_form_request_new_from_hash ("POST", PHOTOBUCKET_HTTPS_REST_SERVER, data_set);
+ oauth_connection_send_message (self->priv->conn,
+ msg,
+ cancellable,
+ callback,
+ user_data,
+ photobucket_service_get_user_info,
+ get_user_info_ready_cb,
+ self);
+
+ g_hash_table_destroy (data_set);
+}
+
+
+PhotobucketUser *
+photobucket_service_get_user_info_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+ else
+ return g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+}
+
+
+#endif
+
+
+/* -- photobucket_service_get_albums -- */
+
+
+static DomElement *
+get_content (DomDocument *doc)
+{
+ DomElement *root;
+
+ for (root = DOM_ELEMENT (doc)->first_child; root; root = root->next_sibling) {
+ if (g_strcmp0 (root->tag_name, "response") == 0) {
+ DomElement *child;
+
+ for (child = root->first_child; child; child = child->next_sibling)
+ if (g_strcmp0 (child->tag_name, "content") == 0)
+ return child;
+ }
+ }
+
+ g_assert_not_reached ();
+
+ return NULL;
+}
+
+
+static void
+get_albums_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ PhotobucketService *self = user_data;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc = NULL;
+ GError *error = NULL;
+
+ result = oauth_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);
+ if (photobucket_utils_parse_response (body, &doc, result, &error)) {
+ GList *albums = NULL;
+ DomElement *node;
+
+ for (node = get_content (doc)->first_child; node; node = node->next_sibling) {
+ if (g_strcmp0 (node->tag_name, "album") == 0) {
+ PhotobucketAlbum *album;
+
+ album = photobucket_album_new ();
+ dom_domizable_load_from_element (DOM_DOMIZABLE (album), node);
+ 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);
+
+ g_object_unref (doc);
+ }
+ else
+ g_simple_async_result_set_from_error (result, error);
+
+ g_simple_async_result_complete_in_idle (result);
+
+ soup_buffer_free (body);
+}
+
+
+void
+photobucket_service_get_albums (PhotobucketService *self,
+ PhotobucketAccount *account,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GHashTable *data_set;
+ char *url;
+ SoupMessage *msg;
+
+ g_return_if_fail (account != NULL);
+ g_return_if_fail (account->subdomain != NULL);
+
+ gth_task_progress (GTH_TASK (self->priv->conn), _("Getting the album list"), NULL, TRUE, 0.0);
+
+ data_set = g_hash_table_new (g_str_hash, g_str_equal);
+ url = g_strconcat ("http://api.photobucket.com/album/", OAUTH_ACCOUNT (account)->username, NULL);
+ oauth_connection_add_signature (self->priv->conn, "GET", url, data_set);
+ g_free (url);
+
+ url = g_strconcat ("http://", account->subdomain, "/album/", OAUTH_ACCOUNT (account)->username, NULL);
+ msg = soup_form_request_new_from_hash ("GET", url, data_set);
+ oauth_connection_send_message (self->priv->conn,
+ msg,
+ cancellable,
+ callback,
+ user_data,
+ photobucket_service_get_albums,
+ get_albums_ready_cb,
+ self);
+
+ g_hash_table_destroy (data_set);
+ g_free (url);
+}
+
+
+GList *
+photobucket_service_get_albums_finish (PhotobucketService *service,
+ GAsyncResult *result,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+ else
+ return _g_object_list_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+}
+
+
+/* -- photobucket_service_create_album -- */
+
+
+static void
+create_album_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ PhotobucketService *self = user_data;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc = NULL;
+ GError *error = NULL;
+
+ result = oauth_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);
+ if (photobucket_utils_parse_response (body, &doc, result, &error)) {
+ DomElement *node;
+ PhotobucketAlbum *album = NULL;
+
+ for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
+ if (g_strcmp0 (node->tag_name, "photos_createAlbum_response") == 0) {
+ album = photobucket_album_new ();
+ dom_domizable_load_from_element (DOM_DOMIZABLE (album), node);
+ break;
+ }
+ }
+
+ if (album == NULL) {
+ error = g_error_new_literal (OAUTH_CONNECTION_ERROR, 0, _("Unknown error"));
+ g_simple_async_result_set_from_error (result, error);
+ }
+ else
+ g_simple_async_result_set_op_res_gpointer (result, album, (GDestroyNotify) _g_object_unref);
+
+ g_object_unref (doc);
+ }
+ else
+ g_simple_async_result_set_from_error (result, error);
+
+ g_simple_async_result_complete_in_idle (result);
+
+ soup_buffer_free (body);
+}
+
+
+void
+photobucket_service_create_album (PhotobucketService *self,
+ PhotobucketAlbum *album,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GHashTable *data_set;
+ const char *privacy;
+ SoupMessage *msg;
+
+ g_return_if_fail (album != NULL);
+ g_return_if_fail (album->name != NULL);
+
+ gth_task_progress (GTH_TASK (self->priv->conn), _("Creating the new album"), NULL, TRUE, 0.0);
+
+ /* FIXME
+ data_set = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (data_set, "method", "photobucket.photos.createAlbum");
+ g_hash_table_insert (data_set, "name", album->name);
+ if (album->description != NULL)
+ g_hash_table_insert (data_set, "description", album->description);
+ if (album->location != NULL)
+ g_hash_table_insert (data_set, "location", album->location);
+ privacy = get_privacy_from_visibility (album->visibility);
+ if (privacy != NULL)
+ g_hash_table_insert (data_set, "privacy", (char *) privacy);
+ oauth_connection_add_api_sig (self->priv->conn, data_set);
+ msg = soup_form_request_new_from_hash ("POST", PHOTOBUCKET_HTTPS_REST_SERVER, data_set);
+ oauth_connection_send_message (self->priv->conn,
+ msg,
+ cancellable,
+ callback,
+ user_data,
+ photobucket_service_create_album,
+ create_album_ready_cb,
+ self);
+
+ g_hash_table_destroy (data_set);
+ */
+}
+
+
+PhotobucketAlbum *
+photobucket_service_create_album_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+ else
+ return g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+}
+
+
+/* -- photobucket_service_upload_photos -- */
+
+
+static void
+upload_photos_done (PhotobucketService *self,
+ GError *error)
+{
+ GSimpleAsyncResult *result;
+
+ result = oauth_connection_get_result (self->priv->conn);
+ if (error == NULL) {
+ self->priv->post_photos->ids = g_list_reverse (self->priv->post_photos->ids);
+ g_simple_async_result_set_op_res_gpointer (result, self->priv->post_photos->ids, (GDestroyNotify) _g_string_list_free);
+ self->priv->post_photos->ids = NULL;
+ }
+ else {
+ if (self->priv->post_photos->current != NULL) {
+ GthFileData *file_data = self->priv->post_photos->current->data;
+ char *msg;
+
+ msg = g_strdup_printf (_("Could not upload '%s': %s"), g_file_info_get_display_name (file_data->info), error->message);
+ g_free (error->message);
+ error->message = msg;
+ }
+ g_simple_async_result_set_from_error (result, error);
+ }
+
+ g_simple_async_result_complete_in_idle (result);
+}
+
+
+static void photobucket_service_upload_current_file (PhotobucketService *self);
+
+
+static void
+upload_photo_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ PhotobucketService *self = user_data;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc = NULL;
+ GError *error = NULL;
+ GthFileData *file_data;
+
+ result = oauth_connection_get_result (self->priv->conn);
+
+ if (msg->status_code != 200) {
+ GError *error;
+
+ error = g_error_new_literal (SOUP_HTTP_ERROR, msg->status_code, soup_status_get_phrase (msg->status_code));
+ upload_photos_done (self, error);
+ g_error_free (error);
+
+ return;
+ }
+
+ body = soup_message_body_flatten (msg->response_body);
+ if (photobucket_utils_parse_response (body, &doc, result, &error)) {
+ DomElement *node;
+
+ /* save the photo id */
+
+ for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
+ if (g_strcmp0 (node->tag_name, "pid") == 0) {
+ const char *id;
+
+ id = dom_element_get_inner_text (node);
+ self->priv->post_photos->ids = g_list_prepend (self->priv->post_photos->ids, g_strdup (id));
+ }
+ }
+
+ g_object_unref (doc);
+ }
+ else {
+ soup_buffer_free (body);
+ upload_photos_done (self, error);
+ return;
+ }
+
+ soup_buffer_free (body);
+
+ file_data = self->priv->post_photos->current->data;
+ self->priv->post_photos->uploaded_size += g_file_info_get_size (file_data->info);
+ self->priv->post_photos->current = self->priv->post_photos->current->next;
+ photobucket_service_upload_current_file (self);
+}
+
+
+static void
+upload_photo_file_buffer_ready_cb (void **buffer,
+ gsize count,
+ GError *error,
+ gpointer user_data)
+{
+ PhotobucketService *self = user_data;
+ GthFileData *file_data;
+ SoupMultipart *multipart;
+ char *uri;
+ SoupBuffer *body;
+ SoupMessage *msg;
+
+ if (error != NULL) {
+ upload_photos_done (self, error);
+ return;
+ }
+
+ file_data = self->priv->post_photos->current->data;
+ multipart = soup_multipart_new ("multipart/form-data");
+
+ /* the metadata part */
+
+ {
+ GHashTable *data_set;
+ char *title;
+ char *description;
+ GList *keys;
+ GList *scan;
+
+ data_set = g_hash_table_new (g_str_hash, g_str_equal);
+
+ g_hash_table_insert (data_set, "method", "photobucket.photos.upload");
+
+ title = gth_file_data_get_attribute_as_string (file_data, "general::title");
+ description = gth_file_data_get_attribute_as_string (file_data, "general::description");
+ if (description != NULL)
+ g_hash_table_insert (data_set, "caption", description);
+ else if (title != NULL)
+ g_hash_table_insert (data_set, "caption", title);
+
+ if (self->priv->post_photos->album != NULL)
+ g_hash_table_insert (data_set, "aid", self->priv->post_photos->album->name);
+
+ oauth_connection_add_signature (self->priv->conn, "POST", "FIXME", data_set); /* FIXME */
+
+ keys = g_hash_table_get_keys (data_set);
+ for (scan = keys; scan; scan = scan->next) {
+ char *key = scan->data;
+ soup_multipart_append_form_string (multipart, key, g_hash_table_lookup (data_set, key));
+ }
+
+ g_list_free (keys);
+ g_hash_table_unref (data_set);
+ }
+
+ /* the file part */
+
+ uri = g_file_get_uri (file_data->file);
+ body = soup_buffer_new (SOUP_MEMORY_TEMPORARY, *buffer, count);
+ soup_multipart_append_form_file (multipart,
+ NULL,
+ _g_uri_get_basename (uri),
+ gth_file_data_get_mime_type (file_data),
+ body);
+
+ soup_buffer_free (body);
+ g_free (uri);
+
+ /* send the file */
+
+ {
+ char *details;
+
+ /* Translators: %s is a filename */
+ details = g_strdup_printf (_("Uploading '%s'"), g_file_info_get_display_name (file_data->info));
+ gth_task_progress (GTH_TASK (self->priv->conn),
+ NULL, details,
+ FALSE,
+ (double) (self->priv->post_photos->uploaded_size + (g_file_info_get_size (file_data->info) / 2.0)) / self->priv->post_photos->total_size);
+
+ g_free (details);
+ }
+
+ /* FIXME
+ msg = soup_form_request_new_from_multipart (PHOTOBUCKET_HTTPS_REST_SERVER, multipart);
+ oauth_connection_send_message (self->priv->conn,
+ msg,
+ self->priv->post_photos->cancellable,
+ self->priv->post_photos->callback,
+ self->priv->post_photos->user_data,
+ photobucket_service_upload_photos,
+ upload_photo_ready_cb,
+ self);
+ */
+
+ soup_multipart_free (multipart);
+}
+
+
+static void
+photobucket_service_upload_current_file (PhotobucketService *self)
+{
+ GthFileData *file_data;
+
+ if (self->priv->post_photos->current == NULL) {
+ upload_photos_done (self, NULL);
+ return;
+ }
+
+ file_data = self->priv->post_photos->current->data;
+ g_load_file_async (file_data->file,
+ G_PRIORITY_DEFAULT,
+ self->priv->post_photos->cancellable,
+ upload_photo_file_buffer_ready_cb,
+ self);
+}
+
+
+static void
+upload_photos_info_ready_cb (GList *files,
+ GError *error,
+ gpointer user_data)
+{
+ PhotobucketService *self = user_data;
+ GList *scan;
+
+ if (error != NULL) {
+ upload_photos_done (self, error);
+ return;
+ }
+
+ self->priv->post_photos->file_list = _g_object_list_ref (files);
+ for (scan = self->priv->post_photos->file_list; scan; scan = scan->next) {
+ GthFileData *file_data = scan->data;
+
+ self->priv->post_photos->total_size += g_file_info_get_size (file_data->info);
+ self->priv->post_photos->n_files += 1;
+ }
+
+ self->priv->post_photos->current = self->priv->post_photos->file_list;
+ photobucket_service_upload_current_file (self);
+}
+
+
+void
+photobucket_service_upload_photos (PhotobucketService *self,
+ PhotobucketAlbum *album,
+ GList *file_list, /* GFile list */
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gth_task_progress (GTH_TASK (self->priv->conn), _("Uploading the files to the server"), NULL, TRUE, 0.0);
+
+ post_photos_data_free (self->priv->post_photos);
+ self->priv->post_photos = g_new0 (PostPhotosData, 1);
+ self->priv->post_photos->album = _g_object_ref (album);
+ self->priv->post_photos->cancellable = _g_object_ref (cancellable);
+ self->priv->post_photos->callback = callback;
+ self->priv->post_photos->user_data = user_data;
+ self->priv->post_photos->total_size = 0;
+ self->priv->post_photos->n_files = 0;
+
+ _g_query_all_metadata_async (file_list,
+ FALSE,
+ TRUE,
+ "*",
+ self->priv->post_photos->cancellable,
+ upload_photos_info_ready_cb,
+ self);
+}
+
+
+GList *
+photobucket_service_upload_photos_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+ else
+ return _g_string_list_dup (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+}
+
+
+#if 0
+
+/* -- photobucket_service_list_photos -- */
+
+
+static void
+list_photos_ready_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ PhotobucketService *self = user_data;
+ GSimpleAsyncResult *result;
+ SoupBuffer *body;
+ DomDocument *doc = NULL;
+ GError *error = NULL;
+
+ result = oauth_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);
+ if (photobucket_utils_parse_response (body, &doc, &error)) {
+ DomElement *response;
+ DomElement *node;
+ GList *photos = NULL;
+
+ response = DOM_ELEMENT (doc)->first_child;
+ for (node = response->first_child; node; node = node->next_sibling) {
+ if (g_strcmp0 (node->tag_name, "photoset") == 0) {
+ DomElement *child;
+ int position;
+
+ position = 0;
+ for (child = node->first_child; child; child = child->next_sibling) {
+ if (g_strcmp0 (child->tag_name, "photo") == 0) {
+ PhotobucketPhoto *photo;
+
+ photo = photobucket_photo_new ();
+ dom_domizable_load_from_element (DOM_DOMIZABLE (photo), child);
+ photo->position = position++;
+ photos = g_list_prepend (photos, photo);
+ }
+ }
+ }
+ }
+
+ photos = g_list_reverse (photos);
+ g_simple_async_result_set_op_res_gpointer (result, photos, (GDestroyNotify) _g_object_list_unref);
+
+ g_object_unref (doc);
+ }
+ else
+ g_simple_async_result_set_from_error (result, error);
+
+ g_simple_async_result_complete_in_idle (result);
+
+ soup_buffer_free (body);
+}
+
+
+void
+photobucket_service_list_photos (PhotobucketService *self,
+ PhotobucketPhotoset *photoset,
+ const char *extras,
+ int per_page,
+ int page,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GHashTable *data_set;
+ char *s;
+ SoupMessage *msg;
+
+ g_return_if_fail (photoset != NULL);
+
+ gth_task_progress (GTH_TASK (self->priv->conn), _("Getting the photo list"), NULL, TRUE, 0.0);
+
+ data_set = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (data_set, "method", "photobucket.photosets.getPhotos");
+ g_hash_table_insert (data_set, "photoset_id", photoset->id);
+ if (extras != NULL)
+ g_hash_table_insert (data_set, "extras", (char *) extras);
+ if (per_page > 0) {
+ s = g_strdup_printf ("%d", per_page);
+ g_hash_table_insert (data_set, "per_page", s);
+ g_free (s);
+ }
+ if (page > 0) {
+ s = g_strdup_printf ("%d", page);
+ g_hash_table_insert (data_set, "page", s);
+ g_free (s);
+ }
+ oauth_connection_add_api_sig (self->priv->conn, data_set);
+ msg = soup_form_request_new_from_hash ("GET", "http://api.photobucket.com/services/rest", data_set);
+ oauth_connection_send_message (self->priv->conn,
+ msg,
+ cancellable,
+ callback,
+ user_data,
+ photobucket_service_list_photos,
+ list_photos_ready_cb,
+ self);
+
+ g_hash_table_destroy (data_set);
+}
+
+
+GList *
+photobucket_service_list_photos_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ return NULL;
+ else
+ return _g_object_list_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+}
+
+#endif
diff --git a/extensions/photobucket/photobucket-service.h b/extensions/photobucket/photobucket-service.h
new file mode 100644
index 0000000..fb54680
--- /dev/null
+++ b/extensions/photobucket/photobucket-service.h
@@ -0,0 +1,107 @@
+/* -*- 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 PHOTOBUCKET_SERVICE_H
+#define PHOTOBUCKET_SERVICE_H
+
+#include <glib-object.h>
+#include <extensions/oauth/oauth-connection.h>
+#include "photobucket-album.h"
+#include "photobucket-account.h"
+
+#define PHOTOBUCKET_TYPE_SERVICE (photobucket_service_get_type ())
+#define PHOTOBUCKET_SERVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PHOTOBUCKET_TYPE_SERVICE, PhotobucketService))
+#define PHOTOBUCKET_SERVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), PHOTOBUCKET_TYPE_SERVICE, PhotobucketServiceClass))
+#define PHOTOBUCKET_IS_SERVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PHOTOBUCKET_TYPE_SERVICE))
+#define PHOTOBUCKET_IS_SERVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PHOTOBUCKET_TYPE_SERVICE))
+#define PHOTOBUCKET_SERVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), PHOTOBUCKET_TYPE_SERVICE, PhotobucketServiceClass))
+
+typedef struct _PhotobucketService PhotobucketService;
+typedef struct _PhotobucketServicePrivate PhotobucketServicePrivate;
+typedef struct _PhotobucketServiceClass PhotobucketServiceClass;
+
+struct _PhotobucketService
+{
+ GObject __parent;
+ PhotobucketServicePrivate *priv;
+};
+
+struct _PhotobucketServiceClass
+{
+ GObjectClass __parent_class;
+};
+
+GType photobucket_service_get_type (void) G_GNUC_CONST;
+PhotobucketService * photobucket_service_new (OAuthConnection *conn);
+#if 0
+void photobucket_service_get_logged_in_user (PhotobucketService *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+char * photobucket_service_get_logged_in_user_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error);
+void photobucket_service_get_user_info (PhotobucketService *self,
+ const char *fields,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+PhotobucketUser * photobucket_service_get_user_info_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error);
+#endif
+void photobucket_service_get_albums (PhotobucketService *self,
+ PhotobucketAccount *account,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GList * photobucket_service_get_albums_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error);
+void photobucket_service_create_album (PhotobucketService *self,
+ PhotobucketAlbum *album,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+PhotobucketAlbum * photobucket_service_create_album_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error);
+void photobucket_service_upload_photos (PhotobucketService *self,
+ PhotobucketAlbum *album,
+ GList *file_list, /* GFile list */
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GList * photobucket_service_upload_photos_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error);
+#if 0
+void photobucket_service_list_photos (PhotobucketService *self,
+ PhotobucketAlbum *album,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GList * photobucket_service_list_photos_finish (PhotobucketService *self,
+ GAsyncResult *result,
+ GError **error);
+#endif
+
+#endif /* PHOTOBUCKET_SERVICE_H */
diff --git a/gthumb/gsignature.c b/gthumb/gsignature.c
index bc071f7..8c523ed 100644
--- a/gthumb/gsignature.c
+++ b/gthumb/gsignature.c
@@ -121,7 +121,7 @@ g_signature_free (GSignature *signature)
g_checksum_free (signature->primary);
g_checksum_free (signature->internal);
- g_free (signature);
+ g_slice_free (GSignature, signature);
}
@@ -179,13 +179,14 @@ g_signature_get_value (GSignature *signature,
gchar *
g_compute_signature_for_data (GChecksumType checksum_type,
+ GSignatureEnc encoding,
const gchar *key,
gssize key_length,
const guchar *data,
gsize data_length)
{
GSignature *signature;
- gchar *retval;
+ gchar *retval = NULL;
g_return_val_if_fail (data != NULL, NULL);
@@ -194,7 +195,26 @@ g_compute_signature_for_data (GChecksumType checksum_type,
return NULL;
g_signature_update (signature, data, data_length);
- retval = g_strdup (g_signature_get_string (signature));
+ switch (encoding) {
+ case G_SIGNATURE_ENC_BASE64:
+ {
+ gsize buffer_len;
+ guint8 *buffer;
+
+ buffer_len = g_checksum_type_get_length (signature->checksum_type);
+ buffer = g_new (guint8, buffer_len);
+ g_signature_get_value (signature, buffer, &buffer_len);
+ retval = g_base64_encode (buffer, buffer_len);
+
+ g_free (buffer);
+ }
+ break;
+
+ case G_SIGNATURE_ENC_STRING:
+ retval = g_strdup (g_signature_get_string (signature));
+ break;
+ }
+
g_signature_free (signature);
return retval;
@@ -203,6 +223,7 @@ g_compute_signature_for_data (GChecksumType checksum_type,
gchar *
g_compute_signature_for_string (GChecksumType checksum_type,
+ GSignatureEnc encoding,
const gchar *key,
gssize key_length,
const gchar *str,
@@ -213,5 +234,5 @@ g_compute_signature_for_string (GChecksumType checksum_type,
if (str_length < 0)
str_length = strlen (str);
- return g_compute_signature_for_data (checksum_type, key, key_length, (const guchar *) str, str_length);
+ return g_compute_signature_for_data (checksum_type, encoding, key, key_length, (const guchar *) str, str_length);
}
diff --git a/gthumb/gsignature.h b/gthumb/gsignature.h
index 8c15d2e..32ec94c 100644
--- a/gthumb/gsignature.h
+++ b/gthumb/gsignature.h
@@ -28,6 +28,10 @@
G_BEGIN_DECLS
typedef struct _GSignature GSignature;
+typedef enum {
+ G_SIGNATURE_ENC_STRING,
+ G_SIGNATURE_ENC_BASE64
+} GSignatureEnc;
GSignature * g_signature_new (GChecksumType checksum_type,
const gchar *key,
@@ -44,11 +48,13 @@ void g_signature_get_value (GSignature *signature,
gsize *buffer_len);
gchar *g_compute_signature_for_data (GChecksumType checksum_type,
+ GSignatureEnc encoding,
const gchar *key,
gssize key_length,
const guchar *data,
gsize data_length);
gchar *g_compute_signature_for_string (GChecksumType checksum_type,
+ GSignatureEnc encoding,
const gchar *key,
gssize key_length,
const gchar *str,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c579236..242c0c3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,5 +1,5 @@
if BUILD_TEST_SUITE
-bin_PROGRAMS = dom-test glib-utils-test gsignature_test
+bin_PROGRAMS = dom-test glib-utils-test gsignature-test oauth-test
endif
dom_test_SOURCES = dom-test.c $(top_srcdir)/gthumb/dom.c
@@ -14,4 +14,8 @@ gsignature_test_SOURCES = gsignature-test.c $(top_srcdir)/gthumb/gsignature.c
gsignature_test_LDADD = $(GTHUMB_LIBS)
gsignature_test_CFLAGS = $(GTHUMB_CFLAGS) -I$(top_srcdir)/gthumb
+oauth_test_SOURCES = oauth-test.c $(top_srcdir)/gthumb/gsignature.c
+oauth_test_LDADD = $(GTHUMB_LIBS)
+oauth_test_CFLAGS = $(GTHUMB_CFLAGS) -I$(top_srcdir)/gthumb
+
-include $(top_srcdir)/git.mk
diff --git a/tests/gsignature-test.c b/tests/gsignature-test.c
index 2ff4994..bef7bb5 100644
--- a/tests/gsignature-test.c
+++ b/tests/gsignature-test.c
@@ -40,14 +40,14 @@ test_g_signature_md5 (void)
key = g_string_new ("");
for (i = 0; i < 16; i++)
g_string_append (key, "\x0b");
- sig = g_compute_signature_for_string (G_CHECKSUM_MD5, key->str, -1, "Hi There", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_MD5, G_SIGNATURE_ENC_STRING, key->str, -1, "Hi There", -1);
g_assert_cmpstr (sig, == , "9294727a3638bb1c13f48ef8158bfc9d");
g_free (sig);
g_string_free (key, TRUE);
/* test case 2 */
- sig = g_compute_signature_for_string (G_CHECKSUM_MD5, "Jefe", -1, "what do ya want for nothing?", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_MD5, G_SIGNATURE_ENC_STRING, "Jefe", -1, "what do ya want for nothing?", -1);
g_assert_cmpstr (sig, == , "750c783e6ab0b503eaa86e310a5db738");
g_free (sig);
@@ -59,7 +59,7 @@ test_g_signature_md5 (void)
data = g_string_new ("");
for (i = 0; i < 50; i++)
g_string_append (data, "\xdd");
- sig = g_compute_signature_for_string (G_CHECKSUM_MD5, key->str, -1, data->str, -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_MD5, G_SIGNATURE_ENC_STRING, key->str, -1, data->str, -1);
g_assert_cmpstr (sig, == , "56be34521d144c88dbb8c733f0e8b3f6");
g_free (sig);
g_string_free (data, TRUE);
@@ -70,7 +70,7 @@ test_g_signature_md5 (void)
data = g_string_new ("");
for (i = 0; i < 50; i++)
g_string_append (data, "\xcd");
- sig = g_compute_signature_for_string (G_CHECKSUM_MD5, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", -1, data->str, -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_MD5, G_SIGNATURE_ENC_STRING, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", -1, data->str, -1);
g_assert_cmpstr (sig, == , "697eaf0aca3a3aea3a75164746ffaa79");
g_free (sig);
g_string_free (data, TRUE);
@@ -80,7 +80,7 @@ test_g_signature_md5 (void)
key = g_string_new ("");
for (i = 0; i < 16; i++)
g_string_append (key, "\x0c");
- sig = g_compute_signature_for_string (G_CHECKSUM_MD5, key->str, -1, "Test With Truncation", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_MD5, G_SIGNATURE_ENC_STRING, key->str, -1, "Test With Truncation", -1);
g_assert_cmpstr (sig, == , "56461ef2342edc00f9bab995690efd4c");
g_free (sig);
g_string_free (key, TRUE);
@@ -90,7 +90,7 @@ test_g_signature_md5 (void)
key = g_string_new ("");
for (i = 0; i < 80; i++)
g_string_append (key, "\xaa");
- sig = g_compute_signature_for_string (G_CHECKSUM_MD5, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_MD5, G_SIGNATURE_ENC_STRING, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
g_assert_cmpstr (sig, == , "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd");
g_free (sig);
g_string_free (key, TRUE);
@@ -100,7 +100,7 @@ test_g_signature_md5 (void)
key = g_string_new ("");
for (i = 0; i < 80; i++)
g_string_append (key, "\xaa");
- sig = g_compute_signature_for_string (G_CHECKSUM_MD5, key->str, -1, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_MD5, G_SIGNATURE_ENC_STRING, key->str, -1, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", -1);
g_assert_cmpstr (sig, == , "6f630fad67cda0ee1fb1f562db3aa53e");
g_free (sig);
g_string_free (key, TRUE);
@@ -122,14 +122,14 @@ test_g_signature_sha1 (void)
key = g_string_new ("");
for (i = 0; i < 20; i++)
g_string_append (key, "\x0b");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, key->str, -1, "Hi There", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, key->str, -1, "Hi There", -1);
g_assert_cmpstr (sig, == , "b617318655057264e28bc0b6fb378c8ef146be00");
g_free (sig);
g_string_free (key, TRUE);
/* test case 2 */
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, "Jefe", -1, "what do ya want for nothing?", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, "Jefe", -1, "what do ya want for nothing?", -1);
g_assert_cmpstr (sig, == , "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79");
g_free (sig);
@@ -141,7 +141,7 @@ test_g_signature_sha1 (void)
data = g_string_new ("");
for (i = 0; i < 50; i++)
g_string_append (data, "\xdd");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, key->str, -1, data->str, -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, key->str, -1, data->str, -1);
g_assert_cmpstr (sig, == , "125d7342b9ac11cd91a39af48aa17b4f63f175d3");
g_free (sig);
g_string_free (data, TRUE);
@@ -152,7 +152,7 @@ test_g_signature_sha1 (void)
data = g_string_new ("");
for (i = 0; i < 50; i++)
g_string_append (data, "\xcd");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", -1, data->str, -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", -1, data->str, -1);
g_assert_cmpstr (sig, == , "4c9007f4026250c6bc8414f9bf50c86c2d7235da");
g_free (sig);
g_string_free (data, TRUE);
@@ -162,7 +162,7 @@ test_g_signature_sha1 (void)
key = g_string_new ("");
for (i = 0; i < 20; i++)
g_string_append (key, "\x0c");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, key->str, -1, "Test With Truncation", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, key->str, -1, "Test With Truncation", -1);
g_assert_cmpstr (sig, == , "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04");
g_free (sig);
g_string_free (key, TRUE);
@@ -172,7 +172,7 @@ test_g_signature_sha1 (void)
key = g_string_new ("");
for (i = 0; i < 80; i++)
g_string_append (key, "\xaa");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
g_assert_cmpstr (sig, == , "aa4ae5e15272d00e95705637ce8a3b55ed402112");
g_free (sig);
g_string_free (key, TRUE);
@@ -182,27 +182,27 @@ test_g_signature_sha1 (void)
key = g_string_new ("");
for (i = 0; i < 80; i++)
g_string_append (key, "\xaa");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, key->str, -1, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, key->str, -1, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", -1);
g_assert_cmpstr (sig, == , "e8e99d0f45237d786d6bbaa7965c7808bbff1a91");
g_free (sig);
g_string_free (key, TRUE);
/* -- test case taken from php-5.3.2/ext/hash/tests/hash_hmac_bacis.phpt -- */
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, "secret", -1, "This is a sample string used to test the hash_hmac function with various hashing algorithms", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, "secret", -1, "This is a sample string used to test the hash_hmac function with various hashing algorithms", -1);
g_assert_cmpstr (sig, == , "5bfdb62b97e2c987405463e9f7c193139c0e1fd0");
g_free (sig);
/* -- test case created using the crypto-js library (http://code.google.com/p/crypto-js/) -- */
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, "Secret Passphrase", -1, "Message", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, "Secret Passphrase", -1, "Message", -1);
g_assert_cmpstr (sig, == , "e90f713295ea4cc06c92c9248696ffafc5d01faf");
g_free (sig);
key = g_string_new ("");
for (i = 0; i < 1; i++)
g_string_append (key, "aa");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
g_assert_cmpstr (sig, == , "4f8e4da5b85182a352041a22b4d566b4b53abf9e");
g_free (sig);
g_string_free (key, TRUE);
@@ -210,7 +210,7 @@ test_g_signature_sha1 (void)
key = g_string_new ("");
for (i = 0; i < 20; i++)
g_string_append (key, "aa");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
g_assert_cmpstr (sig, == , "cb8da9d75b1cd177c00e8c46bd9c17fa313b9f6c");
g_free (sig);
g_string_free (key, TRUE);
@@ -218,7 +218,7 @@ test_g_signature_sha1 (void)
key = g_string_new ("");
for (i = 0; i < 80; i++)
g_string_append (key, "aa");
- sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
+ sig = g_compute_signature_for_string (G_CHECKSUM_SHA1, G_SIGNATURE_ENC_STRING, key->str, -1, "Test Using Larger Than Block-Size Key - Hash Key First", -1);
g_assert_cmpstr (sig, == , "f196c43f06a566cb096a72227a3196d97236898b");
g_free (sig);
g_string_free (key, TRUE);
diff --git a/tests/oauth-test.c b/tests/oauth-test.c
new file mode 100644
index 0000000..2c1033c
--- /dev/null
+++ b/tests/oauth-test.c
@@ -0,0 +1,133 @@
+/* -*- 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 <string.h>
+#include "gsignature.h"
+
+
+static void
+oauth_connection_add_signature (const char *method,
+ const char *url,
+ GHashTable *parameters,
+ const char *expected)
+{
+ char *timestamp;
+ char *nonce;
+ char *consumer_key;
+ char *consumer_secret;
+ GString *param_string;
+ GList *keys;
+ GList *scan;
+ GString *base_string;
+ GString *signature_key;
+ char *signature;
+
+ /* example values from photobucket */
+
+ timestamp = "1208289833";
+ nonce = "cc09413d20742699147d083d755023f7";
+ consumer_key = "1020304";
+ consumer_secret = "9eb84090956c484e32cb6c08455a667b";
+
+ /* Add the OAuth specific parameters */
+
+ g_hash_table_insert (parameters, "oauth_timestamp", timestamp);
+ g_hash_table_insert (parameters, "oauth_nonce", nonce);
+ g_hash_table_insert (parameters, "oauth_version", "1.0");
+ g_hash_table_insert (parameters, "oauth_signature_method", "HMAC-SHA1");
+ g_hash_table_insert (parameters, "oauth_consumer_key", consumer_key);
+
+ /* Create the parameter string */
+
+ param_string = g_string_new ("");
+ keys = g_hash_table_get_keys (parameters);
+ keys = g_list_sort (keys, (GCompareFunc) strcmp);
+ for (scan = keys; scan; scan = scan->next) {
+ char *key = scan->data;
+
+ g_string_append (param_string, key);
+ g_string_append (param_string, "=");
+ g_string_append_uri_escaped (param_string,
+ g_hash_table_lookup (parameters, key),
+ NULL,
+ TRUE);
+ if (scan->next != NULL)
+ g_string_append (param_string, "&");
+ }
+
+ /* Create the Base String */
+
+ base_string = g_string_new ("");
+ g_string_append_uri_escaped (base_string, method, NULL, TRUE);
+ g_string_append (base_string, "&");
+ g_string_append_uri_escaped (base_string, url, NULL, TRUE);
+ g_string_append (base_string, "&");
+ g_string_append_uri_escaped (base_string, param_string->str, NULL, TRUE);
+
+ /* Calculate the signature value */
+
+ signature_key = g_string_new ("");
+ g_string_append (signature_key, consumer_secret);
+ g_string_append (signature_key, "&");
+ signature = g_compute_signature_for_string (G_CHECKSUM_SHA1,
+ G_SIGNATURE_ENC_BASE64,
+ signature_key->str,
+ signature_key->len,
+ base_string->str,
+ base_string->len);
+ g_hash_table_insert (parameters, "oauth_signature", signature);
+
+ g_assert_cmpstr (signature, == , expected);
+
+ g_free (signature);
+ g_string_free (signature_key, TRUE);
+ g_string_free (base_string, TRUE);
+ g_list_free (keys);
+ g_string_free (param_string, TRUE);
+}
+
+
+static void
+test_oauth_signature (void)
+{
+ GHashTable *data_set;
+
+ data_set = g_hash_table_new (g_str_hash, g_str_equal);
+
+ oauth_connection_add_signature ("GET",
+ "http://api.photobucket.com/ping",
+ data_set,
+ "2j4y6ocB4d4tTxDoHaNulKpA46c=");
+
+ g_hash_table_destroy (data_set);
+}
+
+
+int
+main (int argc,
+ char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+ g_test_add_func ("/oauth/signature", test_oauth_signature);
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]