diff options
author | Bastien Nocera <hadess@hadess.net> | 2007-10-24 10:27:36 +0000 |
---|---|---|
committer | Bastien Nocera <hadess@src.gnome.org> | 2007-10-24 10:27:36 +0000 |
commit | c3bff8894dfd3276a866a551aea9f3fdab028174 (patch) | |
tree | cf038d059a2d8aad65c240383f3c2e0ec7f363f5 | |
parent | c56f52520330598e6e7e4f1df69db43c597f7930 (diff) | |
download | totem-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-- | ChangeLog | 13 | ||||
-rw-r--r-- | src/plparse/totem-pl-parser-podcast.c | 116 | ||||
-rw-r--r-- | src/plparse/totem-pl-parser-podcast.h | 6 | ||||
-rw-r--r-- | src/plparse/totem-pl-parser.c | 1 |
4 files changed, 136 insertions, 0 deletions
@@ -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), |