[libgrss] Added XOXO files parser Corrected error in GError propagation for FeedsGroup



commit 63026ab471ea6a5118641a0c81aaf9829c3f82a3
Author: Roberto Guido <bob4mail gmail com>
Date:   Tue May 25 19:48:27 2010 +0200

    Added XOXO files parser
    Corrected error in GError propagation for FeedsGroup

 NEWS                           |    3 +-
 TODO                           |    1 -
 src/Makefile.am                |    2 +
 src/feeds-group-handler.c      |    4 +-
 src/feeds-group-handler.h      |    8 +-
 src/feeds-group.c              |   12 ++-
 src/feeds-group.h              |    2 +-
 src/feeds-opml-group-handler.c |    8 ++-
 src/feeds-xoxo-group-handler.c |  176 ++++++++++++++++++++++++++++++++++++++++
 src/feeds-xoxo-group-handler.h |   49 +++++++++++
 src/libgrss.h                  |    1 +
 11 files changed, 251 insertions(+), 15 deletions(-)
---
diff --git a/NEWS b/NEWS
index 50521d1..86674a2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 libgrss 0.5 (UNRELEASED)
 ==============================================================================
-- Added function feed_channel_fetch_async()
+- Added XOXO files parser
+- Added functions feed_channel_fetch_async() and feed_channel_new_from_file()
 
 libgrss 0.4
 ==============================================================================
