[totem] Use libsoup directly to load video pages in the YouTube plugin



commit d61fd2d66bc4d45d0d8c86848599c8385f06e4a1
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 |   51 ++++++++++++++++++++++++----------
 3 files changed, 47 insertions(+), 16 deletions(-)
---
diff --git a/configure.in b/configure.in
index 8f3c695..3af59c2 100644
--- a/configure.in
+++ b/configure.in
@@ -527,6 +527,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 574ad6c..0605f6f 100644
--- a/src/plugins/youtube/Makefile.am
+++ b/src/plugins/youtube/Makefile.am
@@ -26,13 +26,16 @@ 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)	\
 	$(PEAS_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 bb653dd..325cc34 100644
--- a/src/plugins/youtube/totem-youtube.c
+++ b/src/plugins/youtube/totem-youtube.c
@@ -32,6 +32,7 @@
 #include <libpeas/peas-object-module.h>
 #include <libpeas/peas-activatable.h>
 #include <gdata/gdata.h>
+#include <libsoup/soup.h>
 
 #include "totem-plugin.h"
 #include "totem.h"
@@ -65,6 +66,7 @@ typedef struct {
 	PeasExtensionBase parent;
 	Totem *totem;
 	GDataYouTubeService *service;
+	SoupSession *session;
 	BaconVideoWidget *bvw;
 
 	guint current_tree_view;
@@ -387,6 +389,8 @@ impl_deactivate (PeasActivatable *plugin)
 		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)
@@ -460,6 +464,9 @@ typedef struct {
 	GDataEntry *entry;
 	GtkTreePath *path;
 	guint tree_view;
+	SoupMessage *message;
+	gulong cancelled_id;
+	GCancellable *cancellable;
 } TParamData;
 
 /* Ranked list of formats to prefer, from http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs */
@@ -480,34 +487,36 @@ static const guint fmt_preferences[] = {
 };
 
 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;
 	GtkTreeIter iter;
 	TotemYouTubePlugin *self = data->plugin;
 
+	/* Prevent cancellation */
+	g_cancellable_disconnect (data->cancellable, 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 */
@@ -594,7 +603,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 */
 	if (gtk_tree_model_get_iter (GTK_TREE_MODEL (self->list_store[data->tree_view]), &iter, data->path) == TRUE) {
@@ -608,6 +616,7 @@ free_data:
 	/* Update the progress bar */
 	increment_progress_bar_fraction (self, data->tree_view);
 
+	g_object_unref (data->cancellable);
 	g_object_unref (data->plugin);
 	g_object_unref (data->entry);
 	gtk_tree_path_free (data->path);
@@ -615,10 +624,16 @@ 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, GCancellable *cancellable)
 {
 	GDataLink *page_link;
-	GFile *video_page;
 	TParamData *data;
 
 	/* We have to get the t parameter from the actual HTML video page, since Google changed how their URIs work */
@@ -630,10 +645,13 @@ resolve_t_param (TotemYouTubePlugin *self, GDataEntry *entry, GtkTreeIter *iter,
 	data->entry = g_object_ref (entry);
 	data->path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->list_store[tree_view]), iter);
 	data->tree_view = tree_view;
+	data->cancellable = g_object_ref (cancellable);
+
+	data->message = soup_message_new (SOUP_METHOD_GET, gdata_link_get_uri (page_link));
+	data->cancelled_id = g_cancellable_connect (cancellable, (GCallback) resolve_t_param_cancelled_cb, data, NULL);
 
-	video_page = g_file_new_for_uri (gdata_link_get_uri (page_link));
-	g_file_load_contents_async (video_page, cancellable, (GAsyncReadyCallback) resolve_t_param_cb, data);
-	g_object_unref (video_page);
+	/* 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 {
@@ -980,6 +998,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]