rpms/rhythmbox/devel rb-delete-ipod-tracks.patch, NONE, 1.1 rb-disable-local-uri-escaping-5.patch, NONE, 1.1 rb-use-newer-plparser-7.patch, NONE, 1.1 rhythmbox-0.11.2-dont-escape-primary-in-notifications.patch, 1.1, 1.2 rhythmbox.spec, 1.138, 1.139

Bastien Nocera (hadess) fedora-extras-commits at redhat.com
Mon Oct 29 13:39:40 UTC 2007


Author: hadess

Update of /cvs/pkgs/rpms/rhythmbox/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv25486

Modified Files:
	rhythmbox-0.11.2-dont-escape-primary-in-notifications.patch 
	rhythmbox.spec 
Added Files:
	rb-delete-ipod-tracks.patch 
	rb-disable-local-uri-escaping-5.patch 
	rb-use-newer-plparser-7.patch 
Log Message:
* Mon Oct 29 2007 - Bastien Nocera <bnocera at redhat.com> - 0.11.2-12
- Update patch for #242260, tooltips weren't working
- Add patch to fix problems importing files with spaces in them (#291571)
- Add patch to remove iPod tracks when removed, rather than put them
  in the trash (#330101)
- Add upstream patch to support new playlist parser in Totem, and add
  better Podcast support, as well as iTunes podcast support


rb-delete-ipod-tracks.patch:

--- NEW FILE rb-delete-ipod-tracks.patch ---
Index: rb-ipod-source.c
===================================================================
--- rb-ipod-source.c	(revision 5381)
+++ rb-ipod-source.c	(working copy)
@@ -1064,6 +1064,7 @@
 	for (tem = sel; tem != NULL; tem = tem->next) {
 		RhythmDBEntry *entry;
 		const gchar *uri;
+		gchar *file;
 		Itdb_Track *track;
 
 		entry = (RhythmDBEntry *)tem->data;
@@ -1077,7 +1078,11 @@
 
 		rb_ipod_db_remove_track (priv->ipod_db, track);
 		g_hash_table_remove (priv->entry_map, entry);
-		rhythmdb_entry_move_to_trash (db, entry);
+		file = g_filename_from_uri (uri, NULL, NULL);
+		if (file != NULL)
+			g_unlink (file);
+		g_free (file);
+		rhythmdb_entry_delete (db, entry);
 		rhythmdb_commit (db);
 	}
 

rb-disable-local-uri-escaping-5.patch:

--- NEW FILE rb-disable-local-uri-escaping-5.patch ---
Index: lib/rb-file-helpers.c
===================================================================
--- lib/rb-file-helpers.c	(revision 5418)
+++ lib/rb-file-helpers.c	(working copy)
@@ -1070,41 +1070,37 @@
 {
 	char *result = NULL;
 
+	g_return_val_if_fail (uri != NULL, NULL);
+
 	if (uri[0] == '/') {
 		/* local path */
 		char *tmp;
 		result = gnome_vfs_make_path_name_canonical (uri);
-		tmp = gnome_vfs_escape_path_string (result);
+		tmp = gnome_vfs_get_uri_from_local_path (result);
 		g_free (result);
 		if (tmp == NULL)
 			return NULL;
-		tmp = escape_extra_gnome_vfs_chars (tmp);
-		result = g_strconcat ("file://", tmp, NULL);
-		g_free (tmp);
-	} else  if (g_str_has_prefix (uri, "file://")) {
-	    	/* local file, rhythmdb wants this path escaped */
-		char *tmp1, *tmp2;
-		tmp1  = gnome_vfs_unescape_string (uri + 7, NULL);  /* ignore "file://" */
-		tmp2 = gnome_vfs_escape_path_string (tmp1);
-		g_free (tmp1);
-		if (tmp2 == NULL)
-			return NULL;
-		tmp2 = escape_extra_gnome_vfs_chars (tmp2);
-		result = g_strconcat ("file://", tmp2, NULL); /* re-add scheme */
-		g_free (tmp2);
-	} else {
-		GnomeVFSURI *vfsuri = gnome_vfs_uri_new (uri);
+		result = tmp;
+	} else if (strstr (uri, "://") == NULL) {
+		/* local relative path */
+		char *curdir, *escaped, *curdir_withslash;
 
-		if (vfsuri != NULL) {
-			/* non-local uri, leave as-is */
-			gnome_vfs_uri_unref (vfsuri);
+		curdir = g_get_current_dir ();
+		escaped = gnome_vfs_escape_path_string (curdir);
+		curdir_withslash = g_strdup_printf ("file://%s%c",
+						    escaped, G_DIR_SEPARATOR);
+		g_free (escaped);
+		g_free (curdir);
+
+		escaped = gnome_vfs_escape_path_string (uri);
+		result = gnome_vfs_uri_make_full_from_relative
+			(curdir_withslash, escaped);
+		g_free (curdir_withslash);
+		g_free (escaped);
+	} else {
+		result = gnome_vfs_make_uri_canonical (uri);
+		if (result == NULL)
 			result = g_strdup (uri);
-		} else {
-			/* this may just mean that gnome-vfs doesn't recognise the
-			 * uri scheme, so return it as is */
-			rb_debug ("Error processing probable URI %s", uri);
-			result = g_strdup (uri);
-		}
 	}
 
 	return result;
Index: rhythmdb/rhythmdb-tree.c
===================================================================
--- rhythmdb/rhythmdb-tree.c	(revision 5418)
+++ rhythmdb/rhythmdb-tree.c	(working copy)
@@ -107,7 +107,9 @@
 					RBTreePropertyItFunc genres_func,
 					gpointer data);
 
-#define RHYTHMDB_TREE_XML_VERSION "1.3"
+/* Update both of those! */
+#define RHYTHMDB_TREE_XML_VERSION "1.4"
+#define RHYTHMDB_TREE_XML_VERSION_INT 140
 
 static void destroy_tree_property (RhythmDBTreeProperty *prop);
 static RhythmDBTreeProperty *get_or_create_album (RhythmDBTree *db, RhythmDBTreeProperty *artist,
@@ -326,6 +328,20 @@
 	gboolean reload_all_metadata;
 };
 
+/* Returns the version as an int, multiplied by 100,
+ * eg. "1.4" becomes 140 */
+static int
+version_to_int (const char *version)
+{
+	float ver;
+
+	if (sscanf (version, "%f", &ver) != 1) {
+		return (int) (1.0 * 100);
+	}
+
+	return ver * 100;
+}
+
 static void
 rhythmdb_tree_parser_start_element (struct RhythmDBTreeLoadContext *ctx,
 				    const char *name,
@@ -351,22 +367,32 @@
 				if (!strcmp (*attrs, "version")) {
 					const char *version = *(attrs+1);
 
-					if (!strcmp (version, "1.0") || !strcmp (version, "1.1")) {
+					switch (version_to_int (version)) {
+					case 100:
+					case 110:
+						rb_debug ("old version of rhythmdb, performing URI canonicalisation for all entries (DB version 1.0 or 1.1)");
 						ctx->canonicalise_uris = TRUE;
-						rb_debug ("old version of rhythmdb, performing URI canonicalisation for all entries");
-					} else if (!strcmp (version, "1.2")) {
-						/* current version*/
-						rb_debug ("reloading all file metadata to get MusicBrainz tags");
+					case 120:
+						rb_debug ("reloading all file metadata to get MusicBrainz tags (DB version 1.2)");
 						ctx->reload_all_metadata = TRUE;
-					} else if (!strcmp (version, "1.3")) {
-						/* current version*/
-					} else {
-						g_set_error (ctx->error,
-							     RHYTHMDB_TREE_ERROR,
-							     RHYTHMDB_TREE_ERROR_DATABASE_TOO_NEW,
-							     _("The database was created by a later version of rhythmbox."
-							       "  This version of rhythmbox cannot read the database."));
-						xmlStopParser (ctx->xmlctx);
+					case 130:
+						/* Avoid being warned twice for very old DBs */
+						if (ctx->canonicalise_uris == FALSE) {
+							rb_debug ("old version of rhythmdb, performing URI canonicalisation for all entries (DB version 1.3)");
+							ctx->canonicalise_uris = TRUE;
+						}
+					case RHYTHMDB_TREE_XML_VERSION_INT:
+						/* current version */
+						break;
+					default:
+						if (version_to_int (version) > RHYTHMDB_TREE_XML_VERSION_INT) {
+							g_set_error (ctx->error,
+								     RHYTHMDB_TREE_ERROR,
+								     RHYTHMDB_TREE_ERROR_DATABASE_TOO_NEW,
+								     _("The database was created by a later version of rhythmbox."
+								       "  This version of rhythmbox cannot read the database."));
+							xmlStopParser (ctx->xmlctx);
+						}
 					}
 				} else {
 					g_assert_not_reached ();

rb-use-newer-plparser-7.patch:

--- NEW FILE rb-use-newer-plparser-7.patch ---
Index: podcast/test-podcast-parse.c
===================================================================
--- podcast/test-podcast-parse.c	(revision 5413)
+++ podcast/test-podcast-parse.c	(working copy)
@@ -66,7 +66,6 @@
 	g_date_strftime (datebuf, 1024, "%F %T", &date);
 
 	g_print ("Podcast title: %s\n", data->title);
-	g_print ("Summary: %s\n", data->summary);
 	g_print ("Description: %s\n", data->description);
 	g_print ("Author: %s\n", data->author);
 	g_print ("Date: %s\n", datebuf);
Index: podcast/rb-podcast-manager.c
===================================================================
--- podcast/rb-podcast-manager.c	(revision 5413)
+++ podcast/rb-podcast-manager.c	(working copy)
@@ -816,7 +816,7 @@
 	RBPodcastThreadInfo *info;
 	gchar *valid_url;
 
-	if (g_str_has_prefix (url, "feed://")) {
+	if (g_str_has_prefix (url, "feed://") || g_str_has_prefix (url, "itpc://")) {
 		char *tmp;
 
 		tmp = g_strdup_printf ("http://%s", url + strlen ("feed://"));
@@ -841,6 +841,7 @@
 					 "If this is a podcast feed, please remove the radio station."), url);
 			return FALSE;
 		}
+		return FALSE;
 	}
 
 	info = g_new0 (RBPodcastThreadInfo, 1);
@@ -898,7 +899,7 @@
 {
 	RBPodcastChannel *feed = g_new0 (RBPodcastChannel, 1);
 
-	if (rb_podcast_parse_load_feed (feed, info->url)) {
+	if (rb_podcast_parse_load_feed (feed, info->url) && (feed->is_opml == FALSE)) {
 		RBPodcastManagerParseResult *result;
 
 		result = g_new0 (RBPodcastManagerParseResult, 1);
@@ -910,6 +911,16 @@
 				 (GSourceFunc) rb_podcast_manager_parse_complete_cb,
 				 result,
 				 (GDestroyNotify) rb_podcast_manager_free_parse_result);
+	} else if (feed->is_opml) {
+		GList *l;
+
+		rb_debug ("Loading OPML feeds from %s", info->url);
+
+		for (l = feed->posts; l != NULL; l = l->next) {
+			RBPodcastItem *item = l->data;
+			rb_podcast_manager_subscribe_feed (info->pd, item->url);
+		}
+		rb_podcast_parse_channel_free (feed);
 	}
 
 	g_object_unref (info->pd);
@@ -1496,8 +1507,6 @@
 {
 	GValue description_val = { 0, };
 	GValue title_val = { 0, };
-	GValue subtitle_val = { 0, };
-	GValue summary_val = { 0, };
 	GValue lang_val = { 0, };
 	GValue copyright_val = { 0, };
 	GValue image_val = { 0, };
@@ -1568,13 +1577,6 @@
 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ARTIST, &author_val);
 	g_value_unset (&author_val);
 
-	if (data->subtitle) {
-		g_value_init (&subtitle_val, G_TYPE_STRING);
-		g_value_set_string (&subtitle_val, (gchar *) data->subtitle);
-		rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_SUBTITLE, &subtitle_val);
-		g_value_unset (&subtitle_val);
-	}
-
 	if (data->description) {
 		g_value_init (&description_val, G_TYPE_STRING);
 		g_value_set_string (&description_val, (gchar *) data->description);
@@ -1582,13 +1584,6 @@
 		g_value_unset (&description_val);
 	}
 
-	if (data->summary) {
-		g_value_init (&summary_val, G_TYPE_STRING);
-		g_value_set_string (&summary_val, (gchar *) data->summary);
-		rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_SUMMARY, &summary_val);
-		g_value_unset (&summary_val);
-	}
-
 	if (data->lang) {
 		g_value_init (&lang_val, G_TYPE_STRING);
 		g_value_set_string (&lang_val, (gchar *) data->lang);
Index: podcast/rb-podcast-parse.c
===================================================================
--- podcast/rb-podcast-parse.c	(revision 5413)
+++ podcast/rb-podcast-parse.c	(working copy)
@@ -22,427 +22,116 @@
 
 #include "config.h"
 
-#define _XOPEN_SOURCE
-#define __EXTENSIONS__  /* get strptime */
 #include <string.h>
-#include <time.h>
 
-#include <libxml/entities.h>
-#include <libxml/SAX.h>
-#include <libxml/parserInternals.h>
+#include <totem-pl-parser.h>
 #include <libgnomevfs/gnome-vfs.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
 #include "rb-debug.h"
 #include "rb-podcast-parse.h"
+#include "rb-file-helpers.h"
 
-#define BUFFER_SIZE 256
-
-struct RBPoadcastLoadContext
-{
-	guint in_unknown_elt;
-	xmlParserCtxtPtr xmlctx;
-	GString *prop_value;
-	RBPodcastChannel *channel_data;
-	RBPodcastItem *item_data;
-
-	enum {
-		RB_PODCAST_PARSER_STATE_START,
-		RB_PODCAST_PARSER_STATE_RSS,
-		RB_PODCAST_PARSER_STATE_CHANNEL,
-		RB_PODCAST_PARSER_STATE_CHANNEL_PROPERTY,
-		RB_PODCAST_PARSER_STATE_IMG,
-		RB_PODCAST_PARSER_STATE_IMG_PROPERTY,
-		RB_PODCAST_PARSER_STATE_ITEM,
-		RB_PODCAST_PARSER_STATE_ITEM_PROPERTY,
-		RB_PODCAST_PARSER_STATE_END,
-	} state;
-};
-
-static gboolean rb_validate_channel_propert (const char *name);
-static gboolean rb_validate_item_propert (const char *name);
-static uintmax_t rb_podcast_parse_date (const char* date_str);
-static gulong rb_podcast_parse_time (const char *time_str);
-static void rb_podcast_parser_start_element (struct RBPoadcastLoadContext* ctx, const char *name, const char **attrs);
-static void rb_podcast_parser_end_element (struct RBPoadcastLoadContext* ctx, const char *name);
-static void rb_podcast_parser_characters (struct RBPoadcastLoadContext* ctx, const char *data, guint len);
-static void rb_set_channel_value (struct RBPoadcastLoadContext* ctx, const char* name, const char* value);
-static void rb_set_item_value (struct RBPoadcastLoadContext* ctx, const char* name, const char* value);
-
-static RBPodcastItem *
-rb_podcast_initializa_item ()
-{
-	RBPodcastItem *data = g_new0 (RBPodcastItem, 1);
-	return data;
-}
-
 static void
-rb_set_channel_value (struct RBPoadcastLoadContext *ctx,
-		      const char *name,
-		      const char *value)
+playlist_metadata_foreach (const char *key,
+			   const char *value,
+			   gpointer data)
 {
-	xmlChar *dvalue;
+	RBPodcastChannel *channel = (RBPodcastChannel *) data;
 
-	if (value == NULL)
-		return;
-
-	if (name == NULL)
-		return;
-
-	dvalue = xmlCharStrdup (value);
-	g_strstrip ((char *)dvalue);
-
-	if (!strcmp (name, "title")) {
-		ctx->channel_data->title = dvalue;
-	} else if (!strcmp (name, "language")) {
-		ctx->channel_data->lang = dvalue;
-	} else if (!strcmp (name, "itunes:subtitle")) {
-		ctx->channel_data->subtitle = dvalue;
-	} else if (!strcmp (name, "itunes:summary")) {
-		ctx->channel_data->summary = dvalue;
-	} else if (!strcmp (name, "description")) {
-		ctx->channel_data->description = dvalue;
-	} else if (!strcmp (name, "generator")) {
-		if (ctx->channel_data->author == NULL)
-			ctx->channel_data->author = dvalue;
-	} else if (!strcmp (name, "itunes:author")) {
-		g_free (ctx->channel_data->author);
-		ctx->channel_data->author = dvalue;
-	} else if (!strcmp (name, "webMaster")) {
-		ctx->channel_data->contact = dvalue;
-	} else if (!strcmp (name, "pubDate")) {
-		ctx->channel_data->pub_date = rb_podcast_parse_date ((char *)dvalue);
-		g_free (dvalue);
-	} else if (!strcmp (name, "copyright")) {
-		ctx->channel_data->copyright = dvalue;
-	} else if (!strcmp (name, "img")) {
-		ctx->channel_data->img = dvalue;
-	} else {
-		g_free (dvalue);
+	if (strcmp (key, TOTEM_PL_PARSER_FIELD_TITLE) == 0) {
+		channel->title = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_LANGUAGE) == 0) {
+		channel->lang = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_DESCRIPTION) == 0) {
+		channel->description = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_AUTHOR) == 0) {
+		channel->author = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_CONTACT) == 0) {
+		channel->contact = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_IMAGE_URL) == 0) {
+		channel->img = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_PUB_DATE) == 0) {
+		channel->pub_date = totem_pl_parser_parse_date (value, FALSE);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_COPYRIGHT) == 0) {
+		channel->copyright = g_strdup (value);
 	}
 }
 
 static void
