[gthumb] [photobucket] implemented album creation and photo uploading



commit faaffd8555b6d864a554b0f7f6129fffdd5f7001
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Wed May 19 20:24:27 2010 +0200

    [photobucket] implemented album creation and photo uploading

 extensions/oauth/oauth-connection.c                |    5 +-
 extensions/oauth/oauth-connection.h                |    1 -
 .../photobucket/data/ui/export-to-photobucket.ui   |   88 +++++-
 .../data/ui/photobucket-album-properties.ui        |  112 +-----
 extensions/photobucket/dlg-export-to-photobucket.c |  125 +++++--
 extensions/photobucket/photobucket-account.c       |   13 +
 extensions/photobucket/photobucket-account.h       |    3 +
 .../photobucket-album-properties-dialog.c          |   92 +++++-
 .../photobucket-album-properties-dialog.h          |    8 +-
 extensions/photobucket/photobucket-consumer.c      |   17 +-
 extensions/photobucket/photobucket-consumer.h      |    7 +-
 extensions/photobucket/photobucket-service.c       |  379 ++++++--------------
 extensions/photobucket/photobucket-service.h       |   16 +-
 13 files changed, 439 insertions(+), 427 deletions(-)
---
diff --git a/extensions/oauth/oauth-connection.c b/extensions/oauth/oauth-connection.c
index 996a581..8e64ef7 100644
--- a/extensions/oauth/oauth-connection.c
+++ b/extensions/oauth/oauth-connection.c
@@ -520,7 +520,6 @@ check_token_ready_cb (SoupSession *session,
 {
 	CheckTokenData  *check_token_data = user_data;
 	OAuthConnection *self = check_token_data->conn;
-	SoupBuffer      *body;
 
 	if (msg->status_code != 200) {
 		g_simple_async_result_set_error (self->priv->result,
@@ -532,11 +531,9 @@ check_token_ready_cb (SoupSession *session,
 		return;
 	}
 
-	body = soup_message_body_flatten (msg->response_body);
-	self->consumer->check_token_response (self, msg, body, self->priv->result, check_token_data->account);
+	self->consumer->check_token_response (self, msg, 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);
 }
 
diff --git a/extensions/oauth/oauth-connection.h b/extensions/oauth/oauth-connection.h
index 5b5ab6b..98c6da9 100644
--- a/extensions/oauth/oauth-connection.h
+++ b/extensions/oauth/oauth-connection.h
@@ -114,7 +114,6 @@ typedef void   (*OAuthResponseFunc)        (OAuthConnection    *self,
 				            GSimpleAsyncResult *result);
 typedef void   (*OAuthAccountResponseFunc) (OAuthConnection    *self,
 				            SoupMessage        *msg,
-				            SoupBuffer         *body,
 				            GSimpleAsyncResult *result,
 				            OAuthAccount       *account);
 typedef char * (*OAuthStringFunc)          (OAuthConnection    *self);
diff --git a/extensions/photobucket/data/ui/export-to-photobucket.ui b/extensions/photobucket/data/ui/export-to-photobucket.ui
index 8010dd9..3ca4fc5 100644
--- a/extensions/photobucket/data/ui/export-to-photobucket.ui
+++ b/extensions/photobucket/data/ui/export-to-photobucket.ui
@@ -68,7 +68,7 @@
                 <child>
                   <object class="GtkTable" id="table2">
                     <property name="visible">True</property>
-                    <property name="n_rows">2</property>
+                    <property name="n_rows">4</property>
                     <property name="n_columns">2</property>
                     <property name="column_spacing">6</property>
                     <property name="row_spacing">5</property>
@@ -233,6 +233,54 @@
                         <property name="bottom_attach">2</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">_Resize to:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">resize_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="resize_combobox">
+                        <property name="visible">True</property>
+                        <property name="model">resize_liststore</property>
+                        <property name="active">6</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="cellrenderertext1"/>
+                          <attributes>
+                            <attribute name="text">0</attribute>
+                          </attributes>
+                        </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="scramble_checkbutton">
+                        <property name="label" translatable="yes">_Scramble filenames</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -313,4 +361,42 @@
       <action-widget response="-11">button1</action-widget>
     </action-widgets>
   </object>
+  <object class="GtkListStore" id="resize_liststore">
+    <columns>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+      <!-- column-name size -->
+      <column type="gint"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Tiny ( 100 x 75 )</col>
+        <col id="1">100</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Small ( 160 x 120 )</col>
+        <col id="1">160</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Medium ( 320 x 240 )</col>
+        <col id="1">320</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Large ( 640 x 480 )</col>
+        <col id="1">640</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">15ʺ screen ( 800 x 600 )</col>
+        <col id="1">800</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">17ʺ screen ( 1024 x 768 )</col>
+        <col id="1">1024</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">1 megabyte file size</col>
+        <col id="1">0</col>
+      </row>
+    </data>
+  </object>
 </interface>
diff --git a/extensions/photobucket/data/ui/photobucket-album-properties.ui b/extensions/photobucket/data/ui/photobucket-album-properties.ui
index 410c2ac..3cd9002 100644
--- a/extensions/photobucket/data/ui/photobucket-album-properties.ui
+++ b/extensions/photobucket/data/ui/photobucket-album-properties.ui
@@ -7,7 +7,7 @@
     <child>
       <object class="GtkTable" id="table1">
         <property name="visible">True</property>
-        <property name="n_rows">4</property>
+        <property name="n_rows">2</property>
         <property name="n_columns">2</property>
         <property name="column_spacing">6</property>
         <property name="row_spacing">6</property>
@@ -36,79 +36,23 @@
           </packing>
         </child>
         <child>
-          <object class="GtkLabel" id="label2">
+          <object class="GtkLabel" id="label4">
             <property name="visible">True</property>
             <property name="xalign">0</property>
-            <property name="label" translatable="yes">_Visibility:</property>
+            <property name="label" translatable="yes">_Container:</property>
             <property name="use_underline">True</property>
+            <property name="mnemonic_widget">album_combobox</property>
           </object>
           <packing>
-            <property name="top_attach">3</property>
-            <property name="bottom_attach">4</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</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>
+          <object class="GtkComboBox" id="album_combobox">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="invisible_char">â??</property>
-            <property name="invisible_char_set">True</property>
+            <property name="model">album_liststore</property>
           </object>
           <packing>
             <property name="left_attach">1</property>
@@ -117,20 +61,6 @@
             <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>
@@ -138,26 +68,16 @@
       </packing>
     </child>
   </object>
-  <object class="GtkListStore" id="visibility_liststore">
+  <object class="GtkListStore" id="album_liststore">
     <columns>
-      <!-- column-name name -->
+      <!-- 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"/>
-      <!-- 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 6f28f1b..45c963c 100644
--- a/extensions/photobucket/dlg-export-to-photobucket.c
+++ b/extensions/photobucket/dlg-export-to-photobucket.c
@@ -49,6 +49,12 @@ enum {
 };
 
 
+enum {
+	RESIZE_NAME_COLUMN,
+	RESIZE_SIZE_COLUMN
+};
+
+
 typedef struct {
 	GthBrowser          *browser;
 	GthFileData         *location;
@@ -62,7 +68,6 @@ typedef struct {
 	PhotobucketAccount  *account;
 	GList               *albums;
 	PhotobucketAlbum    *album;
-	GList               *photos_ids;
 	GCancellable        *cancellable;
 } DialogData;
 
@@ -74,7 +79,6 @@ export_dialog_destroy_cb (GtkWidget  *widget,
 	if (data->conn != NULL)
 		gth_task_completed (GTH_TASK (data->conn), NULL);
 	_g_object_unref (data->cancellable);
-	_g_string_list_free (data->photos_ids);
 	_g_object_unref (data->album);
 	_g_object_list_unref (data->albums);
 	_g_object_unref (data->account);
@@ -103,41 +107,23 @@ 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;
-
-				ids = g_string_new ("");
-				for (scan = data->photos_ids; scan; scan = scan->next) {
-					if (scan != data->photos_ids)
-						g_string_append (ids, ",");
-					g_string_append (ids, (char *) scan->data);
-				}
-				url = g_strconcat (data->server->url, "/photos/upload/edit/?ids=", ids->str, NULL);
-
-				g_string_free (ids, TRUE);
-			}
-			else if (data->album->url != NULL)
-				url = g_strdup (data->album->url);
-			else if (data->album->id != NULL)
-				url = g_strconcat (data->server->url, "/photos/", data->user->id, "/sets/", data->album->id, NULL);
+			if (data->account->album_url)
+				url = g_strconcat (data->account->album_url, data->album->name + strlen (OAUTH_ACCOUNT (data->account)->username), NULL);
 
 			if ((url != NULL) && ! gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (dialog)), url, 0, &error)) {
 				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);
 
-			/*g_free (url);*/
+			g_free (url);
 		}
 		break;
 
@@ -177,8 +163,7 @@ upload_photos_ready_cb (GObject      *source_object,
 	DialogData *data = user_data;
 	GError     *error = NULL;
 
-	data->photos_ids = photobucket_service_upload_photos_finish (PHOTOBUCKET_SERVICE (source_object), result, &error);
-	if (error != NULL) {
+	if (! photobucket_service_upload_photos_finish (data->service, result, &error)) {
 		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not upload the files"), &error);
 		gtk_widget_destroy (data->dialog);
 		return;
@@ -209,11 +194,12 @@ export_dialog_response_cb (GtkDialog *dialog,
 		{
 			GtkTreeIter  iter;
 			GList       *file_list;
+			int          size;
 
 			gtk_widget_hide (data->dialog);
 			gth_task_dialog (GTH_TASK (data->conn), FALSE);
 
-			data->album = NULL;
+			_g_clear_object (&data->album);
 			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,
@@ -221,9 +207,20 @@ export_dialog_response_cb (GtkDialog *dialog,
 						    -1);
 			}
 
+			size = 0;
+			if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (GET_WIDGET ("resize_combobox")), &iter)) {
+				gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (GET_WIDGET ("resize_combobox"))),
+						    &iter,
+						    RESIZE_SIZE_COLUMN, &size,
+						    -1);
+			}
+
 			file_list = gth_file_data_list_to_file_list (data->file_list);
 			photobucket_service_upload_photos (data->service,
+							   data->account,
 							   data->album,
+							   size,
+							   gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("scramble_checkbutton"))),
 							   file_list,
 							   data->cancellable,
 							   upload_photos_ready_cb,
