[gthumb: 12/22] [picasaweb] implemented the post_photos service



commit 510d76a9019543269757da3158389a4c1f78a1a3
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Wed Jan 27 21:37:05 2010 +0100

    [picasaweb] implemented the post_photos service

 .../picasaweb/data/ui/export-to-picasaweb.ui       |   40 ++--
 extensions/picasaweb/dlg-export-to-picasaweb.c     |   88 +++++++-
 extensions/picasaweb/picasa-web-album.c            |    8 +-
 extensions/picasaweb/picasa-web-service.c          |  239 ++++++++++++++++++++
 extensions/picasaweb/picasa-web-service.h          |    9 +
 5 files changed, 351 insertions(+), 33 deletions(-)
---
diff --git a/extensions/picasaweb/data/ui/export-to-picasaweb.ui b/extensions/picasaweb/data/ui/export-to-picasaweb.ui
index c76507a..8a703d5 100644
--- a/extensions/picasaweb/data/ui/export-to-picasaweb.ui
+++ b/extensions/picasaweb/data/ui/export-to-picasaweb.ui
@@ -2,6 +2,16 @@
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy project-wide -->
+  <object class="GtkListStore" id="account_liststore">
+    <columns>
+      <!-- column-name email -->
+      <column type="gchararray"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+      <!-- column-name icon -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkListStore" id="album_liststore">
     <columns>
       <!-- column-name data -->
@@ -14,15 +24,7 @@
       <column type="gchararray"/>
       <!-- column-name size -->
       <column type="gchararray"/>
-    </columns>
-  </object>
-  <object class="GtkListStore" id="account_liststore">
-    <columns>
-      <!-- column-name email -->
-      <column type="gchararray"/>
-      <!-- column-name name -->
-      <column type="gchararray"/>
-      <!-- column-name icon -->
+      <!-- column-name emblem -->
       <column type="gchararray"/>
     </columns>
   </object>
@@ -39,10 +41,12 @@
           <object class="GtkHBox" id="hbox1">
             <property name="visible">True</property>
             <property name="border_width">5</property>
+            <property name="orientation">vertical</property>
             <property name="spacing">12</property>
             <child>
               <object class="GtkVBox" id="images_box">
-                <property name="width_request">166</property>
+                <property name="width_request">460</property>
+                <property name="height_request">220</property>
                 <property name="visible">True</property>
                 <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
@@ -58,7 +62,6 @@
                 </child>
               </object>
               <packing>
-                <property name="expand">False</property>
                 <property name="position">0</property>
               </packing>
             </child>
@@ -231,21 +234,9 @@
                                 <property name="rules_hint">True</property>
                                 <property name="search_column">1</property>
                                 <child>
-                                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                                  <object class="GtkTreeViewColumn" id="name_treeviewcolumn">
                                     <property name="title">Name</property>
                                     <property name="expand">True</property>
-                                    <child>
-                                      <object class="GtkCellRendererPixbuf" id="cellrendererpixbuf1"/>
-                                      <attributes>
-                                        <attribute name="icon-name">2</attribute>
-                                      </attributes>
-                                    </child>
-                                    <child>
-                                      <object class="GtkCellRendererText" id="cellrenderertext5"/>
-                                      <attributes>
-                                        <attribute name="text">1</attribute>
-                                      </attributes>
-                                    </child>
                                   </object>
                                 </child>
                                 <child>
@@ -318,6 +309,7 @@
                 </child>
               </object>
               <packing>
+                <property name="expand">False</property>
                 <property name="position">1</property>
               </packing>
             </child>
diff --git a/extensions/picasaweb/dlg-export-to-picasaweb.c b/extensions/picasaweb/dlg-export-to-picasaweb.c
index f4d054e..f86c226 100644
--- a/extensions/picasaweb/dlg-export-to-picasaweb.c
+++ b/extensions/picasaweb/dlg-export-to-picasaweb.c
@@ -51,7 +51,8 @@ enum {
 	ALBUM_NAME_COLUMN,
 	ALBUM_ICON_COLUMN,
 	ALBUM_REMAINING_IMAGES_COLUMN,
-	ALBUM_USED_BYTES_COLUMN
+	ALBUM_USED_BYTES_COLUMN,
+	ALBUM_EMBLEM_COLUMN
 };
 
 
@@ -95,6 +96,29 @@ export_dialog_destroy_cb (GtkWidget  *widget,
 }
 
 
