static gchar* feed_rss_formatter_format (GrssFeedFormatter *formatter) { const gchar *str; const gchar *title; const gchar *link; gchar *formatted; time_t date; GList *iter; GList *items; GrssPerson *person; const GList *list; GString *text; GrssFeedChannel *channel; GrssFeedItem *item; /* Based on http://cyber.law.harvard.edu/rss/examples/rss2sample.xml */ text = g_string_new ("<?xml version=\"1.0\"?>\n<rss version=\"2.0\">\n"); channel = grss_feed_formatter_get_channel (formatter); items = grss_feed_formatter_get_items (formatter); if (channel != NULL) { g_string_append_printf (text, "<channel>\n"); title = grss_feed_channel_get_title (channel); if (title != NULL) g_string_append_printf (text, "\t<title>%s</title>\n", title); else title = ""; str = grss_feed_channel_get_description (channel); if (str != NULL) g_string_append_printf (text, "\t<description>%s</description>\n", str); link = grss_feed_channel_get_homepage (channel); if (link != NULL) g_string_append_printf (text, "\t<link>%s</link>\n", link); else link = ""; str = grss_feed_channel_get_copyright (channel); if (str != NULL) g_string_append_printf (text, "\t<copyright>%s</copyright>\n", str); person = grss_feed_channel_get_editor (channel); if (person != NULL) // TODO: implement handling additional attrs g_string_append_printf (text, "\t<managingEditor>%s</managingEditor>\n", grss_person_get_name (person)); str = grss_feed_channel_get_generator (channel); if (str != NULL) g_string_append_printf (text, "\t<generator>%s</generator>\n", str); date = grss_feed_channel_get_update_time (channel); formatted = date_to_ISO8601 (date); g_string_append_printf (text, "\t<pubDate>%s</pubDate>\n", formatted); g_free (formatted); str = grss_feed_channel_get_image (channel); if (str != NULL) { g_string_append_printf (text, "\t<image>\n"); g_string_append_printf (text, "\t\t<title>%s</title>\n", title); g_string_append_printf (text, "\t\t<url>%s</url>\n", str); g_string_append_printf (text, "\t\t<link>%s</link>\n", link); g_string_append_printf (text, "\t</image>\n"); } for (iter = items; iter; iter = iter->next) { item = iter->data; g_string_append (text, "\t<item>\n"); str = grss_feed_item_get_title (item); if (str != NULL) g_string_append_printf (text, "\t\t<title>%s</title>\n", str); str = grss_feed_item_get_id (item); if (str != NULL) g_string_append_printf (text, "\t\t<guid>%s</guid>\n", str); str = grss_feed_item_get_source (item); if (str != NULL) g_string_append_printf (text, "\t\t<link>%s</link>\n", str); str = grss_feed_item_get_description (item); if (str != NULL) g_string_append_printf (text, "\t\t<description>%s</description>\n", str); person = grss_feed_item_get_author (item); if (person != NULL) // FIXME: implement adding email and uri g_string_append_printf (text, "\t\t<author>%s</author>\n", grss_person_get_name (person)); date = grss_feed_item_get_publish_time (item); formatted = date_to_ISO8601 (date); g_string_append_printf (text, "\t\t<pubDate>%s</pubDate>\n", formatted); g_free (formatted); g_string_append (text, "\t</item>\n"); } } g_string_append (text, "</channel>\n</rss>"); return g_string_free (text, FALSE); }
static gchar* feed_atom_formatter_format (GrssFeedFormatter *formatter) { const gchar *str; gchar *formatted; time_t date; GList *iter; GList *items; const GList *list; GString *text; GrssFeedChannel *channel; GrssFeedItem *item; text = g_string_new ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"); channel = grss_feed_formatter_get_channel (formatter); items = grss_feed_formatter_get_items (formatter); if (channel != NULL) { str = grss_feed_channel_get_title (channel); if (str != NULL) g_string_append_printf (text, "\t<title>%s</title>\n", str); str = grss_feed_channel_get_description (channel); if (str != NULL) g_string_append_printf (text, "\t<subtitle>%s</subtitle>\n", str); str = grss_feed_channel_get_homepage (channel); if (str != NULL) g_string_append_printf (text, "\t<link href=\"%s\" />\n", str); str = grss_feed_channel_get_copyright (channel); if (str != NULL) g_string_append_printf (text, "\t<rights>%s</rights>\n", str); str = grss_feed_channel_get_editor (channel); if (str != NULL) g_string_append_printf (text, "\t<author>%s</author>\n", str); str = grss_feed_channel_get_generator (channel); if (str != NULL) g_string_append_printf (text, "\t<generator>%s</generator>\n", str); list = grss_feed_channel_get_contributors (channel); while (list != NULL) { g_string_append_printf (text, "\t<contributor>%s</contributor>\n", (gchar*) list->data); list = list->next; } date = grss_feed_channel_get_update_time (channel); if (date == 0) date = grss_feed_channel_get_publish_time (channel); formatted = date_to_ISO8601 (date); g_string_append_printf (text, "\t<updated>%s</updated>\n", formatted); g_free (formatted); str = grss_feed_channel_get_icon (channel); if (str != NULL) g_string_append_printf (text, "\t<icon>%s</icon>\n", str); str = grss_feed_channel_get_image (channel); if (str != NULL) g_string_append_printf (text, "\t<logo>%s</logo>\n", str); for (iter = items; iter; iter = iter->next) { item = iter->data; g_string_append (text, "\t<entry>\n"); str = grss_feed_item_get_title (item); if (str != NULL) g_string_append_printf (text, "\t\t<title>%s</title>\n", str); str = grss_feed_item_get_id (item); if (str != NULL) g_string_append_printf (text, "\t\t<id>%s</id>\n", str); str = grss_feed_item_get_source (item); if (str != NULL) g_string_append_printf (text, "\t\t<link href=\"%s\" />\n", str); str = grss_feed_item_get_description (item); if (str != NULL) g_string_append_printf (text, "\t\t<summary>%s</summary>\n", str); str = grss_feed_item_get_author (item); if (str != NULL) g_string_append_printf (text, "\t\t<author>%s</author>\n", str); str = grss_feed_item_get_copyright (item); if (str != NULL) g_string_append_printf (text, "\t\t<rights>%s</rights>\n", str); list = grss_feed_item_get_contributors (item); while (list != NULL) { g_string_append_printf (text, "\t\t<contributor>%s</contributor>\n", (gchar*) list->data); list = list->next; } date = grss_feed_item_get_publish_time (item); formatted = date_to_ISO8601 (date); g_string_append_printf (text, "\t\t<published>%s</published>\n", formatted); g_free (formatted); g_string_append (text, "\t</entry>\n"); } } g_string_append (text, "</feed>"); return g_string_free (text, FALSE); }
static GrssFeedItem* parse_rss_item (FeedRssHandler *parser, GrssFeedChannel *feed, xmlDocPtr doc, xmlNodePtr cur) { gchar *tmp; gchar *tmp2; gchar *tmp3; time_t t; GrssFeedItem *item; g_assert (cur != NULL); item = grss_feed_item_new (feed); /* try to get an item about id */ tmp = (gchar*) xmlGetProp (cur, BAD_CAST"about"); if (tmp) { grss_feed_item_set_id (item, tmp); grss_feed_item_set_source (item, tmp); g_free (tmp); } cur = cur->xmlChildrenNode; while (cur) { if (cur->type != XML_ELEMENT_NODE || !cur->name) { cur = cur->next; continue; } /* check namespace of this tag */ if (cur->ns) { if (ns_handler_item (parser->priv->handler, item, cur)) { cur = cur->next; continue; } } if (!xmlStrcmp (cur->name, BAD_CAST"category")) { tmp = (gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); if (tmp) { grss_feed_item_add_category (item, tmp); g_free (tmp); } } else if (!xmlStrcmp (cur->name, BAD_CAST"author")) { tmp = (gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); if (tmp) { grss_feed_item_set_author (item, tmp); g_free (tmp); } } else if (!xmlStrcmp (cur->name, BAD_CAST"comments")) { tmp = (gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); if (tmp) { grss_feed_item_set_comments_url (item, tmp); g_free (tmp); } } else if (!xmlStrcmp (cur->name, BAD_CAST"pubDate")) { tmp = (gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); if (tmp) { t = date_parse_RFC822 (tmp); grss_feed_item_set_publish_time (item, t); g_free (tmp); } } else if (!xmlStrcmp (cur->name, BAD_CAST"enclosure")) { /* RSS 0.93 allows multiple enclosures */ tmp = (gchar*) xmlGetProp (cur, BAD_CAST"url"); if (tmp) { gchar *type = (gchar*) xmlGetProp (cur, BAD_CAST"type"); gssize length = 0; GrssFeedEnclosure *enclosure; tmp2 = (gchar*) xmlGetProp (cur, BAD_CAST"length"); if (tmp2) { length = atol (tmp2); xmlFree (tmp2); } tmp3 = (gchar*) grss_feed_channel_get_homepage (feed); if ((strstr (tmp, "://") == NULL) && (tmp3 != NULL) && (strstr (tmp3, "://") != NULL)) { /* add base URL if necessary and possible */ tmp2 = g_strdup_printf ("%s/%s", tmp3, tmp); xmlFree (tmp); tmp = tmp2; } enclosure = grss_feed_enclosure_new (tmp); grss_feed_enclosure_set_format (enclosure, type); grss_feed_enclosure_set_length (enclosure, length); grss_feed_item_add_enclosure (item, enclosure); xmlFree (tmp); xmlFree (type); } } else if (!xmlStrcmp (cur->name, BAD_CAST"guid")) { if (!grss_feed_item_get_id (item)) { tmp = (gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); if (tmp) { if (strlen (tmp) > 0) { grss_feed_item_set_id (item, tmp); tmp2 = (gchar*) xmlGetProp (cur, BAD_CAST"isPermaLink"); if (!grss_feed_item_get_source (item) && (tmp2 == NULL || g_str_equal (tmp2, "true"))) grss_feed_item_set_source (item, tmp); /* Per the RSS 2.0 spec. */ if (tmp2) xmlFree (tmp2); } xmlFree (tmp); } } } else if (!xmlStrcmp (cur->name, BAD_CAST"title")) { tmp = unhtmlize ((gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, TRUE)); if (tmp) { grss_feed_item_set_title (item, tmp); g_free (tmp); } } else if (!xmlStrcmp (cur->name, BAD_CAST"link")) { tmp = unhtmlize ((gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, TRUE)); if (tmp) { grss_feed_item_set_source (item, tmp); g_free (tmp); } } else if (!xmlStrcmp (cur->name, BAD_CAST"description")) { tmp = xhtml_extract (cur, 0, NULL); if (tmp) { /* don't overwrite content:encoded descriptions... */ if (!grss_feed_item_get_description (item)) grss_feed_item_set_description (item, tmp); g_free (tmp); } } else if (!xmlStrcmp (cur->name, BAD_CAST"source")) { tmp = (gchar*) xmlGetProp (cur, BAD_CAST"url"); tmp2 = unhtmlize ((gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, 1)); if (tmp) { grss_feed_item_set_real_source (item, g_strchomp (tmp), tmp2 ? g_strchomp (tmp2) : NULL); g_free (tmp); } if (tmp2) g_free (tmp2); } cur = cur->next; } return item; }