-rb_set_item_value (struct RBPoadcastLoadContext *ctx,
-		   const char *name,
-		   const char *value)
+playlist_started (TotemPlParser *parser,
+		  const char *uri,
+		  GHashTable *metadata,
+		  gpointer data)
 {
-	xmlChar *dvalue;
-
-	dvalue = xmlCharStrdup (value);
-	g_strstrip ((char *)dvalue);
-
-	if (!strcmp (name, "title")) {
-		ctx->item_data->title = dvalue;
-	} else if (!strcmp (name, "url")) {
-		ctx->item_data->url = dvalue;
-	} else if (!strcmp (name, "pubDate")) {
-		ctx->item_data->pub_date = rb_podcast_parse_date ((char *)dvalue);
-		g_free (dvalue);
-	} else if (!strcmp (name, "description")) {
-		ctx->item_data->description = dvalue;
-	} else if (!strcmp (name, "author")) {
-		ctx->item_data->author = dvalue;
-	} else if (!strcmp (name, "itunes:duration")) {
-		ctx->item_data->duration = rb_podcast_parse_time ((char *)dvalue);
-		g_free (dvalue);
-	} else if (!strcmp (name, "length")) {
-		ctx->item_data->filesize = g_ascii_strtoull ((char *)dvalue, NULL, 10);
-	} else {
-		g_free (dvalue);
-	}
+	g_hash_table_foreach (metadata, (GHFunc) playlist_metadata_foreach, data);
 }
 
 static void