+static void get_album_list (DialogData *data);
+
+
+static void
+post_photos_ready_cb (GObject      *source_object,
+		      GAsyncResult *result,
+		      gpointer      user_data)
+{
+	DialogData       *data = user_data;
+	PicasaWebService *picasaweb = PICASA_WEB_SERVICE (source_object);
+	GError           *error = NULL;
+
+	gth_task_dialog (GTH_TASK (data->conn), TRUE);
+
+	if (! picasa_web_service_post_photos_finish (picasaweb, result, &error)) {
+		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not upload the files"), &error);
+		return;
+	}
+
+	get_album_list (data);
+}
+
+
 static void
 export_dialog_response_cb (GtkDialog *dialog,
 			   int        response_id,
@@ -114,7 +138,30 @@ export_dialog_response_cb (GtkDialog *dialog,
 		break;
 
 	case GTK_RESPONSE_OK:
-		/* FIXME */
+		{
+			GtkTreeModel   *tree_model;
+			GtkTreeIter     iter;
+			PicasaWebAlbum *album;
+
+			if (! gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (GET_WIDGET ("albums_treeview"))), &tree_model, &iter)) {
+				gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), FALSE);
+				return;
+			}
+
+			gtk_tree_model_get (tree_model, &iter,
+					    ALBUM_DATA_COLUMN, &album,
+					    -1);
+
+			gth_task_dialog (GTH_TASK (data->conn), FALSE);
+			picasa_web_service_post_photos (data->picasaweb,
+							album,
+							data->file_list,
+							data->cancellable,
+							post_photos_ready_cb,
+							data);
+
+			g_object_unref (album);
+		}
 		break;
 
 	default:
@@ -179,13 +226,19 @@ update_album_list (DialogData *data)
 				    ALBUM_NAME_COLUMN, album->title,
 				    ALBUM_REMAINING_IMAGES_COLUMN, n_photos_remaining,
 				    ALBUM_USED_BYTES_COLUMN, used_bytes,
+				    ALBUM_EMBLEM_COLUMN, "emblem-readonly",
 				    -1);
 
+		if (album->access == PICASA_WEB_ACCESS_PRIVATE)
+			gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("album_liststore")), &iter,
+					    ALBUM_EMBLEM_COLUMN, "emblem-readonly",
+					    -1);
+
 		g_free (used_bytes);
 		g_free (n_photos_remaining);
 	}
 
-	gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), data->albums != NULL);
+	gtk_widget_set_sensitive (GET_WIDGET ("upload_button"), FALSE);
 }
 
 
@@ -583,7 +636,7 @@ add_album_button_clicked_cb (GtkButton *button,
 			  data);
 
 	gtk_window_set_title (GTK_WINDOW (dialog), _("New Album"));
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
+	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));
 }
@@ -669,7 +722,7 @@ edit_accounts_button_clicked_cb (GtkButton *button,
 			  data);
 
 	gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Accounts"));
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
+	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));
 }
