[tracker/miner-rss: 1/3] Merge miner rss project into tracker tree



commit e1bfa360f6ff4bdb049b13d0d352a6721f51f9ee
Author: Michele Tameni <michele amdplanet it>
Date:   Sun Jan 31 11:25:18 2010 +0100

    Merge miner rss project into tracker tree

 configure.ac                               |   40 +++
 data/Makefile.am                           |   18 ++
 data/miners/Makefile.am                    |    8 +
 data/miners/tracker-miner-feeds.desktop.in |    6 +
 data/tracker-miner-rss.desktop.in.in       |    6 +
 src/Makefile.am                            |    3 +
 src/tracker-miner-rss/Makefile.am          |   30 ++
 src/tracker-miner-rss/tracker-main.c       |   34 +++
 src/tracker-miner-rss/tracker-miner-rss.c  |  446 ++++++++++++++++++++++++++++
 src/tracker-miner-rss/tracker-miner-rss.h  |   51 ++++
 10 files changed, 642 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index dd8e544..bc15295 100644
--- a/configure.ac
+++ b/configure.ac
@@ -157,6 +157,7 @@ EDS_REQUIRED=2.25.5
 LIBSTREAMANALYZER_REQUIRED=0.7.0
 GEE_REQUIRED=0.3
 ID3LIB_REQUIRED=3.8.3
+LIBGRSS_REQUIRED=0.2
 
 # Library Checks
 PKG_CHECK_MODULES(GLIB2, [glib-2.0 >= $GLIB_REQUIRED])
