[tracker/wip/passive-extraction: 6/7] libtracker-extract: Add TrackerDataSniffer



commit 02a94b550bc6932f9c81e0e0a1fafa80be6e7d86
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Jan 3 02:19:27 2014 +0100

    libtracker-extract: Add TrackerDataSniffer
    
    This is a basic abstract object that implements passive data extraction.
    This object will listen for updates through the tracker-store GraphUpdated
    signal, and trigger signals so the updated resources can be processed.

 src/libtracker-extract/Makefile.am            |   13 ++
 src/libtracker-extract/tracker-data-sniffer.c |  281 +++++++++++++++++++++++++
 src/libtracker-extract/tracker-data-sniffer.h |   68 ++++++
 src/libtracker-extract/tracker-marshal.list   |    1 +
 4 files changed, 363 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-extract/Makefile.am b/src/libtracker-extract/Makefile.am
index b7f0df9..2f7729a 100644
--- a/src/libtracker-extract/Makefile.am
+++ b/src/libtracker-extract/Makefile.am
@@ -21,6 +21,8 @@ libtracker_extractincludedir=$(includedir)/tracker-$(TRACKER_API_VERSION)/libtra
 
 libtracker_extract_ TRACKER_API_VERSION@_la_SOURCES =  \
        tracker-data.h                                 \
+       tracker-data-sniffer.c                         \
+       tracker-data-sniffer.h                         \
        tracker-encoding.c                             \
        tracker-exif.c                                 \
        tracker-exif.h                                 \
@@ -79,6 +81,17 @@ libtracker_extract_ TRACKER_API_VERSION@_la_LDFLAGS =  \
        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
        -export-symbols-regex '^tracker_.*'
 
+tracker-marshal.h: tracker-marshal.list
+       $(AM_V_GEN)$(GLIB_GENMARSHAL) $< --prefix=tracker_marshal --header > $@
+
+tracker-marshal.c: tracker-marshal.list
+       $(AM_V_GEN)(echo "#include \"tracker-marshal.h\""; \
+                   $(GLIB_GENMARSHAL) $< --prefix=tracker_marshal --body) > $@
+
+BUILT_SOURCES =                 \
+       tracker-marshal.c       \
+       tracker-marshal.h
+
 # Introspection foo
 -include $(INTROSPECTION_MAKEFILE)
 INTROSPECTION_GIRS =