-rb_insert_item (struct RBPoadcastLoadContext *ctx)
+playlist_ended (TotemPlParser *parser,
+		const char *uri,
+		gpointer data)
 {
-	RBPodcastItem *data = ctx->item_data;
+	RBPodcastChannel *channel = (RBPodcastChannel *) data;
 
-	rb_debug ("Inserting item as post");
-
-	if (!data->url) {
-		rb_debug ("Item does not have a URL, skipping");
-		return;
-	}
-
-	ctx->channel_data->posts = g_list_prepend (ctx->channel_data->posts, ctx->item_data);
+	channel->posts = g_list_reverse (channel->posts);
 }
 
-static gboolean
-rb_validate_channel_propert (const char *name)
-{
-	if (name == NULL) {
-		return FALSE;
-	}
-
-	if (!strcmp (name, "title") ||
-	    !strcmp (name, "language") ||
-	    !strcmp (name, "itunes:subtitle") ||
-	    !strcmp (name, "itunes:summary") ||
-	    !strcmp (name, "description") ||
-	    !strcmp (name, "generator") ||
-	    !strcmp (name, "itunes:author") ||
-	    !strcmp (name, "webMaster") ||
-	    !strcmp (name, "lastBuildDate") ||
-	    !strcmp (name, "pubDate") ||
-	    !strcmp (name, "copyright")) {
-		return TRUE;
-	} else {
-		return FALSE;
-	}
-
-}
-
-static gboolean
-rb_validate_item_propert (const char *name)
-{
-	if (name == NULL) {
-		return FALSE;
-	}
-
-	if (!strcmp (name, "title") ||
-	    !strcmp (name, "url") ||
-	    !strcmp (name, "pubDate") ||
-	    !strcmp (name, "description") ||
-	    !strcmp (name, "author") ||
-	    !strcmp (name, "itunes:duration") ) {
-
-		return TRUE;
-	} else {
-		return FALSE;
-	}
-}
-
 static void