@@ -270,6 +267,38 @@ update_account_list (DialogData *data)
 	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);
+
+	if (data->account != NULL) {
+		struct {
+			char *name;
+			int   size;
+		} sizes[] = { { N_("Tiny ( 100 Ã? 75 )"), 100 },
+			      { N_("Small ( 160 Ã? 120 )"), 160 },
+			      { N_("Medium ( 320 Ã? 240 )"), 320 },
+			      { N_("Large ( 640 Ã? 480 )"), 640 },
+			      { N_("15ʺ screen ( 800 � 600 )"), 800 },
+			      { N_("17ʺ screen ( 1024 � 768 )"), 1024 },
+			      { N_("1 megabyte file size"), 0 },
+			      { "1280 Ã? 960", 1280 },
+			      { "1600 Ã? 1200", 1600 },
+			      { "2048 Ã? 1536", 2048 },
+			      { "2592 Ã? 1944", 2592 },
+			      { "3648 Ã? 2736", 3648 },
+			      { "4000 Ã? 3000", 4000 },
+			      { N_("2 megabyte file size"), 0 } };
+		int i;
+
+		gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("resize_liststore")));
+		for (i = 0; i <= (data->account->is_premium ? 13 : 6); i++) {
+			gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("resize_liststore")), &iter);
+			gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("resize_liststore")), &iter,
+					    RESIZE_NAME_COLUMN, _(sizes[i].name),
+					    RESIZE_SIZE_COLUMN, sizes[i].size,
+					    -1);
+		}
+
+		gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("resize_combobox")), (data->account->is_premium ? 13 : 5));
+	}
 }
 
 
