diff --git a/gtk/gtksearchenginetracker.c b/gtk/gtksearchenginetracker.c index 62447f8c29..7a8e26c9fe 100644 --- a/gtk/gtksearchenginetracker.c +++ b/gtk/gtksearchenginetracker.c @@ -23,9 +23,6 @@ #include "config.h" #include #include "gtksearchenginetracker.h" -#if 0 -#include -#endif /* we dlopen() libtracker at runtime */ @@ -34,9 +31,12 @@ typedef struct _TrackerClient TrackerClient; typedef enum { TRACKER_0_6 = 1 << 0, - TRACKER_0_7 = 1 << 1 + TRACKER_0_7 = 1 << 1, + TRACKER_0_8 = 1 << 2 } TrackerVersion; + +/* tracker 0.6 API */ typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data); static TrackerClient * (*tracker_connect) (gboolean enable_warnings, gint timeout) = NULL; @@ -53,6 +53,23 @@ static void (*tracker_search_metadata_by_text_and_location_async) (TrackerClient const char *location, TrackerArrayReply callback, gpointer user_data) = NULL; +/* tracker 0.8 API */ +typedef enum { + TRACKER_CLIENT_ENABLE_WARNINGS = 1 << 0 +} TrackerClientFlags; + +typedef void (*TrackerReplyGPtrArray) (GPtrArray *result, + GError *error, + gpointer user_data); + +static TrackerClient * (*tracker_client_new) (TrackerClientFlags flags, + gint timeout) = NULL; +static gchar * (*tracker_sparql_escape) (const gchar *str) = NULL; +static guint (*tracker_resources_sparql_query_async) (TrackerClient *client, + const gchar *query, + TrackerReplyGPtrArray callback, + gpointer user_data) = NULL; + static struct TrackerDlMapping { @@ -65,9 +82,12 @@ static struct TrackerDlMapping MAP (tracker_connect, TRACKER_0_6 | TRACKER_0_7), MAP (tracker_disconnect, TRACKER_0_6 | TRACKER_0_7), MAP (tracker_get_version, TRACKER_0_6), - MAP (tracker_cancel_last_call, TRACKER_0_6 | TRACKER_0_7), + MAP (tracker_cancel_last_call, TRACKER_0_6 | TRACKER_0_7 | TRACKER_0_8), MAP (tracker_search_metadata_by_text_async, TRACKER_0_6 | TRACKER_0_7), MAP (tracker_search_metadata_by_text_and_location_async, TRACKER_0_6 | TRACKER_0_7), + MAP (tracker_client_new, TRACKER_0_8), + MAP (tracker_sparql_escape, TRACKER_0_8), + MAP (tracker_resources_sparql_query_async, TRACKER_0_8) #undef MAP }; @@ -76,6 +96,7 @@ open_libtracker (void) { static gboolean done = FALSE; static TrackerVersion version = 0; + gpointer x; if (!done) { @@ -89,6 +110,11 @@ open_libtracker (void) tracker = g_module_open ("libtracker-client-0.7.so.0", flags); version = TRACKER_0_7; + if (tracker && g_module_symbol (tracker, "tracker_resources_sparql_query_async", &x)) + { + version = TRACKER_0_8; + } + if (!tracker) { tracker = g_module_open ("libtrackerclient.so.0", flags); @@ -151,20 +177,43 @@ finalize (GObject *object) tracker->priv->query = NULL; } - tracker_disconnect (tracker->priv->client); + if (tracker->priv->version == TRACKER_0_8) + g_object_unref (tracker->priv->client); + else + tracker_disconnect (tracker->priv->client); G_OBJECT_CLASS (_gtk_search_engine_tracker_parent_class)->finalize (object); } +/* stolen from tracker sources, tracker.c */ static void -search_callback (gchar **results, +sparql_append_string_literal (GString *sparql, + const gchar *str) +{ + char *s; + + s = tracker_sparql_escape (str); + + g_string_append_c (sparql, '"'); + g_string_append (sparql, s); + g_string_append_c (sparql, '"'); + + g_free (s); +} + + +static void +search_callback (gpointer results, GError *error, gpointer user_data) { GtkSearchEngineTracker *tracker; gchar **results_p; GList *hit_uris; + GPtrArray *OUT_result; + gchar *uri; + gint i; tracker = GTK_SEARCH_ENGINE_TRACKER (user_data); hit_uris = NULL; @@ -173,33 +222,47 @@ search_callback (gchar **results, if (error) { - _gtk_search_engine_error ( GTK_SEARCH_ENGINE (tracker), error->message); + _gtk_search_engine_error (GTK_SEARCH_ENGINE (tracker), error->message); g_error_free (error); return; } if (!results) return; - - for (results_p = results; *results_p; results_p++) + + if (tracker->priv->version == TRACKER_0_8) { - gchar *uri; + OUT_result = (GPtrArray*) results; - if (tracker->priv->version == TRACKER_0_6) - uri = g_filename_to_uri (*results_p, NULL, NULL); - else - uri = *results_p; + for (i = 0; i < OUT_result->len; i++) + { + uri = g_strdup (((gchar **) OUT_result->pdata[i])[0]); + if (uri) + hit_uris = g_list_prepend (hit_uris, uri); + } - if (uri) - hit_uris = g_list_prepend (hit_uris, uri); + g_ptr_array_foreach (OUT_result, (GFunc) g_free, NULL); + g_ptr_array_free (OUT_result, TRUE); + } + else + { + for (results_p = results; *results_p; results_p++) + { + if (tracker->priv->version == TRACKER_0_6) + uri = g_filename_to_uri (*results_p, NULL, NULL); + else + uri = g_strdup (*results_p); + + if (uri) + hit_uris = g_list_prepend (hit_uris, uri); + } + g_strfreev ((gchar **) results); } _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (tracker), hit_uris); _gtk_search_engine_finished (GTK_SEARCH_ENGINE (tracker)); - g_strfreev (results); - if (tracker->priv->version == TRACKER_0_6) - g_list_foreach (hit_uris, (GFunc)g_free, NULL); + g_list_foreach (hit_uris, (GFunc) g_free, NULL); g_list_free (hit_uris); } @@ -209,6 +272,7 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine) { GtkSearchEngineTracker *tracker; gchar *search_text, *location, *location_uri; + GString *sparql; tracker = GTK_SEARCH_ENGINE_TRACKER (engine); @@ -233,25 +297,46 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine) location = location_uri; } - if (location) + if (tracker->priv->version == TRACKER_0_8) { - tracker_search_metadata_by_text_and_location_async (tracker->priv->client, - search_text, - location, - search_callback, - tracker); - g_free (location); + sparql = g_string_new ("SELECT ?url WHERE { ?file a nfo:FileDataObject; nie:url ?url; fts:match "); + sparql_append_string_literal (sparql, search_text); + if (location) + { + g_string_append (sparql, " . FILTER (fn:starts-with(?url,"); + sparql_append_string_literal (sparql, location); + g_string_append (sparql, "))"); + } + g_string_append (sparql, " }"); + + tracker_resources_sparql_query_async (tracker->priv->client, + sparql->str, + (TrackerReplyGPtrArray) search_callback, + tracker); + g_string_free (sparql, TRUE); } else { - tracker_search_metadata_by_text_async (tracker->priv->client, - search_text, - search_callback, - tracker); + if (location) + { + tracker_search_metadata_by_text_and_location_async (tracker->priv->client, + search_text, + location, + (TrackerArrayReply) search_callback, + tracker); + } + else + { + tracker_search_metadata_by_text_async (tracker->priv->client, + search_text, + (TrackerArrayReply) search_callback, + tracker); + } } tracker->priv->query_pending = TRUE; g_free (search_text); + g_free (location); } static void @@ -326,14 +411,22 @@ _gtk_search_engine_tracker_new (void) version = open_libtracker (); - if (!tracker_connect) - return NULL; + if (version == TRACKER_0_8) + { + tracker_client = tracker_client_new (TRACKER_CLIENT_ENABLE_WARNINGS, G_MAXINT); + } + else + { + if (!tracker_connect) + return NULL; + + tracker_client = tracker_connect (FALSE, -1); + } - tracker_client = tracker_connect (FALSE, -1); - if (!tracker_client) return NULL; + if (version == TRACKER_0_6) { if (!tracker_get_version)