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 <gmodule.h>
#include "gtksearchenginetracker.h"
#if 0
#include <tracker.h>
#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)