@@ -284,15 +313,20 @@ authentication_accounts_changed_cb (OAuthAuthentication *auth,
 static void
 update_album_list (DialogData *data)
 {
+	int    album_idx = 0;
 	GList *scan;
+	int    i;
 
 	gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("album_liststore")));
-	for (scan = data->albums; scan; scan = scan->next) {
+	for (scan = data->albums, i = 0; scan; scan = scan->next, i++) {
 		PhotobucketAlbum *album = scan->data;
 		char             *size;
 		GtkTreeIter       iter;
 
-		size = g_strdup_printf ("(%d)", album->photo_count); /* FIXME: show video_count as well */
+		if (data->album != NULL && g_str_equal (data->album->name, album->name))
+			album_idx = i;
+
+		size = g_strdup_printf ("(%d)", album->photo_count + album->video_count);
 
 		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter);
 		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter,
@@ -304,6 +338,9 @@ update_album_list (DialogData *data)
 
 		g_free (size);
 	}
+
+	if (data->albums != NULL)
+		gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")), album_idx);
 }
 
 
@@ -397,11 +434,11 @@ create_album_ready_cb (GObject      *source_object,
 		       GAsyncResult *result,
 		       gpointer      user_data)
 {
-	DialogData       *data = user_data;
-	PhotobucketAlbum *album;
-	GError           *error = NULL;
+	DialogData *data = user_data;
+	GError     *error = NULL;
 
-	album = photobucket_service_create_album_finish (data->service, result, &error);
+	_g_object_unref (data->album);
+	data->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);
@@ -409,7 +446,7 @@ create_album_ready_cb (GObject      *source_object,
 		return;
 	}
 
-	data->albums = g_list_append (data->albums, album);
+	data->albums = g_list_append (data->albums, data->album);
 	update_album_list (data);
 }
 