@@ -732,6 +785,31 @@ dlg_export_to_picasaweb (GthBrowser *browser,
 	data->dialog = _gtk_builder_get_widget (data->builder, "export_dialog");
 	data->cancellable = g_cancellable_new ();
 
+	{
+		GtkTreeViewColumn *tree_column;
+		GtkCellRenderer   *renderer;
+
+		tree_column = GTK_TREE_VIEW_COLUMN (GET_WIDGET ("name_treeviewcolumn"));
+
+		renderer = gtk_cell_renderer_pixbuf_new ();
+		gtk_tree_view_column_pack_start (tree_column, renderer, FALSE);
+		gtk_tree_view_column_set_attributes (tree_column, renderer,
+						     "icon-name", ALBUM_ICON_COLUMN,
+						     NULL);
+
+		renderer = gtk_cell_renderer_text_new ();
+		gtk_tree_view_column_pack_start (tree_column, renderer, TRUE);
+		gtk_tree_view_column_set_attributes (tree_column, renderer,
+						     "text", ALBUM_NAME_COLUMN,
+						     NULL);
+
+		renderer = gtk_cell_renderer_pixbuf_new ();
+		gtk_tree_view_column_pack_start (tree_column, renderer, FALSE);
+		gtk_tree_view_column_set_attributes (tree_column, renderer,
+						     "icon-name", ALBUM_EMBLEM_COLUMN,
+						     NULL);
+	}
+
 	data->file_list = NULL;
 	n_total = 0;
 	total_size = 0;
diff --git a/extensions/picasaweb/picasa-web-album.c b/extensions/picasaweb/picasa-web-album.c
index 4e006bf..2a8859c 100644
--- a/extensions/picasaweb/picasa-web-album.c
+++ b/extensions/picasaweb/picasa-web-album.c
@@ -284,13 +284,13 @@ picasa_web_album_set_access (PicasaWebAlbum *self,
 {
 	if (value == NULL)
 		self->access = PICASA_WEB_ACCESS_PRIVATE;
-	else if (strcmp (value, "all"))
+	else if (strcmp (value, "all") == 0)
 		self->access = PICASA_WEB_ACCESS_ALL;
-	else if (strcmp (value, "private"))
+	else if (strcmp (value, "private") == 0)
 		self->access = PICASA_WEB_ACCESS_PRIVATE;
-	else if (strcmp (value, "public"))
+	else if (strcmp (value, "public") == 0)
 		self->access = PICASA_WEB_ACCESS_PUBLIC;
-	else if (strcmp (value, "visible"))
+	else if (strcmp (value, "visible") == 0)
 		self->access = PICASA_WEB_ACCESS_VISIBLE;
 	else
 		self->access = PICASA_WEB_ACCESS_PRIVATE;
diff --git a/extensions/picasaweb/picasa-web-service.c b/extensions/picasaweb/picasa-web-service.c
index 8b79976..e1badf0 100644
--- a/extensions/picasaweb/picasa-web-service.c
+++ b/extensions/picasaweb/picasa-web-service.c
@@ -28,10 +28,37 @@
 #include "picasa-web-service.h"
 
 
+typedef struct {
+	PicasaWebAlbum      *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;
+} PostPhotosData;
+
+
+static void
+post_photos_data_free (PostPhotosData *post_photos)
+{
+	if (post_photos == NULL)
+		return;
+	_g_object_unref (post_photos->cancellable);
+	_g_object_list_unref (post_photos->file_list);
+	g_object_unref (post_photos->album);
+	g_free (post_photos);
+}
+
+
 struct _PicasaWebServicePrivate
 {
 	GoogleConnection *conn;
 	PicasaWebUser    *user;
+	PostPhotosData   *post_photos;
 };
 
 
@@ -44,8 +71,10 @@ picasa_web_service_finalize (GObject *object)
 	PicasaWebService *self;
 
 	self = PICASA_WEB_SERVICE (object);
+
 	_g_object_unref (self->priv->conn);
 	_g_object_unref (self->priv->user);
+	post_photos_data_free (self->priv->post_photos);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -70,6 +99,7 @@ picasa_web_service_init (PicasaWebService *self)
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, PICASA_TYPE_WEB_SERVICE, PicasaWebServicePrivate);
 	self->priv->conn = NULL;
 	self->priv->user = NULL;
+	self->priv->post_photos = NULL;
 }
 
 
@@ -334,6 +364,215 @@ picasa_web_service_create_album_finish (PicasaWebService  *service,
 }
 
 
+/* -- picasa_web_service_post_photos -- */
+
+
+static void
+post_photos_done (PicasaWebService *self,
+		  GError           *error)
+{
+	GSimpleAsyncResult *result;
+
+	result = google_connection_get_result (self->priv->conn);
+	if (error == NULL)
+		g_simple_async_result_set_op_res_gboolean (result, TRUE);
+	else
+		g_simple_async_result_set_from_error (result, error);
+	g_simple_async_result_complete_in_idle (result);
+}
+
+
+static void picasa_wev_service_post_current_file (PicasaWebService *self);
+
+
+static void
+post_photo_ready_cb (SoupSession *session,
+		     SoupMessage *msg,
+		     gpointer     user_data)
+{
+	PicasaWebService *self = user_data;
+
+	if (msg->status_code != 201) {
+		GError *error;
+
+		error = g_error_new (SOUP_HTTP_ERROR, msg->status_code, "%s", soup_status_get_phrase (msg->status_code));
+		post_photos_done (self, error);
+		g_error_free (error);
+
+		return;
+	}
+
+	self->priv->post_photos->current = self->priv->post_photos->current->next;
+	picasa_wev_service_post_current_file (self);
+}
+
+
+static void
+post_photo_file_buffer_ready_cb (void     *buffer,
+				 gsize     count,
+				 GError   *error,
+				 gpointer  user_data)
+{
+	PicasaWebService   *self = user_data;
+	GthFileData        *file_data;
+	SoupMultipart      *multipart;
+	const char         *filename;
+	char               *summary;
+	DomDocument        *doc;
+	DomElement         *entry;
+	char               *entry_buffer;
+	gsize               entry_len;
+	SoupMessageHeaders *headers;
+	SoupBuffer         *body;
+	char               *details;
+	char               *url;
+	SoupMessage        *msg;
+
+	if (error != NULL) {
+		post_photos_done (self, error);
+		return;
+	}
+
+	file_data = self->priv->post_photos->current->data;
+	multipart = soup_multipart_new ("multipart/related");
+
+	/* the metadata part */
+
+	filename = g_file_info_get_display_name (file_data->info);
+	summary = gth_file_data_get_attribute_as_string (file_data, "general::description");
+	if (summary == NULL)
+		summary = gth_file_data_get_attribute_as_string (file_data, "general::title");
+
+	doc = dom_document_new ();
+	entry = dom_document_create_element (doc, "entry",
+					     "xmlns", "http://www.w3.org/2005/Atom";,
+					     NULL);
+	dom_element_append_child (entry,
+				  dom_document_create_element_with_text (doc, filename, "title", NULL));
+	dom_element_append_child (entry,
+				  dom_document_create_element_with_text (doc, summary, "summary", NULL));
+	dom_element_append_child (entry,
+				  dom_document_create_element (doc, "category",
+							       "scheme", "http://schemas.google.com/g/2005#kind";,
+							       "term", "http://schemas.google.com/photos/2007#photo";,
+							       NULL));
+	dom_element_append_child (DOM_ELEMENT (doc), entry);
+	entry_buffer = dom_document_dump (doc, &entry_len);
+
+	headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
+	soup_message_headers_append (headers, "Content-Type", "application/atom+xml");
+	body = soup_buffer_new (SOUP_MEMORY_TAKE, entry_buffer, entry_len);
+	soup_multipart_append_part (multipart, headers, body);
+
+	soup_buffer_free (body);
+	soup_message_headers_free (headers);
+	g_object_unref (doc);
+	g_free (summary);
+
+	/* the file part */
+
+	body = soup_buffer_new (SOUP_MEMORY_TEMPORARY, buffer, count);
+	soup_multipart_append_form_file (multipart,
+					 "file",
+					 NULL,
+					 gth_file_data_get_mime_type (file_data),
+					 body);
+
+	soup_buffer_free (body);
+
+	/* send the file */
+
+	/* Translators: %s is a filename */
+	details = g_strdup_printf (_("Uploading '%s'"), filename);
+	gth_task_progress (GTH_TASK (self->priv->conn), NULL, details, TRUE, 0.0);
+	g_free (details);
+
+	url = g_strconcat ("http://picasaweb.google.com/data/feed/api/user/";,
+			   self->priv->user->id,
+			   "/albumid/",
+			   self->priv->post_photos->album->id,
+			   NULL);
+	msg = soup_form_request_new_from_multipart (url, multipart);
+	google_connection_send_message (self->priv->conn,
+					msg,
+					self->priv->post_photos->cancellable,
+					self->priv->post_photos->callback,
+					self->priv->post_photos->user_data,
+					picasa_web_service_post_photos,
+					post_photo_ready_cb,
+					self);
+
+	g_free (url);
+	soup_multipart_free (multipart);
+}
+
+
+static void
+picasa_wev_service_post_current_file (PicasaWebService *self)
+{
+	GthFileData *file_data;
+
+	if (self->priv->post_photos->current == NULL) {
+		post_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,
+			   post_photo_file_buffer_ready_cb,
+			   self);
+}
+
+
+void
+picasa_web_service_post_photos (PicasaWebService    *self,
+			        PicasaWebAlbum      *album,
+			        GList               *file_list, /* GthFileData list */
+			        GCancellable        *cancellable,
+			        GAsyncReadyCallback  callback,
+			        gpointer             user_data)
+{
+	GList *scan;
+
+	g_return_if_fail (album != NULL);
+	g_return_if_fail (self->priv->post_photos == NULL);
+
+	gth_task_progress (GTH_TASK (self->priv->conn), _("Uploading the files to the server"), NULL, TRUE, 0.0);
+
+	self->priv->post_photos = g_new0 (PostPhotosData, 1);
+	self->priv->post_photos->album = g_object_ref (album);
+	self->priv->post_photos->file_list = _g_object_list_ref (file_list);
+	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;
+	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;
+	picasa_wev_service_post_current_file (self);
+}
+
+
+gboolean
+picasa_web_service_post_photos_finish (PicasaWebService  *self,
+				       GAsyncResult      *result,
+				       GError           **error)
+{
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+		return FALSE;
+	else
+		return TRUE;
+}
+
+
 /* utilities */
 
 
diff --git a/extensions/picasaweb/picasa-web-service.h b/extensions/picasaweb/picasa-web-service.h
index d6e2fdb..82c96e5 100644
--- a/extensions/picasaweb/picasa-web-service.h
+++ b/extensions/picasaweb/picasa-web-service.h
@@ -69,6 +69,15 @@ void                 picasa_web_service_create_album        (PicasaWebService
 PicasaWebAlbum *     picasa_web_service_create_album_finish (PicasaWebService     *self,
 							     GAsyncResult         *result,
 							     GError              **error);
+void                 picasa_web_service_post_photos         (PicasaWebService     *self,
+							     PicasaWebAlbum       *album,
+							     GList                *file_list, /* GthFileData list */
+							     GCancellable         *cancellable,
+							     GAsyncReadyCallback   callback,
+							     gpointer              user_data);
+gboolean             picasa_web_service_post_photos_finish  (PicasaWebService     *self,
+							     GAsyncResult         *result,
+							     GError              **error);
 
 /* utilities */
 



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