[totem/gnome-2-30] Use libsoup directly to load video pages in the YouTube plugin



commit 2ea91242a77f97da863ce8b11e82f41c1b6e94ac
Author: Philip Withnall <philip tecnocode co uk>
Date:   Mon Aug 9 09:53:09 2010 +0100

    Use libsoup directly to load video pages in the YouTube plugin
    
    This means we can ignore cookies, and don't encounter the cookie sharing
    problem we previously had between libsoup and gvfs. Closes: bgo#619207

 configure.in                        |    7 ++++
 src/plugins/youtube/Makefile.am     |    5 ++-
 src/plugins/youtube/totem-youtube.c |   54 +++++++++++++++++++++++-----------
 3 files changed, 47 insertions(+), 19 deletions(-)
---
diff --git a/configure.in b/configure.in
index a5b3f8c..e403b22 100644
--- a/configure.in
+++ b/configure.in
@@ -552,6 +552,13 @@ for plugin in ${used_plugins}; do
 				AC_DEFINE([HAVE_LIBGDATA_0_7],[1],[Define if libgdata >= 0.7.0 is available])
 			fi
 
+			PKG_CHECK_MODULES(LIBSOUP, libsoup-2.4,
+				[HAVE_LIBSOUP=yes], [HAVE_LIBSOUP=no])
+			if test "${HAVE_LIBSOUP}" != "yes" ; then
+				plugin_error_or_ignore "you need libsoup-2.4 installed for the YouTube plugin"
+				add_plugin="0"
+			fi
+
 			dnl We need the souphttpsrc element for the YouTube plugin
 			AC_MSG_CHECKING([GStreamer 0.10 souphttpsrc plugin])
 			if $gst010_inspect souphttpsrc >/dev/null 2>/dev/null; then
diff --git a/src/plugins/youtube/Makefile.am b/src/plugins/youtube/Makefile.am
index c12af21..9676b37 100644
--- a/src/plugins/youtube/Makefile.am
+++ b/src/plugins/youtube/Makefile.am
@@ -26,12 +26,15 @@ common_defines = \
 
 libyoutube_la_SOURCES = totem-youtube.c
 libyoutube_la_LDFLAGS = $(modules_flags)
-libyoutube_la_LIBADD = $(LIBGDATA_LIBS)
+libyoutube_la_LIBADD = \
+	$(LIBGDATA_LIBS)	\
+	$(LIBSOUP_LIBS)
 libyoutube_la_CPPFLAGS = $(common_defines)
 
 libyoutube_la_CFLAGS = \
 	$(DEPENDENCY_CFLAGS)	\
 	$(LIBGDATA_CFLAGS)	\
+	$(LIBSOUP_CFLAGS)	\
 	$(WARN_CFLAGS)		\
 	$(DBUS_CFLAGS)		\
 	$(AM_CFLAGS)		\
diff --git a/src/plugins/youtube/totem-youtube.c b/src/plugins/youtube/totem-youtube.c
index 45a2698..c3eaadf 100644
--- a/src/plugins/youtube/totem-youtube.c
+++ b/src/plugins/youtube/totem-youtube.c
@@ -29,6 +29,7 @@
 #include <glib-object.h>
 #include <glib/gi18n-lib.h>
 #include <gdata/gdata.h>
+#include <libsoup/soup.h>
 
 #include "totem-plugin.h"
 #include "totem.h"
