[totem-pl-parser] Add Genre extension to XSPF playlists



commit 99d25e17e008fa0b6ecd92cf460a9492058a4853
Author: Bastien Nocera <hadess hadess net>
Date:   Sun Jul 18 03:01:30 2010 +0100

    Add Genre extension to XSPF playlists
    
    Both reading and writing, including test.

 plparse/tests/Makefile.am      |    3 +-
 plparse/tests/parser.c         |   42 ++++++++++++++++++++++++++++++++++++++++
 plparse/tests/playlist.xspf    |   14 +++++++++++++
 plparse/totem-pl-parser-xspf.c |   37 +++++++++++++++++++++++++++++-----
 4 files changed, 89 insertions(+), 7 deletions(-)
---
diff --git a/plparse/tests/Makefile.am b/plparse/tests/Makefile.am
index e6fd73f..2cea063 100644
--- a/plparse/tests/Makefile.am
+++ b/plparse/tests/Makefile.am
@@ -55,4 +55,5 @@ EXTRA_DIST =			\
 	asf-with-asx-suffix.asx	\
 	remote_xspf.php		\
 	HackerMedley		\
-	missing-items.pls
+	missing-items.pls	\
+	playlist.xspf
diff --git a/plparse/tests/parser.c b/plparse/tests/parser.c
index ec8fc54..9d24989 100644
--- a/plparse/tests/parser.c
+++ b/plparse/tests/parser.c
@@ -369,6 +369,47 @@ simple_parser_test (const char *uri)
 }
 
 static void
+entry_parsed_genre_cb (TotemPlParser *parser,
+		 const char *uri,
+		 GHashTable *metadata,
+		 char **ret)
+{
+	if (*ret == NULL)
+		*ret = g_strdup (g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_GENRE));
+}
+
+static char *
+parser_test_get_parse_genre (const char *uri)
+{
+	TotemPlParserResult retval;
+	char *ret = NULL;
+	TotemPlParser *pl = totem_pl_parser_new ();
+
+	g_object_set (pl, "recurse", !option_no_recurse,
+			  "debug", option_debug,
+			  "force", option_force,
+			  "disable-unsafe", option_disable_unsafe,
+			  NULL);
+	g_signal_connect (G_OBJECT (pl), "entry-parsed",
+			  G_CALLBACK (entry_parsed_genre_cb), &ret);
+
+	retval = totem_pl_parser_parse_with_base (pl, uri, option_base_uri, FALSE);
+	g_test_message ("Got retval %d for uri '%s'", retval, uri);
+	g_object_unref (pl);
+
+	return ret;
+}
+
+static void
+test_parsing_xspf_genre (void)
+{
+	char *uri;
+	uri = get_relative_uri (TEST_SRCDIR "playlist.xspf");
+	g_assert_cmpstr (parser_test_get_parse_genre (uri), ==, "Test Genre");
+	g_free (uri);
+}
+
+static void
 test_parsing_rtsp_text_multi (void)
 {
 	char *uri;
@@ -691,6 +732,7 @@ main (int argc, char *argv[])
 		g_test_add_func ("/parser/parsing/not_really_php", test_parsing_not_really_php);
 		g_test_add_func ("/parser/parsing/not_really_php_but_html_instead", test_parsing_not_really_php_but_html_instead);
 		g_test_add_func ("/parser/parsing/num_items_in_pls", test_parsing_num_entries);
+		g_test_add_func ("/parser/parsing/xspf_genre", test_parsing_xspf_genre);
 
 		return g_test_run ();
 	}
diff --git a/plparse/tests/playlist.xspf b/plparse/tests/playlist.xspf
new file mode 100644
index 0000000..543780d
--- /dev/null
+++ b/plparse/tests/playlist.xspf
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<playlist version="1" xmlns="http://xspf.org/ns/0/";>
+  <creator>audacious-plugins-1.4.5</creator>
+  <trackList>
+    <track>
+      <location>http://207.200.96.226:8000</location>
+      <title>Sven Van Hess - Ocean Jive (Groove Salad: a nicely chilled plate of ambient beats and grooves. [SomaFM])</title>
+      <meta rel="mtime">0</meta>
+      <extension application="http://www.rhythmbox.org";>
+        <genre>Test Genre</genre>
+      </extension>
+    </track>
+  </trackList>
+</playlist>
diff --git a/plparse/totem-pl-parser-xspf.c b/plparse/totem-pl-parser-xspf.c
index 2666a1d..647b57c 100644
--- a/plparse/totem-pl-parser-xspf.c
+++ b/plparse/totem-pl-parser-xspf.c
@@ -82,6 +82,7 @@ static struct {
 	{ TOTEM_PL_PARSER_FIELD_IMAGE_URI, "image" },
 	{ TOTEM_PL_PARSER_FIELD_ALBUM, "album" },
 	{ TOTEM_PL_PARSER_FIELD_DURATION_MS, "duration" },
+	{ TOTEM_PL_PARSER_FIELD_GENRE, NULL },
 };
 
 gboolean