@@ -430,16 +467,24 @@ new_album_dialog_response_cb (GtkDialog *dialog,
 	case GTK_RESPONSE_OK:
 		{
 			PhotobucketAlbum *album;
+			char             *parent_album;
+
+			parent_album = photobucket_album_properties_dialog_get_parent_album (PHOTOBUCKET_ALBUM_PROPERTIES_DIALOG (dialog));
+			if (parent_album == NULL)
+				return;
 
 			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,
+							  data->account,
+							  parent_album,
 						          album,
 						          data->cancellable,
 						          create_album_ready_cb,
 						          data);
 
 			g_object_unref (album);
+			g_free (parent_album);
 		}
 		gtk_widget_destroy (GTK_WIDGET (dialog));
 		break;
@@ -457,7 +502,8 @@ add_album_button_clicked_cb (GtkButton *button,
 	DialogData *data = user_data;
 	GtkWidget  *dialog;
 
-	dialog = photobucket_album_properties_dialog_new (g_file_info_get_edit_name (data->location->info));
+	dialog = photobucket_album_properties_dialog_new (g_file_info_get_edit_name (data->location->info),
+							  data->albums);
 	g_signal_connect (dialog,
 			  "response",
 			  G_CALLBACK (new_album_dialog_response_cb),
@@ -515,6 +561,8 @@ dlg_export_to_photobucket (GthBrowser *browser,
 						NULL);
 	}
 
+	_gtk_window_resize_to_fit_screen_height (data->dialog, 500);
+
 	data->file_list = NULL;
 	n_total = 0;
 	total_size = 0;
@@ -533,7 +581,10 @@ dlg_export_to_photobucket (GthBrowser *browser,
 			data->file_list = g_list_prepend (data->file_list, g_object_ref (file_data));
 		}
 	}
-	data->file_list = g_list_reverse (data->file_list);
+
+	/* upload in reverse order because photobucket orders the files from
+	 * the newest to the oldest.
+	  data->file_list = g_list_reverse (data->file_list);  */
 
 	if (data->file_list == NULL) {
 		GError *error;
diff --git a/extensions/photobucket/photobucket-account.c b/extensions/photobucket/photobucket-account.c
index bc3e0ef..442110e 100644
--- a/extensions/photobucket/photobucket-account.c
+++ b/extensions/photobucket/photobucket-account.c
@@ -90,6 +90,9 @@ photobucket_account_load_from_element (DomDomizable *base,
 			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, "premium")) {
+				photobucket_account_set_is_premium (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));
 			}
@@ -116,6 +119,8 @@ photobucket_account_instance_init (PhotobucketAccount *self)
 	self->subdomain = NULL;
 	self->home_url = NULL;
 	self->album_url = NULL;
+	self->is_premium = FALSE;
+	self->is_public = TRUE;
 }
 
 
@@ -202,6 +207,14 @@ photobucket_account_set_megabytes_allowed (PhotobucketAccount *self,
 
 
 void
+photobucket_account_set_is_premium (PhotobucketAccount *self,
+				    const char         *value)
+{
+	self->is_premium =  g_str_equal (value, "1");
+}
+
+
+void
 photobucket_account_set_is_public (PhotobucketAccount *self,
 				   const char         *value)
 {
diff --git a/extensions/photobucket/photobucket-account.h b/extensions/photobucket/photobucket-account.h
index 68230ec..b43eb99 100644
--- a/extensions/photobucket/photobucket-account.h
+++ b/extensions/photobucket/photobucket-account.h
@@ -47,6 +47,7 @@ struct _PhotobucketAccount {
 	char     *album_url;
 	goffset   megabytes_used;
 	goffset   megabytes_allowed;
+	gboolean  is_premium;
 	gboolean  is_public;
 };
 
@@ -66,6 +67,8 @@ void              photobucket_account_set_megabytes_used     (PhotobucketAccount
 							      const char         *value);
 void              photobucket_account_set_megabytes_allowed  (PhotobucketAccount *self,
 						              const char         *value);
+void              photobucket_account_set_is_premium         (PhotobucketAccount *self,
+							      const char         *value);
 void              photobucket_account_set_is_public          (PhotobucketAccount *self,
 							      const char         *value);
 
diff --git a/extensions/photobucket/photobucket-album-properties-dialog.c b/extensions/photobucket/photobucket-album-properties-dialog.c
index 34012b1..b9e04d2 100644
--- a/extensions/photobucket/photobucket-album-properties-dialog.c
+++ b/extensions/photobucket/photobucket-album-properties-dialog.c
@@ -28,6 +28,14 @@
 #define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
 
 
+enum {
+	ALBUM_DATA_COLUMN,
+	ALBUM_ICON_COLUMN,
+	ALBUM_TITLE_COLUMN,
+	ALBUM_N_PHOTOS_COLUMN
+};
+
+
 static gpointer parent_class = NULL;
 
 
@@ -83,6 +91,32 @@ photobucket_album_properties_dialog_init (PhotobucketAlbumPropertiesDialog *self
 				GTK_STOCK_OK, GTK_RESPONSE_OK,
 				NULL);
 	gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
+
+
+	{
+		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);
+	}
 }
 
 
