Exemple #1
0
bool Downloader::ParseRSS(xmlDocPtr doc) {
	xmlXPathContextPtr xp_ctx = xmlXPathNewContext(doc);

	xmlXPathObjectPtr xpath_obj = xmlXPathEvalExpression(BAD_CAST "/rss/channel/item", xp_ctx);

	bool ok = false;

	if (xpath_obj->nodesetval) {

		wxDateTime time;
		wxString md5;
		wxString version;
		wxString url;

		for (int i = 0; i < xpath_obj->nodesetval->nodeNr; i++) {
			wxDateTime itime;
			if (parse_rss_item(xpath_obj->nodesetval->nodeTab[i], url, version, md5, itime)
					&& (!time.IsValid() || itime > time)) {
				m_url = url;
				m_version = version;
				m_md5 = md5;
				time = itime;

				ok = true;
			}
		}

	}

	xmlXPathFreeObject(xpath_obj);
	xmlXPathFreeContext(xp_ctx);

	return ok;

}
static TotemPlParserResult
parse_rss_items (TotemPlParser *parser, const char *uri, xml_node_t *parent)
{
	const char *title, *language, *description, *author;
	const char *contact, *img, *pub_date, *copyright;
	xml_node_t *node;

	title = language = description = author = NULL;
	contact = img = pub_date = copyright = NULL;

	/* We need to parse for the feed metadata first, then for the items */
	for (node = parent->child; node != NULL; node = node->next) {
		if (node->name == NULL)
			continue;

		if (g_ascii_strcasecmp (node->name, "title") == 0) {
			title = node->data;
		} else if (g_ascii_strcasecmp (node->name, "language") == 0) {
			language = node->data;
		} else if (g_ascii_strcasecmp (node->name, "description") == 0
			 || g_ascii_strcasecmp (node->name, "itunes:subtitle") == 0) {
		    	description = node->data;
		} else if (g_ascii_strcasecmp (node->name, "author") == 0
			 || g_ascii_strcasecmp (node->name, "itunes:author") == 0
			 || (g_ascii_strcasecmp (node->name, "generator") == 0 && author == NULL)) {
		    	author = node->data;
		} else if (g_ascii_strcasecmp (node->name, "webMaster") == 0) {
			contact = node->data;
		} else if (g_ascii_strcasecmp (node->name, "image") == 0) {
			img = node->data;
		} else if (g_ascii_strcasecmp (node->name, "itunes:image") == 0) {
			const char *href;

			href = xml_parser_get_property (node, "href");
			if (href != NULL)
				img = href;
		} else if (g_ascii_strcasecmp (node->name, "lastBuildDate") == 0
			 || g_ascii_strcasecmp (node->name, "pubDate") == 0) {
		    	pub_date = node->data;
		} else if (g_ascii_strcasecmp (node->name, "copyright") == 0) {
			copyright = node->data;
		}
	}

	/* Send the info we already have about the feed */
	totem_pl_parser_add_uri (parser,
				 TOTEM_PL_PARSER_FIELD_IS_PLAYLIST, TRUE,
				 TOTEM_PL_PARSER_FIELD_URI, uri,
				 TOTEM_PL_PARSER_FIELD_TITLE, title,
				 TOTEM_PL_PARSER_FIELD_LANGUAGE, language,
				 TOTEM_PL_PARSER_FIELD_DESCRIPTION, description,
				 TOTEM_PL_PARSER_FIELD_AUTHOR, author,
				 TOTEM_PL_PARSER_FIELD_PUB_DATE, pub_date,
				 TOTEM_PL_PARSER_FIELD_COPYRIGHT, copyright,
				 TOTEM_PL_PARSER_FIELD_IMAGE_URI, img,
				 TOTEM_PL_PARSER_FIELD_CONTACT, contact,
				 NULL);

	for (node = parent->child; node != NULL; node = node->next) {
		if (node->name == NULL)
			continue;

		if (g_ascii_strcasecmp (node->name, "item") == 0)
			parse_rss_item (parser, node);
	}

	totem_pl_parser_playlist_end (parser, uri);

	return TOTEM_PL_PARSER_RESULT_SUCCESS;
}
Exemple #3
0
static GList*
feed_rss_handler_parse (FeedHandler *self, GrssFeedChannel *feed, xmlDocPtr doc, gboolean do_items, GError **error)
{
	gchar *tmp;
	gboolean rdf;
	time_t now;
	GList *items;
	xmlNodePtr cur;
	GrssFeedItem *item;
	FeedRssHandler *parser;

	items = NULL;
	rdf = FALSE;
	now = time (NULL);
	parser = FEED_RSS_HANDLER (self);

	cur = xmlDocGetRootElement (doc);
	while (cur && xmlIsBlankNode (cur))
		cur = cur->next;

	if (!xmlStrcmp (cur->name, BAD_CAST"rss")) {
		cur = cur->xmlChildrenNode;
		rdf = FALSE;
	}
	else if (!xmlStrcmp (cur->name, BAD_CAST"rdf") ||
	         !xmlStrcmp (cur->name, BAD_CAST"RDF")) {
		cur = cur->xmlChildrenNode;
		rdf = TRUE;
	}
	else if (!xmlStrcmp (cur->name, BAD_CAST"Channel")) {
		rdf = FALSE;
	}
	else {
		g_set_error (error, FEED_RSS_HANDLER_ERROR, FEED_RSS_HANDLER_PARSE_ERROR, "Could not find RDF/RSS header!");
		return NULL;
	}

	while (cur && xmlIsBlankNode (cur))
		cur = cur->next;

	while (cur) {
		if (!cur->name) {
			g_warning ("invalid XML: parser returns NULL value -> tag ignored!");
			cur = cur->next;
			continue;
		}

		if ((!xmlStrcmp (cur->name, BAD_CAST"channel")) ||
		    (!xmlStrcmp (cur->name, BAD_CAST"Channel"))) {
			parse_channel (parser, feed, doc, cur);
			if (rdf == FALSE)
				cur = cur->xmlChildrenNode;
			break;
		}

		cur = cur->next;
	}

	/* For RDF (rss 0.9 or 1.0), cur now points to the item after the channel tag. */
	/* For RSS, cur now points to the first item inside of the channel tag */
	/* This ends up being the thing with the items, (and images/textinputs for RDF) */

	/* parse channel contents */
	while (cur) {
		if (cur->type != XML_ELEMENT_NODE || NULL == cur->name) {
			cur = cur->next;
			continue;
		}

		/* save link to channel image */
		if ((!xmlStrcmp (cur->name, BAD_CAST"image"))) {
			if (NULL != (tmp = parse_image (cur))) {
				grss_feed_channel_set_image (feed, tmp);
				g_free (tmp);
			}
		}
		else if (do_items == TRUE && (!xmlStrcmp (cur->name, BAD_CAST"items"))) { /* RSS 1.1 */
			xmlNodePtr iter = cur->xmlChildrenNode;

			while (iter) {
				item = parse_rss_item (parser, feed, doc, iter);

				if (item != NULL) {
					if (grss_feed_item_get_publish_time (item) == 0)
						grss_feed_item_set_publish_time (item, now);
					items = g_list_append (items, item);
				}

				iter = iter->next;
			}
		}
		else if (do_items == TRUE && (!xmlStrcmp (cur->name, BAD_CAST"item"))) { /* RSS 1.0, 2.0 */
			item = parse_rss_item (parser, feed, doc, cur);

			if (item != NULL) {
				if (grss_feed_item_get_publish_time (item) == 0)
					grss_feed_item_set_publish_time (item, now);
				items = g_list_append (items, item);
			}
		}

		cur = cur->next;
	}

	grss_feed_channel_set_format (feed, "application/rss+xml");

	if (items != NULL)
		items = g_list_reverse (items);
	return items;
}