diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2010-08-09 09:53:09 +0100 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2010-08-09 22:52:57 +0100 |
commit | 2ea91242a77f97da863ce8b11e82f41c1b6e94ac (patch) | |
tree | b4b06fbfb9c1cca533e525ea34432c8162091a5a | |
parent | 6294338e2c389e8cd5e89352cfd488bc41caef06 (diff) | |
download | totem-2ea91242a77f97da863ce8b11e82f41c1b6e94ac.tar.gz |
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
-rw-r--r-- | configure.in | 7 | ||||
-rw-r--r-- | src/plugins/youtube/Makefile.am | 5 | ||||
-rw-r--r-- | src/plugins/youtube/totem-youtube.c | 54 |
3 files changed, 47 insertions, 19 deletions
diff --git a/configure.in b/configure.in index a5b3f8ce5..e403b2223 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 c12af213c..9676b3711 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 45a2698d4..c3eaadf48 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 */ |