-rb_podcast_parser_start_element (struct RBPoadcastLoadContext *ctx,
-				 const char *name,
-				 const char **attrs)
+entry_metadata_foreach (const char *key,
+			const char *value,
+			gpointer data)
 {
+	RBPodcastItem *item = (RBPodcastItem *) data;
 
-	rb_debug ("Start element: %s state: %d", name, ctx->state);
-
-	switch (ctx->state) {
-        case RB_PODCAST_PARSER_STATE_START:
-		{
-			if (!strcmp (name, "rss")) {
-				ctx->state = RB_PODCAST_PARSER_STATE_RSS;
-			} else {
-				ctx->in_unknown_elt++;
-			}
-
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_RSS:
-		{
-			if (!strcmp (name, "channel")) {
-				ctx->state = RB_PODCAST_PARSER_STATE_CHANNEL;
-			} else {
-				ctx->in_unknown_elt++;
-			}
-
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_CHANNEL:
-		{
-			if (strcmp (name, "image") == 0)
-			{
-				ctx->state = RB_PODCAST_PARSER_STATE_IMG;
-			} else if (strcmp (name, "itunes:image") == 0) {
-				for (; attrs && *attrs; attrs +=2) {
-					if (!strcmp (*attrs, "href")) {
-						const char *href_value = *(attrs + 1);
-						rb_set_channel_value (ctx, "img", href_value);
-					}
-				}
-
-				ctx->state = RB_PODCAST_PARSER_STATE_IMG;
-
-			} else if (!strcmp (name, "item")) {
-				ctx->item_data = rb_podcast_initializa_item ();
-				ctx->state = RB_PODCAST_PARSER_STATE_ITEM;
-			} else if (!rb_validate_channel_propert (name)) {
-				rb_debug ("Unknown property");
-				ctx->in_unknown_elt++;
-			} else {
-				ctx->state = RB_PODCAST_PARSER_STATE_CHANNEL_PROPERTY;
-			}
-
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_ITEM:
-		{
-			if (!strcmp (name, "enclosure")) {
-				for (; *attrs; attrs +=2) {
-					if (!strcmp (*attrs, "url")) {
-						const char *url_value = *(attrs + 1);
-						rb_set_item_value (ctx, "url", url_value);
-					} else if (!strcmp (*attrs, "length")) {
-						const char *length_value = *(attrs + 1);
-						rb_set_item_value (ctx, "length", length_value);
-					}
-				}
-
-				ctx->state = RB_PODCAST_PARSER_STATE_ITEM_PROPERTY;
-
-			} else if (!rb_validate_item_propert (name)) {
-				ctx->in_unknown_elt++;
-			} else {
-				ctx->state = RB_PODCAST_PARSER_STATE_ITEM_PROPERTY;
-			}
-
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_IMG:
-		{
-			if (strcmp (name, "url") != 0) {
-				ctx->in_unknown_elt++;
-			} else {
-				ctx->state = RB_PODCAST_PARSER_STATE_IMG_PROPERTY;
-			}
-
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_CHANNEL_PROPERTY:
-        case RB_PODCAST_PARSER_STATE_ITEM_PROPERTY:
-        case RB_PODCAST_PARSER_STATE_IMG_PROPERTY:
-		rb_debug ("nested element inside property; treating as unknown");
-		ctx->in_unknown_elt++;
-		break;
-
-        case RB_PODCAST_PARSER_STATE_END:
-		break;
-	default:
-		g_warning ("Unknown podcast parser state: %d", ctx->state);
-		break;
+	if (strcmp (key, TOTEM_PL_PARSER_FIELD_TITLE) == 0) {
+		item->title = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_URL) == 0) {
+		item->url = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_DESCRIPTION) == 0) {
+		item->description = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_AUTHOR) == 0) {
+		item->author = g_strdup (value);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_PUB_DATE) == 0) {
+		item->pub_date = totem_pl_parser_parse_date (value, FALSE);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_DURATION) == 0) {
+		item->duration = totem_pl_parser_parse_duration (value, FALSE);
+	} else if (strcmp (key, TOTEM_PL_PARSER_FIELD_FILESIZE) == 0) {
+		item->filesize = g_ascii_strtoull (value, NULL, 10);
 	}
 }
 
 static void
-rb_podcast_parser_end_element (struct RBPoadcastLoadContext *ctx,
-			       const char *name)
+entry_parsed (TotemPlParser *parser,
+	      const char *uri,
+	      GHashTable *metadata,
+	      gpointer data)
 {
-	rb_debug ("End element: %s state: %d", name, ctx->state);
+	RBPodcastChannel *channel = (RBPodcastChannel *) data;
+	RBPodcastItem *item;
 
-	if (ctx->in_unknown_elt > 0) {
-		ctx->in_unknown_elt--;
-		rb_debug ("Unknown element");
-		return;
-	}
-
-	switch (ctx->state) {
-        case RB_PODCAST_PARSER_STATE_START:
-		ctx->state = RB_PODCAST_PARSER_STATE_END;
-		break;
-
-        case RB_PODCAST_PARSER_STATE_RSS:
-		ctx->state = RB_PODCAST_PARSER_STATE_START;
-		break;
-
-        case RB_PODCAST_PARSER_STATE_CHANNEL:
-		ctx->state = RB_PODCAST_PARSER_STATE_RSS;
-		break;
-
-        case RB_PODCAST_PARSER_STATE_CHANNEL_PROPERTY:
-		{
-			rb_set_channel_value (ctx, name, ctx->prop_value->str);
-			ctx->state = RB_PODCAST_PARSER_STATE_CHANNEL;
-			g_string_truncate (ctx->prop_value, 0);
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_ITEM:
-		{
-			rb_insert_item (ctx);
-			ctx->state = RB_PODCAST_PARSER_STATE_CHANNEL;
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_ITEM_PROPERTY:
-		{
-			rb_set_item_value (ctx, name, ctx->prop_value->str);
-			ctx->state = RB_PODCAST_PARSER_STATE_ITEM;
-			g_string_truncate (ctx->prop_value, 0);
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_IMG_PROPERTY:
-		{
-			rb_set_channel_value (ctx, "img", ctx->prop_value->str);
-			ctx->state = RB_PODCAST_PARSER_STATE_IMG;
-			g_string_truncate (ctx->prop_value, 0);
-			break;
-		}
-
-        case RB_PODCAST_PARSER_STATE_IMG:
-		ctx->state = RB_PODCAST_PARSER_STATE_CHANNEL;
-		break;
-
-        case RB_PODCAST_PARSER_STATE_END:
-		break;
-
-	default:
-		g_warning ("Unknown podcast parser state: %d", ctx->state);
-		break;
-	}
+	item = g_new0 (RBPodcastItem, 1);
+	g_hash_table_foreach (metadata, (GHFunc) entry_metadata_foreach, item);
+	channel->posts = g_list_prepend (channel->posts, item);
 }
 
-static void
-rb_podcast_parser_characters (struct RBPoadcastLoadContext *ctx,
-			      const char *data,
-			      guint len)
-{
-	switch (ctx->state) {
-        case RB_PODCAST_PARSER_STATE_CHANNEL_PROPERTY:
-        case RB_PODCAST_PARSER_STATE_ITEM_PROPERTY:
-        case RB_PODCAST_PARSER_STATE_IMG_PROPERTY:
-		g_string_append_len (ctx->prop_value, data, len);
-           	break;
-        case RB_PODCAST_PARSER_STATE_START:
-        case RB_PODCAST_PARSER_STATE_IMG:
-        case RB_PODCAST_PARSER_STATE_RSS:
-        case RB_PODCAST_PARSER_STATE_CHANNEL:
-        case RB_PODCAST_PARSER_STATE_ITEM:
-        case RB_PODCAST_PARSER_STATE_END:
-		break;
-	default:
-		g_warning ("Unknown podcast parser state: %d", ctx->state);
-		break;
-	}
-}
-
 gboolean
 rb_podcast_parse_load_feed (RBPodcastChannel *data,
 			    const char *file_name)
 {
-	xmlParserCtxtPtr parser;
-	xmlSAXHandlerPtr sax_handler = NULL;
 	GnomeVFSResult result;
 	GnomeVFSFileInfo *info;
-	gint file_size;
-	gchar *buffer = NULL;
-	const char *query_string;
+	TotemPlParser *plparser;
 
-	struct RBPoadcastLoadContext *ctx = NULL;
+	data->url = g_strdup (file_name);
 
-	data->url = xmlCharStrdup (file_name);
-
-	/* if the URL has a .rss or .xml extension (before the query string),
+	/* if the URL has a .rss, .xml or .atom extension (before the query string),
 	 * don't bother checking the MIME type.
 	 */
-	query_string = strchr (file_name, '?');
-	if (query_string == NULL) {
-		query_string = file_name + strlen (file_name);
-	}
-
-	if (strncmp (query_string - 4, ".rss", 4) == 0 ||
-	    strncmp (query_string - 4, ".xml", 4) == 0) {
-		rb_debug ("not checking mime type for %s", file_name);
+	if (rb_uri_could_be_podcast (file_name, &data->is_opml)) {
+		rb_debug ("not checking mime type for %s (should be %s file)", file_name,
+			  data->is_opml ? "OPML" : "Podcast");
 	} else {
 		gboolean invalid_mime_type;
 
@@ -451,22 +140,33 @@
 
 		result = gnome_vfs_get_file_info (file_name, info, GNOME_VFS_FILE_INFO_DEFAULT);
 
+		if ((result != GNOME_VFS_OK)) {
+			if (info->mime_type != NULL) {
+				rb_debug ("Invalid mime-type in podcast feed %s", info->mime_type);
+			} else {
+				rb_debug ("Couldn't get mime type for %s: %s", file_name,
+					  gnome_vfs_result_to_string (result));
+			}
+			gnome_vfs_file_info_unref (info);
+			return TRUE;
+		}
+
 		if (info != NULL
 		    && info->mime_type != NULL
 		    && strstr (info->mime_type, "html") == NULL
 		    && strstr (info->mime_type, "xml") == NULL
-		    && strstr (info->mime_type, "rss") == NULL) {
+		    && strstr (info->mime_type, "rss") == NULL
+		    && strstr (info->mime_type, "opml") == NULL) {
 			invalid_mime_type = TRUE;
+		} else if (info != NULL
+			   && info->mime_type != NULL
+			   && strstr (info->mime_type, "opml") != NULL) {
+			data->is_opml = TRUE;
+			invalid_mime_type = FALSE;
 		} else {
 			invalid_mime_type = FALSE;
 		}
 
-		if ((result != GNOME_VFS_OK)) {
-			rb_debug ("Invalid mime-type in podcast feed %s", info->mime_type);
-			gnome_vfs_file_info_unref (info);
-			return TRUE;
-		}
-
 		if (invalid_mime_type) {
 			GtkWidget *dialog;
 
@@ -492,173 +192,22 @@
 			return FALSE;
 	}
 
-	/* first download file by gnome_vfs for use gnome network configuration */
-	rb_debug ("reading podcast feed %s", file_name);
-	result = gnome_vfs_read_entire_file (file_name, &file_size, &buffer);
-	if (result != GNOME_VFS_OK)
-		return TRUE;
+	plparser = totem_pl_parser_new ();
+	g_object_set (plparser, "recurse", FALSE, NULL);
+	g_signal_connect (G_OBJECT (plparser), "entry-parsed", G_CALLBACK (entry_parsed), data);
+	g_signal_connect (G_OBJECT (plparser), "playlist-started", G_CALLBACK (playlist_started), data);
+	g_signal_connect (G_OBJECT (plparser), "playlist-ended", G_CALLBACK (playlist_ended), data);
 
-	/* initializing parse */
-	sax_handler = g_new0 (xmlSAXHandler, 1);
-	sax_handler->startElement = (startElementSAXFunc) rb_podcast_parser_start_element;
-	sax_handler->endElement = (endElementSAXFunc) rb_podcast_parser_end_element;
-	sax_handler->characters = (charactersSAXFunc) rb_podcast_parser_characters;
-	xmlSubstituteEntitiesDefault (1);
-
-	ctx = g_new0 (struct RBPoadcastLoadContext, 1);
-	ctx->in_unknown_elt = 0;
-	ctx->channel_data = data;
-	ctx->prop_value = g_string_sized_new (512);
-
-	parser = xmlCreateMemoryParserCtxt (buffer, file_size);
-	if (parser == NULL) {
-		g_free (sax_handler);
-		g_free (buffer);
-		g_string_free (ctx->prop_value, TRUE);
-		g_free (ctx);
+	if (totem_pl_parser_parse (plparser, file_name, FALSE) != TOTEM_PL_PARSER_RESULT_SUCCESS) {
+		rb_debug ("Parsing %s as a Podcast failed", file_name);
+		g_object_unref (plparser);
 		return FALSE;
 	}
+	rb_debug ("Parsing %s as a Podcast succeeded", file_name);
 
-	ctx->xmlctx = parser;
-	parser->userData = ctx;
-	parser->sax = sax_handler;
-	xmlParseDocument (parser);
-
-	g_free (sax_handler);
-	parser->sax = NULL;
-	xmlFreeParserCtxt (parser);
-
-	g_free (buffer);
-	g_string_free (ctx->prop_value, TRUE);
-	g_free (ctx);
-
-	data->posts = g_list_reverse (data->posts);
 	return TRUE;
 }
 
-static uintmax_t
-rb_podcast_parse_date (const char *date_str)
-{
-	struct tm tm;
-	char *result;
-
-	/* RFC 2822 date format */
-	result = strptime (date_str, "%a, %d %b %Y %T", &tm);
-
-	/* same as above, but without comma */
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		result = strptime (date_str, "%a %d %b %Y %T", &tm);
-	}
-
-	/* close-to-RFC 2822, but with extra 0 */
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		result = strptime (date_str, "%a, %d %b %Y 0%T", &tm);
-	}
-
-	/* close-to-RFC 2822, but with no seconds */
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		result = strptime (date_str, "%a, %d %b %Y %R", &tm);
-	}
-
-	/* format without weekday */
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		result = strptime (date_str, "%d %b %Y %T", &tm);
-	}
-
-	/* reversed day and long month */
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		result = strptime (date_str, "%a, %B %d %Y %T", &tm);
-	}
-
-	/* ISO date like */
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		result = strptime (date_str, "%Y-%m-%d %T", &tm);
-	}
-
-	/* ISO date like without timezone */
-	if (result == NULL) {
-	memset (&tm, 0, sizeof (struct tm));
-		result = strptime (date_str, "%Y-%m-%d", &tm);
-	}
-
-	/* Broken weekday short names */
-	if (result == NULL) {
-		char *tmp;
-
-		/* strip off the erroneous weekday */
-		tmp = strstr (date_str, ",");
-		if (tmp != NULL) {
-			tmp++;
-			memset (&tm, 0, sizeof (struct tm));
-			result = strptime (tmp, "%d %b %Y %T", &tm);
-		}
-	}
-
-	/* format with timezone offset from GMT */
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		result = strptime (date_str, "%a %b %d %T %z %Y", &tm);
-	}
-
-	/* format with timezone name */
-	if (result == NULL) {
-		char *tmp;
-
-		memset (&tm, 0, sizeof (struct tm));
-
-		/* match first part of time string */
-		result = strptime (date_str, "%a %b %d %T ", &tm);
-
-		/* look for anything with a timezone name-like format
-		   i.e. at least one all caps alphabetical character */
-		if (result != NULL) {
-			size_t n;
-
-			n = strspn(result, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
-			tmp = result+n;
-
-			/* make sure there was at least one character that matched */
-			if ((tmp != NULL) && n > 0)
-				/* remaining part must be the year */
-				result = strptime (tmp, "%Y", &tm);
-			else
-				result = NULL;
-		}
-	}
-
-	if (result == NULL) {
-		rb_debug ("unable to convert date string %s", date_str);
-	}
-
-	return (uintmax_t) ( (result==NULL) ? 0 : mktime (&tm) );
-}
-
-static gulong
-rb_podcast_parse_time (const char *time_str)
-{
-	struct tm tm;
-	char *result;
-
-	memset (&tm, 0, sizeof (struct tm));
-	result = strptime (time_str, "%H:%M:%S", &tm);
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		result = strptime (time_str, "%M:%S", &tm);
-	}
-	if (result == NULL) {
-		memset (&tm, 0, sizeof (struct tm));
-		rb_debug ("unable to convert duration string %s", time_str);
-	}
-
-	return ((tm.tm_hour * 60 + tm.tm_min) * 60 + tm.tm_sec);
-}
-
 void
 rb_podcast_parse_channel_free (RBPodcastChannel *data)
 {
@@ -671,8 +220,6 @@
 	g_free (data->url);
 	g_free (data->title);
 	g_free (data->lang);
-	g_free (data->subtitle);
-	g_free (data->summary);
 	g_free (data->description);
 	g_free (data->author);
 	g_free (data->contact);
Index: podcast/Makefile.am
===================================================================
--- podcast/Makefile.am	(revision 5413)
+++ podcast/Makefile.am	(working copy)
@@ -6,6 +6,9 @@
 	rb-podcast-parse.c				\
 	rb-podcast-parse.h
 
+librbpodcast_parse_la_LIBADD =				\
+	$(top_builddir)/lib/librb.la
+
 librbpodcast_la_SOURCES =				\
 	rb-feed-podcast-properties-dialog.c		\
 	rb-feed-podcast-properties-dialog.h		\
@@ -23,7 +26,8 @@
 	test-podcast-parse.c
 test_podcast_parse_LDADD =				\
 	librbpodcast_parse.la				\
-	$(RHYTHMBOX_LIBS)
+	$(RHYTHMBOX_LIBS)				\
+	$(TOTEM_PLPARSER_LIBS)
 
 INCLUDES =						\
 	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"        \
@@ -36,7 +40,8 @@
 	-I$(top_srcdir)/metadata			\
 	-I$(top_srcdir)/library				\
 	-I$(top_builddir)/lib 				\
-	$(RHYTHMBOX_CFLAGS)
+	$(RHYTHMBOX_CFLAGS)				\
+	$(TOTEM_PLPARSER_CFLAGS)
 
 librbpodcast_la_LDFLAGS = -export-dynamic
 
Index: podcast/rb-podcast-parse.h
===================================================================
--- podcast/rb-podcast-parse.h	(revision 5413)
+++ podcast/rb-podcast-parse.h	(working copy)
@@ -23,36 +23,34 @@
 #define RB_PODCAST_PARSE_H
 
 #include <glib.h>
-#include <libxml/xmlstring.h>
-#include <inttypes.h>
 
 typedef struct
 {
-	xmlChar* title;
-	xmlChar* url;
-	xmlChar* description;
-	xmlChar* author;
-	uintmax_t pub_date;
+	char* title;
+	char* url;
+	char* description;
+	char* author;
+	guint64 pub_date;
 	gulong duration;
 	guint64 filesize;
-}RBPodcastItem;
+} RBPodcastItem;
 
 typedef struct
 {
-	xmlChar* url;
-	xmlChar* title;
-	xmlChar* lang;
-    	xmlChar* subtitle;
-    	xmlChar* summary;
-	xmlChar* description;
-	xmlChar* author;
-	xmlChar* contact;
-	xmlChar* img;
-	uintmax_t pub_date;
-    	xmlChar* copyright;
+	char* url;
+	char* title;
+	char* lang;
+    	char* description;
+	char* author;
+	char* contact;
+	char* img;
+	guint64 pub_date;
+    	char* copyright;
 
+    	gboolean is_opml;
+
 	GList *posts;
-}RBPodcastChannel;
+} RBPodcastChannel;
 
 gboolean rb_podcast_parse_load_feed	(RBPodcastChannel *data, const char *file_name);
 void rb_podcast_parse_channel_free 	(RBPodcastChannel *data);
