[libgrss] Introducing GrssFeedFormatter, GrssFeedRssFormatter and GrssFeedAtomFormatter
- From: Roberto Guido <rguido src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgrss] Introducing GrssFeedFormatter, GrssFeedRssFormatter and GrssFeedAtomFormatter
- Date: Fri, 25 Apr 2014 00:39:28 +0000 (UTC)
commit 1d6b54492b30b24d7c728b6b24c2873c64887c16
Author: Roberto Guido <rguido src gnome org>
Date: Fri Apr 25 02:38:46 2014 +0200
Introducing GrssFeedFormatter, GrssFeedRssFormatter and GrssFeedAtomFormatter
.../{libgrss-docs.sgml => libgrss-0.5-docs.sgml} | 3 +
src/Makefile.am | 6 +
src/feed-atom-formatter.c | 158 +++++++++++++++++
src/feed-atom-formatter.h | 48 +++++
src/feed-atom-handler.c | 1 +
src/feed-enclosure.c | 27 ++-
src/feed-formatter.c | 183 ++++++++++++++++++++
src/feed-formatter.h | 56 ++++++
src/feed-rss-formatter.c | 153 ++++++++++++++++
src/feed-rss-formatter.h | 48 +++++
src/feed-rss-handler.c | 2 +-
src/libgrss.h | 3 +
src/utils.c | 2 +-
tests/formatter.c | 90 ++++++++++
14 files changed, 769 insertions(+), 11 deletions(-)
---
diff --git a/doc/reference/libgrss-docs.sgml b/doc/reference/libgrss-0.5-docs.sgml
similarity index 93%
rename from doc/reference/libgrss-docs.sgml
rename to doc/reference/libgrss-0.5-docs.sgml
index b8c22f3..5533cf1 100644
--- a/doc/reference/libgrss-docs.sgml
+++ b/doc/reference/libgrss-0.5-docs.sgml
@@ -39,6 +39,9 @@
<xi:include href="xml/feeds-pool.xml"/>
<xi:include href="xml/feeds-group.xml"/>
<xi:include href="xml/feeds-subscriber.xml"/>
+ <xi:include href="xml/feed-formatter.xml"/>
+ <xi:include href="xml/feed-rss-formatter.xml"/>
+ <xi:include href="xml/feed-atom-formatter.xml"/>
<xi:include href="xml/feeds-publisher.xml"/>
<xi:include href="xml/feeds-store.xml"/>
</part>
diff --git a/src/Makefile.am b/src/Makefile.am
index 26ff8ef..11f5bbb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,10 +28,13 @@ sources_private_h = \
sources_public_h = \
libgrss.h \
+ feed-atom-formatter.h \
feed-channel.h \
feed-enclosure.h \
+ feed-formatter.h \
feed-item.h \
feed-parser.h \
+ feed-rss-formatter.h \
feeds-group.h \
feeds-pool.h \
feeds-publisher.h \
@@ -39,10 +42,13 @@ sources_public_h = \
feeds-subscriber.h
sources_public_c = \
+ feed-atom-formatter.c \
feed-channel.c \
feed-enclosure.c \
+ feed-formatter.c \
feed-item.c \
feed-parser.c \
+ feed-rss-formatter.c \
feeds-group.c \
feeds-pool.c \
feeds-publisher.c \
diff --git a/src/feed-atom-formatter.c b/src/feed-atom-formatter.c
new file mode 100644
index 0000000..4bb371d
--- /dev/null
+++ b/src/feed-atom-formatter.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2014, Roberto Guido <rguido src gnome org>
+ *
+ * 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 "feed-atom-formatter.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (GrssFeedAtomFormatter, grss_feed_atom_formatter, GRSS_FEED_FORMATTER_TYPE);
+
+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 void
+grss_feed_atom_formatter_class_init (GrssFeedAtomFormatterClass *klass)
+{
+ GrssFeedFormatterClass *formater_class = GRSS_FEED_FORMATTER_CLASS (klass);
+
+ formater_class->format = feed_atom_formatter_format;
+}
+
+static void
+grss_feed_atom_formatter_init (GrssFeedAtomFormatter *object)
+{
+}
+
+GrssFeedAtomFormatter*
+grss_feed_atom_formatter_new ()
+{
+ GrssFeedAtomFormatter *formatter;
+
+ formatter = g_object_new (GRSS_FEED_ATOM_FORMATTER_TYPE, NULL);
+ return formatter;
+}
+
diff --git a/src/feed-atom-formatter.h b/src/feed-atom-formatter.h
new file mode 100644
index 0000000..826e68c
--- /dev/null
+++ b/src/feed-atom-formatter.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014, Roberto Guido <rguido src gnome org>
+ *
+ * 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 __GRSS_FEED_ATOM_FORMATTER_H__
+#define __GRSS_FEED_ATOM_FORMATTER_H__
+
+#include "libgrss.h"
+
+#define GRSS_FEED_ATOM_FORMATTER_TYPE (grss_feed_atom_formatter_get_type())
+#define GRSS_FEED_ATOM_FORMATTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o),
GRSS_FEED_ATOM_FORMATTER_TYPE, GrssFeedAtomFormatter))
+#define GRSS_FEED_ATOM_FORMATTER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GRSS_FEED_ATOM_FORMATTER_TYPE,
GrssFeedAtomFormatterClass))
+#define GRSS_IS_FEED_ATOM_FORMATTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o),
GRSS_FEED_ATOM_FORMATTER_TYPE))
+#define GRSS_IS_FEED_ATOM_FORMATTER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c),
GRSS_FEED_ATOM_FORMATTER_TYPE))
+#define GRSS_FEED_ATOM_FORMATTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),
GRSS_FEED_ATOM_FORMATTER_TYPE, GrssFeedAtomFormatterClass))
+
+typedef struct GrssFeedAtomFormatter GrssFeedAtomFormatter;
+typedef struct GrssFeedAtomFormatterPrivate GrssFeedAtomFormatterPrivate;
+
+struct GrssFeedAtomFormatter {
+ GrssFeedFormatter parent;
+};
+
+typedef struct {
+ GrssFeedFormatterClass parent;
+} GrssFeedAtomFormatterClass;
+
+GType grss_feed_atom_formatter_get_type (void) G_GNUC_CONST;
+
+GrssFeedAtomFormatter* grss_feed_atom_formatter_new ();
+
+#endif /* __GRSS_FEED_ATOM_FORMATTER_H__ */
+
diff --git a/src/feed-atom-handler.c b/src/feed-atom-handler.c
index 7cedb62..84b8564 100644
--- a/src/feed-atom-handler.c
+++ b/src/feed-atom-handler.c
@@ -760,6 +760,7 @@ atom10_parse_feed_updated (xmlNodePtr cur, GrssFeedChannel *feed)
if (timestamp) {
t = date_parse_ISO8601 (timestamp);
grss_feed_channel_set_update_time (feed, t);
+ grss_feed_channel_set_publish_time (feed, t);
g_free (timestamp);
}
}
diff --git a/src/feed-enclosure.c b/src/feed-enclosure.c
index 7a62496..632b9a9 100644
--- a/src/feed-enclosure.c
+++ b/src/feed-enclosure.c
@@ -52,7 +52,8 @@ feed_enclosure_error_quark ()
return g_quark_from_static_string ("feed_enclosure_error");
}
-static void grss_feed_enclosure_finalize (GObject *obj)
+static void
+grss_feed_enclosure_finalize (GObject *obj)
{
GrssFeedEnclosure *enclosure;
@@ -61,7 +62,8 @@ static void grss_feed_enclosure_finalize (GObject *obj)
FREE_STRING (enclosure->priv->type);
}
-static void grss_feed_enclosure_class_init (GrssFeedEnclosureClass *klass)
+static void
+grss_feed_enclosure_class_init (GrssFeedEnclosureClass *klass)
{
GObjectClass *gobject_class;
@@ -71,7 +73,8 @@ static void grss_feed_enclosure_class_init (GrssFeedEnclosureClass *klass)
gobject_class->finalize = grss_feed_enclosure_finalize;
}
-static void grss_feed_enclosure_init (GrssFeedEnclosure *node)
+static void
+grss_feed_enclosure_init (GrssFeedEnclosure *node)
{
node->priv = FEED_ENCLOSURE_GET_PRIVATE (node);
memset (node->priv, 0, sizeof (GrssFeedEnclosurePrivate));
@@ -85,7 +88,8 @@ static void grss_feed_enclosure_init (GrssFeedEnclosure *node)
*
* Return value: a new #GrssFeedEnclosure.
*/
-GrssFeedEnclosure* grss_feed_enclosure_new (gchar *url)
+GrssFeedEnclosure*
+grss_feed_enclosure_new (gchar *url)
{
GrssFeedEnclosure *ret;
@@ -102,7 +106,8 @@ GrssFeedEnclosure* grss_feed_enclosure_new (gchar *url)
*
* Return value: the URL where the enclosure may be found.
*/
-const gchar* grss_feed_enclosure_get_url (GrssFeedEnclosure *enclosure)
+const gchar*
+grss_feed_enclosure_get_url (GrssFeedEnclosure *enclosure)
{
return (const gchar*) enclosure->priv->url;
}
@@ -114,7 +119,8 @@ const gchar* grss_feed_enclosure_get_url (GrssFeedEnclosure *enclosure)
*
* To set the type of the external file.
*/
-void grss_feed_enclosure_set_format (GrssFeedEnclosure *enclosure, gchar *type)
+void
+grss_feed_enclosure_set_format (GrssFeedEnclosure *enclosure, gchar *type)
{
FREE_STRING (enclosure->priv->type);
enclosure->priv->type = g_strdup (type);
@@ -128,7 +134,8 @@ void grss_feed_enclosure_set_format (GrssFeedEnclosure *enclosure, gchar *type)
*
* Return value: type of @enclosure.
*/
-const gchar* grss_feed_enclosure_get_format (GrssFeedEnclosure *enclosure)
+const gchar*
+grss_feed_enclosure_get_format (GrssFeedEnclosure *enclosure)
{
return (const gchar*) enclosure->priv->type;
}
@@ -140,7 +147,8 @@ const gchar* grss_feed_enclosure_get_format (GrssFeedEnclosure *enclosure)
*
* To set the size of the embedded @enclosure.
*/
-void grss_feed_enclosure_set_length (GrssFeedEnclosure *enclosure, gsize length)
+void
+grss_feed_enclosure_set_length (GrssFeedEnclosure *enclosure, gsize length)
{
enclosure->priv->length = length;
}
@@ -153,7 +161,8 @@ void grss_feed_enclosure_set_length (GrssFeedEnclosure *enclosure, gsize length)
*
* Return value: size of the @enclosure, in bytes.
*/
-gsize grss_feed_enclosure_get_length (GrssFeedEnclosure *enclosure)
+gsize
+grss_feed_enclosure_get_length (GrssFeedEnclosure *enclosure)
{
return enclosure->priv->length;
}
diff --git a/src/feed-formatter.c b/src/feed-formatter.c
new file mode 100644
index 0000000..147b271
--- /dev/null
+++ b/src/feed-formatter.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2014, Roberto Guido <rguido src gnome org>
+ *
+ * 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 "feed-formatter.h"
+#include "utils.h"
+#include "feed-item.h"
+#include "feed-channel.h"
+
+#define FEED_FORMATTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),
GRSS_FEED_FORMATTER_TYPE, GrssFeedFormatterPrivate))
+
+/**
+ * SECTION: feed-formatter
+ * @short_description: abstract class to format feeds in plain rappresentation
+ *
+ * #GrssFeedFormatter is a class abstracting the ability to format a
+ * #GrssFeedChannel and related #GrssFeedItems into a plain text string, usually
+ * in XML. Subclasses implement the effective required format (e.g. RSS,
+ * Atom...)
+ */
+
+G_DEFINE_ABSTRACT_TYPE (GrssFeedFormatter, grss_feed_formatter, G_TYPE_OBJECT);
+
+struct _GrssFeedFormatterPrivate {
+ GrssFeedChannel *channel;
+ GList *items;
+};
+
+static void
+grss_feed_formatter_class_init (GrssFeedFormatterClass *klass)
+{
+ g_type_class_add_private (klass, sizeof (GrssFeedFormatterPrivate));
+}
+
+static void
+grss_feed_formatter_init (GrssFeedFormatter *node)
+{
+ node->priv = FEED_FORMATTER_GET_PRIVATE (node);
+ node->priv->channel = NULL;
+ node->priv->items = NULL;
+}
+
+/**
+ * grss_feed_formatter_set_channel:
+ * @formatter: a #GrssFeedFormatter.
+ * @channel: the reference #GrssFeedChannel for the @formatter.
+ *
+ * Inits the #GrssFeedFormatter with the given @channel. A #GrssFeedFormatter
+ * can format a single #GrssFeedChannel each time, but may be reused by calling
+ * grss_feed_formatter_reset()
+ */
+void
+grss_feed_formatter_set_channel (GrssFeedFormatter *formatter, GrssFeedChannel *channel)
+{
+ if (formatter->priv->channel != NULL)
+ g_object_unref (formatter->priv->channel);
+
+ formatter->priv->channel = channel;
+ g_object_ref (channel);
+}
+
+/**
+ * grss_feed_formatter_get_channel:
+ * @formatter: a #GrssFeedFormatter.
+ *
+ * Gets the current #GrssFeedChannel assigned to the @formatter.
+ *
+ * Return value: (transfer none): a #GrssFeedChannel, or %NULL if none has been
+ * assigned.
+ */
+GrssFeedChannel*
+grss_feed_formatter_get_channel (GrssFeedFormatter *formatter)
+{
+ return formatter->priv->channel;
+}
+
+/**
+ * grss_feed_formatter_add_item:
+ * @formatter: a #GrssFeedFormatter.
+ * @item: a #GrssFeedItem to add into the @formatter.
+ *
+ * Adds a single #GrssFeedItem in the @formatter.
+ */
+void
+grss_feed_formatter_add_item (GrssFeedFormatter *formatter, GrssFeedItem *item)
+{
+ g_object_ref (item);
+
+ if (formatter->priv->items == NULL)
+ formatter->priv->items = g_list_prepend (formatter->priv->items, item);
+ else
+ formatter->priv->items = g_list_append (formatter->priv->items, item);
+}
+
+/**
+ * grss_feed_formatter_add_items:
+ * @formatter: a #GrssFeedFormatter.
+ * @items: (element-type GrssFeedItem): a list of #GrssFeedItems to add into
+ * the @formatter.
+ *
+ * Adds a list of #GrssFeedItems in the @formatter.
+ */
+void
+grss_feed_formatter_add_items (GrssFeedFormatter *formatter, GList *items)
+{
+ GList *copy;
+
+ copy = g_list_copy_deep (items, (GCopyFunc) g_object_ref, NULL);
+
+ if (formatter->priv->items == NULL)
+ formatter->priv->items = copy;
+ else
+ formatter->priv->items = g_list_concat (formatter->priv->items, copy);
+}
+
+/**
+ * grss_feed_formatter_get_items:
+ * @formatter: a #GrssFeedFormatter.
+ *
+ * Gets the current #GrssFeedItems assigned to the @formatter.
+ *
+ * Return value: (element-type GrssFeedItem) (transfer none): a list of
+ * #GrssFeedItems, or %NULL if none has been assigned.
+ */
+GList*
+grss_feed_formatter_get_items (GrssFeedFormatter *formatter)
+{
+ return formatter->priv->items;
+}
+
+/**
+ * grss_feed_formatter_reset:
+ * @formatter: a #GrssFeedFormatter.
+ *
+ * Resets the status of the #GrssFeedFormatter, cleaning up the assigned
+ * #GrssFeedChannel and related #GrssFeedItems. This way @formatter is ready to
+ * be used again with new data.
+ */
+void
+grss_feed_formatter_reset (GrssFeedFormatter *formatter)
+{
+ if (formatter->priv->channel != NULL) {
+ g_object_unref (formatter->priv->channel);
+ formatter->priv->channel = NULL;
+ }
+
+ if (formatter->priv->items != NULL) {
+ g_list_free_full (formatter->priv->items, g_object_unref);
+ formatter->priv->items = NULL;
+ }
+}
+
+/**
+ * grss_feed_formatter_format:
+ * @formatter: a #GrssFeedFormatter.
+ *
+ * Formats the assigned #GrssFeedChannel and #GrssFeedItems into a plain text
+ * string, accordly to the current #GrssFeedFormatter instance.
+ *
+ * Return value: (transfer full): a string containing the plain text
+ * rappresentation of the given channel containing the given items.
+ */
+gchar*
+grss_feed_formatter_format (GrssFeedFormatter *formatter)
+{
+ return GRSS_FEED_FORMATTER_GET_CLASS (formatter)->format (formatter);
+}
+
diff --git a/src/feed-formatter.h b/src/feed-formatter.h
new file mode 100644
index 0000000..0668447
--- /dev/null
+++ b/src/feed-formatter.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014, Roberto Guido <rguido src gnome org>
+ *
+ * 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 "libgrss.h"
+
+#ifndef __FEED_FORMATTER_H__
+#define __FEED_FORMATTER_H__
+
+#define GRSS_FEED_FORMATTER_TYPE (grss_feed_formatter_get_type())
+#define GRSS_FEED_FORMATTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GRSS_FEED_FORMATTER_TYPE,
GrssFeedFormatter))
+#define GRSS_FEED_FORMATTER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GRSS_FEED_FORMATTER_TYPE,
GrssFeedFormatterClass))
+#define GRSS_IS_FEED_FORMATTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GRSS_FEED_FORMATTER_TYPE))
+#define GRSS_IS_FEED_FORMATTER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c),
GRSS_FEED_FORMATTER_TYPE))
+#define GRSS_FEED_FORMATTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GRSS_FEED_FORMATTER_TYPE,
GrssFeedFormatterClass))
+
+typedef struct _GrssFeedFormatter GrssFeedFormatter;
+typedef struct _GrssFeedFormatterPrivate GrssFeedFormatterPrivate;
+
+struct _GrssFeedFormatter {
+ GObject parent;
+ GrssFeedFormatterPrivate *priv;
+};
+
+typedef struct {
+ GObjectClass parent;
+
+ gchar* (*format) (GrssFeedFormatter *formatter);
+} GrssFeedFormatterClass;
+
+GType grss_feed_formatter_get_type () G_GNUC_CONST;
+
+void grss_feed_formatter_set_channel (GrssFeedFormatter *formatter, GrssFeedChannel
*channel);
+GrssFeedChannel* grss_feed_formatter_get_channel (GrssFeedFormatter *formatter);
+void grss_feed_formatter_add_item (GrssFeedFormatter *formatter, GrssFeedItem *item);
+void grss_feed_formatter_add_items (GrssFeedFormatter *formatter, GList *items);
+GList* grss_feed_formatter_get_items (GrssFeedFormatter *formatter);
+void grss_feed_formatter_reset (GrssFeedFormatter *formatter);
+gchar* grss_feed_formatter_format (GrssFeedFormatter *formatter);
+
+#endif /* __FEED_FORMATTER_H__ */
diff --git a/src/feed-rss-formatter.c b/src/feed-rss-formatter.c
new file mode 100644
index 0000000..254174b
--- /dev/null
+++ b/src/feed-rss-formatter.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2014, Roberto Guido <rguido src gnome org>
+ *
+ * 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 "feed-rss-formatter.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (GrssFeedRssFormatter, grss_feed_rss_formatter, GRSS_FEED_FORMATTER_TYPE);
+
+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;
+ 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);
+
+ str = grss_feed_channel_get_editor (channel);
+ if (str != NULL)
+ g_string_append_printf (text, "\t<managingEditor>%s</managingEditor>\n", str);
+
+ 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);
+
+ str = grss_feed_item_get_author (item);
+ if (str != NULL)
+ g_string_append_printf (text, "\t\t<author>%s</author>\n", str);
+
+ 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 void
+grss_feed_rss_formatter_class_init (GrssFeedRssFormatterClass *klass)
+{
+ GrssFeedFormatterClass *formater_class = GRSS_FEED_FORMATTER_CLASS (klass);
+
+ formater_class->format = feed_rss_formatter_format;
+}
+
+static void
+grss_feed_rss_formatter_init (GrssFeedRssFormatter *object)
+{
+}
+
+GrssFeedRssFormatter*
+grss_feed_rss_formatter_new ()
+{
+ GrssFeedRssFormatter *formatter;
+
+ formatter = g_object_new (GRSS_FEED_RSS_FORMATTER_TYPE, NULL);
+ return formatter;
+}
+
diff --git a/src/feed-rss-formatter.h b/src/feed-rss-formatter.h
new file mode 100644
index 0000000..5a3764b
--- /dev/null
+++ b/src/feed-rss-formatter.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014, Roberto Guido <rguido src gnome org>
+ *
+ * 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 __GRSS_FEED_RSS_FORMATTER_H__
+#define __GRSS_FEED_RSS_FORMATTER_H__
+
+#include "libgrss.h"
+
+#define GRSS_FEED_RSS_FORMATTER_TYPE (grss_feed_rss_formatter_get_type())
+#define GRSS_FEED_RSS_FORMATTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o),
GRSS_FEED_RSS_FORMATTER_TYPE, GrssFeedRssFormatter))
+#define GRSS_FEED_RSS_FORMATTER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GRSS_FEED_RSS_FORMATTER_TYPE,
GrssFeedRssFormatterClass))
+#define GRSS_IS_FEED_RSS_FORMATTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o),
GRSS_FEED_RSS_FORMATTER_TYPE))
+#define GRSS_IS_FEED_RSS_FORMATTER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GRSS_FEED_RSS_FORMATTER_TYPE))
+#define GRSS_FEED_RSS_FORMATTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),
GRSS_FEED_RSS_FORMATTER_TYPE, GrssFeedRssFormatterClass))
+
+typedef struct GrssFeedRssFormatter GrssFeedRssFormatter;
+typedef struct GrssFeedRssFormatterPrivate GrssFeedRssFormatterPrivate;
+
+struct GrssFeedRssFormatter {
+ GrssFeedFormatter parent;
+};
+
+typedef struct {
+ GrssFeedFormatterClass parent;
+} GrssFeedRssFormatterClass;
+
+GType grss_feed_rss_formatter_get_type (void) G_GNUC_CONST;
+
+GrssFeedRssFormatter* grss_feed_rss_formatter_new ();
+
+#endif /* __GRSS_FEED_RSS_FORMATTER_H__ */
+
diff --git a/src/feed-rss-handler.c b/src/feed-rss-handler.c
index 3a7f379..2782c24 100644
--- a/src/feed-rss-handler.c
+++ b/src/feed-rss-handler.c
@@ -226,7 +226,7 @@ parse_channel (FeedRssHandler *parser, GrssFeedChannel *feed, xmlDocPtr doc, xml
}
}
else if (!xmlStrcmp (cur->name, BAD_CAST"description")) {
- tmp = xhtml_extract (cur, 0, NULL);
+ tmp = (gchar*) xmlNodeListGetString (doc, cur->xmlChildrenNode, TRUE);
if (tmp) {
grss_feed_channel_set_description (feed, tmp);
g_free (tmp);
diff --git a/src/libgrss.h b/src/libgrss.h
index 1d5addc..84032ca 100644
--- a/src/libgrss.h
+++ b/src/libgrss.h
@@ -35,6 +35,9 @@
#include "feed-enclosure.h"
#include "feed-item.h"
#include "feed-parser.h"
+#include "feed-formatter.h"
+#include "feed-atom-formatter.h"
+#include "feed-rss-formatter.h"
#include "feeds-store.h"
#include "feeds-pool.h"
#include "feeds-subscriber.h"
diff --git a/src/utils.c b/src/utils.c
index d87c78a..d5dd1c1 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -519,7 +519,7 @@ date_to_ISO8601 (time_t date)
struct tm broken;
localtime_r (&date, &broken);
- strftime (text, 100, "%Y-%m-%dT%H:%M", &broken);
+ strftime (text, 100, "%Y-%m-%dT%H:%MZ", &broken);
return g_strdup (text);
}
diff --git a/tests/formatter.c b/tests/formatter.c
new file mode 100644
index 0000000..c88eace
--- /dev/null
+++ b/tests/formatter.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014, Roberto Guido <rguido src gnome org>
+ *
+ * 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 <libgrss.h>
+
+#define TEST_CHANNEL_TITLE "Test Feed"
+#define TEST_CHANNEL_COPYRIGHT "Copyright 2014 John Doe"
+#define TEST_CHANNEL_DESCRIPTION "A test fake feed"
+
+static void
+do_the_job (GrssFeedFormatter *formatter)
+{
+ gchar *xml;
+ GrssFeedChannel *channel;
+ GError *error;
+
+ channel = grss_feed_channel_new ();
+ grss_feed_channel_set_title (channel, TEST_CHANNEL_TITLE);
+ grss_feed_channel_set_copyright (channel, TEST_CHANNEL_COPYRIGHT);
+ grss_feed_channel_set_description (channel, TEST_CHANNEL_DESCRIPTION);
+
+ grss_feed_formatter_set_channel (formatter, channel);
+ g_object_unref (channel);
+
+ xml = grss_feed_formatter_format (formatter);
+ g_assert (xml != NULL);
+
+ error = NULL;
+ channel = grss_feed_channel_new_from_memory (xml, &error);
+ g_free (xml);
+
+ if (error != NULL) {
+ printf ("%s\n", error->message);
+ g_error_free (error);
+ g_test_fail ();
+ }
+
+ g_assert (channel != NULL);
+ g_assert_cmpstr (grss_feed_channel_get_title (channel), ==, TEST_CHANNEL_TITLE);
+ g_assert_cmpstr (grss_feed_channel_get_copyright (channel), ==, TEST_CHANNEL_COPYRIGHT);
+ g_assert_cmpstr (grss_feed_channel_get_description (channel), ==, TEST_CHANNEL_DESCRIPTION);
+
+ g_object_unref (channel);
+}
+
+static void
+test_format_atom ()
+{
+ GrssFeedAtomFormatter *formatter;
+
+ formatter = grss_feed_atom_formatter_new ();
+ do_the_job (GRSS_FEED_FORMATTER (formatter));
+}
+
+static void
+test_format_rss ()
+{
+ GrssFeedRssFormatter *formatter;
+
+ formatter = grss_feed_rss_formatter_new ();
+ do_the_job (GRSS_FEED_FORMATTER (formatter));
+}
+
+int
+main (int argc, char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/formatter/format_atom", test_format_atom);
+ g_test_add_func ("/formatter/format_rss", test_format_rss);
+
+ return g_test_run ();
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]