[gvfs/tracker-metadata: 4/4] metadata: Introduce basic tracker pusher
- From: Tomas Bzatek <tbzatek src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/tracker-metadata: 4/4] metadata: Introduce basic tracker pusher
- Date: Tue, 14 Dec 2010 17:04:19 +0000 (UTC)
commit 5c2a4f4e982d3af96a4b3012ea906ba1a2b14d50
Author: Tomas Bzatek <tbzatek redhat com>
Date: Tue Dec 14 17:49:24 2010 +0100
metadata: Introduce basic tracker pusher
metadata/Makefile.am | 7 +-
metadata/meta-daemon.c | 30 +++
metadata/metadata-tracker-miner.c | 515 +++++++++++++++++++++++++++++++++++++
metadata/metadata-tracker-miner.h | 92 +++++++
4 files changed, 643 insertions(+), 1 deletions(-)
---
diff --git a/metadata/Makefile.am b/metadata/Makefile.am
index becf13e..d1147b0 100644
--- a/metadata/Makefile.am
+++ b/metadata/Makefile.am
@@ -21,7 +21,7 @@ libexec_PROGRAMS =\
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/common \
$(LIBXML_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) \
- $(UDEV_CFLAGS) \
+ $(UDEV_CFLAGS) $(TRACKER_CFLAGS) \
-DGVFS_LOCALEDIR=\""$(localedir)"\" \
-DG_LOG_DOMAIN=\"GVFS\" -DG_DISABLE_DEPRECATED \
-DDBUS_API_SUBJECT_TO_CHANGE
@@ -52,6 +52,11 @@ convert_nautilus_metadata_SOURCES = metadata-nautilus.c
gvfsd_metadata_LDADD = libmetadata.la $(DBUS_LIBS) ../common/libgvfscommon.la
gvfsd_metadata_SOURCES = meta-daemon.c
+if HAVE_TRACKER
+gvfsd_metadata_LDADD += $(TRACKER_LIBS)
+gvfsd_metadata_SOURCES += metadata-tracker-miner.c metadata-tracker-miner.h
+endif
+
# D-BUS service file
%.service: %.service.in ../config.log
$(AM_V_GEN) $(SED) -e "s|\ libexecdir\@|$(libexecdir)|" $< > $@
diff --git a/metadata/meta-daemon.c b/metadata/meta-daemon.c
index 0e21696..b37f275 100644
--- a/metadata/meta-daemon.c
+++ b/metadata/meta-daemon.c
@@ -32,8 +32,17 @@
#include "metatree.h"
#include "gvfsdaemonprotocol.h"
+#ifdef HAVE_TRACKER
+# include "metadata-tracker-miner.h"
+#endif
+
#define WRITEOUT_TIMEOUT_SECS 60
+#ifdef HAVE_TRACKER
+static MetadataTrackerMiner *tracker_miner;
+#endif
+
+
typedef struct {
char *filename;
MetaTree *tree;
@@ -160,6 +169,9 @@ metadata_set (const char *treefile,
_("Unable to set metadata key"));
res = FALSE;
}
+#ifdef HAVE_TRACKER
+ metadata_tracker_miner_set_stringv (tracker_miner, info->tree, path, key, strv);
+#endif
g_strfreev (strv);
}
else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING)
@@ -179,6 +191,9 @@ metadata_set (const char *treefile,
_("Unable to set metadata key"));
res = FALSE;
}
+#ifdef HAVE_TRACKER
+ metadata_tracker_miner_set_string (tracker_miner, info->tree, path, key, str);
+#endif
}
else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BYTE)
{
@@ -197,6 +212,9 @@ metadata_set (const char *treefile,
_("Unable to unset metadata key"));
res = FALSE;
}
+#ifdef HAVE_TRACKER
+ metadata_tracker_miner_unset (tracker_miner, info->tree, path, key);
+#endif
}
}
@@ -429,6 +447,10 @@ metadata_remove (const char *treefile,
return FALSE;
}
+#ifdef HAVE_TRACKER
+ metadata_tracker_miner_remove (tracker_miner, info->tree, path);
+#endif
+
tree_info_schedule_writeout (info);
return TRUE;
}
@@ -780,7 +802,15 @@ main (int argc, char *argv[])
NULL,
(GDestroyNotify)tree_info_free);
+#ifdef HAVE_TRACKER
+ tracker_miner = metadata_tracker_miner_new ();
+#endif
+
g_main_loop_run (loop);
+#ifdef HAVE_TRACKER
+ g_object_unref (tracker_miner);
+#endif
+
return 0;
}
diff --git a/metadata/metadata-tracker-miner.c b/metadata/metadata-tracker-miner.c
new file mode 100644
index 0000000..69e4846
--- /dev/null
+++ b/metadata/metadata-tracker-miner.c
@@ -0,0 +1,515 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Tomas Bzatek <tbzatek redhat com>
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "metatree.h"
+#include "metabuilder.h"
+
+#include "metadata-tracker-miner.h"
+
+#include <libtracker-sparql/tracker-sparql.h>
+
+
+#define METADATA_TRACKER_MINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), METADATA_TYPE_TRACKER_MINER, MetadataTrackerMinerPrivate))
+
+struct MetadataTrackerMinerPrivate
+{
+ TrackerSparqlConnection *connection;
+
+ GQueue *queue;
+ guint running_queue_id;
+};
+
+typedef enum {
+ METADATA_OP_SET,
+ METADATA_OP_UNSET,
+ METADATA_OP_REMOVE,
+} MetadataOperation;
+
+
+/* Forward declarations */
+static void queue_push_data_to_tracker (MetadataTrackerMiner *miner,
+ const char *filename,
+ MetadataOperation op,
+ const char *keyname,
+ MetaKeyType type,
+ gpointer value);
+
+
+
+
+void
+metadata_tracker_miner_set_string (MetadataTrackerMiner *miner,
+ MetaTree *tree,
+ const char *path,
+ const char *key,
+ const char *value)
+{
+ char *real_path;
+
+ real_path = meta_tree_get_real_path (tree, path);
+
+ queue_push_data_to_tracker (miner, real_path, METADATA_OP_SET,
+ key, META_KEY_TYPE_STRING, (gpointer) value);
+
+// scan_treefile_for_changes (miner, meta_tree_get_filename (tree), 0);
+
+ g_free (real_path);
+}
+
+void
+metadata_tracker_miner_set_stringv (MetadataTrackerMiner *miner,
+ MetaTree *tree,
+ const char *path,
+ const char *key,
+ char **value)
+{
+ char *real_path;
+
+ real_path = meta_tree_get_real_path (tree, path);
+
+ queue_push_data_to_tracker (miner, real_path, METADATA_OP_SET,
+ key, META_KEY_TYPE_STRINGV, (gpointer) value);
+
+ g_free (real_path);
+}
+
+void
+metadata_tracker_miner_unset (MetadataTrackerMiner *miner,
+ MetaTree *tree,
+ const char *path,
+ const char *key)
+{
+ char *real_path;
+
+ real_path = meta_tree_get_real_path (tree, path);
+
+ queue_push_data_to_tracker (miner, real_path, METADATA_OP_UNSET,
+ key, META_KEY_TYPE_NONE, NULL);
+
+ g_free (real_path);
+}
+
+void
+metadata_tracker_miner_remove (MetadataTrackerMiner *miner,
+ MetaTree *tree,
+ const char *path)
+{
+ char *real_path;
+
+ real_path = meta_tree_get_real_path (tree, path);
+
+ queue_push_data_to_tracker (miner, real_path, METADATA_OP_REMOVE,
+ NULL, META_KEY_TYPE_NONE, NULL);
+
+ g_free (real_path);
+}
+
+
+
+
+
+
+typedef struct {
+ MetadataTrackerMiner *miner;
+ char *path;
+ MetaTree *tree;
+} TreeScanDirEntry;
+
+typedef struct {
+ MetadataTrackerMiner *miner;
+ char *real_path;
+ MetaTree *tree;
+} TreeScanKeyEntry;
+
+static gboolean
+scan_enumerate_keys_callback (const char *key,
+ MetaKeyType type,
+ gpointer value,
+ gpointer user_data)
+{
+ TreeScanKeyEntry *entry;
+
+ entry = user_data;
+
+ switch (type)
+ {
+ case META_KEY_TYPE_NONE:
+ g_warning ("found key of type META_KEY_TYPE_NONE: '%s', file '%s ", key, entry->real_path);
+ break;
+ case META_KEY_TYPE_STRING:
+ case META_KEY_TYPE_STRINGV:
+ queue_push_data_to_tracker (entry->miner, entry->real_path, METADATA_OP_SET,
+ key, type, value);
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+scan_enumerate_dir_callback (const char *entry_name,
+ guint64 last_changed,
+ gboolean has_children,
+ gboolean has_data,
+ gpointer user_data)
+{
+ TreeScanDirEntry *entry, *new_entry;
+ TreeScanKeyEntry *key_entry;
+
+ entry = user_data;
+
+ if (has_children)
+ {
+ new_entry = g_new0 (TreeScanDirEntry, 1);
+ new_entry->tree = entry->tree; /* FIXME: ref? */
+ new_entry->path = g_build_path (G_DIR_SEPARATOR_S, entry->path, entry_name, NULL);
+ new_entry->miner = g_object_ref (entry->miner);
+
+ meta_tree_enumerate_dir (new_entry->tree, new_entry->path, scan_enumerate_dir_callback, new_entry);
+
+ g_object_unref (new_entry->miner);
+ g_free (new_entry->path);
+ g_free (new_entry);
+ }
+
+ if (has_data)
+ {
+ char *local_path;
+
+ local_path = g_build_filename (entry->path, entry_name, NULL);
+
+ key_entry = g_new0 (TreeScanKeyEntry, 1);
+ key_entry->tree = entry->tree; /* FIXME: ref? */
+ key_entry->real_path = meta_tree_get_real_path (entry->tree, local_path);
+ key_entry->miner = g_object_ref (entry->miner);
+
+ meta_tree_enumerate_keys (key_entry->tree, local_path, scan_enumerate_keys_callback, key_entry);
+
+ g_object_unref (key_entry->miner);
+ g_free (key_entry->real_path);
+ g_free (key_entry);
+
+ g_free (local_path);
+ }
+
+ return TRUE;
+}
+
+void
+scan_treefile_for_changes (MetadataTrackerMiner *miner,
+ const char *treefile,
+ guint64 last_update)
+{
+ MetaTree *tree;
+ TreeScanDirEntry *entry;
+
+ /* TODO: implement last_update */
+
+ tree = meta_tree_open (treefile, FALSE);
+ if (tree == NULL)
+ {
+ g_warning ("can't open file '%s'", treefile);
+ return;
+ }
+
+ entry = g_new0 (TreeScanDirEntry, 1);
+ entry->tree = tree; /* FIXME: ref? */
+ entry->path = g_strdup ("/");
+ entry->miner = g_object_ref (miner);
+ meta_tree_enumerate_dir (tree, entry->path,
+ scan_enumerate_dir_callback, entry);
+ g_object_unref (entry->miner);
+ g_free (entry->path);
+ g_free (entry);
+
+ meta_tree_unref (tree);
+}
+
+
+
+
+
+
+typedef struct {
+ char *filename;
+ MetadataOperation op;
+ char *key;
+ MetaKeyType type;
+ gpointer value;
+} MetadataTrackerMinerEntry;
+
+static gboolean process_queue (MetadataTrackerMiner *miner);
+
+static void
+push_to_tracker_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error;
+
+ error = NULL;
+
+ tracker_sparql_connection_update_finish (TRACKER_SPARQL_CONNECTION (source), result, &error);
+ if (error != NULL)
+ {
+ g_critical ("Could not push metadata to Tracker: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* continue with next item or bail out if no more available */
+ g_idle_add ((GSourceFunc) process_queue, user_data);
+}
+
+static gboolean
+process_queue (MetadataTrackerMiner *miner)
+{
+ MetadataTrackerMinerEntry *entry;
+ TrackerSparqlBuilder *sparql;
+ GFile *file;
+ char *data;
+
+ g_print ("process_queue: Picking up queue\n");
+
+ entry = g_queue_pop_head (miner->priv->queue);
+ if (entry == NULL)
+ {
+ miner->priv->running_queue_id = 0;
+ return FALSE;
+ }
+
+
+ g_print ("process_queue: Pushing '%s' key for '%s'\n", entry->key, entry->filename);
+ file = g_file_new_for_path (entry->filename);
+
+ /*
+ * tracker-sparql -q 'SELECT ?file ?comm WHERE { ?file nie:comment ?comm }'
+ * tracker-sparql -u -q "insert { <file:///mnt/flash/105E4003.NIC> a nie:InformationElement ; nie:comment 'ahoj' }"
+ *
+ */
+
+ /* FIXME: 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 ();
+
+
+ if (entry->op == METADATA_OP_SET ||
+ entry->op == METADATA_OP_UNSET ||
+ entry->op == METADATA_OP_REMOVE)
+ {
+ tracker_sparql_builder_delete_open (sparql, NULL);
+ tracker_sparql_builder_subject_iri (sparql, g_file_get_uri (file));
+ tracker_sparql_builder_predicate (sparql, "nie:comment");
+ 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, g_file_get_uri (file));
+ tracker_sparql_builder_predicate (sparql, "nie:comment");
+ tracker_sparql_builder_object_variable (sparql, "unknown");
+ tracker_sparql_builder_where_close (sparql);
+ }
+
+ if (entry->op == METADATA_OP_SET)
+ {
+ data = NULL;
+ switch (entry->type)
+ {
+ case META_KEY_TYPE_NONE:
+ g_assert_not_reached();
+ break;
+ case META_KEY_TYPE_STRING:
+ data = g_strdup_printf ("%s=%s", entry->key, (char *) entry->value);
+ break;
+ case META_KEY_TYPE_STRINGV:
+ data = g_strdup_printf ("%s=%s", entry->key, *((char **) entry->value)); /* FIXME */
+ break;
+ }
+
+ tracker_sparql_builder_insert_open (sparql, NULL);
+ tracker_sparql_builder_subject_iri (sparql, g_file_get_uri (file));
+ tracker_sparql_builder_predicate (sparql, "a");
+ // tracker_sparql_builder_object (sparql, "nfo:FileDataObject");
+ tracker_sparql_builder_object (sparql, "nie:InformationElement");
+ tracker_sparql_builder_predicate (sparql, "nie:comment");
+ tracker_sparql_builder_object_string (sparql, data);
+ tracker_sparql_builder_insert_close (sparql);
+
+ g_free (data);
+ }
+
+ tracker_sparql_connection_update_async (miner->priv->connection,
+ tracker_sparql_builder_get_result (sparql),
+ G_PRIORITY_DEFAULT,
+ NULL,
+ push_to_tracker_cb,
+ miner);
+ g_object_unref (sparql);
+ g_object_unref (file);
+
+ /* free the entry data */
+ g_free (entry->filename);
+ g_free (entry->key);
+ switch (entry->type)
+ {
+ case META_KEY_TYPE_NONE:
+ break;
+ case META_KEY_TYPE_STRING:
+ g_free (entry->value);
+ break;
+ case META_KEY_TYPE_STRINGV:
+ g_strfreev (entry->value);
+ break;
+ }
+
+ return FALSE;
+}
+
+
+static void
+queue_push_data_to_tracker (MetadataTrackerMiner *miner,
+ const char *filename,
+ MetadataOperation op,
+ const char *keyname,
+ MetaKeyType type,
+ gpointer value)
+{
+ MetadataTrackerMinerEntry *entry;
+
+ g_print ("queue_push_string_to_tracker: pushing '%s' for '%s'\n", keyname, filename);
+
+ entry = g_new0 (MetadataTrackerMinerEntry, 1);
+ entry->filename = g_strdup (filename);
+ entry->op = op;
+ entry->key = g_strdup (keyname);
+ entry->type = type;
+ switch (entry->type)
+ {
+ case META_KEY_TYPE_NONE:
+ g_assert (entry->op != METADATA_OP_SET);
+ break;
+ case META_KEY_TYPE_STRING:
+ entry->value = g_strdup (value);
+ break;
+ case META_KEY_TYPE_STRINGV:
+ entry->value = g_strdupv (value);
+ break;
+ }
+
+ /* FIXME: mutex? */
+ g_queue_push_head (miner->priv->queue, entry);
+
+ /* FIXME: mutex? */
+ if (miner->priv->connection != NULL && miner->priv->running_queue_id == 0)
+ miner->priv->running_queue_id = g_idle_add ((GSourceFunc) process_queue, miner);
+}
+
+
+
+
+
+G_DEFINE_TYPE (MetadataTrackerMiner, metadata_tracker_miner, G_TYPE_OBJECT)
+
+static void
+metadata_tracker_miner_finalize (GObject *object)
+{
+ MetadataTrackerMinerPrivate *priv;
+
+ priv = METADATA_TRACKER_MINER_GET_PRIVATE (object);
+
+ g_queue_free (priv->queue);
+
+ if (priv->connection)
+ g_object_unref (priv->connection);
+
+ G_OBJECT_CLASS (metadata_tracker_miner_parent_class)->finalize (object);
+}
+
+static void
+metadata_tracker_miner_class_init (MetadataTrackerMinerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = metadata_tracker_miner_finalize;
+
+ g_type_class_add_private (object_class, sizeof (MetadataTrackerMinerPrivate));
+}
+
+static void
+create_connection_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ TrackerSparqlConnection *connection;
+ MetadataTrackerMiner *miner;
+ GError *error;
+
+ miner = user_data;
+ error = NULL;
+
+ connection = tracker_sparql_connection_get_finish (res, &error);
+ if (error != NULL)
+ {
+ g_critical ("Could not initialize Tracker: %s", error->message);
+ g_error_free (error);
+ }
+ miner->priv->connection = connection;
+ g_print ("create_connection_cb: Initialized.\n");
+
+ /* Process queue */
+ if (connection != NULL && miner->priv->running_queue_id == 0)
+ miner->priv->running_queue_id = g_idle_add ((GSourceFunc) process_queue, miner);
+}
+
+static void
+metadata_tracker_miner_init (MetadataTrackerMiner *object)
+{
+ object->priv = METADATA_TRACKER_MINER_GET_PRIVATE (object);
+
+ object->priv->running_queue_id = 0;
+
+ /* FIXME: do we need cancellable? */
+ tracker_sparql_connection_get_async (NULL, create_connection_cb, object);
+ object->priv->queue = g_queue_new ();
+}
+
+MetadataTrackerMiner *
+metadata_tracker_miner_new ()
+{
+ MetadataTrackerMiner *result;
+
+ result = g_object_new (METADATA_TYPE_TRACKER_MINER, NULL);
+
+ return result;
+}
diff --git a/metadata/metadata-tracker-miner.h b/metadata/metadata-tracker-miner.h
new file mode 100644
index 0000000..1926ee5
--- /dev/null
+++ b/metadata/metadata-tracker-miner.h
@@ -0,0 +1,92 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Tomas Bzatek <tbzatek redhat com>
+ */
+
+#ifndef __TRACKER_MINER_H__
+#define __TRACKER_MINER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "metatree.h"
+
+
+G_BEGIN_DECLS
+
+
+/* TODO:
+ * - queue messages, send them in a separate thread
+ * - if sending fails, set a flag to manually reindex, start watching for tracker-store to come up
+ * - what to do if connection to tracker fails? don't queue messages to prevent overflow and increasing memory consumption?
+ * - offline indexer: how to delete old metadata, not available in the metatree file? (no way to determine which ones have been deleted)
+ * - handle moves
+ * - move scan_treefile_for_changes() to thread? (time consuming operation)
+ *
+ */
+
+#define METADATA_TYPE_TRACKER_MINER (metadata_tracker_miner_get_type())
+#define METADATA_TRACKER_MINER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), METADATA_TYPE_TRACKER_MINER, MetadataTrackerMiner))
+#define METADATA_TRACKER_MINER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), METADATA_TYPE_TRACKER_MINER, MetadataTrackerMinerClass))
+#define METADATA_IS_TRACKER_MINER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), METADATA_TYPE_TRACKER_MINER))
+#define METADATA_IS_TRACKER_MINER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), METADATA_TYPE_TRACKER_MINER))
+#define METADATA_TRACKER_MINER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), METADATA_TYPE_TRACKER_MINER, MetadataTrackerMinerClass))
+
+typedef struct MetadataTrackerMinerPrivate MetadataTrackerMinerPrivate;
+
+typedef struct {
+ GObject parent;
+ MetadataTrackerMinerPrivate *priv;
+} MetadataTrackerMiner;
+
+typedef struct {
+ GObjectClass parent_class;
+} MetadataTrackerMinerClass;
+
+
+GType metadata_tracker_miner_get_type (void);
+
+MetadataTrackerMiner * metadata_tracker_miner_new (void);
+
+void metadata_tracker_miner_set_string (MetadataTrackerMiner *miner,
+ MetaTree *tree,
+ const char *path,
+ const char *key,
+ const char *value);
+void metadata_tracker_miner_set_stringv (MetadataTrackerMiner *miner,
+ MetaTree *tree,
+ const char *path,
+ const char *key,
+ char **value);
+void metadata_tracker_miner_unset (MetadataTrackerMiner *miner,
+ MetaTree *tree,
+ const char *path,
+ const char *key);
+void metadata_tracker_miner_remove (MetadataTrackerMiner *miner,
+ MetaTree *tree,
+ const char *path);
+
+void scan_treefile_for_changes (MetadataTrackerMiner *miner,
+ const char *treefile,
+ guint64 last_update);
+
+G_END_DECLS
+
+#endif /* __TRACKER_MINER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]