diff --git a/src/libtracker-extract/tracker-data-sniffer.c b/src/libtracker-extract/tracker-data-sniffer.c
new file mode 100644
index 0000000..8f0ffa5
--- /dev/null
+++ b/src/libtracker-extract/tracker-data-sniffer.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2013, Carlos Garnacho  <carlosg 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 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 "config.h"
+
+#include "tracker-data-sniffer.h"
+#include "tracker-marshal.h"
+
+#define TRACKER_DATA_SNIFFER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_DATA_SNIFFER, 
TrackerDataSnifferPrivate))
+
+typedef struct _TrackerDataSnifferPrivate TrackerDataSnifferPrivate;
+
+struct _TrackerDataSnifferPrivate {
+       TrackerSparqlConnection *sparql_conn;
+       GDBusConnection *conn;
+       GCancellable *cancellable;
+       guint graph_updated_signal_id;
+       gchar *data_source;
+       gchar *class_name;
+};
+
+enum {
+       PROP_DATA_SOURCE = 1,
+       PROP_CLASS_NAME
+};
+
+enum {
+       UPDATED,
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (TrackerDataSniffer, tracker_data_sniffer, G_TYPE_OBJECT)
+
+static void
+tracker_data_sniffer_get_property (GObject    *object,
+                                  guint       param_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+       TrackerDataSnifferPrivate *priv;
+
+       priv = TRACKER_DATA_SNIFFER (object)->priv;
+
+       switch (param_id) {
+       case PROP_DATA_SOURCE:
+               g_value_set_string (value, priv->data_source);
+               break;
+       case PROP_CLASS_NAME:
+               g_value_set_string (value, priv->class_name);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+       }
+}
+
+static void
+tracker_data_sniffer_set_property (GObject      *object,
+                                  guint         param_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+       TrackerDataSnifferPrivate *priv;
+
+       priv = TRACKER_DATA_SNIFFER (object)->priv;
+
+       switch (param_id) {
+       case PROP_DATA_SOURCE:
+               priv->data_source = g_value_dup_string (value);
+               break;
+       case PROP_CLASS_NAME:
+               priv->class_name = g_value_dup_string (value);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+       }
+}
+
+static void
+query_async_cb (GObject      *object,
+               GAsyncResult *result,
+               gpointer      user_data)
+{
+       TrackerSparqlConnection *conn;
+       TrackerSparqlCursor *cursor;
+       GError *error = NULL;
+
+       conn = TRACKER_SPARQL_CONNECTION (object);
+       cursor = tracker_sparql_connection_query_finish (conn, result, &error);
+
+        if (error) {
+                g_critical ("Could not query updates: %s", error->message);
+                g_error_free (error);
+               return;
+       }
+
+       while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
+               const gchar *urn, *url;
+
+               urn = tracker_sparql_cursor_get_string (cursor, 0, NULL);
+               url = tracker_sparql_cursor_get_string (cursor, 1, NULL);
+               g_signal_emit (user_data, signals[UPDATED], 0, urn, url);
+       }
+
+       g_object_unref (cursor);
+}
+
+static void
+class_signal_cb (GDBusConnection *connection,
+                const gchar     *sender_name,
+                const gchar     *object_path,
+                const gchar     *interface_name,
+                const gchar     *signal_name,
+                GVariant        *parameters,
+                gpointer         user_data)
+{
+       gint graph, subject, predicate, object;
+       TrackerDataSnifferPrivate *priv;
+       GVariantIter *iter1, *iter2;
+       GString *id_string = NULL;
+       gchar *class_name, *query;
+
+       priv = TRACKER_DATA_SNIFFER (user_data)->priv;
+       g_variant_get (parameters, "(&sa(iiii)a(iiii))", &class_name, &iter1, &iter2);
+
+       /* Process updates */
+        while (g_variant_iter_loop (iter2, "(iiii)",
+                                   &graph, &subject, &predicate, &object)) {
+               if (!id_string) {
+                       id_string = g_string_new (NULL);
+                       g_string_append_printf (id_string, "%d", predicate);
+               } else {
+                       g_string_append_printf (id_string, ",%d", predicate);
+               }
+       }
+
+       query = g_strdup_printf ("SELECT ?urn ?url { "
+                                "  ?urn nie:url ?url ; "
+                                "       tracker:available true . "
+                                "  FILTER (tracker:id(?urn) IN (%s) && "
+                                "          NOT EXISTS { ?urn nie:dataSource <%s> })"
+                                "}", id_string->str, priv->data_source);
+
+       tracker_sparql_connection_query_async (priv->sparql_conn, query, NULL,
+                                              query_async_cb, user_data);
+       g_string_free (id_string, TRUE);
+       g_free (class_name);
+       g_free (query);
+}
+
+static void
+on_bus_ready_cb (GObject      *object,
+                GAsyncResult *result,
+                gpointer      user_data)
+{
+       TrackerDataSnifferPrivate *priv;
+       GError *error = NULL;
+
+       priv = TRACKER_DATA_SNIFFER (object)->priv;
+       priv->sparql_conn = tracker_sparql_connection_get (NULL, &error);
+
+       if (error) {
+               g_critical ("Could not get sparql connection: %s", error->message);
+               g_error_free (error);
+               return;
+       }
+
+       priv->conn = g_bus_get_finish (result, &error);
+
+       if (error) {
+               g_critical ("Could not get session bus: %s", error->message);
+               g_error_free (error);
+               return;
+       }
+
+       priv->graph_updated_signal_id =
+               g_dbus_connection_signal_subscribe (priv->conn,
+                                                   TRACKER_DBUS_SERVICE,
+                                                   TRACKER_DBUS_INTERFACE_RESOURCES,
+                                                   "GraphUpdated",
+                                                   TRACKER_DBUS_OBJECT_RESOURCES,
+                                                   priv->class_name,
+                                                   G_DBUS_SIGNAL_FLAGS_NONE,
+                                                   class_signal_cb,
+                                                   user_data, NULL);
+}
+
+static void
+tracker_data_sniffer_constructed (GObject *object)
+{
+       TrackerDataSnifferPrivate *priv;
+
+       priv = TRACKER_DATA_SNIFFER (object)->priv;
+       g_assert (priv->data_source);
+
+       priv->cancellable = g_cancellable_new ();
+       g_bus_get (G_BUS_TYPE_SESSION, priv->cancellable,
+                  (GAsyncReadyCallback) on_bus_ready_cb, object);
+}
+
+static void
+tracker_data_sniffer_class_init (TrackerDataSnifferClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->get_property = tracker_data_sniffer_get_property;
+       object_class->set_property = tracker_data_sniffer_set_property;
+       object_class->constructed = tracker_data_sniffer_constructed;
+
+       g_object_class_install_property (object_class,
+                                        PROP_DATA_SOURCE,
+                                        g_param_spec_string ("data-source",
+                                                             "Data source URN",
+                                                             "nie:DataSource to use in this sniffer",
+                                                             NULL,
+                                                             G_PARAM_READWRITE |
+                                                             G_PARAM_CONSTRUCT_ONLY));
+       g_object_class_install_property (object_class,
+                                        PROP_CLASS_NAME,
+                                        g_param_spec_string ("class-name",
+                                                             "Class name",
+                                                             "rdfs:Class to listen to for changes",
+                                                             NULL,
+                                                             G_PARAM_READWRITE |
+                                                             G_PARAM_CONSTRUCT_ONLY));
+       signals[UPDATED] =
+               g_signal_new ("updated",
+                             G_OBJECT_CLASS_TYPE (object_class),
+                             G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (TrackerDataSnifferClass, updated),
+                             NULL, NULL,
+                             tracker_marshal_VOID__STRING_STRING,
+                             G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+
+       g_type_class_add_private (object_class, sizeof (TrackerDataSnifferPrivate));
+}
+
+static void
+tracker_data_sniffer_init (TrackerDataSniffer *sniffer)
+{
+       sniffer->priv = TRACKER_DATA_SNIFFER_GET_PRIVATE (sniffer);
+}
+
+const gchar *
+tracker_data_sniffer_get_data_source (TrackerDataSniffer *sniffer)
+{
+       TrackerDataSnifferPrivate *priv;
+
+       g_return_val_if_fail (TRACKER_IS_DATA_SNIFFER (sniffer), NULL);
+
+       priv = sniffer->priv;
+       return priv->data_source;
+}
+
+const gchar *
+tracker_data_sniffer_get_class_name (TrackerDataSniffer *sniffer)
+{
+       TrackerDataSnifferPrivate *priv;
+
+       g_return_val_if_fail (TRACKER_IS_DATA_SNIFFER (sniffer), NULL);
+
+       priv = sniffer->priv;
+       return priv->class_name;
+}
diff --git a/src/libtracker-extract/tracker-data-sniffer.h b/src/libtracker-extract/tracker-data-sniffer.h
new file mode 100644
index 0000000..329f828
--- /dev/null
+++ b/src/libtracker-extract/tracker-data-sniffer.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013, Carlos Garnacho  <carlosg 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 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 __LIBTRACKER_DATA_SNIFFER_H__
+#define __LIBTRACKER_DATA_SNIFFER_H__
+
+#if !defined (__LIBTRACKER_EXTRACT_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "only <libtracker-extract/tracker-extract.h> must be included directly."
+#endif
+
+#include <libtracker-sparql/tracker-sparql.h>
+#include "tracker-module-manager.h"
+#include "tracker-extract-info.h"
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_DATA_SNIFFER         (tracker_data_sniffer_get_type())
+#define TRACKER_DATA_SNIFFER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DATA_SNIFFER, 
TrackerDataSniffer))
+#define TRACKER_DATA_SNIFFER_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DATA_SNIFFER, 
TrackerDataSnifferClass))
+#define TRACKER_IS_DATA_SNIFFER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DATA_SNIFFER))
+#define TRACKER_IS_DATA_SNIFFER_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),  TRACKER_TYPE_DATA_SNIFFER))
+#define TRACKER_DATA_SNIFFER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DATA_SNIFFER, 
TrackerDataSnifferClass))
+
+typedef struct _TrackerDataSniffer TrackerDataSniffer;
+typedef struct _TrackerDataSnifferClass TrackerDataSnifferClass;
+
+struct _TrackerDataSniffer {
+       GObject parent_instance;
+       gpointer priv;
+};
+
+struct _TrackerDataSnifferClass {
+       GObjectClass parent_class;
+
+       void (* updated) (TrackerDataSniffer *sniffer,
+                         const gchar        *urn,
+                         const gchar        *uri,
+                         GAsyncResult       *res);
+};
+
+GType         tracker_data_sniffer_get_type        (void) G_GNUC_CONST;
+
+void          tracker_data_sniffer_finish          (TrackerDataSniffer *sniffer,
+                                                   GAsyncResult       *res,
+                                                   const gchar        *query);
+
+const gchar * tracker_data_sniffer_get_data_source (TrackerDataSniffer *sniffer);
+const gchar * tracker_data_sniffer_get_class_name  (TrackerDataSniffer *sniffer);
+
+G_END_DECLS
+
+#endif /* __LIBTRACKER_DATA_SNIFFER_H__ */
diff --git a/src/libtracker-extract/tracker-marshal.list b/src/libtracker-extract/tracker-marshal.list
new file mode 100644
index 0000000..72f9937
--- /dev/null
+++ b/src/libtracker-extract/tracker-marshal.list
@@ -0,0 +1 @@
+VOID:STRING,STRING


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