@@ -61,6 +62,7 @@ typedef struct {
 	TotemPlugin parent;
 	Totem *totem;
 	GDataYouTubeService *service;
+	SoupSession *session;
 	BaconVideoWidget *bvw;
 
 	guint current_tree_view;
@@ -388,6 +390,8 @@ impl_deactivate	(TotemPlugin *plugin, TotemObject *totem)
 		g_object_unref (self->playing_video);
 	if (self->service != NULL)
 		g_object_unref (self->service);
+	if (self->session != NULL)
+		g_object_unref (self->session);
 	g_object_unref (self->bvw);
 	g_object_unref (self->totem);
 	if (self->regex != NULL)
@@ -470,36 +474,40 @@ typedef struct {
 	GDataEntry *entry;
 	GtkTreeIter iter;
 	guint tree_view;
+	SoupMessage *message;
+	gulong cancelled_id;
 } TParamData;
 
 static void
-resolve_t_param_cb (GObject *source_object, GAsyncResult *result, TParamData *data)
+resolve_t_param_cb (SoupSession *session, SoupMessage *message, TParamData *data)
 {
-	gchar *contents, *video_uri = NULL;
-	const gchar *video_id;
+	gchar *video_uri = NULL;
+	const gchar *video_id, *contents;
 	gsize length;
 	GMatchInfo *match_info;
-	GError *error = NULL;
 	TotemYouTubePlugin *self = data->plugin;
 
+	/* Prevent cancellation */
+	g_cancellable_disconnect (self->cancellable[data->tree_view], data->cancelled_id);
+
 	/* Finish loading the page */
-	if (g_file_load_contents_finish (G_FILE (source_object), result, &contents, &length, NULL, &error) == FALSE) {
+	if (message->status_code != SOUP_STATUS_OK) {
 		GtkWindow *window;
 
 		/* Bail out if the operation was cancelled */
-		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) == TRUE) {
-			g_error_free (error);
+		if (message->status_code == SOUP_STATUS_CANCELLED)
 			goto free_data;
-		}
 
 		/* Couldn't load the page contents; error */
 		window = totem_get_main_window (data->plugin->totem);
-		totem_interface_error (_("Error Looking Up Video URI"), error->message, window);
+		totem_interface_error (_("Error Looking Up Video URI"), message->response_body->data, window);
 		g_object_unref (window);
-		g_error_free (error);
 		goto free_data;
 	}
 
+	contents = message->response_body->data;
+	length = message->response_body->length;
+
 	video_id = gdata_youtube_video_get_video_id (GDATA_YOUTUBE_VIDEO (data->entry));
 
 	/* Check for the fmt_url_map parameter */
@@ -544,7 +552,6 @@ resolve_t_param_cb (GObject *source_object, GAsyncResult *result, TParamData *da
 		}
 	}
 	g_match_info_free (match_info);
-	g_free (contents);
 
 	/* Update the tree view with the new MRL */
 	gtk_list_store_set (self->list_store[data->tree_view], &(data->iter), 2, video_uri, -1);
@@ -562,15 +569,21 @@ free_data:
 }
 
 static void
+resolve_t_param_cancelled_cb (GCancellable *cancellable, TParamData *data)
+{
+	/* This will cause resolve_t_param_cb() to be called, which will free the data */
+	soup_session_cancel_message (data->plugin->session, data->message, SOUP_STATUS_CANCELLED);
+}
+
+static void
 resolve_t_param (TotemYouTubePlugin *self, GDataEntry *entry, GtkTreeIter *iter, guint tree_view)
 {
-	GDataLink *link;
-	GFile *video_page;
+	GDataLink *page_link;
 	TParamData *data;
 
 	/* We have to get the t parameter from the actual HTML video page, since Google changed how their URIs work */
-	link = gdata_entry_look_up_link (entry, GDATA_LINK_ALTERNATE);
-	g_assert (link != NULL);
+	page_link = gdata_entry_look_up_link (entry, GDATA_LINK_ALTERNATE);
+	g_assert (page_link != NULL);
 
 	data = g_slice_new (TParamData);
 	data->plugin = g_object_ref (self);
@@ -578,9 +591,11 @@ resolve_t_param (TotemYouTubePlugin *self, GDataEntry *entry, GtkTreeIter *iter,
 	data->iter = *iter;
 	data->tree_view = tree_view;
 
-	video_page = g_file_new_for_uri (gdata_link_get_uri (link));
-	g_file_load_contents_async (video_page, self->cancellable[tree_view], (GAsyncReadyCallback) resolve_t_param_cb, data);
-	g_object_unref (video_page);
+	data->message = soup_message_new (SOUP_METHOD_GET, gdata_link_get_uri (page_link));
+	data->cancelled_id = g_cancellable_connect (self->cancellable[tree_view], (GCallback) resolve_t_param_cancelled_cb, data, NULL);
+
+	/* Send the message. Consumes a reference to data->message after resolve_t_param_cb() finishes */
+	soup_session_queue_message (self->session, data->message, (SoupSessionCallback) resolve_t_param_cb, data);
 }
 
 typedef struct {
@@ -864,6 +879,9 @@ search_button_clicked_cb (GtkButton *button, TotemYouTubePlugin *self)
 		/* Set up the queries */
 		self->query[SEARCH_TREE_VIEW] = gdata_query_new_with_limits (NULL, 0, MAX_RESULTS);
 		self->query[RELATED_TREE_VIEW] = gdata_query_new_with_limits (NULL, 0, MAX_RESULTS);
+
+		/* Lazily create the SoupSession used in resolve_t_param() */
+		self->session = soup_session_async_new ();
 	}
 
 	/* Do the query */



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