[libgrss] New "FeedsGroup" object, to parse and produce groups of feeds Added OPML files parser
- From: Roberto Guido <rguido src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgrss] New "FeedsGroup" object, to parse and produce groups of feeds Added OPML files parser
- Date: Sun, 28 Mar 2010 15:30:59 +0000 (UTC)
commit 0ed8c4843434e53438db4b797851664ea4fa58a2
Author: Roberto Guido <bob4mail gmail com>
Date: Sun Mar 28 17:31:53 2010 +0200
New "FeedsGroup" object, to parse and produce groups of feeds
Added OPML files parser
src/Makefile.am | 58 +++++----
src/feed-atom-handler.c | 6 +-
src/feed-channel.c | 2 +-
src/feed-parser.c | 2 +-
src/feeds-group-handler.c | 114 +++++++++++++++++
src/feeds-group-handler.h | 49 ++++++++
src/feeds-group.c | 193 +++++++++++++++++++++++++++++
src/feeds-group.h | 52 ++++++++
src/feeds-opml-group-handler.c | 267 ++++++++++++++++++++++++++++++++++++++++
src/feeds-opml-group-handler.h | 50 ++++++++
src/feeds-pool.c | 2 +-
src/feeds-subscriber.c | 2 +-
src/libgrss.h | 1 +
src/utils.c | 2 +-
src/utils.h | 2 +-
15 files changed, 767 insertions(+), 35 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 93c9be7..e3d8afb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,35 +14,41 @@ sources_private_h = \
utils.h
sources_public_h = \
- common.h \
- libgrss.h \
- feed-atom-handler.h \
- feed-channel.h \
- feed-enclosure.h \
- feed-handler.h \
- feed-item.h \
- feed-parser.h \
- feed-rss-handler.h \
- feed-pie-handler.h \
- feeds-pool.h \
- feeds-store.h \
- feeds-subscriber.h \
+ common.h \
+ libgrss.h \
+ feed-atom-handler.h \
+ feed-channel.h \
+ feed-enclosure.h \
+ feed-handler.h \
+ feed-item.h \
+ feed-parser.h \
+ feed-rss-handler.h \
+ feed-pie-handler.h \
+ feeds-group.h \
+ feeds-group-handler.h \
+ feeds-opml-group-handler.h \
+ feeds-pool.h \
+ feeds-store.h \
+ feeds-subscriber.h \
ns-handler.h
sources_c = \
- $(marshal_source) \
- feed-atom-handler.c \
- feed-channel.c \
- feed-enclosure.c \
- feed-handler.c \
- feed-item.c \
- feed-parser.c \
- feed-rss-handler.c \
- feed-pie-handler.c \
- feeds-pool.c \
- feeds-store.c \
- feeds-subscriber.c \
- ns-handler.c \
+ $(marshal_source) \
+ feed-atom-handler.c \
+ feed-channel.c \
+ feed-enclosure.c \
+ feed-handler.c \
+ feed-item.c \
+ feed-parser.c \
+ feed-rss-handler.c \
+ feed-pie-handler.c \
+ feeds-group.c \
+ feeds-group-handler.c \
+ feeds-opml-group-handler.c \
+ feeds-pool.c \
+ feeds-store.c \
+ feeds-subscriber.c \
+ ns-handler.c \
utils.c
marshal_source = \
diff --git a/src/feed-atom-handler.c b/src/feed-atom-handler.c
index 3ec23d5..72247ee 100644
--- a/src/feed-atom-handler.c
+++ b/src/feed-atom-handler.c
@@ -305,13 +305,13 @@ atom10_parse_person_construct (xmlNodePtr cur)
if (xmlStrEqual (cur->name, BAD_CAST"email")) {
if (email)
invalid = TRUE;
- g_free(email);
+ g_free (email);
tmp = (gchar *)xmlNodeListGetString(cur->doc, cur->xmlChildrenNode, 1);
email = g_strdup_printf(" - <a href=\"mailto:%s\">%s</a>", tmp, tmp);
g_free(tmp);
}
- if (xmlStrEqual(cur->name, BAD_CAST"uri")) {
+ if (xmlStrEqual (cur->name, BAD_CAST"uri")) {
if (!uri)
invalid = TRUE;
g_free (uri);
@@ -599,7 +599,7 @@ atom10_parse_entry (FeedHandler *self, FeedChannel *feed, xmlNodePtr cur)
}
- if (xmlStrcmp(cur->ns->href, ATOM10_NS)) {
+ if (xmlStrcmp (cur->ns->href, ATOM10_NS)) {
cur = cur->next;
continue;
}
diff --git a/src/feed-channel.c b/src/feed-channel.c
index c68c1c6..6535edd 100644
--- a/src/feed-channel.c
+++ b/src/feed-channel.c
@@ -667,7 +667,7 @@ feed_channel_fetch (FeedChannel *channel)
status = soup_session_send_message (session, msg);
if (status >= 200 && status <= 299) {
- doc = feed_content_to_xml (msg->response_body->data, msg->response_body->length);
+ doc = content_to_xml (msg->response_body->data, msg->response_body->length);
if (doc != NULL) {
parser = feed_parser_new ();
diff --git a/src/feed-parser.c b/src/feed-parser.c
index 7e237f3..d95d381 100644
--- a/src/feed-parser.c
+++ b/src/feed-parser.c
@@ -86,7 +86,7 @@ feed_parser_init (FeedParser *object)
object->priv = FEED_PARSER_GET_PRIVATE (object);
}
-static GSList *
+static GSList*
feed_parsers_get_list (FeedParser *parser)
{
FeedHandler *feed;
diff --git a/src/feeds-group-handler.c b/src/feeds-group-handler.c
new file mode 100644
index 0000000..eea04a1
--- /dev/null
+++ b/src/feeds-group-handler.c
@@ -0,0 +1,114 @@
+/*
+ * 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 "utils.h"
+#include "feeds-group-handler.h"
+
+/**
+ * SECTION: feeds-group-handler
+ * @short_description: interface for specialized groups parsers
+ *
+ * The #FeedsGroupHandler interface defines a unique API for all specialized
+ * groups parsers implementations
+ */
+
+static void
+feeds_group_handler_base_init (gpointer g_class)
+{
+}
+
+GType
+feeds_group_handler_get_type ()
+{
+ static GType iface_type = 0;
+
+ if (iface_type == 0) {
+ static const GTypeInfo info = {
+ sizeof (FeedsGroupHandlerInterface),
+ feeds_group_handler_base_init,
+ NULL,
+ };
+
+ iface_type = g_type_register_static (G_TYPE_INTERFACE, "FeedsGroupHandler", &info, 0);
+ }
+
+ return iface_type;
+}
+
+/**
+ * feeds_group_handler_check_format:
+ * @self: a #FeedsGroupHandler
+ * @doc: XML document from a parsed feed
+ * @cur: first valid node into the XML document
+ *
+ * Used to check validity of an XML document against the given group parser
+ *
+ * Return value: %TRUE if the document can be parsed with the given
+ * #FeedsGroupHandler, %FALSE otherwise
+ */
+gboolean
+feeds_group_handler_check_format (FeedsGroupHandler *self, xmlDocPtr doc, xmlNodePtr cur)
+{
+ if (IS_FEEDS_GROUP_HANDLER (self) == FALSE)
+ return FALSE;
+
+ return FEEDS_GROUP_HANDLER_GET_INTERFACE (self)->check_format (self, doc, cur);
+}
+
+/**
+ * feeds_group_handler_parse:
+ * @self: a #FeedsGroupHandler
+ * @doc: XML document from the feed
+ * @error: location for eventual errors
+ *
+ * Parses the given @doc and extracts a list of #FeedChannels
+ *
+ * Return value: a list of #FeedChannels, to be freed when no longer in use,
+ * or %NULL if an error occours (and @error is set accordly)
+ */
+GList*
+feeds_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError *error)
+{
+ if (IS_FEEDS_GROUP_HANDLER (self) == FALSE)
+ return FALSE;
+
+ return FEEDS_GROUP_HANDLER_GET_INTERFACE (self)->parse (self, doc, error);
+}
+
+/**
+ * feeds_group_handler_dump:
+ * @self: a #FeedsGroupHandler
+ * @channels: list of #FeedChannels
+ * @error: location for eventual errors
+ *
+ * Builds a rappresentation of the given list of @channels for the managed
+ * group type
+ *
+ * Return value: a text to be dump on a file or transmitted, to be freed when
+ * 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)
+{
+ if (IS_FEEDS_GROUP_HANDLER (self) == FALSE)
+ return FALSE;
+
+ return FEEDS_GROUP_HANDLER_GET_INTERFACE (self)->dump (self, channels, error);
+}
diff --git a/src/feeds-group-handler.h b/src/feeds-group-handler.h
new file mode 100644
index 0000000..7eb82d8
--- /dev/null
+++ b/src/feeds-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_GROUP_HANDLER_H__
+#define __FEEDS_GROUP_HANDLER_H__
+
+#include "common.h"
+#include "feed-channel.h"
+
+#define FEEDS_GROUP_HANDLER_TYPE (feeds_group_handler_get_type ())
+#define FEEDS_GROUP_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FEEDS_GROUP_HANDLER_TYPE, FeedsGroupHandler))
+#define IS_FEEDS_GROUP_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FEEDS_GROUP_HANDLER_TYPE))
+#define FEEDS_GROUP_HANDLER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), FEEDS_GROUP_HANDLER_TYPE, FeedsGroupHandlerInterface))
+
+typedef struct _FeedsGroupHandler FeedsGroupHandler;
+typedef struct _FeedsGroupHandlerInterface FeedsGroupHandlerInterface;
+
+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);
+};
+
+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);
+
+#endif /* __FEEDS_GROUP_HANDLER_H__ */
diff --git a/src/feeds-group.c b/src/feeds-group.c
new file mode 100644
index 0000000..5ecd173
--- /dev/null
+++ b/src/feeds-group.c
@@ -0,0 +1,193 @@
+/*
+ * 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 "utils.h"
+#include "feeds-group.h"
+#include "feeds-group-handler.h"
+
+#include "feeds-opml-group-handler.h"
+
+#define FEEDS_GROUP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FEEDS_GROUP_TYPE, FeedsGroupPrivate))
+
+/**
+ * SECTION: feeds-group
+ * @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
+ */
+
+#define FEEDS_GROUP_ERROR feeds_group_error_quark()
+
+struct _FeedsGroupPrivate {
+ GSList *handlers;
+};
+
+enum {
+ FEEDS_GROUP_PARSE_ERROR,
+};
+
+G_DEFINE_TYPE (FeedsGroup, feeds_group, G_TYPE_OBJECT)
+
+static GQuark
+feeds_group_error_quark ()
+{
+ return g_quark_from_static_string ("feeds_group_error");
+}
+
+static void
+feeds_group_finalize (GObject *object)
+{
+ FeedsGroup *group;
+
+ group = FEEDS_GROUP (object);
+ G_OBJECT_CLASS (feeds_group_parent_class)->finalize (object);
+}
+
+static void
+feeds_group_class_init (FeedsGroupClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (FeedsGroupPrivate));
+ object_class->finalize = feeds_group_finalize;
+}
+
+static void
+feeds_group_init (FeedsGroup *object)
+{
+ object->priv = FEEDS_GROUP_GET_PRIVATE (object);
+}
+
+static GSList*
+feeds_groups_get_list (FeedsGroup *group)
+{
+ FeedsGroupHandler *parser;
+
+ if (group->priv->handlers == NULL) {
+ /*
+ TODO Parsers may be dinamically loaded and managed as external plugins
+ */
+
+ parser = FEEDS_GROUP_HANDLER (feeds_opml_group_handler_new ());
+ group->priv->handlers = g_slist_append (group->priv->handlers, parser);
+ }
+
+ return group->priv->handlers;
+}
+
+/**
+ * feeds_group_new:
+ *
+ * Allocates a new #FeedsGroup
+ *
+ * Return value: a new #FeedsGroup
+ */
+FeedsGroup*
+feeds_group_new ()
+{
+ FeedsGroup *group;
+
+ group = g_object_new (FEEDS_GROUP_TYPE, NULL);
+ return group;
+}
+
+static FeedsGroupHandler*
+retrieve_group_handler (FeedsGroup *group, xmlDocPtr doc, xmlNodePtr cur)
+{
+ GSList *iter;
+ FeedsGroupHandler *handler;
+
+ iter = feeds_groups_get_list (group);
+
+ while (iter) {
+ handler = (FeedsGroupHandler*) (iter->data);
+
+ if (handler && feeds_group_handler_check_format (handler, doc, cur))
+ return handler;
+
+ iter = g_slist_next (iter);
+ }
+
+ return NULL;
+}
+
+GList*
+feeds_group_parse_file (FeedsGroup *groups, const gchar *path, GError *error)
+{
+ gchar *contents;
+ gsize len;
+ GList *items;
+ GError *err;
+ xmlDocPtr doc;
+ xmlNodePtr cur;
+ FeedsGroupHandler *handler;
+
+ items = NULL;
+ doc = NULL;
+ contents = NULL;
+
+ do {
+ err = NULL;
+ if (g_file_get_contents (path, &contents, &len, &err) == FALSE) {
+ g_propagate_error (&error, err);
+ break;
+ }
+
+ doc = content_to_xml (contents, len);
+
+ g_set_error (&error, FEEDS_GROUP_ERROR, FEEDS_GROUP_PARSE_ERROR, "Empty document");
+
+ if ((cur = xmlDocGetRootElement (doc)) == NULL)
+ break;
+
+ while (cur && xmlIsBlankNode (cur))
+ cur = cur->next;
+
+ if (!cur)
+ break;
+
+ if (!cur->name) {
+ g_set_error (&error, FEEDS_GROUP_ERROR, FEEDS_GROUP_PARSE_ERROR, "Invalid XML");
+ break;
+ }
+
+ handler = retrieve_group_handler (groups, doc, cur);
+ if (handler == NULL)
+ break;
+
+ items = feeds_group_handler_parse (handler, doc, error);
+
+ } while (0);
+
+ if (doc != NULL)
+ xmlFreeDoc (doc);
+
+ if (contents != NULL)
+ g_free (contents);
+
+ return items;
+}
+
+gboolean
+feeds_group_export_file (FeedsGroup *groups, GList *channels, const gchar *path, GError *error)
+{
+ return FALSE;
+}
diff --git a/src/feeds-group.h b/src/feeds-group.h
new file mode 100644
index 0000000..dfa5a6d
--- /dev/null
+++ b/src/feeds-group.h
@@ -0,0 +1,52 @@
+/*
+ * 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_GROUP_H__
+#define __FEEDS_GROUP_H__
+
+#include "common.h"
+
+#define FEEDS_GROUP_TYPE (feeds_group_get_type())
+#define FEEDS_GROUP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FEEDS_GROUP_TYPE, FeedsGroup))
+#define FEEDS_GROUP_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), FEEDS_GROUP_TYPE, FeedsGroupClass))
+#define IS_FEEDS_GROUP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), FEEDS_GROUP_TYPE))
+#define IS_FEEDS_GROUP_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), FEEDS_GROUP_TYPE))
+#define FEEDS_GROUP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), FEEDS_GROUP_TYPE, FeedsGroupClass))
+
+typedef struct _FeedsGroup FeedsGroup;
+typedef struct _FeedsGroupPrivate FeedsGroupPrivate;
+
+struct _FeedsGroup {
+ GObject parent;
+ FeedsGroupPrivate *priv;
+};
+
+typedef struct {
+ GObjectClass parent;
+} FeedsGroupClass;
+
+GType feeds_group_get_type () G_GNUC_CONST;
+
+FeedsGroup* feeds_group_new ();
+
+GList* feeds_group_parse_file (FeedsGroup *groups, const gchar *path, GError *error);
+gboolean feeds_group_export_file (FeedsGroup *groups, 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
new file mode 100644
index 0000000..4c84f2a
--- /dev/null
+++ b/src/feeds-opml-group-handler.c
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+
+/*
+ * Original code is from Liferea:
+ *
+ * opml_source.c OPML Planet/Blogroll feed list source
+ *
+ * Copyright (C) 2006-2010 Lars Lindner <lars lindner gmail com>
+ */
+
+#include "feeds-opml-group-handler.h"
+#include "utils.h"
+#include "feed-channel.h"
+
+#define FEEDS_OPML_GROUP_HANDLER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FEEDS_OPML_GROUP_HANDLER_TYPE, FeedsOpmlGroupHandlerPrivate))
+
+/**
+ * SECTION: feeds-opml-group-handler
+ * @short_description: specialized parser for OPML files
+ *
+ * #FeedsOpmlGroupHandler is a #FeedsGroupHandler specialized for OPML contents
+ */
+
+struct FeedsOpmlGroupHandlerPrivate {
+ int rfu;
+};
+
+static void feeds_group_handler_interface_init (FeedsGroupHandlerInterface *iface);
+G_DEFINE_TYPE_WITH_CODE (FeedsOpmlGroupHandler, feeds_opml_group_handler, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (FEEDS_GROUP_HANDLER_TYPE,
+ feeds_group_handler_interface_init));
+
+static GQuark
+feeds_opml_group_handler_error_quark ()
+{
+ return g_quark_from_static_string ("feeds_opml_group_handler_error");
+}
+
+static void
+feeds_opml_group_handler_finalize (GObject *object)
+{
+ FeedsOpmlGroupHandler *parser;
+
+ parser = FEEDS_OPML_GROUP_HANDLER (object);
+ G_OBJECT_CLASS (feeds_opml_group_handler_parent_class)->finalize (object);
+}
+
+static gboolean
+feeds_opml_group_handler_check_format (FeedsGroupHandler *self, xmlDocPtr doc, xmlNodePtr cur)
+{
+ if (!xmlStrcmp (cur->name, BAD_CAST"opml"))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static xmlChar*
+get_source_url (xmlNodePtr cur)
+{
+ xmlChar *tmp;
+
+ tmp = xmlGetProp (cur, BAD_CAST "xmlUrl");
+ if (!tmp)
+ tmp = xmlGetProp (cur, BAD_CAST "xmlurl"); /* e.g. for AmphetaDesk */
+ if (!tmp)
+ tmp = xmlGetProp (cur, BAD_CAST"xmlURL"); /* e.g. for LiveJournal */
+
+ return tmp;
+}
+
+static FeedChannel*
+import_parse_outline (xmlNodePtr cur)
+{
+ xmlChar *tmp;
+ FeedChannel *channel;
+
+ channel = feed_channel_new ();
+
+ tmp = xmlGetProp (cur, BAD_CAST"title");
+ if (!tmp || !xmlStrcmp (tmp, BAD_CAST"")) {
+ if (tmp)
+ xmlFree (tmp);
+ tmp = xmlGetProp (cur, BAD_CAST"text");
+ }
+
+ if (tmp) {
+ feed_channel_set_title (channel, (gchar*) tmp);
+ xmlFree (tmp);
+ }
+
+ tmp = get_source_url (cur);
+
+ if (tmp) {
+ feed_channel_set_source (channel, (gchar*) tmp);
+ xmlFree (tmp);
+
+ tmp = xmlGetProp (cur, BAD_CAST"htmlUrl");
+ if (tmp && xmlStrcmp (tmp, BAD_CAST""))
+ feed_channel_set_homepage (channel, (gchar*) tmp);
+ xmlFree (tmp);
+ }
+
+ return channel;
+}
+
+static GList*
+import_parse_body (xmlNodePtr n)
+{
+ xmlChar *type;
+ xmlChar *tmp;
+ GList *items;
+ GList *subitems;
+ FeedChannel *outline;
+ xmlNodePtr cur;
+
+ cur = n->xmlChildrenNode;
+ items = NULL;
+
+ while (cur) {
+ if (!xmlStrcmp (cur->name, BAD_CAST"outline")) {
+ outline = NULL;
+ subitems = NULL;
+ type = xmlGetProp (cur, BAD_CAST"type");
+
+ if (type) {
+ if (xmlStrcasecmp (type, BAD_CAST"rss") == 0 || xmlStrcasecmp (type, BAD_CAST"atom") == 0)
+ outline = import_parse_outline (cur);
+ else if (xmlStrcasecmp (type, BAD_CAST"folder") == 0)
+ subitems = import_parse_body (cur);
+
+ xmlFree (type);
+ }
+ else {
+ /* if we didn't find a type attribute we use heuristics */
+
+ tmp = get_source_url (cur);
+
+ if (tmp) {
+ outline = import_parse_outline (cur);
+ xmlFree (tmp);
+ }
+ else {
+ subitems = import_parse_body (cur);
+ }
+ }
+
+ if (outline != NULL)
+ items = g_list_prepend (items, outline);
+ else if (subitems != NULL)
+ items = g_list_concat (items, subitems);
+ }
+
+ cur = cur->next;
+ }
+
+ return items;
+}
+
+static GList*
+import_parse_OPML (xmlNodePtr n)
+{
+ GList *items;
+ xmlNodePtr cur;
+
+ cur = n->xmlChildrenNode;
+ items = NULL;
+
+ while (cur) {
+ if (!xmlStrcmp (cur->name, BAD_CAST"body")) {
+ items = import_parse_body (cur);
+ break;
+ }
+
+ cur = cur->next;
+ }
+
+ return items;
+}
+
+static GList*
+feeds_opml_group_handler_parse (FeedsGroupHandler *self, xmlDocPtr doc, GError *error)
+{
+ xmlNodePtr cur;
+ GList *items;
+ FeedsOpmlGroupHandler *parser;
+
+ items = NULL;
+ parser = FEEDS_OPML_GROUP_HANDLER (self);
+ cur = xmlDocGetRootElement (doc);
+
+ while (cur) {
+ if (!xmlIsBlankNode (cur))
+ if (!xmlStrcmp (cur->name, BAD_CAST"opml")) {
+ items = import_parse_OPML (cur);
+ break;
+ }
+
+ cur = cur->next;
+ }
+
+ if (items != NULL)
+ items = g_list_reverse (items);
+ return items;
+}
+
+static gchar*
+feeds_opml_group_handler_dump (FeedsGroupHandler *self, GList *channels, GError *error)
+{
+ return NULL;
+}
+
+static void
+feeds_group_handler_interface_init (FeedsGroupHandlerInterface *iface)
+{
+ iface->check_format = feeds_opml_group_handler_check_format;
+ iface->parse = feeds_opml_group_handler_parse;
+ iface->dump = feeds_opml_group_handler_dump;
+}
+
+static void
+feeds_opml_group_handler_class_init (FeedsOpmlGroupHandlerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (FeedsOpmlGroupHandlerPrivate));
+ object_class->finalize = feeds_opml_group_handler_finalize;
+}
+
+static void
+feeds_opml_group_handler_init (FeedsOpmlGroupHandler *object)
+{
+ object->priv = FEEDS_OPML_GROUP_HANDLER_GET_PRIVATE (object);
+}
+
+/**
+ * feeds_opml_group_handler_new:
+ *
+ * Allocates a new #FeedsOpmlGroupHandler
+ *
+ * Return value: a new #FeedsOpmlGroupHandler
+ */
+FeedsOpmlGroupHandler*
+feeds_opml_group_handler_new ()
+{
+ FeedsOpmlGroupHandler *parser;
+
+ parser = g_object_new (FEEDS_OPML_GROUP_HANDLER_TYPE, NULL);
+ return parser;
+}
diff --git a/src/feeds-opml-group-handler.h b/src/feeds-opml-group-handler.h
new file mode 100644
index 0000000..39c341d
--- /dev/null
+++ b/src/feeds-opml-group-handler.h
@@ -0,0 +1,50 @@
+/*
+ * 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_OPML_GROUP_HANDLER_H__
+#define __FEEDS_OPML_GROUP_HANDLER_H__
+
+#include "common.h"
+#include "feeds-group-handler.h"
+
+#define FEEDS_OPML_GROUP_HANDLER_TYPE (feeds_opml_group_handler_get_type())
+#define FEEDS_OPML_GROUP_HANDLER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FEEDS_OPML_GROUP_HANDLER_TYPE, FeedsOpmlGroupHandler))
+#define FEEDS_OPML_GROUP_HANDLER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), FEEDS_OPML_GROUP_HANDLER_TYPE, FeedsOpmlGroupHandlerClass))
+#define IS_FEEDS_OPML_GROUP_HANDLER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), FEEDS_OPML_GROUP_HANDLER_TYPE))
+#define IS_FEEDS_OPML_GROUP_HANDLER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), FEEDS_OPML_GROUP_HANDLER_TYPE))
+#define FEEDS_OPML_GROUP_HANDLER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), FEEDS_OPML_GROUP_HANDLER_TYPE, FeedsOpmlGroupHandlerClass))
+
+typedef struct FeedsOpmlGroupHandler FeedsOpmlGroupHandler;
+typedef struct FeedsOpmlGroupHandlerPrivate FeedsOpmlGroupHandlerPrivate;
+
+struct FeedsOpmlGroupHandler {
+ GObject parent;
+ FeedsOpmlGroupHandlerPrivate *priv;
+};
+
+typedef struct {
+ GObjectClass parent;
+} FeedsOpmlGroupHandlerClass;
+
+GType feeds_opml_group_handler_get_type (void) G_GNUC_CONST;
+
+FeedsOpmlGroupHandler* feeds_opml_group_handler_new ();
+
+#endif /* __FEEDS_OPML_GROUP_HANDLER_H__ */
diff --git a/src/feeds-pool.c b/src/feeds-pool.c
index a8cd612..154fddb 100644
--- a/src/feeds-pool.c
+++ b/src/feeds-pool.c
@@ -275,7 +275,7 @@ feed_downloaded (SoupSession *session, SoupMessage *msg, gpointer user_data)
g_warning ("Unable to download from %s", feed_channel_get_source (feed->channel));
}
else {
- doc = feed_content_to_xml ((const gchar*) msg->response_body->data, msg->response_body->length);
+ doc = content_to_xml ((const gchar*) msg->response_body->data, msg->response_body->length);
if (doc != NULL) {
error = NULL;
diff --git a/src/feeds-subscriber.c b/src/feeds-subscriber.c
index 9bba100..6653f88 100644
--- a/src/feeds-subscriber.c
+++ b/src/feeds-subscriber.c
@@ -322,7 +322,7 @@ handle_incoming_notification_cb (SoupServer *server, SoupMessage *msg, const cha
server as soon as possible
*/
- doc = feed_content_to_xml (msg->request_body->data, strlen (msg->request_body->data));
+ doc = content_to_xml (msg->request_body->data, strlen (msg->request_body->data));
error = NULL;
items = feed_parser_parse (feed->sub->priv->parser, feed->channel, doc, &error);
diff --git a/src/libgrss.h b/src/libgrss.h
index 822c42b..6e4c966 100644
--- a/src/libgrss.h
+++ b/src/libgrss.h
@@ -27,5 +27,6 @@
#include "feeds-store.h"
#include "feeds-pool.h"
#include "feeds-subscriber.h"
+#include "feeds-group.h"
#endif /* __LIBGRSS_H__ */
diff --git a/src/utils.c b/src/utils.c
index 2735efb..2224a8d 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -285,7 +285,7 @@ xml_process_entities (void *ctxt, const xmlChar *name)
}
xmlDocPtr
-feed_content_to_xml (const gchar *contents, gsize size)
+content_to_xml (const gchar *contents, gsize size)
{
xmlParserCtxtPtr ctxt;
xmlDocPtr doc;
diff --git a/src/utils.h b/src/utils.h
index 9affff5..77ac6b3 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -32,7 +32,7 @@ gchar* unhtmlize (gchar *string);
gchar* unxmlize (gchar * string);
gchar* xhtml_extract (xmlNodePtr xml, gint xhtmlMode, const gchar *defaultBase);
-xmlDocPtr feed_content_to_xml (const gchar *contents, gsize size);
+xmlDocPtr content_to_xml (const gchar *contents, gsize size);
time_t date_parse_RFC822 (const gchar *date);
time_t date_parse_ISO8601 (const gchar *date);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]