@@ -116,20 +150,46 @@ photobucket_album_properties_dialog_get_type (void)
 
 static void
 photobucket_album_properties_dialog_construct (PhotobucketAlbumPropertiesDialog *self,
-				               const char                       *name)
+				               const char                       *name,
+				               GList                            *albums)
 {
+	GList *scan;
+
 	if (name != NULL)
 		gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("name_entry")), name);
+
+	gtk_list_store_clear (GTK_LIST_STORE (GET_WIDGET ("album_liststore")));
+	for (scan = albums; scan; scan = scan->next) {
+		PhotobucketAlbum *album = scan->data;
+		char             *size;
+		GtkTreeIter       iter;
+
+		size = g_strdup_printf ("(%d)", album->photo_count + album->video_count);
+
+		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->name,
+				    ALBUM_N_PHOTOS_COLUMN, size,
+				    -1);
+
+		g_free (size);
+	}
+
+	if (albums != NULL)
+		gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("album_combobox")), 0);
 }
 
 
 GtkWidget *
-photobucket_album_properties_dialog_new (const char *name)
+photobucket_album_properties_dialog_new (const char *name,
+					 GList      *albums)
 {
 	PhotobucketAlbumPropertiesDialog *self;
 
 	self = g_object_new (PHOTOBUCKET_TYPE_ALBUM_PROPERTIES_DIALOG, NULL);
-	photobucket_album_properties_dialog_construct (self, name);
+	photobucket_album_properties_dialog_construct (self, name, albums);
 
 	return (GtkWidget *) self;
 }
@@ -140,3 +200,29 @@ photobucket_album_properties_dialog_get_name (PhotobucketAlbumPropertiesDialog *
 {
 	return gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("name_entry")));
 }
+
+
+char *
+photobucket_album_properties_dialog_get_parent_album (PhotobucketAlbumPropertiesDialog *self)
+{
+	GtkTreeIter       iter;
+	PhotobucketAlbum *album;
+	char             *name;
+
+	album = NULL;
+	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, &album,
+				    -1);
+	}
+
+	if (album == NULL)
+		return NULL;
+
+	name = g_strdup (album->name);
+
+	g_object_unref (album);
+
+	return name;
+}
diff --git a/extensions/photobucket/photobucket-album-properties-dialog.h b/extensions/photobucket/photobucket-album-properties-dialog.h
index 51944df..964bdd4 100644
--- a/extensions/photobucket/photobucket-album-properties-dialog.h
+++ b/extensions/photobucket/photobucket-album-properties-dialog.h
@@ -49,9 +49,11 @@ 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);
+GType          photobucket_album_properties_dialog_get_type         (void);
+GtkWidget *    photobucket_album_properties_dialog_new              (const char *name,
+								     GList      *albums);
+const char *   photobucket_album_properties_dialog_get_name         (PhotobucketAlbumPropertiesDialog *self);
+char *         photobucket_album_properties_dialog_get_parent_album (PhotobucketAlbumPropertiesDialog *self);
 
 G_END_DECLS
 
diff --git a/extensions/photobucket/photobucket-consumer.c b/extensions/photobucket/photobucket-consumer.c
index 2490e20..e5586aa 100644
--- a/extensions/photobucket/photobucket-consumer.c
+++ b/extensions/photobucket/photobucket-consumer.c
@@ -29,20 +29,29 @@
 
 
 gboolean
