[PATCH 02/14] tracker: add search support



From: Lionel Landwerlin <lionel g landwerlin linux intel com>

Signed-off-by: Lionel Landwerlin <lionel g landwerlin linux intel com>
---
 src/tracker/grl-tracker.c |  122 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 115 insertions(+), 7 deletions(-)

diff --git a/src/tracker/grl-tracker.c b/src/tracker/grl-tracker.c
index 5946290..50ea307 100644
--- a/src/tracker/grl-tracker.c
+++ b/src/tracker/grl-tracker.c
@@ -69,6 +69,18 @@ enum {
 
 /* --- Other --- */
 
+#define TRACKER_SEARCH_REQUEST "                                    \
+  SELECT %s                                                         \
+  WHERE {                                                           \
+    { ?urn a nmm:Video } UNION                                      \
+    { ?urn a nmm:Photo } UNION                                      \
+    { ?urn a nmm:MusicPiece } .                                     \
+    ?urn tracker:available ?tr .                                    \
+    ?urn fts:match '%s'                                             \
+  }                                                                 \
+  ORDER BY DESC(nfo:fileLastModified(?urn))                         \
+  OFFSET %i LIMIT %i"
+
 typedef enum {
   MEDIA_PROP_NONE = 0,
   MEDIA_PROP_STRING,
@@ -118,6 +130,9 @@ static const GList *grl_tracker_source_supported_keys (GrlMetadataSource *source
 static void grl_tracker_source_query (GrlMediaSource *source,
                                       GrlMediaSourceQuerySpec *qs);
 
+static void grl_tracker_source_search (GrlMediaSource *source,
+                                       GrlMediaSourceSearchSpec *ss);
+
 static void setup_key_mappings (void);
 
 /* ===================== Globals  ================= */
@@ -197,7 +212,8 @@ grl_tracker_source_class_init (GrlTrackerSourceClass * klass)
   GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
   GObjectClass *g_class = G_OBJECT_CLASS (klass);
 
-  source_class->query = grl_tracker_source_query;
+  source_class->query  = grl_tracker_source_query;
+  source_class->search = grl_tracker_source_search;
 
   metadata_class->supported_keys       = grl_tracker_source_supported_keys;
   metadata_class->supported_operations = grl_tracker_source_supported_operations;
@@ -217,6 +233,21 @@ grl_tracker_source_init (GrlTrackerSource *source)
 
 /* ======================= Utilities ==================== */
 
+static gchar *
+build_flavored_key (gchar *key, const gchar *flavor)
+{
+  gint i = 0;
+
+  while (key[i] != '\0') {
+    if (!g_ascii_isalnum (key[i])) {
+      key[i] = '_';
+    }
+    i++;
+  }
+
+  return g_strdup_printf ("%s_%s", key, flavor);
+}
+
 static void
 insert_key_mapping (GrlKeyID            grl_key,
                     tracker_grl_type_t  grl_key_type,
@@ -229,10 +260,7 @@ insert_key_mapping (GrlKeyID            grl_key,
 
   assoc->grl_key           = grl_key;
   assoc->grl_key_type      = grl_key_type;
-  assoc->sparql_key_name   = g_strdup_printf ("%s_%s",
-                                              g_strcanon (canon_name,
-                                                          ".-", '_'),
-                                              sparql_key_flavor);
+  assoc->sparql_key_name   = build_flavored_key (canon_name, sparql_key_flavor);
   assoc->sparql_key_attr   = sparql_key_attr;
   assoc->sparql_key_flavor = sparql_key_flavor;
 
@@ -323,7 +351,7 @@ setup_key_mappings (void)
                       "audio");
   insert_key_mapping (GRL_METADATA_KEY_TITLE,
                       MEDIA_PROP_STRING,
-                      "nfo:filename(?urn)",
+                      "nfo:fileName(?urn)",
                       "file");
 
   insert_key_mapping (GRL_METADATA_KEY_URL,
@@ -344,6 +372,38 @@ get_mapping_from_sparql (const gchar *key)
                                                        key);
 }
 
+static GList *
+get_mapping_from_grl (const GrlKeyID key)
+{
+  return (GList *) g_hash_table_lookup (grl_to_sparql_mapping, key);
+}
+
+static gchar *
+get_select_string (GrlMediaSource *source, const GList *keys)
+{
+  const GList *key = keys;
+  GString *gstr = g_string_new ("rdf:type(?urn) ");
+  GList *assoc_list;
+  tracker_grl_sparql_t *assoc;
+
+  while (key != NULL) {
+    assoc_list = get_mapping_from_grl ((GrlKeyID) key->data);
+    while (assoc_list != NULL) {
+      assoc = (tracker_grl_sparql_t *) assoc_list->data;
+      if (assoc != NULL) {
+        g_string_append_printf (gstr, "%s AS %s",
+                                assoc->sparql_key_attr,
+                                assoc->sparql_key_name);
+        g_string_append (gstr, " ");
+      }
+      assoc_list = assoc_list->next;
+    }
+    key = key->next;
+  }
+
+  return g_string_free (gstr, FALSE);
+}
+
 /* Builds an appropriate GrlMedia based on ontology type returned by tracker, or
    NULL if unknown */
 static GrlMedia *
@@ -499,7 +559,7 @@ grl_tracker_source_supported_operations (GrlMetadataSource *metadata_source)
   GrlTrackerSource *source;
 
   source = GRL_TRACKER_SOURCE (metadata_source);
-  caps = GRL_OP_QUERY;
+  caps = GRL_OP_QUERY | GRL_OP_SEARCH;
 
   return caps;
 }
@@ -612,3 +672,51 @@ grl_tracker_source_query (GrlMediaSource *source,
   qs->callback (qs->source, qs->query_id, NULL, 0, qs->user_data, error);
   g_error_free (error);
 }
+
+static void
+grl_tracker_source_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
+{
+  GrlTrackerSourcePriv *priv  = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
+  gchar                *sparql_select;
+  gchar                *sparql_final;
+  GError               *error = NULL;
+  struct OperationSpec *os;
+
+  GRL_DEBUG ("grl_tracker_source_search");
+
+  if (priv->tracker_connection == NULL) {
+    error = g_error_new (GRL_CORE_ERROR,
+                         GRL_CORE_ERROR_SEARCH_FAILED,
+                         "Failed to start search action");
+    ss->callback (ss->source, ss->search_id, NULL, 0, ss->user_data, error);
+    g_error_free (error);
+          return;
+  }
+
+  sparql_select = get_select_string (source, ss->keys);
+  sparql_final = g_strdup_printf (TRACKER_SEARCH_REQUEST, sparql_select,
+                                  ss->text, ss->skip, ss->count);
+
+  GRL_DEBUG ("select: '%s'", sparql_final);
+
+  os = g_slice_new0 (struct OperationSpec);
+  os->source       = ss->source;
+  os->priv         = priv;
+  os->operation_id = ss->search_id;
+  os->keys         = ss->keys;
+  os->skip         = ss->skip;
+  os->count        = ss->count;
+  os->callback     = ss->callback;
+  os->user_data    = ss->user_data;
+
+  tracker_sparql_connection_query_async (priv->tracker_connection,
+                                         sparql_final,
+                                         NULL,
+                                         (GAsyncReadyCallback) tracker_query_cb,
+                                         os);
+
+  if (sparql_select != NULL)
+    g_free (sparql_select);
+  if (sparql_final != NULL)
+    g_free (sparql_final);
+}
-- 
1.7.2.3



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]