Index: configure.ac
===================================================================
--- configure.ac	(revision 5413)
+++ configure.ac	(working copy)
@@ -34,7 +34,7 @@
 LIBGPOD_REQS=0.4
 MUSICBRAINZ_REQS=2.1.0
 NCB_MIN_REQS=2.9.0
-TOTEM_PLPARSER_REQS=1.1.5
+TOTEM_PLPARSER_REQS=2.21.0
 VALA_REQS=0.0.8
 
 AC_MSG_CHECKING([for GNU extension fwrite_unlocked])
Index: lib/rb-file-helpers.c
===================================================================
--- lib/rb-file-helpers.c	(revision 5413)
+++ lib/rb-file-helpers.c	(working copy)
@@ -774,6 +774,65 @@
 	return g_utf8_strrchr (text_uri, -1, GNOME_VFS_URI_PATH_CHR)[1] == '.';
 }
 
+gboolean
+rb_uri_could_be_podcast (const char *uri, gboolean *is_opml)
+{
+	const char *query_string;
+
+	if (is_opml != NULL)
+		*is_opml = FALSE;
+
+	/* Check the scheme is a possible one first */
+	if (g_str_has_prefix (uri, "http") == FALSE &&
+	    g_str_has_prefix (uri, "itpc:") == FALSE &&
+	    g_str_has_prefix (uri, "itms:") == FALSE) {
+	    	rb_debug ("'%s' can't be a Podcast or OPML file, not the right scheme", uri);
+	    	return FALSE;
+	}
+
+	/* Now, check whether the iTunes Music Store link
+	 * is a podcast */
+	if (g_str_has_prefix (uri, "itms:") != FALSE
+	    && strstr (uri, "phobos.apple.com") != NULL
+	    && strstr (uri, "viewPodcast") != NULL)
+		return TRUE;
+
+	query_string = strchr (uri, '?');
+	if (query_string == NULL) {
+		query_string = uri + strlen (uri);
+	}
+
+	/* FIXME hacks */
+	if (strstr (uri, "rss") != NULL ||
+	    strstr (uri, "atom") != NULL ||
+	    strstr (uri, "feed") != NULL) {
+	    	rb_debug ("'%s' should be Podcast file, HACK", uri);
+	    	return TRUE;
+	} else if (strstr (uri, "opml") != NULL) {
+		rb_debug ("'%s' should be an OPML file, HACK", uri);
+		if (is_opml != NULL)
+			*is_opml = TRUE;
+		return TRUE;
+	}
+
+	if (strncmp (query_string - 4, ".rss", 4) == 0 ||
+	    strncmp (query_string - 4, ".xml", 4) == 0 ||
+	    strncmp (query_string - 5, ".atom", 5) == 0 ||
+	    strncmp (uri, "itpc", 4) == 0 ||
+	    (strstr (uri, "phobos.apple.com/") != NULL && strstr (uri, "viewPodcast") != NULL) ||
+	    strstr (uri, "itunes.com/podcast") != NULL) {
+	    	rb_debug ("'%s' should be Podcast file", uri);
+	    	return TRUE;
+	} else if (strncmp (query_string - 5, ".opml", 5) == 0) {
+		rb_debug ("'%s' should be an OPML file", uri);
+		if (is_opml != NULL)
+			*is_opml = TRUE;
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 char *
 rb_uri_make_hidden (const char *text_uri)
 {
Index: lib/rb-file-helpers.h
===================================================================
--- lib/rb-file-helpers.h	(revision 5413)
+++ lib/rb-file-helpers.h	(working copy)
@@ -44,6 +44,7 @@
 gboolean	rb_uri_is_writable	(const char *uri);
 gboolean	rb_uri_is_local		(const char *uri);
 gboolean	rb_uri_is_hidden	(const char *uri);
+gboolean	rb_uri_could_be_podcast (const char *uri, gboolean *is_opml);
 char *		rb_uri_make_hidden      (const char *uri);
 char *		rb_uri_get_dir_name	(const char *uri);
 char *		rb_uri_get_short_path_name (const char *uri);
Index: shell/rb-shell.c
===================================================================
--- shell/rb-shell.c	(revision 5413)
+++ shell/rb-shell.c	(working copy)
@@ -3202,20 +3205,11 @@
 	gboolean source_is_entry;
 } PlaylistParseData;
 
-#if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
 static void
 handle_playlist_entry_cb (TotemPlParser *playlist,
 			  const char *uri,
 			  GHashTable *metadata,
 			  PlaylistParseData *data)
-#else
-static void
-handle_playlist_entry_cb (TotemPlParser *playlist,
-			  const char *uri,
-			  const char *title,
-			  const char *genre,
-			  PlaylistParseData *data)
-#endif /* TOTEM_PL_PARSER_CHECK_VERSION */
 {
 	RBSource *source;
 
@@ -3264,6 +3258,14 @@
 	entry = rhythmdb_entry_lookup_by_location (shell->priv->db, uri);
 	playlist_source = NULL;
 
+	/* If the URI points to a Podcast, pass it on to
+	 * the Podcast source */
+	if (rb_uri_could_be_podcast (uri, NULL)) {
+		rb_podcast_source_add_feed (shell->priv->podcast_source, uri);
+		rb_shell_select_source (shell, RB_SOURCE (shell->priv->podcast_source));
+		return TRUE;
+	}
+
 	if (entry == NULL) {
 		TotemPlParser *parser;
 		TotemPlParserResult result;
@@ -3277,15 +3279,9 @@
 		rb_debug ("adding uri %s, play %d", uri, play);
 		parser = totem_pl_parser_new ();
 
-#if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
 		g_signal_connect_data (G_OBJECT (parser), "entry-parsed",
 				       G_CALLBACK (handle_playlist_entry_cb),
 				       &data, NULL, 0);
-#else
-		g_signal_connect_data (G_OBJECT (parser), "entry",
-				       G_CALLBACK (handle_playlist_entry_cb),
-				       &data, NULL, 0);
-#endif /* TOTEM_PL_PARSER_CHECK_VERSION */
 
 		totem_pl_parser_add_ignored_mimetype (parser, "x-directory/normal");
 		if (g_object_class_find_property (G_OBJECT_GET_CLASS (parser), "recurse"))
Index: shell/rb-playlist-manager.c
===================================================================
--- shell/rb-playlist-manager.c	(revision 5413)
+++ shell/rb-playlist-manager.c	(working copy)
@@ -502,20 +502,11 @@
 	return quark;
 }
 
-#if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
 static void
 handle_playlist_entry_cb (TotemPlParser *playlist,
 			  const char *uri_maybe,
 			  GHashTable *metadata,
 			  RBPlaylistManager *mgr)
-#else
-static void
-handle_playlist_entry_cb (TotemPlParser *playlist,
-			  const char *uri_maybe,
-			  const char *title,
-			  const char *genre,
-			  RBPlaylistManager *mgr)
-#endif /* TOTEM_PL_PARSER_CHECK_VERSION */
 {
 	char *uri;
 #if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
@@ -550,19 +541,29 @@
 }
 
 static void
-playlist_load_start_cb (TotemPlParser *parser, const char *title, RBPlaylistManager *mgr)
+playlist_load_started_cb (TotemPlParser *parser, const char *uri, GHashTable *metadata, RBPlaylistManager *mgr)
 {
-	rb_debug ("loading new playlist %s", title);
+	const char *title;
 
+	rb_debug ("loading new playlist %s", uri);
+
+	title = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_TITLE);
+	if (title == NULL)
+		title = _("Unnamed playlist");
+
 	mgr->priv->loading_playlist =
 			RB_STATIC_PLAYLIST_SOURCE (rb_playlist_manager_new_playlist (mgr, title, FALSE));
 }
 
 static void
-playlist_load_end_cb (TotemPlParser *parser, const char *title, RBPlaylistManager *mgr)
+playlist_load_ended_cb (TotemPlParser *parser, const char *uri, GHashTable *metadata, RBPlaylistManager *mgr)
 {
-	rb_debug ("finished loading playlist %s", title);
+	const char *title;
 
+	rb_debug ("finished loading playlist %s", uri);
+
+	title = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_TITLE);
+
 	if (title) {
 		g_object_set (mgr->priv->loading_playlist, "name", title, NULL);
 		mgr->priv->loading_playlist = NULL;
@@ -591,22 +592,16 @@
 	{
 		TotemPlParser *parser = totem_pl_parser_new ();
 
-#if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
 		g_signal_connect_object (parser, "entry-parsed",
 					 G_CALLBACK (handle_playlist_entry_cb),
 					 mgr, 0);
-#else
-		g_signal_connect_object (parser, "entry",
-					 G_CALLBACK (handle_playlist_entry_cb),
-					 mgr, 0);
-#endif /* TOTEM_PL_PARSER_CHECK_VERSION */
 
-		g_signal_connect_object (parser, "playlist-start",
-					 G_CALLBACK (playlist_load_start_cb),
+		g_signal_connect_object (parser, "playlist-started",
+					 G_CALLBACK (playlist_load_started_cb),
 					 mgr, 0);
 
-		g_signal_connect_object (parser, "playlist-end",
-					 G_CALLBACK (playlist_load_end_cb),
+		g_signal_connect_object (parser, "playlist-ended",
+					 G_CALLBACK (playlist_load_ended_cb),
 					 mgr, 0);
 
 		if (g_object_class_find_property (G_OBJECT_GET_CLASS (parser), "recurse"))
Index: shell/rb-shell-player.c
===================================================================
--- shell/rb-shell-player.c	(revision 5413)
+++ shell/rb-shell-player.c	(working copy)
@@ -1264,20 +1264,11 @@
 	PlaybackStartType play_type;
 } OpenLocationThreadData;
 
-#if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
 static void
 playlist_entry_cb (TotemPlParser *playlist,
 		   const char *uri,
 		   GHashTable *metadata,
 		   RBShellPlayer *player)
-#else
-static void
-playlist_entry_cb (TotemPlParser *playlist,
-		   const char *uri,
-		   const char *title,
-		   const char *genre,
-		   RBShellPlayer *player)
-#endif
 {
 	rb_debug ("adding stream url %s", uri);
 	g_queue_push_tail (player->priv->playlist_urls, g_strdup (uri));
@@ -1291,15 +1282,9 @@
 
 	playlist = totem_pl_parser_new ();
 
-#if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
 	g_signal_connect_data (G_OBJECT (playlist), "entry-parsed",
 			       G_CALLBACK (playlist_entry_cb),
 			       data->player, NULL, 0);
-#else
-	g_signal_connect_data (G_OBJECT (playlist), "entry",
-			       G_CALLBACK (playlist_entry_cb),
-			       data->player, NULL, 0);
-#endif /* TOTEM_PL_PARSER_CHECK_VERSION */
 
 	totem_pl_parser_add_ignored_mimetype (playlist, "x-directory/normal");
 
Index: data/rhythmbox.schemas
===================================================================
--- data/rhythmbox.schemas	(revision 5413)
+++ data/rhythmbox.schemas	(working copy)
@@ -136,9 +136,9 @@
 	<long>Main window X position.</long>
         </locale>
       </schema>
- 
 
-<schema>
+
+      <schema>
         <key>/schemas/apps/rhythmbox/state/window_position_y</key>
         <applyto>/apps/rhythmbox/state/window_position_y</applyto>
         <owner>rhythmbox</owner>
@@ -150,10 +150,7 @@
         </locale>
       </schema>
  
-
-
-
-<schema>
+      <schema>
         <key>/schemas/apps/rhythmbox/state/window_height</key>
         <applyto>/apps/rhythmbox/state/window_height</applyto>
         <owner>rhythmbox</owner>
@@ -439,6 +436,106 @@
         </locale>
       </schema>
       <schema>
+        <key>/schemas/desktop/gnome/url-handlers/itpc/command</key>
+	<applyto>/desktop/gnome/url-handlers/itpc/command</applyto>
+        <owner>rhythmbox</owner>
+        <type>string</type>
+        <default>rhythmbox "%s"</default>
+        <locale name="C">
+	  <short>The command to handle ITPC scheme URLs</short>
+	  <long>The command to handle ITPC scheme URLs.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/desktop/gnome/url-handlers/itpc/needs_terminal</key>
+	<applyto>/desktop/gnome/url-handlers/itpc/needs_terminal</applyto>
+        <owner>rhythmbox</owner>
+        <type>bool</type>
+        <default>false</default>
+        <locale name="C">
+	  <short>Whether command to handle ITPC scheme URLs needs a terminal</short>
+	  <long>Whether command to handle ITPC scheme URLs needs a terminal.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/desktop/gnome/url-handlers/itpc/enabled</key>
+	<applyto>/desktop/gnome/url-handlers/itpc/enabled</applyto>
+        <owner>rhythmbox</owner>
+        <type>bool</type>
+        <default>true</default>
+        <locale name="C">
+	  <short>Whether command to handle ITPC scheme URLs is enabled</short>
+	  <long>Whether command to handle ITPC scheme URLs is enabled.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/desktop/gnome/url-handlers/itms/command</key>
+	<applyto>/desktop/gnome/url-handlers/itms/command</applyto>
+        <owner>rhythmbox</owner>
+        <type>string</type>
+        <default>rhythmbox "%s"</default>
+        <locale name="C">
+	  <short>The command to handle ITMS scheme URLs</short>
+	  <long>The command to handle ITMS scheme URLs.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/desktop/gnome/url-handlers/itms/needs_terminal</key>
+	<applyto>/desktop/gnome/url-handlers/itms/needs_terminal</applyto>
+        <owner>rhythmbox</owner>
+        <type>bool</type>
+        <default>false</default>
+        <locale name="C">
+	  <short>Whether command to handle ITMS scheme URLs needs a terminal</short>
+	  <long>Whether command to handle ITMS scheme URLs needs a terminal.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/desktop/gnome/url-handlers/itms/enabled</key>
+	<applyto>/desktop/gnome/url-handlers/itms/enabled</applyto>
+        <owner>rhythmbox</owner>
+        <type>bool</type>
+        <default>true</default>
+        <locale name="C">
+	  <short>Whether command to handle ITMS scheme URLs is enabled</short>
+	  <long>Whether command to handle ITMS scheme URLs is enabled.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/desktop/gnome/url-handlers/feed/command</key>
+	<applyto>/desktop/gnome/url-handlers/feed/command</applyto>
+        <owner>rhythmbox</owner>
+        <type>string</type>
+        <default>rhythmbox "%s"</default>
+        <locale name="C">
+	  <short>The command to handle FEED scheme URLs</short>
+	  <long>The command to handle FEED scheme URLs.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/desktop/gnome/url-handlers/feed/needs_terminal</key>
+	<applyto>/desktop/gnome/url-handlers/feed/needs_terminal</applyto>
+        <owner>rhythmbox</owner>
+        <type>bool</type>
+        <default>false</default>
+        <locale name="C">
+	  <short>Whether command to handle FEED scheme URLs needs a terminal</short>
+	  <long>Whether command to handle FEED scheme URLs needs a terminal.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/desktop/gnome/url-handlers/feed/enabled</key>
+	<applyto>/desktop/gnome/url-handlers/feed/enabled</applyto>
+        <owner>rhythmbox</owner>
+        <type>bool</type>
+        <default>true</default>
+        <locale name="C">
+	  <short>Whether command to handle FEED scheme URLs is enabled</short>
+	  <long>Whether command to handle FEED scheme URLs is enabled.</long>
+        </locale>
+      </schema>
+
+      <schema>
         <key>/schemas/apps/rhythmbox/state/podcast/show_browser</key>
         <applyto>/apps/rhythmbox/state/podcast/show_browser</applyto>
         <owner>rhythmbox</owner>

rhythmbox-0.11.2-dont-escape-primary-in-notifications.patch:

Index: rhythmbox-0.11.2-dont-escape-primary-in-notifications.patch
===================================================================
RCS file: /cvs/pkgs/rpms/rhythmbox/devel/rhythmbox-0.11.2-dont-escape-primary-in-notifications.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- rhythmbox-0.11.2-dont-escape-primary-in-notifications.patch	11 Oct 2007 15:36:03 -0000	1.1
+++ rhythmbox-0.11.2-dont-escape-primary-in-notifications.patch	29 Oct 2007 13:39:37 -0000	1.2
@@ -43,3 +43,65 @@
  
  	if (title != NULL)
  		shell->priv->cached_notify_primary = title;
+Index: shell/rb-shell.c
+===================================================================
+--- shell/rb-shell.c	(revision 5414)
++++ shell/rb-shell.c	(working copy)
+@@ -1964,7 +1964,7 @@
+ 
+ 	rb_shell_notify_playing_entry (shell, entry, FALSE);
+ 
+-	rb_tray_icon_set_tooltip_primary_markup (shell->priv->tray_icon, shell->priv->cached_notify_primary);
++	rb_tray_icon_set_tooltip_primary_text (shell->priv->tray_icon, shell->priv->cached_notify_primary);
+ 	rb_tray_icon_set_tooltip_icon (shell->priv->tray_icon, shell->priv->cached_art_icon);
+ 	rb_shell_update_tray_tooltip_elapsed (shell);
+ }
+@@ -2044,7 +2044,7 @@
+ 	 */
+ 	entry = rb_shell_player_get_playing_entry (shell->priv->player_shell);
+ 	rb_shell_construct_notify_titles (shell, entry);
+-	rb_tray_icon_set_tooltip_primary_markup (shell->priv->tray_icon, shell->priv->cached_notify_primary);
++	rb_tray_icon_set_tooltip_primary_text (shell->priv->tray_icon, shell->priv->cached_notify_primary);
+ 	rb_shell_update_tray_tooltip_elapsed (shell);
+ 	
+ 	if (entry)
+Index: shell/rb-tray-icon.c
+===================================================================
+--- shell/rb-tray-icon.c	(revision 5414)
++++ shell/rb-tray-icon.c	(working copy)
+@@ -640,16 +640,16 @@
+ }
+ 
+ void
+-rb_tray_icon_set_tooltip_primary_markup (RBTrayIcon *icon,
+-					 const char *primary_markup)
++rb_tray_icon_set_tooltip_primary_text (RBTrayIcon *icon,
++				       const char *primary_text)
+ {
+ 	/* hide, then reshow in the right position & size */
+ 	gtk_widget_hide (icon->priv->tooltip);
+ 
+-	if (primary_markup == NULL)
+-		primary_markup = TRAY_ICON_DEFAULT_TOOLTIP;
+-	gtk_label_set_markup (GTK_LABEL (icon->priv->tooltip_primary),
+-			      primary_markup);
++	if (primary_text == NULL)
++		primary_text = TRAY_ICON_DEFAULT_TOOLTIP;
++	gtk_label_set_text (GTK_LABEL (icon->priv->tooltip_primary),
++			    primary_text);
+ 
+ 	if (icon->priv->tooltip_unhide_id > 0)
+ 		g_source_remove (icon->priv->tooltip_unhide_id);
+Index: shell/rb-tray-icon.h
+===================================================================
+--- shell/rb-tray-icon.h	(revision 5414)
++++ shell/rb-tray-icon.h	(working copy)
+@@ -66,7 +66,7 @@
+ 
+ void                    rb_tray_icon_cancel_notify (RBTrayIcon *icon);
+ 
+-void rb_tray_icon_set_tooltip_primary_markup (RBTrayIcon *icon, const char *primary_markup);
++void rb_tray_icon_set_tooltip_primary_text (RBTrayIcon *icon, const char *primary_text);
+ void rb_tray_icon_set_tooltip_icon (RBTrayIcon *icon, GtkWidget *msgicon);
+ void rb_tray_icon_set_tooltip_secondary_markup (RBTrayIcon *icon, const char *secondary_markup);
+ 


Index: rhythmbox.spec
===================================================================
RCS file: /cvs/pkgs/rpms/rhythmbox/devel/rhythmbox.spec,v
retrieving revision 1.138
retrieving revision 1.139
diff -u -r1.138 -r1.139
--- rhythmbox.spec	23 Oct 2007 02:00:00 -0000	1.138
+++ rhythmbox.spec	29 Oct 2007 13:39:37 -0000	1.139
@@ -3,7 +3,7 @@
 Name: rhythmbox
 Summary: Music Management Application 
 Version: 0.11.2
-Release: 11%{?dist}
+Release: 12%{?dist}
 License: GPLv2+ and GFDL+
 Group: Applications/Multimedia
 URL: http://www.gnome.org/projects/rhythmbox/
@@ -50,7 +50,14 @@
 Patch1: rhythmbox-upnp-assert.patch
 Patch2: rhythmbox-enable-stores.patch
 Patch3: rhythmbox-0.11.2-make-gpm-plugin-work.patch
+# http://bugzilla.gnome.org/show_bug.cgi?id=487415
 Patch4: rhythmbox-0.11.2-dont-escape-primary-in-notifications.patch
+# http://bugzilla.gnome.org/show_bug.cgi?id=445659
+Patch5: rb-disable-local-uri-escaping-5.patch
+# http://bugzilla.gnome.org/show_bug.cgi?id=346434
+Patch6: rb-delete-ipod-tracks.patch
+# http://bugzilla.gnome.org/show_bug.cgi?id=484768
+Patch7: rb-use-newer-plparser-7.patch
 
 %description
 Rhythmbox is an integrated music management application based on the powerful
@@ -90,6 +97,12 @@
 pushd shell/
 %patch4 -p0 -b .notification-markup
 popd
+%patch5 -p0 -b .files-uri-escaping
+pushd plugins/ipod/
+%patch6 -p0 -b .ipod-trash
+popd
+%patch7 -p0 -b .podcast
+
 
 %build
 
@@ -201,6 +214,14 @@
 %{_libdir}/rhythmbox/plugins/upnp_coherence
 
 %changelog
+* Mon Oct 29 2007 - Bastien Nocera <bnocera at redhat.com> - 0.11.2-12
+- Update patch for #242260, tooltips weren't working
+- Add patch to fix problems importing files with spaces in them (#291571)
+- Add patch to remove iPod tracks when removed, rather than put them
+  in the trash (#330101)
+- Add upstream patch to support new playlist parser in Totem, and add
+  better Podcast support, as well as iTunes podcast support
+
 * Mon Oct 22 2007  Matthias Clasen <mclasen at redhat.com> - 0.11.2-11
 - Rebuild against new dbus-glib
 




More information about the fedora-extras-commits mailing list