-photobucket_utils_parse_response (SoupBuffer          *body,
+photobucket_utils_parse_response (SoupMessage         *msg,
 				  DomDocument        **doc_p,
-				  GSimpleAsyncResult  *result,
 				  GError             **error)
 {
+	SoupBuffer  *body;
 	DomDocument *doc;
 	DomElement  *node;
 
+	body = soup_message_body_flatten (msg->response_body);
+
 	doc = dom_document_new ();
 	if (! dom_document_load (doc, body->data, body->length, error)) {
+		if (msg->status_code != 200) {
+			g_clear_error (error);
+			*error = g_error_new_literal (SOUP_HTTP_ERROR, msg->status_code, soup_status_get_phrase (msg->status_code));
+		}
 		g_object_unref (doc);
+		soup_buffer_free (body);
 		return FALSE;
 	}
 
+	soup_buffer_free (body);
+
 	for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
 		if (g_strcmp0 (node->tag_name, "response") == 0) {
 			DomElement *child;
@@ -64,7 +73,6 @@ 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 (result, *error);
 			}
 			else if (strcmp (status, "Exception") == 0) {
 				*error = g_error_new_literal (OAUTH_CONNECTION_ERROR,
@@ -183,14 +191,13 @@ photobucket_get_check_token_url (OAuthConnection *self,
 static void
 photobucket_check_token_response (OAuthConnection    *self,
 				  SoupMessage        *msg,
-				  SoupBuffer         *body,
 				  GSimpleAsyncResult *result,
 				  OAuthAccount       *account)
 {
 	DomDocument *doc = NULL;
 	GError      *error = NULL;
 
-	if (photobucket_utils_parse_response (body, &doc, result, &error)) {
+	if (photobucket_utils_parse_response (msg, &doc, &error)) {
 		DomElement *node;
 
 		for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
diff --git a/extensions/photobucket/photobucket-consumer.h b/extensions/photobucket/photobucket-consumer.h
index 8cbebb6..719dfb3 100644
--- a/extensions/photobucket/photobucket-consumer.h
+++ b/extensions/photobucket/photobucket-consumer.h
@@ -28,9 +28,8 @@
 
 extern OAuthConsumer photobucket_consumer;
 
-gboolean  photobucket_utils_parse_response (SoupBuffer          *body,
-				            DomDocument        **doc_p,
-				            GSimpleAsyncResult  *result,
-				            GError             **error);
+gboolean  photobucket_utils_parse_response (SoupMessage  *msg,
+					    DomDocument **doc_p,
+					    GError      **error);
 
 #endif /* PHOTOBUCKET_CONSUMER_H */
diff --git a/extensions/photobucket/photobucket-service.c b/extensions/photobucket/photobucket-service.c
index 965107f..4e97710 100644
--- a/extensions/photobucket/photobucket-service.c
+++ b/extensions/photobucket/photobucket-service.c
@@ -31,7 +31,10 @@
 
 
 typedef struct {
+	PhotobucketAccount  *account;
 	PhotobucketAlbum    *album;
+	int                  size;
+	gboolean             scramble;
 	GList               *file_list;
 	GCancellable        *cancellable;
         GAsyncReadyCallback  callback;
@@ -41,7 +44,6 @@ typedef struct {
 	goffset              uploaded_size;
 	int                  n_files;
 	int                  uploaded_files;
-	GList               *ids;
 } PostPhotosData;
 
 
@@ -50,9 +52,10 @@ 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_object_unref (post_photos->album);
+	g_object_unref (post_photos->account);
 	g_free (post_photos);
 }
 
@@ -147,7 +150,7 @@ photobucket_service_new (OAuthConnection *conn)
 
 
 static DomElement *
-get_content (DomDocument *doc)
+get_content_root (DomDocument *doc)
 {
 	DomElement *root;
 
@@ -168,43 +171,42 @@ get_content (DomDocument *doc)
 
 
 static void
+read_albums_recursively (DomElement  *root,
+			 GList      **albums)
+{
+	DomElement *node;
+
+	for (node = root->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);
+
+			if (atoi (dom_element_get_attribute (node, "subalbum_count")) > 0)
+				read_albums_recursively (node, albums);
+		}
+	}
+}
+
+
+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);
-			}
-		}
+	if (photobucket_utils_parse_response (msg, &doc, &error)) {
+		GList *albums = NULL;
 
+		read_albums_recursively (get_content_root (doc), &albums);
 		albums = g_list_reverse (albums);
 		g_simple_async_result_set_op_res_gpointer (result, albums, (GDestroyNotify) _g_object_list_unref);
 
@@ -214,8 +216,6 @@ get_albums_ready_cb (SoupSession *session,
 		g_simple_async_result_set_from_error (result, error);
 
 	g_simple_async_result_complete_in_idle (result);
-
-	soup_buffer_free (body);
 }
 
 
@@ -236,6 +236,9 @@ photobucket_service_get_albums (PhotobucketService  *self,
 	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);
+	g_hash_table_insert (data_set, "recurse", "true");
+	g_hash_table_insert (data_set, "view", "nested");
+	g_hash_table_insert (data_set, "media", "none");
 	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);
@@ -251,8 +254,8 @@ photobucket_service_get_albums (PhotobucketService  *self,
 				       get_albums_ready_cb,
 				       self);
 
-	g_hash_table_destroy (data_set);
 	g_free (url);
+	g_hash_table_destroy (data_set);
 }
 
 
@@ -271,49 +274,36 @@ photobucket_service_get_albums_finish (PhotobucketService  *service,
 /* -- photobucket_service_create_album -- */
 
 
+typedef struct {
+	PhotobucketService *service;
+	PhotobucketAlbum   *album;
+} CreateAlbumData;
+
+
+static void
+create_album_data_free (CreateAlbumData *create_album_data)
+{
+	g_object_unref (create_album_data->service);
+	g_object_unref (create_album_data->album);
+	g_free (create_album_data);
+}
+
+
 static void
 create_album_ready_cb (SoupSession *session,
 		       SoupMessage *msg,
 		       gpointer     user_data)
 {
-	PhotobucketService *self = user_data;
+	CreateAlbumData    *create_album_data = user_data;
+	PhotobucketService *self = create_album_data->service;
 	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);
-
+	if (photobucket_utils_parse_response (msg, &doc, &error)) {
+		g_simple_async_result_set_op_res_gpointer (result, g_object_ref (create_album_data->album), g_object_unref);
 		g_object_unref (doc);
 	}
 	else
@@ -321,39 +311,50 @@ create_album_ready_cb (SoupSession *session,
 
 	g_simple_async_result_complete_in_idle (result);
 
-	soup_buffer_free (body);
+	create_album_data_free (create_album_data);
 }
 
 
 void
 photobucket_service_create_album (PhotobucketService  *self,
+				  PhotobucketAccount  *account,
+				  const char          *parent_album,
 			          PhotobucketAlbum    *album,
 			          GCancellable        *cancellable,
 			          GAsyncReadyCallback  callback,
 			          gpointer             user_data)
 {
-	GHashTable  *data_set;
-	const char  *privacy;
-	SoupMessage *msg;
+	CreateAlbumData *create_album_data;
+	char            *path;
+	GHashTable      *data_set;
+	char            *identifier;
+	char            *url;
+	SoupMessage     *msg;
 
 	g_return_if_fail (album != NULL);
 	g_return_if_fail (album->name != NULL);
 
+	create_album_data = g_new0 (CreateAlbumData, 1);
+	create_album_data->service = g_object_ref (self);
+	create_album_data->album = photobucket_album_new ();
+
+	path = g_strconcat (parent_album, "/", album->name, NULL);
+	photobucket_album_set_name (create_album_data->album, path);
+	g_free (path);
+
 	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);
+	identifier = soup_uri_encode (parent_album, NULL);
+	url = g_strconcat ("http://api.photobucket.com/album/";, identifier, NULL);
+	oauth_connection_add_signature (self->priv->conn, "POST", url, data_set);
+
+	g_free (identifier);
+	g_free (url);
+
+	url = g_strconcat ("http://";, account->subdomain, "/album/", parent_album, NULL);
+	msg = soup_form_request_new_from_hash ("POST", url, data_set);
 	oauth_connection_send_message (self->priv->conn,
 				       msg,
 				       cancellable,
@@ -361,10 +362,10 @@ photobucket_service_create_album (PhotobucketService  *self,
 				       user_data,
 				       photobucket_service_create_album,
 				       create_album_ready_cb,
-				       self);
+				       create_album_data);
 
+	g_free (url);
 	g_hash_table_destroy (data_set);
-	*/
 }
 
 
@@ -391,9 +392,7 @@ upload_photos_done (PhotobucketService *self,
 
 	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;
+		g_simple_async_result_set_op_res_gboolean (result, TRUE);
 	}
 	else {
 		if (self->priv->post_photos->current != NULL) {
@@ -421,47 +420,17 @@ upload_photo_ready_cb (SoupSession *session,
 {
 	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));
+	if (! photobucket_utils_parse_response (msg, &doc, &error)) {
 		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));
-			}
-		}
-
+	else
 		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);
@@ -479,8 +448,10 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 	PhotobucketService *self = user_data;
 	GthFileData        *file_data;
 	SoupMultipart      *multipart;
+	char               *identifier;
 	char               *uri;
 	SoupBuffer         *body;
+	char               *url;
 	SoupMessage        *msg;
 
 	if (error != NULL) {
@@ -490,6 +461,7 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 
 	file_data = self->priv->post_photos->current->data;
 	multipart = soup_multipart_new ("multipart/form-data");
+	identifier = soup_uri_encode (self->priv->post_photos->album->name, NULL);
 
 	/* the metadata part */
 
@@ -497,24 +469,27 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 		GHashTable *data_set;
 		char       *title;
 		char       *description;
+		char       *url;
+		char       *s_size = NULL;
 		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");
-
+		g_hash_table_insert (data_set, "type", "image");
 		title = gth_file_data_get_attribute_as_string (file_data, "general::title");
+		if (title != NULL)
+			g_hash_table_insert (data_set, "title", 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 */
+			g_hash_table_insert (data_set, "description", description);
+		if (self->priv->post_photos->size != 0) {
+			s_size = g_strdup_printf ("%d", self->priv->post_photos->size);
+			g_hash_table_insert (data_set, "size", s_size);
+		}
+		if (self->priv->post_photos->scramble)
+			g_hash_table_insert (data_set, "scramble", "true");
+		url = g_strconcat ("http://api.photobucket.com";, "/album/", identifier, "/upload", NULL);
+		oauth_connection_add_signature (self->priv->conn, "POST", url, data_set);
 
 		keys = g_hash_table_get_keys (data_set);
 		for (scan = keys; scan; scan = scan->next) {
@@ -523,6 +498,8 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 		}
 
 		g_list_free (keys);
+		g_free (url);
+		g_free (s_size);
 		g_hash_table_unref (data_set);
 	}
 
@@ -531,7 +508,7 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 	uri = g_file_get_uri (file_data->file);
 	body = soup_buffer_new (SOUP_MEMORY_TEMPORARY, *buffer, count);
 	soup_multipart_append_form_file (multipart,
-					 NULL,
+					 "uploadfile",
 					 _g_uri_get_basename (uri),
 					 gth_file_data_get_mime_type (file_data),
 					 body);
@@ -554,8 +531,8 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 		g_free (details);
 	}
 
-	/* FIXME
-	msg = soup_form_request_new_from_multipart (PHOTOBUCKET_HTTPS_REST_SERVER, multipart);
+	url = g_strconcat ("http://";, self->priv->post_photos->account->subdomain, "/album/", identifier, "/upload", NULL);
+	msg = soup_form_request_new_from_multipart (url, multipart);
 	oauth_connection_send_message (self->priv->conn,
 				       msg,
 				       self->priv->post_photos->cancellable,
@@ -564,8 +541,8 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
 				       photobucket_service_upload_photos,
 				       upload_photo_ready_cb,
 				       self);
-	*/
 
+	g_free (url);
 	soup_multipart_free (multipart);
 }
 