@@ -160,10 +161,17 @@ totem_pl_parser_save_xspf (TotemPlParser    *parser,
 			g_free (str);
 			if (!escaped)
 				continue;
-			buf = g_strdup_printf ("   <%s>%s</%s>\n",
-					       fields[i].element,
-					       escaped,
-					       fields[i].element);
+			if (g_str_equal (fields[i].field, TOTEM_PL_PARSER_FIELD_GENRE) == FALSE) {
+				buf = g_strdup_printf ("   <%s>%s</%s>\n",
+						       fields[i].element,
+						       escaped,
+						       fields[i].element);
+			} else {
+				buf = g_strdup_printf ("   <extension application=\"http://www.rhythmbox.org\";>\n"
+						       "     <genre>%s</genre>\n"
+						       "   </extension>\n",
+						       escaped);
+			}
 
 			success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error);
 			g_free (buf);
@@ -199,11 +207,11 @@ parse_xspf_track (TotemPlParser *parser, GFile *base_file, xmlDocPtr doc,
 {
 	xmlNodePtr node;
 	xmlChar *title, *uri, *image_uri, *artist, *album, *duration, *moreinfo;
-	xmlChar *download_uri, *id;
+	xmlChar *download_uri, *id, *genre;
 	GFile *resolved;
 	char *resolved_uri;
 	TotemPlParserResult retval = TOTEM_PL_PARSER_RESULT_ERROR;
-	
+
 	title = NULL;
 	uri = NULL;
 	image_uri = NULL;
@@ -213,6 +221,7 @@ parse_xspf_track (TotemPlParser *parser, GFile *base_file, xmlDocPtr doc,
 	moreinfo = NULL;
 	download_uri = NULL;
 	id = NULL;
+	genre = NULL;
 
 	for (node = parent->children; node != NULL; node = node->next)
 	{
@@ -244,6 +253,20 @@ parse_xspf_track (TotemPlParser *parser, GFile *base_file, xmlDocPtr doc,
 				/* If we don't have a rel="", then it's not a last.fm playlist */
 				moreinfo = xmlNodeListGetString (doc, node->xmlChildrenNode, 1);
 			}
+		/* Parse the genre extension for Rhythmbox */
+		} else if (g_ascii_strcasecmp ((char *)node->name, "extension") == 0) {
+			xmlChar *app;
+			app = xmlGetProp (node, (const xmlChar *) "application");
+			if (app != NULL && g_ascii_strcasecmp ((char *) app, "http://www.rhythmbox.org";) == 0) {
+				xmlNodePtr child;
+				for (child = node->xmlChildrenNode ; child; child = child->next) {
+					if (child->name != NULL &&
+					    g_ascii_strcasecmp ((char *)child->name, "genre") == 0) {
+						genre = xmlNodeListGetString (doc, child->xmlChildrenNode, 0);
+						break;
+					}
+				}
+			}
 		} else if (g_ascii_strcasecmp ((char *)node->name, "album") == 0)
 			album = xmlNodeListGetString (doc, node->xmlChildrenNode, 1);
 		else if (g_ascii_strcasecmp ((char *)node->name, "trackauth") == 0)
@@ -269,6 +292,7 @@ parse_xspf_track (TotemPlParser *parser, GFile *base_file, xmlDocPtr doc,
 				 TOTEM_PL_PARSER_FIELD_MOREINFO, moreinfo,
 				 TOTEM_PL_PARSER_FIELD_DOWNLOAD_URI, download_uri,
 				 TOTEM_PL_PARSER_FIELD_ID, id,
+				 TOTEM_PL_PARSER_FIELD_GENRE, genre,
 				 NULL);
 	g_object_unref (resolved);
 
@@ -284,6 +308,7 @@ bail:
 	SAFE_FREE (moreinfo);
 	SAFE_FREE (download_uri);
 	SAFE_FREE (id);
+	SAFE_FREE (genre);
 
 	return retval;
 }



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