summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2007-10-24 10:27:36 +0000
committerBastien Nocera <hadess@src.gnome.org>2007-10-24 10:27:36 +0000
commitc3bff8894dfd3276a866a551aea9f3fdab028174 (patch)
treecf038d059a2d8aad65c240383f3c2e0ec7f363f5
parentc56f52520330598e6e7e4f1df69db43c597f7930 (diff)
downloadtotem-c3bff8894dfd3276a866a551aea9f3fdab028174.tar.gz
Add support for OPML feeds (Closes: #489519)
2007-10-24 Bastien Nocera <hadess@hadess.net> * src/plparse/totem-pl-parser-podcast.c: (totem_pl_parser_is_opml), (totem_pl_parser_is_xml_feed), (parse_rss_items), (totem_pl_parser_add_rss), (parse_opml_outline), (parse_opml_head_body), (totem_pl_parser_add_opml): * src/plparse/totem-pl-parser-podcast.h: * src/plparse/totem-pl-parser.c: (totem_pl_parser_ignore), (totem_pl_parser_ignore_from_mimetype), (totem_pl_parser_parse_internal), (totem_pl_parser_can_parse_from_data): Add support for OPML feeds (Closes: #489519) svn path=/trunk/; revision=4813
-rw-r--r--ChangeLog13
-rw-r--r--src/plparse/totem-pl-parser-podcast.c116
-rw-r--r--src/plparse/totem-pl-parser-podcast.h6
-rw-r--r--src/plparse/totem-pl-parser.c1
4 files changed, 136 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 60bf127fb..18787dc08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2007-10-24 Bastien Nocera <hadess@hadess.net>
+
+ * src/plparse/totem-pl-parser-podcast.c: (totem_pl_parser_is_opml),
+ (totem_pl_parser_is_xml_feed), (parse_rss_items),
+ (totem_pl_parser_add_rss), (parse_opml_outline),
+ (parse_opml_head_body), (totem_pl_parser_add_opml):
+ * src/plparse/totem-pl-parser-podcast.h:
+ * src/plparse/totem-pl-parser.c: (totem_pl_parser_ignore),
+ (totem_pl_parser_ignore_from_mimetype),
+ (totem_pl_parser_parse_internal),
+ (totem_pl_parser_can_parse_from_data): Add support for OPML feeds
+ (Closes: #489519)
+
2007-10-23 Philip Withnall <pwithnall@svn.gnome.org>
* src/Makefile.am:
diff --git a/src/plparse/totem-pl-parser-podcast.c b/src/plparse/totem-pl-parser-podcast.c
index ac9a39b22..4f708404c 100644
--- a/src/plparse/totem-pl-parser-podcast.c
+++ b/src/plparse/totem-pl-parser-podcast.c
@@ -94,12 +94,39 @@ totem_pl_parser_is_atom (const char *data, gsize len)
}
gboolean
+totem_pl_parser_is_opml (const char *data, gsize len)
+{
+ char *buffer;
+
+ if (len == 0)
+ return FALSE;
+ if (len > MIME_READ_CHUNK_SIZE)
+ len = MIME_READ_CHUNK_SIZE;
+
+ /* FIXME would be nicer to have an strnstr */
+ buffer = g_memdup (data, len);
+ if (buffer == NULL) {
+ g_warning ("Couldn't dup data in totem_pl_parser_is_opml");
+ return FALSE;
+ }
+ buffer[len - 1] = '\0';
+ if (strstr (buffer, "<opml ") != NULL) {
+ g_free (buffer);
+ return TRUE;
+ }
+ g_free (buffer);
+ return FALSE;
+}
+
+gboolean
totem_pl_parser_is_xml_feed (const char *data, gsize len)
{
if (totem_pl_parser_is_rss (data, len) != FALSE)
return TRUE;
if (totem_pl_parser_is_atom (data, len) != FALSE)
return TRUE;
+ if (totem_pl_parser_is_opml (data, len) != FALSE)
+ return TRUE;
return FALSE;
}
@@ -686,5 +713,94 @@ totem_pl_parser_is_itms_feed (const char *url)
return FALSE;
}
+static TotemPlParserResult
+parse_opml_outline (TotemPlParser *parser, xml_node_t *parent)
+{
+ xml_node_t* node;
+ const char *title, *url;
+
+ title = url = NULL;
+ for (node = parent->child; node != NULL; node = node->next) {
+ if (node->name == NULL || g_ascii_strcasecmp (node->name, "outline") != 0)
+ continue;
+
+ url = xml_parser_get_property (node, "xmlUrl");
+ title = xml_parser_get_property (node, "text");
+
+ if (url == NULL)
+ continue;
+
+ totem_pl_parser_add_url (parser,
+ TOTEM_PL_PARSER_FIELD_TITLE, title,
+ TOTEM_PL_PARSER_FIELD_URL, url,
+ NULL);
+ }
+
+ return TOTEM_PL_PARSER_RESULT_SUCCESS;
+}
+
+static TotemPlParserResult
+parse_opml_head_body (TotemPlParser *parser, const char *url, xml_node_t *parent)
+{
+ xml_node_t* node;
+ gboolean started;
+
+ started = FALSE;
+
+ for (node = parent->child; node != NULL; node = node->next) {
+ if (node->name == NULL)
+ continue;
+
+ if (g_ascii_strcasecmp (node->name, "body") == 0) {
+ if (started == FALSE) {
+ /* Send the info we already have about the feed */
+ totem_pl_parser_add_url (parser,
+ TOTEM_PL_PARSER_FIELD_IS_PLAYLIST, TRUE,
+ TOTEM_PL_PARSER_FIELD_URL, url,
+ NULL);
+ started = TRUE;
+ }
+
+ parse_opml_outline (parser, node);
+ }
+ }
+
+ return TOTEM_PL_PARSER_RESULT_SUCCESS;
+}
+
+TotemPlParserResult
+totem_pl_parser_add_opml (TotemPlParser *parser,
+ const char *url,
+ const char *base,
+ gpointer data)
+{
+ xml_node_t* doc;
+ char *contents;
+ int size;
+
+ if (gnome_vfs_read_entire_file (url, &size, &contents) != GNOME_VFS_OK)
+ return TOTEM_PL_PARSER_RESULT_ERROR;
+
+ xml_parser_init (contents, size, XML_PARSER_CASE_INSENSITIVE);
+ if (xml_parser_build_tree_with_options (&doc, XML_PARSER_RELAXED | XML_PARSER_MULTI_TEXT) < 0) {
+ g_free (contents);
+ return TOTEM_PL_PARSER_RESULT_ERROR;
+ }
+ /* If the document has no name */
+ if (doc->name == NULL
+ || g_ascii_strcasecmp (doc->name , "opml") != 0) {
+ g_free (contents);
+ xml_parser_free_tree (doc);
+ return TOTEM_PL_PARSER_RESULT_ERROR;
+ }
+
+ parse_opml_head_body (parser, url, doc);
+
+ g_free (contents);
+ xml_parser_free_tree (doc);
+
+ return TOTEM_PL_PARSER_RESULT_SUCCESS;
+}
+
#endif /* !TOTEM_PL_PARSER_MINI */
diff --git a/src/plparse/totem-pl-parser-podcast.h b/src/plparse/totem-pl-parser-podcast.h
index 2ca88acb3..be89c200f 100644
--- a/src/plparse/totem-pl-parser-podcast.h
+++ b/src/plparse/totem-pl-parser-podcast.h
@@ -32,6 +32,7 @@ G_BEGIN_DECLS
gboolean totem_pl_parser_is_rss (const char *data, gsize len);
gboolean totem_pl_parser_is_atom (const char *data, gsize len);
+gboolean totem_pl_parser_is_opml (const char *data, gsize len);
gboolean totem_pl_parser_is_xml_feed (const char *data, gsize len);
#ifndef TOTEM_PL_PARSER_MINI
@@ -57,6 +58,11 @@ TotemPlParserResult totem_pl_parser_add_itms (TotemPlParser *parser,
const char *url,
const char *base,
gpointer data);
+TotemPlParserResult totem_pl_parser_add_opml (TotemPlParser *parser,
+ const char *url,
+ const char *base,
+ gpointer data);
+
#endif /* !TOTEM_PL_PARSER_MINI */
G_END_DECLS
diff --git a/src/plparse/totem-pl-parser.c b/src/plparse/totem-pl-parser.c
index baa81ba1c..3a7fd9df5 100644
--- a/src/plparse/totem-pl-parser.c
+++ b/src/plparse/totem-pl-parser.c
@@ -964,6 +964,7 @@ static PlaylistTypes special_types[] = {
PLAYLIST_TYPE ("audio/x-iriver-pla", totem_pl_parser_add_pla, NULL, FALSE),
PLAYLIST_TYPE ("application/atom+xml", totem_pl_parser_add_atom, NULL, FALSE),
PLAYLIST_TYPE ("application/rss+xml", totem_pl_parser_add_rss, NULL, FALSE),
+ PLAYLIST_TYPE ("text/x-opml+xml", totem_pl_parser_add_opml, NULL, FALSE),
#ifndef TOTEM_PL_PARSER_MINI
PLAYLIST_TYPE ("application/x-desktop", totem_pl_parser_add_desktop, NULL, TRUE),
PLAYLIST_TYPE ("application/x-gnome-app-info", totem_pl_parser_add_desktop, NULL, TRUE),