[tracker/extraction-improvements: 1/3] libtracker-extract: Add tracker-extract-client API
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/extraction-improvements: 1/3] libtracker-extract: Add tracker-extract-client API
- Date: Wed, 4 May 2011 14:13:49 +0000 (UTC)
commit 0df5f8f95fe95901ca4f55d03250f760e2bff4f2
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed May 4 14:37:44 2011 +0200
libtracker-extract: Add tracker-extract-client API
This API is meant to replace the code in TrackerMinerFiles to
deal with the communication with the extractor.
src/libtracker-extract/Makefile.am | 3 +
src/libtracker-extract/tracker-extract-client.c | 406 ++++++++++++++++++++++
src/libtracker-extract/tracker-extract-client.h | 49 +++
src/libtracker-extract/tracker-extract.h | 1 +
src/miners/fs/tracker-miner-files.c | 412 +---------------------
5 files changed, 478 insertions(+), 393 deletions(-)
---
diff --git a/src/libtracker-extract/Makefile.am b/src/libtracker-extract/Makefile.am
index 5335269..6007011 100644
--- a/src/libtracker-extract/Makefile.am
+++ b/src/libtracker-extract/Makefile.am
@@ -17,6 +17,8 @@ libtracker_extract_ TRACKER_API_VERSION@_la_SOURCES = \
tracker-encoding.c \
tracker-exif.c \
tracker-exif.h \
+ tracker-extract-client.c \
+ tracker-extract-client.h \
tracker-guarantee.c \
tracker-guarantee.h \
tracker-iptc.c \
@@ -33,6 +35,7 @@ libtracker_extractinclude_HEADERS = \
tracker-data.h \
tracker-encoding.h \
tracker-exif.h \
+ tracker-extract-client.h \
tracker-extract.h \
tracker-guarantee.h \
tracker-iptc.h \
diff --git a/src/libtracker-extract/tracker-extract-client.c b/src/libtracker-extract/tracker-extract-client.c
new file mode 100644
index 0000000..8aabcca
--- /dev/null
+++ b/src/libtracker-extract/tracker-extract-client.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2010, Nokia <ivan frade nokia com>
+ *
+ * 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-extract-client.h"
+
+#include <string.h>
+#include <gio/gunixfdlist.h>
+#include <gio/gunixinputstream.h>
+
+/* Size of buffers used when sending data over a pipe, using DBus FD passing */
+#define DBUS_PIPE_BUFFER_SIZE 65536
+
+#define DBUS_SERVICE_EXTRACT "org.freedesktop.Tracker1.Extract"
+#define DBUS_PATH_EXTRACT "/org/freedesktop/Tracker1/Extract"
+#define DBUS_INTERFACE_EXTRACT "org.freedesktop.Tracker1.Extract"
+
+struct TrackerExtractInfo {
+ gchar *preupdate;
+ gchar *update;
+ gchar *where;
+};
+
+typedef void (* SendAndSpliceCallback) (void *buffer,
+ gssize buffer_size,
+ GError *error, /* Don't free */
+ gpointer user_data);
+
+typedef struct {
+ GInputStream *unix_input_stream;
+ GInputStream *buffered_input_stream;
+ GOutputStream *output_stream;
+ SendAndSpliceCallback callback;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *res;
+ gboolean splice_finished;
+ gboolean dbus_finished;
+ GError *error;
+} SendAndSpliceData;
+
+static TrackerExtractInfo *
+tracker_extract_info_new (const gchar *preupdate,
+ const gchar *update,
+ const gchar *where)
+{
+ TrackerExtractInfo *info;
+
+ info = g_slice_new0 (TrackerExtractInfo);
+ info->preupdate = g_strdup (preupdate);
+ info->update = g_strdup (update);
+ info->where = g_strdup (where);
+
+ return info;
+}
+
+static void
+tracker_extract_info_free (TrackerExtractInfo *info)
+{
+ g_free (info->preupdate);
+ g_free (info->update);
+ g_free (info->where);
+
+ g_slice_free (TrackerExtractInfo, info);
+}
+
+static SendAndSpliceData *
+send_and_splice_data_new (GInputStream *unix_input_stream,
+ GInputStream *buffered_input_stream,
+ GOutputStream *output_stream,
+ GCancellable *cancellable,
+ SendAndSpliceCallback callback,
+ GSimpleAsyncResult *res)
+{
+ SendAndSpliceData *data;
+
+ data = g_slice_new0 (SendAndSpliceData);
+ data->unix_input_stream = unix_input_stream;
+ data->buffered_input_stream = buffered_input_stream;
+ data->output_stream = output_stream;
+
+ if (cancellable) {
+ data->cancellable = g_object_ref (cancellable);
+ }
+
+ data->callback = callback;
+ data->res = g_object_ref (res);
+
+ return data;
+}
+
+static void
+send_and_splice_data_free (SendAndSpliceData *data)
+{
+ g_object_unref (data->unix_input_stream);
+ g_object_unref (data->buffered_input_stream);
+ g_object_unref (data->output_stream);
+
+ if (data->cancellable) {
+ g_object_unref (data->cancellable);
+ }
+
+ if (data->error) {
+ g_error_free (data->error);
+ }
+
+ if (data->res) {
+ g_object_unref (data->res);
+ }
+
+ g_slice_free (SendAndSpliceData, data);
+}
+
+static void
+dbus_send_and_splice_async_finish (SendAndSpliceData *data)
+{
+ if (!data->error) {
+ (* data->callback) (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->output_stream)),
+ g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->output_stream)),
+ NULL,
+ data->res);
+ } else {
+ (* data->callback) (NULL, -1, data->error, data->res);
+ }
+
+ send_and_splice_data_free (data);
+}
+
+static void
+send_and_splice_splice_callback (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ SendAndSpliceData *data = user_data;
+ GError *error = NULL;
+
+ g_output_stream_splice_finish (G_OUTPUT_STREAM (source), result, &error);
+
+ if (error) {
+ if (!data->error) {
+ data->error = error;
+ } else {
+ g_error_free (error);
+ }
+ }
+
+ data->splice_finished = TRUE;
+
+ if (data->dbus_finished) {
+ dbus_send_and_splice_async_finish (data);
+ }
+}
+
+static void
+send_and_splice_dbus_callback (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ SendAndSpliceData *data = user_data;
+ GDBusMessage *reply;
+ GError *error = NULL;
+
+ reply = g_dbus_connection_send_message_with_reply_finish (G_DBUS_CONNECTION (source),
+ result, &error);
+
+ if (reply) {
+ if (g_dbus_message_get_message_type (reply) == G_DBUS_MESSAGE_TYPE_ERROR) {
+ g_dbus_message_to_gerror (reply, &error);
+ }
+
+ g_object_unref (reply);
+ }
+
+ if (error) {
+ if (!data->error) {
+ data->error = error;
+ } else {
+ g_error_free (error);
+ }
+ }
+
+ data->dbus_finished = TRUE;
+
+ if (data->splice_finished) {
+ dbus_send_and_splice_async_finish (data);
+ }
+}
+
+static void
+dbus_send_and_splice_async (GDBusConnection *connection,
+ GDBusMessage *message,
+ int fd,
+ GCancellable *cancellable,
+ SendAndSpliceCallback callback,
+ GSimpleAsyncResult *res)
+{
+ SendAndSpliceData *data;
+ GInputStream *unix_input_stream;
+ GInputStream *buffered_input_stream;
+ GOutputStream *output_stream;
+
+ unix_input_stream = g_unix_input_stream_new (fd, TRUE);
+ buffered_input_stream = g_buffered_input_stream_new_sized (unix_input_stream,
+ DBUS_PIPE_BUFFER_SIZE);
+ output_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+
+ data = send_and_splice_data_new (unix_input_stream,
+ buffered_input_stream,
+ output_stream,
+ cancellable,
+ callback,
+ res);
+
+ g_dbus_connection_send_message_with_reply (connection,
+ message,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ -1,
+ NULL,
+ cancellable,
+ send_and_splice_dbus_callback,
+ data);
+
+ g_output_stream_splice_async (data->output_stream,
+ data->buffered_input_stream,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
+ G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ 0,
+ cancellable,
+ send_and_splice_splice_callback,
+ data);
+}
+
+static void
+get_metadata_fast_cb (void *buffer,
+ gssize buffer_size,
+ GError *error,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+
+ res = user_data;
+
+ if (G_UNLIKELY (error)) {
+ g_simple_async_result_set_from_error (res, error);
+ } else {
+ const gchar *preupdate, *sparql, *where, *end;
+ TrackerExtractInfo *info;
+ gsize len;
+
+ preupdate = sparql = where = NULL;
+ end = (gchar *) buffer + buffer_size;
+
+ if (buffer) {
+ preupdate = buffer;
+ len = strlen (preupdate);
+
+ if (preupdate + len < end) {
+ buffer_size -= len;
+ sparql = preupdate + len + 1;
+ len = strlen (sparql);
+
+ if (sparql + len < end) {
+ where = sparql + len + 1;
+ }
+ }
+ }
+
+ info = tracker_extract_info_new (preupdate, sparql, where);
+ g_simple_async_result_set_op_res_gpointer (res, info,
+ (GDestroyNotify) tracker_extract_info_free);
+ }
+
+ g_simple_async_result_complete_in_idle (res);
+}
+
+static void
+get_metadata_fast_async (GDBusConnection *connection,
+ const gchar *uri,
+ const gchar *mime_type,
+ GCancellable *cancellable,
+ GSimpleAsyncResult *res)
+{
+ GDBusMessage *message;
+ GUnixFDList *fd_list;
+ int pipefd[2];
+
+ if (pipe (pipefd) < 0) {
+ g_critical ("Coudln't open pipe");
+ /* FIXME: Report async error */
+ return;
+ }
+
+ message = g_dbus_message_new_method_call (DBUS_SERVICE_EXTRACT,
+ DBUS_PATH_EXTRACT,
+ DBUS_INTERFACE_EXTRACT,
+ "GetMetadataFast");
+
+ fd_list = g_unix_fd_list_new ();
+
+ g_dbus_message_set_body (message,
+ g_variant_new ("(ssh)",
+ uri,
+ mime_type,
+ g_unix_fd_list_append (fd_list,
+ pipefd[1],
+ NULL)));
+ g_dbus_message_set_unix_fd_list (message, fd_list);
+
+ /* We need to close the fd as g_unix_fd_list_append duplicates the fd */
+
+ close (pipefd[1]);
+
+ g_object_unref (fd_list);
+
+ dbus_send_and_splice_async (connection,
+ message,
+ pipefd[0],
+ cancellable,
+ get_metadata_fast_cb,
+ res);
+ g_object_unref (message);
+}
+
+void
+tracker_extract_client_get_metadata (GFile *file,
+ const gchar *mime_type,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ static GDBusConnection *connection = NULL;
+ GSimpleAsyncResult *res;
+ GError *error = NULL;
+ gchar *uri;
+
+ g_return_if_fail (G_IS_FILE (file));
+ g_return_if_fail (mime_type != NULL);
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+
+ if (G_UNLIKELY (!connection)) {
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, &error);
+
+ if (error) {
+ g_simple_async_report_gerror_in_idle (G_OBJECT (file), callback, user_data, error);
+ g_error_free (error);
+ return;
+ }
+ }
+
+ uri = g_file_get_uri (file);
+
+ res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, NULL);
+ g_simple_async_result_set_handle_cancellation (res, TRUE);
+
+ get_metadata_fast_async (connection, uri, mime_type, cancellable, res);
+}
+
+TrackerExtractInfo *
+tracker_extract_client_get_metadata_finish (GFile *file,
+ GAsyncResult *res,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
+ g_return_val_if_fail (!error || !*error, NULL);
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) {
+ return NULL;
+ }
+
+ return g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
+}
+
+G_CONST_RETURN gchar *
+tracker_extract_info_get_preupdate (TrackerExtractInfo *info)
+{
+ return info->preupdate;
+}
+
+G_CONST_RETURN gchar *
+tracker_extract_info_get_update (TrackerExtractInfo *info)
+{
+ return info->update;
+}
+
+G_CONST_RETURN gchar *
+tracker_extract_info_get_where_clause (TrackerExtractInfo *info)
+{
+ return info->where;
+}
diff --git a/src/libtracker-extract/tracker-extract-client.h b/src/libtracker-extract/tracker-extract-client.h
new file mode 100644
index 0000000..bd72a2d
--- /dev/null
+++ b/src/libtracker-extract/tracker-extract-client.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011, Nokia <ivan frade nokia com>
+ *
+ * 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_EXTRACT_CLIENT_H__
+#define __TRACKER_EXTRACT_CLIENT_H__
+
+#if !defined (__LIBTRACKER_EXTRACT_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "only <libtracker-extract/tracker-extract.h> must be included directly."
+#endif
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef struct TrackerExtractInfo TrackerExtractInfo;
+
+void tracker_extract_client_get_metadata (GFile *file,
+ const gchar *mime_type,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+TrackerExtractInfo * tracker_extract_client_get_metadata_finish (GFile *uri,
+ GAsyncResult *res,
+ GError **error);
+
+G_CONST_RETURN gchar * tracker_extract_info_get_preupdate (TrackerExtractInfo *info);
+G_CONST_RETURN gchar * tracker_extract_info_get_update (TrackerExtractInfo *info);
+G_CONST_RETURN gchar * tracker_extract_info_get_where_clause (TrackerExtractInfo *info);
+
+G_END_DECLS
+
+#endif /* __TRACKER_EXTRACT_CLIENT_H__ */
diff --git a/src/libtracker-extract/tracker-extract.h b/src/libtracker-extract/tracker-extract.h
index e66f2b2..8463b5d 100644
--- a/src/libtracker-extract/tracker-extract.h
+++ b/src/libtracker-extract/tracker-extract.h
@@ -27,6 +27,7 @@
#include "tracker-data.h"
#include "tracker-encoding.h"
#include "tracker-exif.h"
+#include "tracker-extract-client.h"
#include "tracker-module-manager.h"
#include "tracker-guarantee.h"
#include "tracker-iptc.h"
diff --git a/src/miners/fs/tracker-miner-files.c b/src/miners/fs/tracker-miner-files.c
index 3dd67c5..7551862 100644
--- a/src/miners/fs/tracker-miner-files.c
+++ b/src/miners/fs/tracker-miner-files.c
@@ -43,25 +43,16 @@
#include <libtracker-data/tracker-db-manager.h>
#include <libtracker-extract/tracker-module-manager.h>
+#include <libtracker-extract/tracker-extract-client.h>
#include "tracker-power.h"
#include "tracker-miner-files.h"
#include "tracker-config.h"
#include "tracker-marshal.h"
-/* Size of buffers used when sending data over a pipe, using DBus FD passing */
-#define DBUS_PIPE_BUFFER_SIZE 65536
-
-#define DBUS_SERVICE_EXTRACT "org.freedesktop.Tracker1.Extract"
-#define DBUS_PATH_EXTRACT "/org/freedesktop/Tracker1/Extract"
-#define DBUS_INTERFACE_EXTRACT "org.freedesktop.Tracker1.Extract"
-
#define DISK_SPACE_CHECK_FREQUENCY 10
#define SECONDS_PER_DAY 86400
-/* Default DBus timeout to be used in requests to extractor (milliseconds) */
-#define EXTRACTOR_DBUS_TIMEOUT 60000
-
#define TRACKER_MINER_FILES_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER_FILES, TrackerMinerFilesPrivate))
static GQuark miner_files_error_quark = 0;
@@ -75,34 +66,6 @@ struct ProcessFileData {
GFile *file;
};
-typedef void (*fast_async_cb) (const gchar *preupdate,
- const gchar *sparql,
- const gchar *where,
- GError *error,
- gpointer user_data);
-
-typedef void (*TrackerDBusSendAndSpliceCallback) (void *buffer,
- gssize buffer_size,
- GError *error, /* Don't free */
- gpointer user_data);
-
-typedef struct {
- GInputStream *unix_input_stream;
- GInputStream *buffered_input_stream;
- GOutputStream *output_stream;
- TrackerDBusSendAndSpliceCallback callback;
- GCancellable *cancellable;
- gpointer user_data;
- gboolean splice_finished;
- gboolean dbus_finished;
- GError *error;
-} SendAndSpliceData;
-
-typedef struct {
- fast_async_cb callback;
- gpointer user_data;
-} FastAsyncData;
-
struct TrackerMinerFilesPrivate {
TrackerConfig *config;
TrackerStorage *storage;
@@ -228,9 +191,6 @@ static gboolean miner_files_ignore_next_update_file (TrackerMinerFS *f
GCancellable *cancellable);
static void miner_files_finished (TrackerMinerFS *fs);
-static void extractor_get_embedded_metadata_cancel (GCancellable *cancellable,
- ProcessFileData *data);
-
static void miner_finished_cb (TrackerMinerFS *fs,
gdouble seconds_elapsed,
guint total_directories_found,
@@ -1937,10 +1897,6 @@ miner_files_add_to_datasource (TrackerMinerFiles *mf,
static void
process_file_data_free (ProcessFileData *data)
{
- g_signal_handlers_disconnect_by_func (data->cancellable,
- extractor_get_embedded_metadata_cancel,
- data);
-
g_object_unref (data->miner);
g_object_unref (data->sparql);
g_object_unref (data->cancellable);
@@ -1949,15 +1905,18 @@ process_file_data_free (ProcessFileData *data)
}
static void
-extractor_get_embedded_metadata_cb (const gchar *preupdate,
- const gchar *sparql,
- const gchar *where,
- GError *error,
- gpointer user_data)
+extractor_get_embedded_metadata_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
{
ProcessFileData *data = user_data;
+ const gchar *preupdate, *sparql, *where;
+ TrackerExtractInfo *info;
+ GError *error = NULL;
const gchar *uuid;
+ info = tracker_extract_client_get_metadata_finish (G_FILE (object), res, &error);
+
if (error) {
/* Something bad happened, notify about the error */
tracker_miner_fs_file_notify (TRACKER_MINER_FS (data->miner), data->file, error);
@@ -1965,6 +1924,10 @@ extractor_get_embedded_metadata_cb (const gchar *preupdate,
return;
}
+ preupdate = tracker_extract_info_get_preupdate (info);
+ sparql = tracker_extract_info_get_update (info);
+ where = tracker_extract_info_get_where_clause (info);
+
if (sparql && *sparql) {
gboolean is_iri;
const gchar *urn;
@@ -2042,347 +2005,6 @@ extractor_get_embedded_metadata_cb (const gchar *preupdate,
}
static void
-extractor_get_embedded_metadata_cancel (GCancellable *cancellable,
- ProcessFileData *data)
-{
- GError *error;
-
- /* TODO: Cancel extractor call
- * Isn't this as simple as g_cancellable_cancel (cancellable) now after the
- * GDBus port? The original dbus-glib code didn't have this so I have not
- * yet implemented it as part of the GDBus port. */
-
- error = g_error_new_literal (miner_files_error_quark, 0,
- "Embedded metadata extraction was cancelled");
- tracker_miner_fs_file_notify (TRACKER_MINER_FS (data->miner), data->file, error);
-
- process_file_data_free (data);
- g_error_free (error);
-}
-
-static gboolean
-extractor_skip_embedded_metadata_idle (gpointer user_data)
-{
- extractor_get_embedded_metadata_cb (NULL, NULL, NULL, NULL, user_data);
- return FALSE;
-}
-
-static SendAndSpliceData *
-send_and_splice_data_new (GInputStream *unix_input_stream,
- GInputStream *buffered_input_stream,
- GOutputStream *output_stream,
- GCancellable *cancellable,
- TrackerDBusSendAndSpliceCallback callback,
- gpointer user_data)
-{
- SendAndSpliceData *data;
-
- data = g_slice_new0 (SendAndSpliceData);
- data->unix_input_stream = unix_input_stream;
- data->buffered_input_stream = buffered_input_stream;
- data->output_stream = output_stream;
- if (cancellable) {
- data->cancellable = g_object_ref (cancellable);
- }
- data->callback = callback;
- data->user_data = user_data;
-
- return data;
-}
-
-static void
-send_and_splice_data_free (SendAndSpliceData *data)
-{
- g_object_unref (data->unix_input_stream);
- g_object_unref (data->buffered_input_stream);
- g_object_unref (data->output_stream);
- if (data->cancellable) {
- g_object_unref (data->cancellable);
- }
- if (data->error) {
- g_error_free (data->error);
- }
- g_slice_free (SendAndSpliceData, data);
-}
-
-static void
-dbus_send_and_splice_async_finish (SendAndSpliceData *data)
-{
- if (!data->error) {
- (* data->callback) (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->output_stream)),
- g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->output_stream)),
- NULL,
- data->user_data);
- } else {
- (* data->callback) (NULL, -1, data->error, data->user_data);
- }
-
- send_and_splice_data_free (data);
-}
-
-static void
-send_and_splice_splice_callback (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- SendAndSpliceData *data = user_data;
- GError *error = NULL;
-
- g_output_stream_splice_finish (G_OUTPUT_STREAM (source), result, &error);
-
- if (error) {
- if (!data->error) {
- data->error = error;
- } else {
- g_error_free (error);
- }
- }
-
- data->splice_finished = TRUE;
-
- if (data->dbus_finished) {
- dbus_send_and_splice_async_finish (data);
- }
-}
-
-static void
-send_and_splice_dbus_callback (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- SendAndSpliceData *data = user_data;
- GDBusMessage *reply;
- GError *error = NULL;
-
- reply = g_dbus_connection_send_message_with_reply_finish (G_DBUS_CONNECTION (source),
- result, &error);
-
- if (reply) {
- if (g_dbus_message_get_message_type (reply) == G_DBUS_MESSAGE_TYPE_ERROR) {
- g_dbus_message_to_gerror (reply, &error);
- }
-
- g_object_unref (reply);
- }
-
- if (error) {
- if (!data->error) {
- data->error = error;
- } else {
- g_error_free (error);
- }
- }
-
- data->dbus_finished = TRUE;
-
- if (data->splice_finished) {
- dbus_send_and_splice_async_finish (data);
- }
-}
-
-static gboolean
-dbus_send_and_splice_async (GDBusConnection *connection,
- GDBusMessage *message,
- int fd,
- GCancellable *cancellable,
- TrackerDBusSendAndSpliceCallback callback,
- gpointer user_data)
-{
- SendAndSpliceData *data;
- GInputStream *unix_input_stream;
- GInputStream *buffered_input_stream;
- GOutputStream *output_stream;
-
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (message != NULL, FALSE);
- g_return_val_if_fail (fd > 0, FALSE);
- g_return_val_if_fail (callback != NULL, FALSE);
-
- unix_input_stream = g_unix_input_stream_new (fd, TRUE);
- buffered_input_stream = g_buffered_input_stream_new_sized (unix_input_stream,
- DBUS_PIPE_BUFFER_SIZE);
- output_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
-
- data = send_and_splice_data_new (unix_input_stream,
- buffered_input_stream,
- output_stream,
- cancellable,
- callback,
- user_data);
-
- g_dbus_connection_send_message_with_reply (connection,
- message,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE,
- -1,
- NULL,
- cancellable,
- send_and_splice_dbus_callback,
- data);
-
- g_output_stream_splice_async (data->output_stream,
- data->buffered_input_stream,
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
- G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- 0,
- data->cancellable,
- send_and_splice_splice_callback,
- data);
-
- return TRUE;
-}
-
-static FastAsyncData*
-fast_async_data_new (fast_async_cb callback,
- gpointer user_data)
-{
- FastAsyncData *data;
-
- data = g_slice_new0 (FastAsyncData);
-
- data->callback = callback;
- data->user_data = user_data;
-
- return data;
-}
-
-static void
-fast_async_data_free (FastAsyncData *data)
-{
- g_slice_free (FastAsyncData, data);
-}
-
-static void
-get_metadata_fast_cb (void *buffer,
- gssize buffer_size,
- GError *error,
- gpointer user_data)
-{
- FastAsyncData *data;
- ProcessFileData *process_data;
- gboolean valid_input = FALSE;
- gboolean free_error = FALSE;
- const gchar *preupdate = NULL;
- const gchar *sparql = NULL;
- const gchar *where = NULL;
-
- data = user_data;
- process_data = data->user_data;
-
- if (!error && buffer_size) {
- gsize preupdate_length, sparql_length, where_length;
-
- preupdate = buffer;
- preupdate_length = strnlen (preupdate, buffer_size - 1);
- if (preupdate[preupdate_length] == '\0') {
- /* sparql is stored just after preupdate in the original buffer */
- sparql = preupdate + preupdate_length + 1;
- sparql_length = strnlen (sparql, preupdate + buffer_size - 1 - sparql);
- if (sparql[sparql_length] == '\0') {
- /* where is stored just after sparql in the original buffer */
- where = sparql + sparql_length + 1;
- where_length = strnlen (where, preupdate + buffer_size - 1 - where);
- if (where[where_length] == '\0') {
- valid_input = TRUE;
- }
- }
- }
-
- if (!valid_input) {
- error = g_error_new_literal (miner_files_error_quark,
- 0,
- "Invalid data received from GetMetadataFast");
- free_error = TRUE;
- }
- }
-
- if (G_UNLIKELY (error)) {
- if (error->code != G_IO_ERROR_CANCELLED) {
- (* data->callback) (NULL, NULL, NULL, error, process_data);
- }
- if (free_error) {
- g_error_free (error);
- }
- } else {
- (* data->callback) (preupdate, sparql, where, NULL, data->user_data);
- }
-
- fast_async_data_free (data);
-}
-
-static void
-get_metadata_fast_async (GDBusConnection *connection,
- const gchar *uri,
- const gchar *mime_type,
- GCancellable *cancellable,
- fast_async_cb callback,
- ProcessFileData *user_data)
-{
- GDBusMessage *message;
- GUnixFDList *fd_list;
- FastAsyncData *data;
- int pipefd[2];
-
- g_return_if_fail (connection);
- g_return_if_fail (uri);
- g_return_if_fail (mime_type);
- g_return_if_fail (callback);
-
- if (pipe (pipefd) < 0) {
- g_critical ("Coudln't open pipe");
- return;
- }
-
- message = g_dbus_message_new_method_call (DBUS_SERVICE_EXTRACT,
- DBUS_PATH_EXTRACT,
- DBUS_INTERFACE_EXTRACT,
- "GetMetadataFast");
-
- fd_list = g_unix_fd_list_new ();
-
- g_dbus_message_set_body (message, g_variant_new ("(ssh)",
- uri,
- mime_type,
- g_unix_fd_list_append (fd_list,
- pipefd[1],
- NULL)));
- g_dbus_message_set_unix_fd_list (message, fd_list);
-
- /* We need to close the fd as g_unix_fd_list_append duplicates the fd */
-
- close (pipefd[1]);
-
- g_object_unref (fd_list);
-
- data = fast_async_data_new (callback,
- user_data);
-
- dbus_send_and_splice_async (connection,
- message,
- pipefd[0],
- cancellable,
- get_metadata_fast_cb,
- data);
-
- g_object_unref (message);
-}
-
-static void
-extractor_get_embedded_metadata (ProcessFileData *data,
- const gchar *uri,
- const gchar *mime_type)
-{
- get_metadata_fast_async (data->miner->private->connection,
- uri,
- mime_type,
- data->cancellable,
- extractor_get_embedded_metadata_cb,
- data);
-
- g_signal_connect (data->cancellable, "cancelled",
- G_CALLBACK (extractor_get_embedded_metadata_cancel), data);
-}
-
-static void
process_file_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
@@ -2474,12 +2096,16 @@ process_file_cb (GObject *object,
if (tracker_extract_module_manager_mimetype_is_handled (mime_type)) {
/* Next step, if handled by the extractor, get embedded metadata */
- extractor_get_embedded_metadata (data, uri, mime_type);
+ tracker_extract_client_get_metadata (data->file,
+ mime_type,
+ data->cancellable,
+ extractor_get_embedded_metadata_cb,
+ data);
} else {
/* Otherwise, don't request embedded metadata extraction.
* We setup an idle so that we keep the previous behavior. */
g_debug ("Avoiding embedded metadata request for uri '%s'", uri);
- g_idle_add (extractor_skip_embedded_metadata_idle, data);
+ tracker_miner_fs_file_notify (TRACKER_MINER_FS (data->miner), data->file, NULL);
}
g_object_unref (file_info);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]