[libgrss] Added grss_feed_channel_fetch_all_async() and relative _finish functions RSSCloud handler fetches it
- From: Roberto Guido <rguido src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgrss] Added grss_feed_channel_fetch_all_async() and relative _finish functions RSSCloud handler fetches it
- Date: Wed, 28 Dec 2011 18:44:11 +0000 (UTC)
commit b6d10a5021ee6636ca20a519efd7dafd079063b2
Author: Roberto Guido <bob4mail gmail com>
Date: Wed Dec 28 10:46:42 2011 -0800
Added grss_feed_channel_fetch_all_async() and relative _finish functions
RSSCloud handler fetches items asyncronously
Added an example about asyncronous feed fetching
Removed some unused variables
doc/reference/libgrss-sections.txt | 5 ++
examples/async-fetcher.c | 83 ++++++++++++++++++++++++
src/Makefile.am | 1 +
src/feed-atom-handler.c | 14 +----
src/feed-channel.c | 120 ++++++++++++++++++++++++++++++++---
src/feed-channel.h | 4 +
src/feed-parser.c | 3 -
src/feed-pie-handler.c | 3 -
src/feed-rss-handler.c | 3 -
src/feeds-group.c | 14 +++-
src/feeds-opml-group-handler.c | 5 --
src/feeds-pool.c | 2 +-
src/feeds-publisher.c | 4 +-
src/feeds-pubsubhubbub-subscriber.c | 2 +-
src/feeds-rsscloud-subscriber.c | 22 ++++++-
src/feeds-subscriber-private.h | 26 ++++++++
src/feeds-subscriber.c | 66 ++++++++++++++++++--
src/feeds-xbel-group-handler.c | 5 --
src/feeds-xoxo-group-handler.c | 5 --
19 files changed, 328 insertions(+), 59 deletions(-)
---
diff --git a/doc/reference/libgrss-sections.txt b/doc/reference/libgrss-sections.txt
index 488af51..96707d9 100644
--- a/doc/reference/libgrss-sections.txt
+++ b/doc/reference/libgrss-sections.txt
@@ -17,6 +17,7 @@ GrssFeedsPool
grss_feeds_pool_new
grss_feeds_pool_listen
grss_feeds_pool_get_listened
+grss_feeds_pool_get_listened_num
grss_feeds_pool_switch
grss_feeds_pool_get_session
</SECTION>
@@ -147,6 +148,10 @@ grss_feed_channel_set_update_interval
grss_feed_channel_get_update_interval
grss_feed_channel_fetch
grss_feed_channel_fetch_async
+grss_feed_channel_fetch_finish
+grss_feed_channel_fetch_all
+grss_feed_channel_fetch_all_async
+grss_feed_channel_fetch_all_finish
</SECTION>
<SECTION>
diff --git a/examples/async-fetcher.c b/examples/async-fetcher.c
new file mode 100644
index 0000000..351422b
--- /dev/null
+++ b/examples/async-fetcher.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011, 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 <libgrss.h>
+
+static int i;
+static GMainLoop *loop;
+
+static gboolean mark_time (gpointer useless)
+{
+ printf ("%d\n", i++);
+
+ if (i >= 10)
+ g_main_loop_quit (loop);
+
+ return TRUE;
+}
+
+static void
+print_items (GObject *source, GAsyncResult *res, gpointer useless)
+{
+ GList *items;
+ GList *iter;
+ GError *error;
+ GrssFeedChannel *channel;
+ GrssFeedItem *it;
+
+ error = NULL;
+ channel = GRSS_FEED_CHANNEL (source);
+ items = grss_feed_channel_fetch_all_finish (channel, res, &error);
+
+ if (items == NULL) {
+ printf ("%s\n", error->message);
+ }
+ else {
+ for (iter = items; iter; iter = g_list_next (iter)) {
+ it = (GrssFeedItem*) iter->data;
+ printf ("%s\n", grss_feed_item_get_title (it));
+ }
+ }
+}
+
+static gboolean do_work (gpointer useless)
+{
+ GrssFeedChannel *feed;
+
+ i = 0;
+ g_timeout_add (100, mark_time, NULL);
+
+ feed = grss_feed_channel_new_from_source ("http://rss.slashdot.org/Slashdot/slashdot");
+ grss_feed_channel_fetch_all_async (feed, print_items, NULL);
+
+ return FALSE;
+}
+
+int main ()
+{
+ g_type_init ();
+ g_thread_init (NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_idle_add (do_work, NULL);
+
+ g_main_run (loop);
+ exit (0);
+}
diff --git a/src/Makefile.am b/src/Makefile.am
index 7643455..8587d73 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,6 +20,7 @@ sources_private_h = \
feeds-pubsubhubbub-subscriber.h \
feeds-rsscloud-subscriber.h \
feeds-subscriber-handler.h \
+ feeds-subscriber-private.h \
feeds-xbel-group-handler.h \
feeds-xoxo-group-handler.h \
ns-handler.h \
diff --git a/src/feed-atom-handler.c b/src/feed-atom-handler.c
index acf05d4..fdfaf04 100644
--- a/src/feed-atom-handler.c
+++ b/src/feed-atom-handler.c
@@ -62,9 +62,6 @@ feed_atom_handler_error_quark ()
static void
feed_atom_handler_finalize (GObject *object)
{
- FeedAtomHandler *parser;
-
- parser = FEED_ATOM_HANDLER (object);
G_OBJECT_CLASS (feed_atom_handler_parent_class)->finalize (object);
}
@@ -277,7 +274,6 @@ atom10_parse_person_construct (xmlNodePtr cur)
gchar *name = NULL;
gchar *uri = NULL;
gchar *email = NULL;
- gboolean invalid = FALSE;
cur = cur->xmlChildrenNode;
while (cur) {
@@ -293,8 +289,6 @@ atom10_parse_person_construct (xmlNodePtr cur)
}
if (xmlStrEqual (cur->name, BAD_CAST"email")) {
- if (email)
- invalid = TRUE;
g_free (email);
tmp = (gchar *)xmlNodeListGetString(cur->doc, cur->xmlChildrenNode, 1);
email = g_strdup_printf(" - <a href=\"mailto:%s\">%s</a>", tmp, tmp);
@@ -302,8 +296,6 @@ atom10_parse_person_construct (xmlNodePtr cur)
}
if (xmlStrEqual (cur->name, BAD_CAST"uri")) {
- if (!uri)
- invalid = TRUE;
g_free (uri);
tmp = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
uri = g_strdup_printf (" (<a href=\"%s\">Website</a>)", tmp);
@@ -316,12 +308,10 @@ atom10_parse_person_construct (xmlNodePtr cur)
cur = cur->next;
}
- if (!name) {
- invalid = TRUE;
+
+ if (!name)
name = g_strdup ("Invalid Atom feed: unknown author");
- }
- /* FIXME: so somthing with "invalid" flag */
tmp = g_strdup_printf ("%s%s%s", name, uri ? uri : "", email ? email : "");
if (uri)
diff --git a/src/feed-channel.c b/src/feed-channel.c
index 9be471f..530d344 100644
--- a/src/feed-channel.c
+++ b/src/feed-channel.c
@@ -68,6 +68,7 @@ struct _GrssFeedChannelPrivate {
enum {
FEEDS_CHANNEL_FETCH_ERROR,
+ FEEDS_CHANNEL_PARSE_ERROR
};
G_DEFINE_TYPE (GrssFeedChannel, grss_feed_channel, G_TYPE_OBJECT);
@@ -827,7 +828,9 @@ feed_downloaded (SoupSession *session, SoupMessage *msg, gpointer user_data) {
g_object_get (msg, "status-code", &status, NULL);
if (status >= 200 && status <= 299) {
- quick_and_dirty_parse (channel, msg, NULL);
+ if (quick_and_dirty_parse (channel, msg, NULL) == FALSE)
+ g_simple_async_result_set_error (result, FEEDS_CHANNEL_ERROR, FEEDS_CHANNEL_PARSE_ERROR,
+ "Unable to parse feed from %s", grss_feed_channel_get_source (channel));
}
else {
g_simple_async_result_set_error (result, FEEDS_CHANNEL_ERROR, FEEDS_CHANNEL_FETCH_ERROR,
@@ -839,6 +842,25 @@ feed_downloaded (SoupSession *session, SoupMessage *msg, gpointer user_data) {
}
/**
+ * grss_feed_channel_fetch_finish:
+ * @channel: a #GrssFeedChannel
+ * @res: the #GAsyncResult passed to the callback
+ * @error: if an error occourred, FALSE is returned and this is filled with the message
+ *
+ * Finalizes an asyncronous operation started with grss_feed_channel_fetch_async()
+ *
+ * Return value: TRUE if @channel informations have been successfully fetched, FALSE otherwise
+ */
+gboolean
+grss_feed_channel_fetch_finish (GrssFeedChannel *channel, GAsyncResult *res, GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+/**
* grss_feed_channel_fetch_async:
* @channel: a #GrssFeedChannel
* @callback: function to invoke at the end of the download
@@ -873,7 +895,6 @@ grss_feed_channel_fetch_async (GrssFeedChannel *channel, GAsyncReadyCallback cal
GList*
grss_feed_channel_fetch_all (GrssFeedChannel *channel)
{
- gboolean ret;
guint status;
GList *items;
SoupMessage *msg;
@@ -884,15 +905,98 @@ grss_feed_channel_fetch_all (GrssFeedChannel *channel)
status = soup_session_send_message (session, msg);
items = NULL;
- if (status >= 200 && status <= 299) {
- ret = quick_and_dirty_parse (channel, msg, &items);
- }
- else {
+ if (status >= 200 && status <= 299)
+ quick_and_dirty_parse (channel, msg, &items);
+ else
g_warning ("Unable to fetch feed from %s: %s", grss_feed_channel_get_source (channel), soup_status_get_phrase (status));
- ret = FALSE;
- }
g_object_unref (session);
g_object_unref (msg);
return items;
}
+
+static void
+free_items_list (gpointer list)
+{
+ GList *items;
+ GList *iter;
+
+ items = list;
+
+ for (iter = items; iter; iter = g_list_next (iter))
+ g_object_unref (iter->data);
+
+ g_list_free (items);
+}
+
+static void
+feed_downloaded_return_items (SoupSession *session, SoupMessage *msg, gpointer user_data)
+{
+ guint status;
+ GList *items;
+ GSimpleAsyncResult *result;
+ GrssFeedChannel *channel;
+
+ result = user_data;
+ channel = GRSS_FEED_CHANNEL (g_async_result_get_source_object (G_ASYNC_RESULT (result)));
+ g_object_get (msg, "status-code", &status, NULL);
+
+ if (status >= 200 && status <= 299) {
+ items = NULL;
+
+ if (quick_and_dirty_parse (channel, msg, &items) == TRUE)
+ g_simple_async_result_set_op_res_gpointer (result, items, free_items_list);
+ else
+ g_simple_async_result_set_error (result, FEEDS_CHANNEL_ERROR, FEEDS_CHANNEL_PARSE_ERROR,
+ "Unable to parse feed from %s", grss_feed_channel_get_source (channel));
+ }
+ else {
+ g_simple_async_result_set_error (result, FEEDS_CHANNEL_ERROR, FEEDS_CHANNEL_FETCH_ERROR,
+ "Unable to download from %s", grss_feed_channel_get_source (channel));
+ }
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+/**
+ * grss_feed_channel_fetch_all_async:
+ * @channel: a #GrssFeedChannel
+ * @callback: function to invoke at the end of the download
+ * @user_data: data passed to the callback
+ *
+ * Similar to grss_feed_channel_fetch_all(), but asyncronous
+ */
+void
+grss_feed_channel_fetch_all_async (GrssFeedChannel *channel, GAsyncReadyCallback callback, gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ SoupMessage *msg;
+ SoupSession *session;
+
+ result = g_simple_async_result_new (G_OBJECT (channel), callback, user_data, grss_feed_channel_fetch_async);
+
+ session = soup_session_async_new ();
+ msg = soup_message_new ("GET", grss_feed_channel_get_source (channel));
+ soup_session_queue_message (session, msg, feed_downloaded_return_items, result);
+}
+
+/**
+ * grss_feed_channel_fetch_all_finish:
+ * @channel: a #GrssFeedChannel
+ * @res: the #GAsyncResult passed to the callback
+ * @error: if an error occourred, NULL is returned and this is filled with the message
+ *
+ * Finalizes an asyncronous operation started with grss_feed_channel_fetch_all_async()
+ *
+ * Return value: list of items fetched from the #GrssFeedChannel, or NULL if @error is set. The
+ * list (and contained items) is freed at the end of the callback
+ */
+GList*
+grss_feed_channel_fetch_all_finish (GrssFeedChannel *channel, GAsyncResult *res, GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ return NULL;
+ else
+ return (GList*) g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
+}
diff --git a/src/feed-channel.h b/src/feed-channel.h
index bb04ba7..4582d6b 100644
--- a/src/feed-channel.h
+++ b/src/feed-channel.h
@@ -45,6 +45,7 @@ typedef struct {
GType grss_feed_channel_get_type (void) G_GNUC_CONST;
GrssFeedChannel* grss_feed_channel_new ();
+GrssFeedChannel* grss_feed_channel_new_from_source (gchar *source);
GrssFeedChannel* grss_feed_channel_new_from_file (const gchar *path);
void grss_feed_channel_set_source (GrssFeedChannel *channel, gchar *source);
@@ -88,6 +89,9 @@ int grss_feed_channel_get_update_interval (GrssFeedChannel *channel);
gboolean grss_feed_channel_fetch (GrssFeedChannel *channel);
void grss_feed_channel_fetch_async (GrssFeedChannel *channel, GAsyncReadyCallback callback, gpointer user_data);
+gboolean grss_feed_channel_fetch_finish (GrssFeedChannel *channel, GAsyncResult *res, GError **error);
GList* grss_feed_channel_fetch_all (GrssFeedChannel *channel);
+void grss_feed_channel_fetch_all_async (GrssFeedChannel *channel, GAsyncReadyCallback callback, gpointer user_data);
+GList* grss_feed_channel_fetch_all_finish (GrssFeedChannel *channel, GAsyncResult *res, GError **error);
#endif /* __FEED_CHANNEL_H__ */
diff --git a/src/feed-parser.c b/src/feed-parser.c
index 37f5d5d..1774ccd 100644
--- a/src/feed-parser.c
+++ b/src/feed-parser.c
@@ -65,9 +65,6 @@ grss_feed_parser_error_quark ()
static void
grss_feed_parser_finalize (GObject *object)
{
- GrssFeedParser *parser;
-
- parser = GRSS_FEED_PARSER (object);
G_OBJECT_CLASS (grss_feed_parser_parent_class)->finalize (object);
}
diff --git a/src/feed-pie-handler.c b/src/feed-pie-handler.c
index 056ffa2..1e32f09 100644
--- a/src/feed-pie-handler.c
+++ b/src/feed-pie-handler.c
@@ -61,9 +61,6 @@ feed_pie_handler_error_quark ()
static void
feed_pie_handler_finalize (GObject *object)
{
- FeedPieHandler *parser;
-
- parser = FEED_PIE_HANDLER (object);
G_OBJECT_CLASS (feed_pie_handler_parent_class)->finalize (object);
}
diff --git a/src/feed-rss-handler.c b/src/feed-rss-handler.c
index bbcfa05..339db79 100644
--- a/src/feed-rss-handler.c
+++ b/src/feed-rss-handler.c
@@ -74,9 +74,6 @@ feed_rss_handler_error_quark ()
static void
feed_rss_handler_finalize (GObject *object)
{
- FeedRssHandler *parser;
-
- parser = FEED_RSS_HANDLER (object);
G_OBJECT_CLASS (feed_rss_handler_parent_class)->finalize (object);
}
diff --git a/src/feeds-group.c b/src/feeds-group.c
index f09e565..fc21966 100644
--- a/src/feeds-group.c
+++ b/src/feeds-group.c
@@ -57,9 +57,6 @@ grss_feeds_group_error_quark ()
static void
grss_feeds_group_finalize (GObject *object)
{
- GrssFeedsGroup *group;
-
- group = FEEDS_GROUP (object);
G_OBJECT_CLASS (grss_feeds_group_parent_class)->finalize (object);
}
@@ -192,8 +189,17 @@ grss_feeds_group_parse_file (GrssFeedsGroup *group, const gchar *path, GError **
return items;
}
+/**
+ * grss_feeds_group_export_file:
+ * @group:
+ * @channels:
+ * @path:
+ * @error:
+ *
+ * Return value: FALSE
+ */
gboolean
-grss_feeds_group_export_file (GrssFeedsGroup *groups, GList *channels, const gchar *path, GError *error)
+grss_feeds_group_export_file (GrssFeedsGroup *group, GList *channels, const gchar *path, GError *error)
{
return FALSE;
}
diff --git a/src/feeds-opml-group-handler.c b/src/feeds-opml-group-handler.c
index 38c21ef..009a42b 100644
--- a/src/feeds-opml-group-handler.c
+++ b/src/feeds-opml-group-handler.c
@@ -45,9 +45,6 @@ G_DEFINE_TYPE_WITH_CODE (FeedsOpmlGroupHandler, feeds_opml_group_handler, G_TYPE
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);
}
@@ -188,10 +185,8 @@ feeds_opml_group_handler_parse (GrssFeedsGroupHandler *self, xmlDocPtr doc, GErr
{
xmlNodePtr cur;
GList *items;
- FeedsOpmlGroupHandler *parser;
items = NULL;
- parser = FEEDS_OPML_GROUP_HANDLER (self);
cur = xmlDocGetRootElement (doc);
while (cur) {
diff --git a/src/feeds-pool.c b/src/feeds-pool.c
index d3233bf..ac73e25 100644
--- a/src/feeds-pool.c
+++ b/src/feeds-pool.c
@@ -239,7 +239,7 @@ grss_feeds_pool_get_listened (GrssFeedsPool *pool)
}
/**
- * grss_feeds_pool_get_listened:
+ * grss_feeds_pool_get_listened_num:
* @pool: a #GrssFeedsPool
*
* Returns number of feeds under the @pool control, as provided by
diff --git a/src/feeds-publisher.c b/src/feeds-publisher.c
index 6bc438a..00b61b9 100644
--- a/src/feeds-publisher.c
+++ b/src/feeds-publisher.c
@@ -164,7 +164,7 @@ grss_feeds_publisher_class_init (GrssFeedsPublisherClass *klass)
gobject_class->finalize = grss_feeds_publisher_finalize;
/**
- * GrssFeedsSubscriber::new_subscription:
+ * GrssFeedsPublisher::new_subscription:
* @pub: the #GrssFeedsPublisher emitting the signal
* @topic: #GrssFeedChannel for which subscription has been added
* @callback: callback required for new subscriber
@@ -176,7 +176,7 @@ grss_feeds_publisher_class_init (GrssFeedsPublisherClass *klass)
G_TYPE_NONE, 2, GRSS_FEED_CHANNEL_TYPE, G_TYPE_STRING);
/**
- * GrssFeedsSubscriber::new_subscription:
+ * GrssFeedsPublisher::new_subscription:
* @pub: the #GrssFeedsPublisher emitting the signal
* @topic: #GrssFeedChannel for which subscription has been removed
* @callback: callback revoked by the subscriber
diff --git a/src/feeds-pubsubhubbub-subscriber.c b/src/feeds-pubsubhubbub-subscriber.c
index 5b38789..9556cda 100644
--- a/src/feeds-pubsubhubbub-subscriber.c
+++ b/src/feeds-pubsubhubbub-subscriber.c
@@ -153,9 +153,9 @@ feeds_pubsubhubbub_subscriber_handler_handle_message (GrssFeedsSubscriberHandler
mode = (gchar*) g_hash_table_lookup (query, "hub.mode");
if (*status == FEED_SUBSCRIPTION_SUBSCRIBING && strcmp (mode, "subscribe") == 0) {
+ *status = FEED_SUBSCRIPTION_SUBSCRIBED;
challenge = g_strdup ((gchar*) g_hash_table_lookup (query, "hub.challenge"));
soup_message_set_response (msg, "application/x-www-form-urlencoded", SOUP_MEMORY_TAKE, challenge, strlen (challenge));
-
soup_message_set_status (msg, 200);
}
else if (*status == FEED_SUBSCRIPTION_UNSUBSCRIBING && strcmp (mode, "unsubscribe") == 0) {
diff --git a/src/feeds-rsscloud-subscriber.c b/src/feeds-rsscloud-subscriber.c
index 24c3445..a8bc172 100644
--- a/src/feeds-rsscloud-subscriber.c
+++ b/src/feeds-rsscloud-subscriber.c
@@ -20,6 +20,7 @@
#include "feeds-rsscloud-subscriber.h"
#include "feeds-subscriber.h"
+#include "feeds-subscriber-private.h"
#include "feeds-subscriber-handler.h"
#include "utils.h"
#include "feed-parser.h"
@@ -81,7 +82,7 @@ subscribe_response_cb (SoupSession *session,
gpointer user_data)
{
gboolean done;
- const xmlChar *success;
+ xmlChar *success;
guint status;
xmlDocPtr doc;
xmlNodePtr cur;
@@ -152,6 +153,22 @@ feeds_rsscloud_subscriber_handler_subscribe (GrssFeedsSubscriberHandler *handler
soup_session_queue_message (grss_feeds_subscriber_get_session (myself->priv->parent), msg, subscribe_response_cb, NULL);
}
+static void
+fetched_items_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GList *items;
+ GrssFeedChannel *channel;
+ GrssFeedsRsscloudSubscriber *handler;
+
+ items = g_async_result_get_user_data (res);
+ channel = GRSS_FEED_CHANNEL (g_async_result_get_source_object (res));
+ handler = user_data;
+
+ grss_feeds_subscriber_dispatch (handler->priv->parent, channel, items);
+}
+
GList*
feeds_rsscloud_subscriber_handler_handle_message (GrssFeedsSubscriberHandler *handler,
GrssFeedChannel *channel,
@@ -171,13 +188,14 @@ feeds_rsscloud_subscriber_handler_handle_message (GrssFeedsSubscriberHandler *ha
challenge = (gchar*) g_hash_table_lookup (query, "challenge");
if (*status == FEED_SUBSCRIPTION_SUBSCRIBING && challenge != NULL) {
+ *status = FEED_SUBSCRIPTION_SUBSCRIBED;
challenge = g_strdup (challenge);
soup_message_set_response (msg, "application/x-www-form-urlencoded", SOUP_MEMORY_TAKE, challenge, strlen (challenge));
soup_message_set_status (msg, 200);
}
}
else if (*status == FEED_SUBSCRIPTION_SUBSCRIBED) {
- ret = grss_feed_channel_fetch_all (channel);
+ grss_feed_channel_fetch_all_async (channel, fetched_items_cb, handler);
soup_message_set_status (msg, 202);
}
else {
diff --git a/src/feeds-subscriber-private.h b/src/feeds-subscriber-private.h
new file mode 100644
index 0000000..da1a56f
--- /dev/null
+++ b/src/feeds-subscriber-private.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011, 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_SUBSCRIBER_PRIVATE_H__
+#define __FEEDS_SUBSCRIBER_PRIVATE_H__
+
+void grss_feeds_subscriber_dispatch (GrssFeedsSubscriber *sub, GrssFeedChannel *channel, GList *items);
+
+#endif
diff --git a/src/feeds-subscriber.c b/src/feeds-subscriber.c
index df56694..9b5be45 100644
--- a/src/feeds-subscriber.c
+++ b/src/feeds-subscriber.c
@@ -77,6 +77,8 @@ typedef struct {
GrssFeedsSubscriber *sub;
GrssFeedsSubscriberHandler *handler;
+
+ GList *items_cache;
} GrssFeedChannelWrap;
enum {
@@ -92,11 +94,19 @@ static void
remove_currently_listened (GrssFeedsSubscriber *sub)
{
GList *iter;
+ GList *cache_iter;
GrssFeedChannelWrap *wrap;
if (sub->priv->feeds_list != NULL) {
for (iter = sub->priv->feeds_list; iter; iter = g_list_next (iter)) {
wrap = (GrssFeedChannelWrap*) iter->data;
+
+ if (wrap->items_cache != NULL) {
+ for (cache_iter = wrap->items_cache; cache_iter; cache_iter = g_list_next (cache_iter))
+ g_object_unref (cache_iter->data);
+ g_list_free (wrap->items_cache);
+ }
+
g_free (wrap->path);
g_object_unref (wrap->channel);
g_free (wrap);
@@ -142,7 +152,8 @@ grss_feeds_subscriber_class_init (GrssFeedsSubscriberClass *klass)
* @item: the #GrssFeedItem received
*
* Emitted when a notification has been received and parsed. The
- * @item is unref'd at the end of signal
+ * @item is cached and unref'd when the #GrssFeedsSubscriber is
+ * destroyed or a new set of feeds is provided
*/
signals [NOTIFICATION_RECEIVED] = g_signal_new ("notification-received", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0,
NULL, NULL, feed_marshal_VOID__OBJECT_OBJECT,
@@ -279,19 +290,64 @@ grss_feeds_subscriber_get_listened (GrssFeedsSubscriber *sub)
}
static void
+dispatch_items (GrssFeedChannelWrap *feed, GList *items)
+{
+ gboolean exists;
+ const gchar* item_id;
+ GList *iter;
+ GList *cache_iter;
+ GrssFeedItem *item;
+ GrssFeedItem *cache_item;
+
+ for (iter = items; iter; iter = g_list_next (iter)) {
+ item = (GrssFeedItem*) iter->data;
+ item_id = grss_feed_item_get_id (item);
+
+ exists = FALSE;
+
+ for (cache_iter = feed->items_cache; cache_iter; cache_iter = g_list_next (cache_iter)) {
+ cache_item = (GrssFeedItem*) cache_iter->data;
+ if (strcmp (item_id, grss_feed_item_get_id (cache_item)) == 0)
+ exists = TRUE;
+ }
+
+ if (exists == FALSE) {
+ g_signal_emit (feed->sub, signals [NOTIFICATION_RECEIVED], 0, feed->channel, item, NULL);
+ feed->items_cache = g_list_prepend (feed->items_cache, item);
+ }
+ }
+}
+
+static void
handle_incoming_notification_cb (SoupServer *server, SoupMessage *msg, const char *path,
GHashTable *query, SoupClientContext *client, gpointer user_data)
{
- GList *iter;
GList *items;
GrssFeedChannelWrap *feed;
feed = (GrssFeedChannelWrap*) user_data;
items = grss_feeds_subscriber_handler_handle_incoming_message (feed->handler, feed->channel, &(feed->status), server, msg, path, query, client);
- for (iter = items; iter; iter = g_list_next (iter))
- g_signal_emit (feed->sub, signals [NOTIFICATION_RECEIVED], 0, feed->channel, (GrssFeedItem*) iter->data, NULL);
- g_list_free (items);
+ if (items != NULL) {
+ dispatch_items (feed, items);
+ g_list_free (items);
+ }
+}
+
+void
+grss_feeds_subscriber_dispatch (GrssFeedsSubscriber *sub, GrssFeedChannel *channel, GList *items)
+{
+ GList *iter;
+ GrssFeedChannelWrap *wrap;
+
+ for (iter = sub->priv->feeds_list; iter; iter = g_list_next (iter)) {
+ wrap = (GrssFeedChannelWrap*) iter->data;
+
+ if (wrap->channel == channel) {
+ dispatch_items (wrap, items);
+ break;
+ }
+ }
}
static void
diff --git a/src/feeds-xbel-group-handler.c b/src/feeds-xbel-group-handler.c
index 1a57dee..1984e9d 100644
--- a/src/feeds-xbel-group-handler.c
+++ b/src/feeds-xbel-group-handler.c
@@ -37,9 +37,6 @@ G_DEFINE_TYPE_WITH_CODE (FeedsXbelGroupHandler, feeds_xbel_group_handler, G_TYPE
static void
feeds_xbel_group_handler_finalize (GObject *object)
{
- FeedsXbelGroupHandler *parser;
-
- parser = FEEDS_XBEL_GROUP_HANDLER (object);
G_OBJECT_CLASS (feeds_xbel_group_handler_parent_class)->finalize (object);
}
@@ -63,10 +60,8 @@ feeds_xbel_group_handler_parse (GrssFeedsGroupHandler *self, xmlDocPtr doc, GErr
xmlXPathObjectPtr xpathObj;
xmlXPathContextPtr xpathCtx;
GrssFeedChannel *channel;
- FeedsXbelGroupHandler *parser;
items = NULL;
- parser = FEEDS_XBEL_GROUP_HANDLER (self);
xpathCtx = xmlXPathNewContext (doc);
diff --git a/src/feeds-xoxo-group-handler.c b/src/feeds-xoxo-group-handler.c
index 14fae46..cad963a 100644
--- a/src/feeds-xoxo-group-handler.c
+++ b/src/feeds-xoxo-group-handler.c
@@ -57,9 +57,6 @@ static xmlNode* find_first_element (xmlDocPtr doc)
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);
}
@@ -79,10 +76,8 @@ feeds_xoxo_group_handler_parse (GrssFeedsGroupHandler *self, xmlDocPtr doc, GErr
xmlXPathObjectPtr xpathObj;
xmlXPathContextPtr xpathCtx;
GrssFeedChannel *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");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]