@@ -617,7 +594,10 @@ upload_photos_info_ready_cb (GList    *files,
 
 void
 photobucket_service_upload_photos (PhotobucketService  *self,
+				   PhotobucketAccount  *account,
 				   PhotobucketAlbum    *album,
+				   int                  size,
+				   gboolean             scramble,
 				   GList               *file_list, /* GFile list */
 				   GCancellable        *cancellable,
 				   GAsyncReadyCallback  callback,
@@ -627,7 +607,10 @@ photobucket_service_upload_photos (PhotobucketService  *self,
 
 	post_photos_data_free (self->priv->post_photos);
 	self->priv->post_photos = g_new0 (PostPhotosData, 1);
+	self->priv->post_photos->account = g_object_ref (account);
 	self->priv->post_photos->album = _g_object_ref (album);
+	self->priv->post_photos->size = size;
+	self->priv->post_photos->scramble = scramble;
 	self->priv->post_photos->cancellable = _g_object_ref (cancellable);
 	self->priv->post_photos->callback = callback;
 	self->priv->post_photos->user_data = user_data;
@@ -644,143 +627,13 @@ photobucket_service_upload_photos (PhotobucketService  *self,
 }
 
 
-GList *
+gboolean
 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;
+		return FALSE;
 	else
-		return _g_string_list_dup (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+		return TRUE;
 }
-
-
-#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
index af51d5c..f1a5acc 100644
--- a/extensions/photobucket/photobucket-service.h
+++ b/extensions/photobucket/photobucket-service.h
@@ -61,6 +61,8 @@ GList *              photobucket_service_get_albums_finish          (Photobucket
 							             GAsyncResult           *result,
 							             GError                **error);
 void                 photobucket_service_create_album               (PhotobucketService     *self,
+								     PhotobucketAccount     *account,
+								     const char             *parent_album,
 						                     PhotobucketAlbum       *album,
 						                     GCancellable           *cancellable,
 						                     GAsyncReadyCallback     callback,
@@ -69,22 +71,16 @@ PhotobucketAlbum *   photobucket_service_create_album_finish        (Photobucket
 						                     GAsyncResult           *result,
 						                     GError                **error);
 void                 photobucket_service_upload_photos              (PhotobucketService     *self,
+								     PhotobucketAccount     *account,
 							             PhotobucketAlbum       *album,
+							             int                     size,
+							             gboolean                scramble,
 							             GList                  *file_list, /* GFile list */
 							             GCancellable           *cancellable,
 							             GAsyncReadyCallback     callback,
 							             gpointer                user_data);
-GList *              photobucket_service_upload_photos_finish       (PhotobucketService     *self,
+gboolean             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 */



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