search: update for tracker 0.8 API

Tracker 0.8 series (and late 0.7.xx) introduces new API based on SPARQL
query language. The queries here use fulltext search, just like with
with previous tracker versions. Old tracker 0.6 support is still maintained.
This commit is contained in:
Tomas Bzatek 2010-03-19 14:40:11 +01:00
parent d2642e7ae3
commit 8dc4a4f954

View File

@ -23,9 +23,6 @@
#include "config.h" #include "config.h"
#include <gmodule.h> #include <gmodule.h>
#include "gtksearchenginetracker.h" #include "gtksearchenginetracker.h"
#if 0
#include <tracker.h>
#endif
/* we dlopen() libtracker at runtime */ /* we dlopen() libtracker at runtime */
@ -34,9 +31,12 @@ typedef struct _TrackerClient TrackerClient;
typedef enum typedef enum
{ {
TRACKER_0_6 = 1 << 0, TRACKER_0_6 = 1 << 0,
TRACKER_0_7 = 1 << 1 TRACKER_0_7 = 1 << 1,
TRACKER_0_8 = 1 << 2
} TrackerVersion; } TrackerVersion;
/* tracker 0.6 API */
typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data); typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data);
static TrackerClient * (*tracker_connect) (gboolean enable_warnings, gint timeout) = NULL; 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, const char *location,
TrackerArrayReply callback, TrackerArrayReply callback,
gpointer user_data) = NULL; 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 static struct TrackerDlMapping
{ {
@ -65,9 +82,12 @@ static struct TrackerDlMapping
MAP (tracker_connect, TRACKER_0_6 | TRACKER_0_7), MAP (tracker_connect, TRACKER_0_6 | TRACKER_0_7),
MAP (tracker_disconnect, TRACKER_0_6 | TRACKER_0_7), MAP (tracker_disconnect, TRACKER_0_6 | TRACKER_0_7),
MAP (tracker_get_version, TRACKER_0_6), 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_async, TRACKER_0_6 | TRACKER_0_7),
MAP (tracker_search_metadata_by_text_and_location_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 #undef MAP
}; };
@ -76,6 +96,7 @@ open_libtracker (void)
{ {
static gboolean done = FALSE; static gboolean done = FALSE;
static TrackerVersion version = 0; static TrackerVersion version = 0;
gpointer x;
if (!done) if (!done)
{ {
@ -89,6 +110,11 @@ open_libtracker (void)
tracker = g_module_open ("libtracker-client-0.7.so.0", flags); tracker = g_module_open ("libtracker-client-0.7.so.0", flags);
version = TRACKER_0_7; version = TRACKER_0_7;
if (tracker && g_module_symbol (tracker, "tracker_resources_sparql_query_async", &x))
{
version = TRACKER_0_8;
}
if (!tracker) if (!tracker)
{ {
tracker = g_module_open ("libtrackerclient.so.0", flags); tracker = g_module_open ("libtrackerclient.so.0", flags);
@ -151,20 +177,43 @@ finalize (GObject *object)
tracker->priv->query = NULL; tracker->priv->query = NULL;
} }
if (tracker->priv->version == TRACKER_0_8)
g_object_unref (tracker->priv->client);
else
tracker_disconnect (tracker->priv->client); tracker_disconnect (tracker->priv->client);
G_OBJECT_CLASS (_gtk_search_engine_tracker_parent_class)->finalize (object); G_OBJECT_CLASS (_gtk_search_engine_tracker_parent_class)->finalize (object);
} }
/* stolen from tracker sources, tracker.c */
static void 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, GError *error,
gpointer user_data) gpointer user_data)
{ {
GtkSearchEngineTracker *tracker; GtkSearchEngineTracker *tracker;
gchar **results_p; gchar **results_p;
GList *hit_uris; GList *hit_uris;
GPtrArray *OUT_result;
gchar *uri;
gint i;
tracker = GTK_SEARCH_ENGINE_TRACKER (user_data); tracker = GTK_SEARCH_ENGINE_TRACKER (user_data);
hit_uris = NULL; hit_uris = NULL;
@ -181,24 +230,38 @@ search_callback (gchar **results,
if (!results) if (!results)
return; return;
if (tracker->priv->version == TRACKER_0_8)
{
OUT_result = (GPtrArray*) results;
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);
}
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++) for (results_p = results; *results_p; results_p++)
{ {
gchar *uri;
if (tracker->priv->version == TRACKER_0_6) if (tracker->priv->version == TRACKER_0_6)
uri = g_filename_to_uri (*results_p, NULL, NULL); uri = g_filename_to_uri (*results_p, NULL, NULL);
else else
uri = *results_p; uri = g_strdup (*results_p);
if (uri) if (uri)
hit_uris = g_list_prepend (hit_uris, 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_hits_added (GTK_SEARCH_ENGINE (tracker), hit_uris);
_gtk_search_engine_finished (GTK_SEARCH_ENGINE (tracker)); _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); g_list_free (hit_uris);
} }
@ -209,6 +272,7 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine)
{ {
GtkSearchEngineTracker *tracker; GtkSearchEngineTracker *tracker;
gchar *search_text, *location, *location_uri; gchar *search_text, *location, *location_uri;
GString *sparql;
tracker = GTK_SEARCH_ENGINE_TRACKER (engine); tracker = GTK_SEARCH_ENGINE_TRACKER (engine);
@ -233,25 +297,46 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine)
location = location_uri; location = location_uri;
} }
if (tracker->priv->version == TRACKER_0_8)
{
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
{
if (location) if (location)
{ {
tracker_search_metadata_by_text_and_location_async (tracker->priv->client, tracker_search_metadata_by_text_and_location_async (tracker->priv->client,
search_text, search_text,
location, location,
search_callback, (TrackerArrayReply) search_callback,
tracker); tracker);
g_free (location);
} }
else else
{ {
tracker_search_metadata_by_text_async (tracker->priv->client, tracker_search_metadata_by_text_async (tracker->priv->client,
search_text, search_text,
search_callback, (TrackerArrayReply) search_callback,
tracker); tracker);
} }
}
tracker->priv->query_pending = TRUE; tracker->priv->query_pending = TRUE;
g_free (search_text); g_free (search_text);
g_free (location);
} }
static void static void
@ -326,14 +411,22 @@ _gtk_search_engine_tracker_new (void)
version = open_libtracker (); version = open_libtracker ();
if (version == TRACKER_0_8)
{
tracker_client = tracker_client_new (TRACKER_CLIENT_ENABLE_WARNINGS, G_MAXINT);
}
else
{
if (!tracker_connect) if (!tracker_connect)
return NULL; return NULL;
tracker_client = tracker_connect (FALSE, -1); tracker_client = tracker_connect (FALSE, -1);
}
if (!tracker_client) if (!tracker_client)
return NULL; return NULL;
if (version == TRACKER_0_6) if (version == TRACKER_0_6)
{ {
if (!tracker_get_version) if (!tracker_get_version)