diff --git a/TODO b/TODO
index 45ddd16..a3f25bd 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,6 @@
 - dynamic loading for parsing modules
 
 - add RSSCloud support (http://rsscloud.org)
-- add XOXO parser (http://microformats.org/wiki/xoxo)
 - add XBEL parser (http://pyxml.sourceforge.net/topics/xbel/)
 
 - namespace OpenSearch (http://a9.com/-/spec/opensearchrss/1.0/)
diff --git a/src/Makefile.am b/src/Makefile.am
index 47bbfe9..c4462ca 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,6 +17,7 @@ sources_private_h = \
 	feed-pie-handler.h         \
 	feeds-group-handler.h      \
 	feeds-opml-group-handler.h \
+	feeds-xoxo-group-handler.h \
 	ns-handler.h               \
 	utils.h
 
@@ -47,6 +48,7 @@ sources_c = \
 	feeds-pool.c               \
 	feeds-store.c              \
 	feeds-subscriber.c         \
+	feeds-xoxo-group-handler.c \
 	ns-handler.c               \
 	utils.c
 
diff --git a/src/feeds-group-handler.c b/src/feeds-group-handler.c
index eea04a1..7042e56 100644
--- a/src/feeds-group-handler.c
+++ b/src/feeds-group-handler.c
@@ -84,7 +84,7 @@ feeds_group_handler_check_format (FeedsGroupHandler *self, xmlDocPtr doc, xmlNod
  * or %NULL if an error occours (and @error is set accordly)
  */
 GList*
-feeds_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError *error)
+feeds_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError **error)
 {
 	if (IS_FEEDS_GROUP_HANDLER (self) == FALSE)
 		return FALSE;
@@ -105,7 +105,7 @@ feeds_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError *error
  * no longer in use, or %NULL if an error occours (and @error is set accordly)
  */
 gchar*
-feeds_group_handler_dump (FeedsGroupHandler *self, GList *channels, GError *error)
+feeds_group_handler_dump (FeedsGroupHandler *self, GList *channels, GError **error)
 {
 	if (IS_FEEDS_GROUP_HANDLER (self) == FALSE)
 		return FALSE;
diff --git a/src/feeds-group-handler.h b/src/feeds-group-handler.h
index dac1845..3e1ea21 100644
--- a/src/feeds-group-handler.h
+++ b/src/feeds-group-handler.h
@@ -35,14 +35,14 @@ struct _FeedsGroupHandlerInterface {
 	GTypeInterface parent_iface;
 
 	gboolean (*check_format) (FeedsGroupHandler *self, xmlDocPtr doc, xmlNodePtr cur);
-	GList* (*parse) (FeedsGroupHandler *self, xmlDocPtr doc, GError *error);
-	gchar* (*dump) (FeedsGroupHandler *self, GList *channels, GError *error);
+	GList* (*parse) (FeedsGroupHandler *self, xmlDocPtr doc, GError **error);
+	gchar* (*dump) (FeedsGroupHandler *self, GList *channels, GError **error);
 };
 
 GType		feeds_group_handler_get_type		();
 
 gboolean	feeds_group_handler_check_format	(FeedsGroupHandler *self, xmlDocPtr doc, xmlNodePtr cur);
-GList*		feeds_group_handler_parse		(FeedsGroupHandler *self, xmlDocPtr doc, GError *error);
-gchar*		feeds_group_handler_dump		(FeedsGroupHandler *self, GList *channels, GError *error);
+GList*		feeds_group_handler_parse		(FeedsGroupHandler *self, xmlDocPtr doc, GError **error);
+gchar*		feeds_group_handler_dump		(FeedsGroupHandler *self, GList *channels, GError **error);
 
 #endif /* __FEEDS_GROUP_HANDLER_H__ */
diff --git a/src/feeds-group.c b/src/feeds-group.c
index ec7c82e..d2a7d03 100644
--- a/src/feeds-group.c
+++ b/src/feeds-group.c
@@ -23,6 +23,7 @@
 #include "feeds-group-handler.h"
 
 #include "feeds-opml-group-handler.h"
+#include "feeds-xoxo-group-handler.h"
 
 #define FEEDS_GROUP_GET_PRIVATE(o)	(G_TYPE_INSTANCE_GET_PRIVATE ((o), FEEDS_GROUP_TYPE, FeedsGroupPrivate))
 
@@ -31,7 +32,7 @@
  * @short_description: import and export group of channels
  *
  * #FeedsGroup is an utility to import and export list of #FeedChannels in
- * different formats, such as OPML.
+ * different formats, such as OPML and XOXO.
  */
 
 #define FEEDS_GROUP_ERROR		feeds_group_error_quark()
@@ -88,6 +89,9 @@ feeds_groups_get_list (FeedsGroup *group)
 
 		parser = FEEDS_GROUP_HANDLER (feeds_opml_group_handler_new ());
 		group->priv->handlers = g_slist_append (group->priv->handlers, parser);
+
+		parser = FEEDS_GROUP_HANDLER (feeds_xoxo_group_handler_new ());
+		group->priv->handlers = g_slist_append (group->priv->handlers, parser);
 	}
 
 	return group->priv->handlers;
@@ -142,7 +146,7 @@ retrieve_group_handler (FeedsGroup *group, xmlDocPtr doc, xmlNodePtr cur)
  * @error is set
  */
 GList*
-feeds_group_parse_file (FeedsGroup *group, const gchar *path, GError *error)
+feeds_group_parse_file (FeedsGroup *group, const gchar *path, GError **error)
 {
 	GList *items;
 	xmlDocPtr doc;
@@ -154,7 +158,7 @@ feeds_group_parse_file (FeedsGroup *group, const gchar *path, GError *error)
 
 	do {
 		doc = file_to_xml (path);
-		g_set_error (&error, FEEDS_GROUP_ERROR, FEEDS_GROUP_PARSE_ERROR, "Empty document");
+		g_set_error (error, FEEDS_GROUP_ERROR, FEEDS_GROUP_PARSE_ERROR, "Empty document");
 
 		if ((cur = xmlDocGetRootElement (doc)) == NULL)
 			break;
@@ -166,7 +170,7 @@ feeds_group_parse_file (FeedsGroup *group, const gchar *path, GError *error)
 			break;
 
 		if (!cur->name) {
-			g_set_error (&error, FEEDS_GROUP_ERROR, FEEDS_GROUP_PARSE_ERROR, "Invalid XML");
+			g_set_error (error, FEEDS_GROUP_ERROR, FEEDS_GROUP_PARSE_ERROR, "Invalid XML");
 			break;
 		}
 
diff --git a/src/feeds-group.h b/src/feeds-group.h
index 91c9c09..134b897 100644
--- a/src/feeds-group.h
+++ b/src/feeds-group.h
@@ -46,7 +46,7 @@ GType		feeds_group_get_type		() G_GNUC_CONST;
 
 FeedsGroup*	feeds_group_new			();
 
-GList*		feeds_group_parse_file		(FeedsGroup *group, const gchar *path, GError *error);
+GList*		feeds_group_parse_file		(FeedsGroup *group, const gchar *path, GError **error);
 gboolean	feeds_group_export_file		(FeedsGroup *group, GList *channels, const gchar *path, GError *error);
 
 #endif /* __FEEDS_GROUP_H__ */
diff --git a/src/feeds-opml-group-handler.c b/src/feeds-opml-group-handler.c
index 2554ce1..1d9b185 100644
--- a/src/feeds-opml-group-handler.c
+++ b/src/feeds-opml-group-handler.c
@@ -191,7 +191,7 @@ import_parse_OPML (xmlNodePtr n)
 }
 
 static GList*
-feeds_opml_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError *error)
+feeds_opml_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError **error)
 {
 	xmlNodePtr cur;
 	GList *items;
@@ -217,8 +217,12 @@ feeds_opml_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError *
 }
 
 static gchar*
-feeds_opml_group_handler_dump (FeedsGroupHandler *self, GList *channels, GError *error)
+feeds_opml_group_handler_dump (FeedsGroupHandler *self, GList *channels, GError **error)
 {
+	/**
+		TODO
+	*/
+
 	return NULL;
 }
 
diff --git a/src/feeds-xoxo-group-handler.c b/src/feeds-xoxo-group-handler.c
new file mode 100644
index 0000000..0ee92c2
--- /dev/null
+++ b/src/feeds-xoxo-group-handler.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2010, Roberto Guido <rguido src gnome org>
+ *                     Michele Tameni <michele amdplanet it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "feeds-group-handler.h"
+#include "feeds-xoxo-group-handler.h"
+#include "utils.h"
+#include "feed-channel.h"
+
+#define FEEDS_XOXO_GROUP_HANDLER_GET_PRIVATE(o)	(G_TYPE_INSTANCE_GET_PRIVATE ((o), FEEDS_XOXO_GROUP_HANDLER_TYPE, FeedsXoxoGroupHandlerPrivate))
+
+/**
+ * SECTION: feeds-xoxo-group-handler
+ * @short_description: specialized parser for XOXO files
+ *
+ * #FeedsXoxoGroupHandler is a #FeedsGroupHandler specialized for XOXO contents
+ */
+
+struct FeedsXoxoGroupHandlerPrivate {
+	int	rfu;
+};
+
+static void feeds_group_handler_interface_init (FeedsGroupHandlerInterface *iface);
+G_DEFINE_TYPE_WITH_CODE (FeedsXoxoGroupHandler, feeds_xoxo_group_handler, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (FEEDS_GROUP_HANDLER_TYPE,
+                                                feeds_group_handler_interface_init));
+
+static xmlNode* find_first_element (xmlDocPtr doc)
+{
+	xmlNode *ret;
+	xmlXPathObjectPtr xpathObj;
+	xmlXPathContextPtr xpathCtx;
+
+	xpathCtx = xmlXPathNewContext (doc);
+	xmlXPathRegisterNs (xpathCtx, BAD_CAST"xhtml", BAD_CAST"http://www.w3.org/1999/xhtml";);
+	xpathObj = xmlXPathEvalExpression (BAD_CAST"//xhtml:ol[ class='xoxo']", xpathCtx);
+
+	if (xpathObj->nodesetval == NULL || xpathObj->nodesetval->nodeNr < 1)
+		ret = NULL;
+	else
+		ret = xpathObj->nodesetval->nodeTab [0];
+
+	xmlXPathFreeObject (xpathObj);
+	xmlXPathFreeContext (xpathCtx);
+	return ret;
+}
+
+static void
+feeds_xoxo_group_handler_finalize (GObject *object)
+{
+	FeedsXoxoGroupHandler *parser;
+
+	parser = FEEDS_XOXO_GROUP_HANDLER (object);
+	G_OBJECT_CLASS (feeds_xoxo_group_handler_parent_class)->finalize (object);
+}
+
+static gboolean
+feeds_xoxo_group_handler_check_format (FeedsGroupHandler *self, xmlDocPtr doc, xmlNodePtr cur)
+{
+	return (find_first_element (doc) != NULL);
+}
+
+static GList*
+feeds_xoxo_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError **error)
+{
+	int i;
+	gchar *str;
+	xmlNodePtr cur;
+	GList *items;
+	xmlXPathObjectPtr xpathObj;
+	xmlXPathContextPtr xpathCtx;
+	FeedChannel *channel;
+	FeedsXoxoGroupHandler *parser;
+
+	items = NULL;
+	parser = FEEDS_XOXO_GROUP_HANDLER (self);
+
+	xpathCtx = xmlXPathNewContext (doc);
+	xmlXPathRegisterNs (xpathCtx, BAD_CAST"xhtml", BAD_CAST"http://www.w3.org/1999/xhtml";);
+	xpathObj = xmlXPathEvalExpression (BAD_CAST"//xhtml:a[ type='webfeed']", xpathCtx);
+
+	for (i = 0; i < xpathObj->nodesetval->nodeNr; ++i) {
+		cur = xpathObj->nodesetval->nodeTab [i];
+
+		if (cur->type == XML_ELEMENT_NODE) {
+			str = (gchar*) xmlGetProp (cur, BAD_CAST"href");
+
+			if (str != NULL && strlen (str) != 0) {
+				channel = feed_channel_new ();
+
+				feed_channel_set_source (channel, str);
+				xmlFree (str);
+
+				str = unhtmlize ((gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, TRUE));
+				if (str != NULL) {
+					feed_channel_set_title (channel, str);
+					g_free (str);
+				}
+
+				items = g_list_prepend (items, channel);
+			}
+		}
+	}
+
+	xmlXPathFreeObject (xpathObj);
+	xmlXPathFreeContext (xpathCtx);
+
+	if (items != NULL)
+		items = g_list_reverse (items);
+	return items;
+}
+
+static gchar*
+feeds_xoxo_group_handler_dump (FeedsGroupHandler *self, GList *channels, GError **error)
+{
+	/**
+		TODO
+	*/
+
+	return NULL;
+}
+
+static void
+feeds_group_handler_interface_init (FeedsGroupHandlerInterface *iface)
+{
+	iface->check_format = feeds_xoxo_group_handler_check_format;
+	iface->parse = feeds_xoxo_group_handler_parse;
+	iface->dump = feeds_xoxo_group_handler_dump;
+}
+
+static void
+feeds_xoxo_group_handler_class_init (FeedsXoxoGroupHandlerClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (object_class, sizeof (FeedsXoxoGroupHandlerPrivate));
+	object_class->finalize = feeds_xoxo_group_handler_finalize;
+}
+
+static void
+feeds_xoxo_group_handler_init (FeedsXoxoGroupHandler *object)
+{
+	object->priv = FEEDS_XOXO_GROUP_HANDLER_GET_PRIVATE (object);
+}
+
+/**
+ * feeds_xoxo_group_handler_new:
+ *
+ * Allocates a new #FeedsXoxoGroupHandler
+ *
+ * Return value: a new #FeedsXoxoGroupHandler
+ */
+FeedsXoxoGroupHandler*
+feeds_xoxo_group_handler_new ()
+{
+	FeedsXoxoGroupHandler *parser;
+
+	parser = g_object_new (FEEDS_XOXO_GROUP_HANDLER_TYPE, NULL);
+	return parser;
+}
diff --git a/src/feeds-xoxo-group-handler.h b/src/feeds-xoxo-group-handler.h
new file mode 100644
index 0000000..2b5dcca
--- /dev/null
+++ b/src/feeds-xoxo-group-handler.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010, Roberto Guido <rguido src gnome org>
+ *                     Michele Tameni <michele amdplanet it>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __FEEDS_XOXO_GROUP_HANDLER_H__
+#define __FEEDS_XOXO_GROUP_HANDLER_H__
+
+#include "libgrss.h"
+
+#define FEEDS_XOXO_GROUP_HANDLER_TYPE		(feeds_xoxo_group_handler_get_type())
+#define FEEDS_XOXO_GROUP_HANDLER(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), FEEDS_XOXO_GROUP_HANDLER_TYPE, FeedsXoxoGroupHandler))
+#define FEEDS_XOXO_GROUP_HANDLER_CLASS(c)	(G_TYPE_CHECK_CLASS_CAST ((c), FEEDS_XOXO_GROUP_HANDLER_TYPE, FeedsXoxoGroupHandlerClass))
+#define IS_FEEDS_XOXO_GROUP_HANDLER(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), FEEDS_XOXO_GROUP_HANDLER_TYPE))
+#define IS_FEEDS_XOXO_GROUP_HANDLER_CLASS(c)	(G_TYPE_CHECK_CLASS_TYPE ((c),  FEEDS_XOXO_GROUP_HANDLER_TYPE))
+#define FEEDS_XOXO_GROUP_HANDLER_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), FEEDS_XOXO_GROUP_HANDLER_TYPE, FeedsXoxoGroupHandlerClass))
+
+typedef struct FeedsXoxoGroupHandler        FeedsXoxoGroupHandler;
+typedef struct FeedsXoxoGroupHandlerPrivate FeedsXoxoGroupHandlerPrivate;
+
+struct FeedsXoxoGroupHandler {
+	GObject parent;
+	FeedsXoxoGroupHandlerPrivate *priv;
+};
+
+typedef struct {
+	GObjectClass parent;
+} FeedsXoxoGroupHandlerClass;
+
+GType			feeds_xoxo_group_handler_get_type	(void) G_GNUC_CONST;
+
+FeedsXoxoGroupHandler*	feeds_xoxo_group_handler_new		();
+
+#endif /* __FEEDS_XOXO_GROUP_HANDLER_H__ */
diff --git a/src/libgrss.h b/src/libgrss.h
index bc48c54..51f45aa 100644
--- a/src/libgrss.h
+++ b/src/libgrss.h
@@ -29,6 +29,7 @@
 #include <libxml/entities.h>
 #include <libxml/HTMLparser.h>
 #include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
 
 #include "feed-channel.h"
 #include "feed-enclosure.h"



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