@@ -779,6 +780,43 @@ AC_ARG_ENABLE([kmail_miner],
 
 AM_CONDITIONAL(USING_KMAIL_MINER, test "x$enable_kmail_miner" = "xyes")
 
+##################################################################
+# Miner RSS
+##################################################################
+
+AC_ARG_ENABLE([miner_rss],
+              AS_HELP_STRING([--enable-miner-rss],
+		             [enable miner rss [[default=auto]]]),,
+	      [enable_miner_rss=auto])
+
+if test "x$enable_miner_rss" != "xno" ; then
+   PKG_CHECK_MODULES(LIBGRSS,
+	             [libgrss-0 >= $LIBGRSS_REQUIRED],
+		     [have_libgrss=yes],
+		     [have_libgrss=no])
+
+   AC_SUBST(LIBGRSS_CFLAGS)
+   AC_SUBST(LIBGRSS_LIBS)
+
+   if test "x$enable_miner_rss" = "xauto"; then
+      if  test "x$have_libgrss" = "xyes"; then
+          enable_miner_rss="yes"
+      else
+        enable_miner_rss="no"
+      fi
+   fi
+
+   if test "x$enable_miner_rss" = "xyes"; then
+      if test "x$have_libgrss" != "xyes"; then
+         AC_MSG_ERROR([Couldn't find libgrss >= $LIBGRSS_REQUIRED. and miner rss requeste])
+      fi
+   fi
+else
+   enable_miner_rss="no  (disabled)"
+fi
+
+AM_CONDITIONAL(USING_MINER_RSS, test "x$enable_miner_rss" = "xyes")
+
 ####################################################################
 # Deskbar Applet Handler/Module
 ####################################################################
@@ -1647,6 +1685,7 @@ AC_CONFIG_FILES([
 	src/tracker-control/Makefile
 	src/tracker-extract/Makefile
 	src/tracker-miner-fs/Makefile
+	src/tracker-miner-rss/Makefile
 	src/tracker-preferences/Makefile
 	src/tracker-preferences/tracker-preferences.desktop.in
 	src/tracker-search-bar/Makefile
@@ -1764,6 +1803,7 @@ Plugins/Extensions:
 	Nautilus            (tagging widget)    $have_nautilus_extension
 	Evolution plugin    (data-push):	$enable_evolution_miner
 	KMail plugin        (data-push):	$enable_kmail_miner
+	Miner RSS:          (data-push):	$enable_miner_rss
 
 Writeback:
 
diff --git a/data/Makefile.am b/data/Makefile.am
index 1849a51..c3e682d 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -15,17 +15,31 @@ tracker-miner-fs.desktop.in: tracker-miner-fs.desktop.in.in
 	@sed -e "s|@libexecdir[ ]|${libexecdir}|" 	\
 	     -e "s|@VERSION[ ]|${VERSION}|" $< > $@
 
+if USING_MINER_RSS
+tracker-miner-rss.desktop.in: tracker-miner-rss.desktop.in.in
+	@sed -e "s|@libexecdir[ ]|${libexecdir}|" 	\
+	     -e "s|@VERSION[ ]|${VERSION}|" $< > $@
+endif
+
 autostartdir = $(sysconfdir)/xdg/autostart
 autostart_in_in_files = 				\
 	tracker-status-icon.desktop.in.in		\
 	tracker-store.desktop.in.in			\
 	tracker-miner-fs.desktop.in.in
 
+if USING_MINER_RSS
+autostart_in_in_files += tracker-miner-rss.desktop.in.in
+endif
+
 autostart_in_files = 					\
 	tracker-status-icon.desktop.in			\
 	tracker-store.desktop.in			\
 	tracker-miner-fs.desktop.in
 
+if USING_MINER_RSS
+autostart_in_files += tracker-miner-rss.desktop.in
+endif
+
 autostart_DATA = 					\
 	tracker-store.desktop				\
 	tracker-miner-fs.desktop
@@ -34,6 +48,10 @@ if HAVE_TRACKER_STATUS_ICON
 autostart_DATA += tracker-status-icon.desktop
 endif
 
+if USING_MINER_RSS
+autostart_DATA += tracker-miner-rss.desktop
+endif
+
 @INTLTOOL_DESKTOP_RULE@
 
 pkgconfigdir = $(libdir)/pkgconfig
diff --git a/data/miners/Makefile.am b/data/miners/Makefile.am
index cdb1db4..efc8cb7 100644
--- a/data/miners/Makefile.am
+++ b/data/miners/Makefile.am
@@ -4,12 +4,20 @@ desktop_in_files = \
 	tracker-miner-applications.desktop.in \
 	tracker-miner-files.desktop.in
 
+if USING_MINER_RSS
+desktop_in_files +=	tracker-miner-feeds.desktop.in
+endif
+
 tracker_minersdir = $(datadir)/tracker/miners
 
 tracker_miners_DATA = \
 	tracker-miner-applications.desktop \
 	tracker-miner-files.desktop
 
+if USING_MINER_RSS
+tracker_miners_DATA += 	tracker-miner-feeds.desktop
+endif
+
 @INTLTOOL_DESKTOP_RULE@
 
 EXTRA_DIST = $(desktop_in_files)
diff --git a/data/miners/tracker-miner-feeds.desktop.in b/data/miners/tracker-miner-feeds.desktop.in
new file mode 100644
index 0000000..77f00df
--- /dev/null
+++ b/data/miners/tracker-miner-feeds.desktop.in
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Encoding=UTF-8
+_Name=RSS/ATOM Feeds
+_Comment=RSS/ATOM feed miner
+DBusName=org.freedesktop.Tracker1.Miner.RSS
+DBusPath=/org/freedesktop/Tracker1/Miner/RSS
\ No newline at end of file
diff --git a/data/tracker-miner-rss.desktop.in.in b/data/tracker-miner-rss.desktop.in.in
new file mode 100644
index 0000000..e01fc59
--- /dev/null
+++ b/data/tracker-miner-rss.desktop.in.in
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=RSS
+Comment=RSS feeds fetcher
+DBusName=org.freedesktop.Tracker1.Miner.RSS
+DBusPath=/org/freedesktop/Tracker1/Miner/RSS
\ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
index 2f5ff33..3823389 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,3 +39,6 @@ if HAVE_TRACKER_EXPLORER
 SUBDIRS += tracker-explorer
 endif
 
+if USING_MINER_RSS
+SUBDIRS += tracker-miner-rss
+endif
diff --git a/src/tracker-miner-rss/Makefile.am b/src/tracker-miner-rss/Makefile.am
new file mode 100644
index 0000000..750bcd4
--- /dev/null
+++ b/src/tracker-miner-rss/Makefile.am
@@ -0,0 +1,30 @@
+include $(top_srcdir)/Makefile.decl
+
+INCLUDES =								\
+	-Wall								\
+	-DSHAREDIR=\""$(datadir)"\"					\
+	-DPKGLIBDIR=\""$(libdir)/tracker"\"				\
+	-DLOCALEDIR=\""$(localedir)"\" 					\
+	-DLIBEXEC_PATH=\""$(libexecdir)"\"				\
+	-DG_LOG_DOMAIN=\"Tracker\"					\
+	-DTRACKER_COMPILATION						\
+	-I$(top_srcdir)/src						\
+	$(GMODULE_CFLAGS)						\
+	$(DBUS_CFLAGS)							\
+	$(WARN_CFLAGS)							\
+	$(LIBGRSS_CFLAGS)
+
+libexec_PROGRAMS = tracker-miner-rss
+
+tracker_miner_rss_SOURCES =						\
+	tracker-main.c						\
+	tracker-miner-rss.h						\
+	tracker-miner-rss.c
+
+tracker_miner_rss_LDADD =						\
+	$(top_builddir)/src/libtracker-miner/libtracker-miner- TRACKER_API_VERSION@.la	\
+	$(GLIB2_LIBS)						\
+	$(DBUS_LIBS)						\
+	$(LIBGRSS_LIBS)
+
+CLEANFILES = $(BUILT_SOURCES)
diff --git a/src/tracker-miner-rss/tracker-main.c b/src/tracker-miner-rss/tracker-main.c
new file mode 100644
index 0000000..921f705
--- /dev/null
+++ b/src/tracker-miner-rss/tracker-main.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009/2010, Roberto Guido <madbob users barberaware 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 2.1 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 <stdlib.h>
+#include "tracker-miner-rss.h"
+
+int
+main () {
+	TrackerMinerRSS *miner;
+
+	g_type_init ();
+	g_thread_init (NULL);
+	miner = g_object_new (TRACKER_TYPE_MINER_RSS, "name", "RSS", NULL);
+	tracker_miner_start (TRACKER_MINER (miner));
+	g_main_loop_run (g_main_loop_new (NULL, FALSE));
+	exit (0);
+}
diff --git a/src/tracker-miner-rss/tracker-miner-rss.c b/src/tracker-miner-rss/tracker-miner-rss.c
new file mode 100644
index 0000000..3c175b5
--- /dev/null
+++ b/src/tracker-miner-rss/tracker-miner-rss.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2009/2010, Roberto Guido <madbob users barberaware 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 2.1 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 "tracker-miner-rss.h"
+
+#include <stdio.h>
+#include <dbus/dbus-glib.h>
+#include <libtracker-miner/tracker-miner.h>
+#include <libtracker-common/tracker-sparql-builder.h>
+#include <libgrss.h>
+
+#define TRACKER_MINER_RSS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER_RSS, TrackerMinerRSSPrivate))
+
+struct TrackerMinerRSSPrivate {
+	gboolean	paused;
+	gboolean	stopped;
+
+	FeedsPool	*pool;
+	int		now_fetching;
+};
+
+static void tracker_miner_rss_started (TrackerMiner *miner);
+static void tracker_miner_rss_stopped (TrackerMiner *miner);
+static void tracker_miner_rss_paused (TrackerMiner *miner);
+static void tracker_miner_rss_resumed (TrackerMiner *miner);
+static void retrieve_and_schedule_feeds (TrackerMinerRSS *miner);
+static void update_updated_interval (TrackerMinerRSS *miner, gchar *uri, time_t *now);
+static void change_status (FeedsPool *pool, FeedChannel *feed, gpointer user_data);
+static void feed_fetched (FeedsPool *pool, FeedChannel *feed, GList *items, gpointer user_data);
+static gchar* get_message_subject (FeedItem *item);
+static const gchar* get_message_url (FeedItem *item);
+
+G_DEFINE_TYPE (TrackerMinerRSS, tracker_miner_rss, TRACKER_TYPE_MINER)
+
+static void
+tracker_miner_rss_finalize (GObject *object)
+{
+	TrackerMinerRSS *rss;
+
+	rss = TRACKER_MINER_RSS (object);
+
+	rss->priv->stopped = TRUE;
+	g_object_unref (rss->priv->pool);
+
+	G_OBJECT_CLASS (tracker_miner_rss_parent_class)->finalize (object);
+}
+
+static void
+tracker_miner_rss_class_init (TrackerMinerRSSClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	TrackerMinerClass *miner_class = TRACKER_MINER_CLASS (klass);
+
+	g_type_class_add_private (object_class, sizeof (TrackerMinerRSSPrivate));
+	object_class->finalize = tracker_miner_rss_finalize;
+
+	miner_class->started = tracker_miner_rss_started;
+	miner_class->stopped = tracker_miner_rss_stopped;
+	miner_class->paused  = tracker_miner_rss_paused;
+	miner_class->resumed = tracker_miner_rss_resumed;
+}
+
+static void
+subjects_added_cb (DBusGProxy *proxy, gchar **subjects, gpointer user_data)
+{
+	TrackerMinerRSS *miner;
+
+	miner = TRACKER_MINER_RSS (user_data);
+
+	/*
+		TODO	Add only the channels added?
+	*/
+	retrieve_and_schedule_feeds (miner);
+}
+
+static void
+subjects_removed_cb (DBusGProxy *proxy, gchar **subjects, gpointer user_data)
+{
+	TrackerMinerRSS *miner;
+
+	miner = TRACKER_MINER_RSS (user_data);
+
+	/*
+		TODO	Remove only the channels removed?
+	*/
+	retrieve_and_schedule_feeds (miner);
+}
+
+static void
+tracker_miner_rss_init (TrackerMinerRSS *object)
+{
+	DBusGProxy *wrap;
+
+	object->priv = TRACKER_MINER_RSS_GET_PRIVATE (object);
+
+	object->priv->pool = feeds_pool_new ();
+	g_signal_connect (object->priv->pool, "feed-fetching", G_CALLBACK (change_status), object);
+	g_signal_connect (object->priv->pool, "feed-ready", G_CALLBACK (feed_fetched), object);
+	object->priv->now_fetching = 0;
+
+	g_object_set (object, "progress", 0.0, "status", "Initializing", NULL);
+
+	wrap = dbus_g_proxy_new_for_name (dbus_g_bus_get (DBUS_BUS_SESSION, NULL),
+	                                  "org.freedesktop.Tracker1",
+					  "/org/freedesktop/Tracker1/Resources/Classes/mfo/FeedChannel",
+	                                  "org.freedesktop.Tracker1.Resources.Class");
+
+	if (wrap == NULL) {
+		g_warning ("Unable to listen for added and removed channels");
+		return;
+	}
+
+	dbus_g_proxy_add_signal (wrap, "SubjectsAdded", G_TYPE_STRV, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (wrap, "SubjectsAdded", G_CALLBACK (subjects_added_cb), object, NULL);
+
+	dbus_g_proxy_add_signal (wrap, "SubjectsRemoved", G_TYPE_STRV, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (wrap, "SubjectsRemoved", G_CALLBACK (subjects_removed_cb), object, NULL);
+}
+
+static void
+update_updated_interval (TrackerMinerRSS *miner, gchar *uri, time_t *now)
+{
+	TrackerSparqlBuilder *sparql;
+
+	/*
+		I hope there will be soon a SPARQL command to just update a
+		value instead to delete and re-insert it
+	*/
+
+	sparql = tracker_sparql_builder_new_update ();
+	tracker_sparql_builder_delete_open (sparql, NULL);
+	tracker_sparql_builder_subject_iri (sparql, uri);
+	tracker_sparql_builder_predicate (sparql, "mfo:updatedTime");
+	tracker_sparql_builder_object_variable (sparql, "unknown");
+	tracker_sparql_builder_delete_close (sparql);
+	tracker_sparql_builder_where_open (sparql);
+	tracker_sparql_builder_subject_iri (sparql, uri);
+	tracker_sparql_builder_predicate (sparql, "mfo:updatedTime");
+	tracker_sparql_builder_object_variable (sparql, "unknown");
+	tracker_sparql_builder_where_close (sparql);
+
+	tracker_sparql_builder_insert_open (sparql, uri);
+	tracker_sparql_builder_subject_iri (sparql, uri);
+	tracker_sparql_builder_predicate (sparql, "mfo:updatedTime");
+	tracker_sparql_builder_object_date (sparql, now);
+	tracker_sparql_builder_insert_close (sparql);
+
+	tracker_miner_execute_update (TRACKER_MINER (miner), tracker_sparql_builder_get_result (sparql), NULL, NULL, NULL);
+	g_object_unref (sparql);
+}
+
+static void
+change_status (FeedsPool *pool, FeedChannel *feed, gpointer user_data)
+{
+	int avail;
+	double prog;
+	TrackerMinerRSS *miner;
+
+	miner = (TrackerMinerRSS*) user_data;
+	avail = feeds_pool_get_listened_num (miner->priv->pool);
+
+	miner->priv->now_fetching++;
+	if (miner->priv->now_fetching > avail)
+		miner->priv->now_fetching = avail;
+
+	prog = (double) miner->priv->now_fetching / (double) avail;
+	g_object_set (miner, "progress", prog, "status", "Fetching...", NULL);
+}
+
+static void
+item_verify_reply_cb (GObject *source_object, GAsyncResult *res, gpointer data)
+{
+	time_t t;
+	gchar *uri;
+	gchar *subject;
+	gchar **values;
+	const gchar *tmp_string;
+	const GPtrArray *response;
+	GError *error;
+	TrackerSparqlBuilder *sparql;
+	FeedItem *item;
+	FeedChannel *feed;
+	TrackerMinerRSS *miner;
+
+	miner = TRACKER_MINER_RSS (source_object);
+	response = tracker_miner_execute_sparql_finish (TRACKER_MINER (source_object), res, &error);
+
+	if (response == NULL) {
+		g_warning ("Unable to verify item: %s\n", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	values = (gchar**) g_ptr_array_index (response, 0);
+	if (strcmp (values [0], "1") == 0)
+		return;
+
+	item = data;
+
+	subject = get_message_subject (item);
+
+	sparql = tracker_sparql_builder_new_update ();
+	tracker_sparql_builder_insert_open (sparql, subject);
+	tracker_sparql_builder_subject (sparql, "_:message");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "mfo:FeedMessage");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "nfo:RemoteDataObject");
+
+	tmp_string = feed_item_get_title (item);
+	if (tmp_string != NULL) {
+		tracker_sparql_builder_predicate (sparql, "nie:title");
+		tracker_sparql_builder_object_string (sparql, tmp_string);
+	}
+
+	tmp_string = feed_item_get_description (item);
+	if (tmp_string != NULL) {
+		tracker_sparql_builder_predicate (sparql, "nmo:plainTextMessageContent");
+		tracker_sparql_builder_object_string (sparql, tmp_string);
+	}
+
+	tmp_string = get_message_url (item);
+	if (tmp_string != NULL) {
+		tracker_sparql_builder_predicate (sparql, "nie:url");
+		tracker_sparql_builder_object_string (sparql, tmp_string);
+	}
+
+	/*
+		nmo:receivedDate and mfo:downloadedTime are the same? Ask for the MFO maintainer
+	*/
+
+	t = time (NULL);
+
+	g_print ("%s\n", feed_item_get_author (item));
+	tracker_sparql_builder_predicate (sparql, "nmo:receivedDate");
+	tracker_sparql_builder_object_date (sparql, &t);
+
+	tracker_sparql_builder_predicate (sparql, "mfo:downloadedTime");
+	tracker_sparql_builder_object_date (sparql, &t);
+
+	t = feed_item_get_publish_time (item);
+	tracker_sparql_builder_predicate (sparql, "nie:contentCreated");
+	tracker_sparql_builder_object_date (sparql, &t);
+
+	tracker_sparql_builder_predicate (sparql, "nmo:isRead");
+	tracker_sparql_builder_object_boolean (sparql, FALSE);
+
+	feed = feed_item_get_parent (item);
+	uri = (gchar*) g_object_get_data (G_OBJECT (feed), "subject");
+	tracker_sparql_builder_predicate (sparql, "nmo:communicationChannel");
+	tracker_sparql_builder_object_iri (sparql, uri);
+
+	tracker_sparql_builder_insert_close (sparql);
+
+	tracker_miner_execute_update (TRACKER_MINER (miner), tracker_sparql_builder_get_result (sparql), NULL, NULL, NULL);
+
+	g_object_unref (sparql);
+	g_free (subject);
+}
+
+static void
+check_if_save (TrackerMinerRSS *miner, FeedItem *item)
+{
+	FeedChannel *feed;
+	gchar *query;
+	gchar *communication_channel;
+	const gchar *url;
+
+	url = get_message_url (item);
+	feed = feed_item_get_parent (item);
+	communication_channel = (gchar*) g_object_get_data (G_OBJECT (feed), "subject");
+
+	query = g_strdup_printf ("ASK { ?message a mfo:FeedMessage; nie:url \"%s\"; nmo:communicationChannel <%s> }",
+	                        url, communication_channel);
+	tracker_miner_execute_sparql (TRACKER_MINER (miner), query, NULL, item_verify_reply_cb, item);
+	g_free (query);
+}
+
+static void
+feed_fetched (FeedsPool *pool, FeedChannel *feed, GList *items, gpointer user_data)
+{
+	gchar *uri;
+	time_t now;
+	GList *iter;
+	FeedItem *item;
+	TrackerMinerRSS *miner;
+
+	miner = (TrackerMinerRSS*) user_data;
+
+	miner->priv->now_fetching--;
+	if (miner->priv->now_fetching <= 0) {
+		miner->priv->now_fetching = 0;
+		g_object_set (miner, "progress", 1.0, "status", "Idle", NULL);
+	}
+
+	if (items == NULL)
+		return;
+
+	now = time (NULL);
+	uri = (gchar*) g_object_get_data (G_OBJECT (feed), "subject");
+	update_updated_interval (miner, uri, &now);
+
+	for (iter = items; iter; iter = g_list_next (iter)) {
+		item = (FeedItem*) iter->data;
+		check_if_save (miner, item);
+	}
+}
+
+static void
+feeds_retrieve_cb (GObject *source_object, GAsyncResult *res, gpointer data)
+{
+	int interval;
+	register int i;
+	gchar **values;
+	GList *channels;
+	const GPtrArray *response;
+	GError *error;
+	TrackerMinerRSS *miner;
+	FeedChannel *chan;
+
+	miner = TRACKER_MINER_RSS (source_object);
+	response = tracker_miner_execute_sparql_finish (TRACKER_MINER (source_object), res, &error);
+
+	if (response == NULL) {
+		g_warning ("Unable to retrieve list of feeds: %s\n", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	channels = NULL;
+
+	for (i = 0; i < response->len; i++) {
+		values = (gchar**) g_ptr_array_index (response, i);
+
+		chan = feed_channel_new ();
+		g_object_set_data_full (G_OBJECT (chan), "subject", g_strdup (values [0]), g_free);
+		feed_channel_set_source (chan, values [0]);
+
+		/*
+			How to manage feeds with an update mfo:updateInterval == 0 ?
+			Here the interval is forced to be at least 1 minute, but perhaps those
+			elements are to be considered "disabled"
+		*/
+		interval = strtoull (values [1], NULL, 10);
+		if (interval <= 0)
+			interval = 1;
+		feed_channel_set_update_interval (chan, interval);
+
+		channels = g_list_prepend (channels, chan);
+	}
+
+	feeds_pool_listen (miner->priv->pool, channels);
+}
+
+static void
+retrieve_and_schedule_feeds (TrackerMinerRSS *miner)
+{
+	gchar *sparql;
+
+	sparql = g_strdup_printf ("SELECT ?chanUrl ?interval WHERE		\
+	                           { ?chan a mfo:FeedChannel .			\
+	                             ?chan mfo:feedSettings ?settings .		\
+	                             ?chan nie:url ?chanUrl .			\
+	                             ?settings mfo:updateInterval ?interval }");
+
+	tracker_miner_execute_sparql (TRACKER_MINER (miner), sparql, NULL, feeds_retrieve_cb, NULL);
+	g_free (sparql);
+}
+
+static gchar*
+get_message_subject (FeedItem *item)
+{
+	return g_strdup_printf ("rss://%s", feed_item_get_id (item));
+}
+
+static const gchar*
+get_message_url (FeedItem *item)
+{
+	const gchar *url;
+
+	feed_item_get_real_source (item, &url, NULL);
+	if (url == NULL)
+		url = feed_item_get_source (item);
+	return url;
+}
+
+static void
+tracker_miner_rss_started (TrackerMiner *miner)
+{
+	TrackerMinerRSS *rss;
+
+	g_object_set (miner, "progress", 0.0, "status", "Initializing", NULL);
+
+	rss = TRACKER_MINER_RSS (miner);
+	retrieve_and_schedule_feeds (rss);
+	feeds_pool_switch (rss->priv->pool, TRUE);
+
+	g_object_set (miner, "status", "Idle", NULL);
+}
+
+static void
+tracker_miner_rss_stopped (TrackerMiner *miner)
+{
+	TrackerMinerRSS *rss;
+
+	rss = TRACKER_MINER_RSS (miner);
+	feeds_pool_switch (rss->priv->pool, FALSE);
+	g_object_set (miner, "progress", 1.0, "status", "Idle", NULL);
+}
+
+static void
+tracker_miner_rss_paused (TrackerMiner *miner)
+{
+	TrackerMinerRSS *rss;
+
+	rss = TRACKER_MINER_RSS (miner);
+	feeds_pool_switch (rss->priv->pool, FALSE);
+	g_object_set (miner, "progress", 1.0, "status", "Paused", NULL);
+}
+
+static void
+tracker_miner_rss_resumed (TrackerMiner *miner)
+{
+	TrackerMinerRSS *rss;
+
+	rss = TRACKER_MINER_RSS (miner);
+	feeds_pool_switch (rss->priv->pool, TRUE);
+	g_object_set (miner, "progress", 1.0, "status", "Idle", NULL);
+}
diff --git a/src/tracker-miner-rss/tracker-miner-rss.h b/src/tracker-miner-rss/tracker-miner-rss.h
new file mode 100644
index 0000000..dffb206
--- /dev/null
+++ b/src/tracker-miner-rss/tracker-miner-rss.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2009/2010, Roberto Guido <madbob users barberaware 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 2.1 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 __TRACKER_MINER_RSS_H__
+#define __TRACKER_MINER_RSS_H__
+
+#include <libtracker-miner/tracker-miner.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_MINER_RSS         (tracker_miner_rss_get_type())
+#define TRACKER_MINER_RSS(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MINER_RSS, TrackerMinerRSS))
+#define TRACKER_MINER_RSS_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_MINER_RSS, TrackerMinerRSSClass))
+#define TRACKER_IS_MINER_RSS(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MINER_RSS))
+#define TRACKER_IS_MINER_RSS_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),  TRACKER_TYPE_MINER_RSS))
+#define TRACKER_MINER_RSS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_MINER_RSS, TrackerMinerRSSClass))
+
+typedef struct TrackerMinerRSS        TrackerMinerRSS;
+typedef struct TrackerMinerRSSPrivate TrackerMinerRSSPrivate;
+
+struct TrackerMinerRSS {
+	TrackerMiner parent;
+	TrackerMinerRSSPrivate *priv;
+};
+
+typedef struct {
+	TrackerMinerClass parent;
+} TrackerMinerRSSClass;
+
+GType    tracker_miner_rss_get_type         (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __TRACKER_MINER_RSS_H__ */



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