[nautilus/sam/tracker-3] Port to Tracker 3



commit 1d7d824bfd3b79155977c0edb39717765fdacd37
Author: Sam Thursfield <sam afuera me uk>
Date:   Wed Apr 29 01:10:30 2020 +0200

    Port to Tracker 3
    
    Mostly the port is straightforward, we connect to tracker-miner-fs
    explicitly over D-Bus instead of the centralized tracker-store daemon
    we connected to previously.
    
    There are more changes in nautilus-tag-manager.c because the
    TrackerNotifier API changed, it no longer queries the URIs for
    us so we need to query these ourselves, and maintain a table
    of ID->URI mappings in addition to the URI->ID mapping that we
    already maintained.

 meson.build                                        |   2 +-
 src/nautilus-batch-rename-utilities.c              |   4 +-
 src/nautilus-search-engine-tracker.c               |   4 +-
 src/nautilus-tag-manager.c                         | 270 ++++++++++-----------
 .../test-nautilus-search-engine-tracker.c          |  16 +-
 5 files changed, 153 insertions(+), 143 deletions(-)
---
diff --git a/meson.build b/meson.build
index 644c58e54..0559f6891 100644
--- a/meson.build
+++ b/meson.build
@@ -119,7 +119,7 @@ selinux = []
 if get_option('selinux')
   selinux = dependency('libselinux', version: '>= 2.0')
 endif
-tracker_sparql = dependency('tracker-sparql-2.0')
+tracker_sparql = dependency('tracker-sparql-3.0')
 x11 = dependency('x11')
 xml = dependency('libxml-2.0', version: '>= 2.7.8')
 
diff --git a/src/nautilus-batch-rename-utilities.c b/src/nautilus-batch-rename-utilities.c
index da0f32113..b31506f5f 100644
--- a/src/nautilus-batch-rename-utilities.c
+++ b/src/nautilus-batch-rename-utilities.c
@@ -63,6 +63,8 @@ enum
     ALBUM_NAME_INDEX,
 } QueryMetadata;
 
+#define TRACKER_MINER_FS_BUSNAME "org.freedesktop.Tracker3.Miner.Files"
+
 static void on_cursor_callback (GObject      *object,
                                 GAsyncResult *result,
                                 gpointer      user_data);
@@ -1117,7 +1119,7 @@ check_metadata_for_selection (NautilusBatchRenameDialog *dialog,
 
     g_string_append (query, "} ORDER BY ASC(nie:contentCreated(?file))");
 
-    connection = tracker_sparql_connection_get (NULL, &error);
+    connection = tracker_sparql_connection_bus_new (TRACKER_MINER_FS_BUSNAME, NULL, NULL, &error);
     if (!connection)
     {
         if (error)
diff --git a/src/nautilus-search-engine-tracker.c b/src/nautilus-search-engine-tracker.c
index d575ba875..b3628d848 100644
--- a/src/nautilus-search-engine-tracker.c
+++ b/src/nautilus-search-engine-tracker.c
@@ -55,6 +55,8 @@ enum
     LAST_PROP
 };
 
+#define TRACKER_MINER_FS_BUSNAME "org.freedesktop.Tracker3.Miner.Files"
+
 static void nautilus_search_provider_init (NautilusSearchProviderInterface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (NautilusSearchEngineTracker,
@@ -559,7 +561,7 @@ nautilus_search_engine_tracker_init (NautilusSearchEngineTracker *engine)
 
     engine->hits_pending = g_queue_new ();
 
-    engine->connection = tracker_sparql_connection_get (NULL, &error);
+    engine->connection = tracker_sparql_connection_bus_new (TRACKER_MINER_FS_BUSNAME, NULL, NULL, &error);
 
     if (error)
     {
diff --git a/src/nautilus-tag-manager.c b/src/nautilus-tag-manager.c
index 78c81e0b6..297d6778e 100644
--- a/src/nautilus-tag-manager.c
+++ b/src/nautilus-tag-manager.c
@@ -27,10 +27,14 @@ struct _NautilusTagManager
 {
     GObject object;
 
+    TrackerSparqlConnection *connection;
     TrackerNotifier *notifier;
-    GError *notifier_error;
 
-    GHashTable *starred_files;
+    /* Map of URI -> tracker ID */
+    GHashTable *starred_file_uris;
+    /* Map of tracker ID -> URI */
+    GHashTable *starred_file_ids;
+
     GCancellable *cancellable;
 };
 
@@ -67,30 +71,12 @@ enum
     LAST_SIGNAL
 };
 
+#define TRACKER_MINER_FS_BUSNAME "org.freedesktop.Tracker3.Miner.Files"
+
 #define STARRED_TAG "<urn:gnome:nautilus:starred>"
 
 static guint signals[LAST_SIGNAL];
 
-static const gchar *
-nautilus_tag_manager_file_with_id_changed_url (GHashTable  *hash_table,
-                                               gint64       id,
-                                               const gchar *url)
-{
-    GHashTableIter iter;
-    gpointer key, value;
-
-    g_hash_table_iter_init (&iter, hash_table);
-    while (g_hash_table_iter_next (&iter, &key, &value))
-    {
-        if ((gint64) value == id && g_strcmp0 (url, key) != 0)
-        {
-            return key;
-        }
-    }
-
-    return NULL;
-}
-
 static void
 destroy_insert_task_data (gpointer data)
 {
@@ -134,23 +120,18 @@ add_selection_filter (GList   *selection,
 }
 
 static void
-start_query_or_update (GString             *query,
-                       GAsyncReadyCallback  callback,
-                       gpointer             user_data,
-                       gboolean             is_query,
-                       GCancellable        *cancellable)
+start_query_or_update (TrackerSparqlConnection *connection,
+                       GString                 *query,
+                       GAsyncReadyCallback      callback,
+                       gpointer                 user_data,
+                       gboolean                 is_query,
+                       GCancellable            *cancellable)
 {
     g_autoptr (GError) error = NULL;
-    TrackerSparqlConnection *connection;
 
-    connection = tracker_sparql_connection_get (cancellable, &error);
     if (!connection)
     {
-        if (error)
-        {
-            g_warning ("Error on getting connection: %s", error->message);
-        }
-
+        g_message ("nautilus-tag-manager: No Tracker connection");
         return;
     }
 
@@ -171,8 +152,6 @@ start_query_or_update (GString             *query,
                                                 callback,
                                                 user_data);
     }
-
-    g_object_unref (connection);
 }
 
 static void
@@ -233,7 +212,7 @@ on_update_callback (GObject      *object,
     TrackerSparqlConnection *connection;
     GError *error;
     UpdateData *data;
-    gint64 *id;
+    gint64 *new_id;
     GList *l;
     gchar *uri;
 
@@ -256,17 +235,24 @@ on_update_callback (GObject      *object,
             {
                 if (g_hash_table_contains (data->ids, uri))
                 {
-                    id = g_new0 (gint64, 1);
+                    new_id = g_new0 (gint64, 1);
 
-                    *id = (gint64) g_hash_table_lookup (data->ids, uri);
-                    g_hash_table_insert (data->tag_manager->starred_files,
+                    *new_id = (gint64) g_hash_table_lookup (data->ids, uri);
+                    g_hash_table_insert (data->tag_manager->starred_file_uris,
                                          nautilus_file_get_uri (NAUTILUS_FILE (l->data)),
-                                         id);
+                                         new_id);
+                    g_hash_table_insert (data->tag_manager->starred_file_ids,
+                                         new_id,
+                                         nautilus_file_get_uri (NAUTILUS_FILE (l->data)));
                 }
             }
             else
             {
-                g_hash_table_remove (data->tag_manager->starred_files, uri);
+                new_id = g_hash_table_lookup (data->tag_manager->starred_file_uris, uri);
+                if (new_id) {
+                    g_hash_table_remove (data->tag_manager->starred_file_uris, uri);
+                    g_hash_table_remove (data->tag_manager->starred_file_ids, new_id);
+                }
             }
 
             g_free (uri);
@@ -352,7 +338,7 @@ get_query_status (TrackerSparqlCursor *cursor,
 GList *
 nautilus_tag_manager_get_starred_files (NautilusTagManager *self)
 {
-    return g_hash_table_get_keys (self->starred_files);
+    return g_hash_table_get_keys (self->starred_file_uris);
 }
 
 static void
@@ -383,9 +369,8 @@ on_get_starred_files_cursor_callback (GObject      *object,
     url = tracker_sparql_cursor_get_string (cursor, 0, NULL);
     *id = tracker_sparql_cursor_get_integer (cursor, 1);
 
-    g_hash_table_insert (self->starred_files,
-                         g_strdup (url),
-                         id);
+    g_hash_table_insert (self->starred_file_uris, g_strdup (url), id);
+    g_hash_table_insert (self->starred_file_ids, id, g_strdup (url));
 
     file = nautilus_file_get_by_uri (url);
     changed_files = g_list_prepend (NULL, file);
@@ -428,7 +413,8 @@ nautilus_tag_manager_query_starred_files (NautilusTagManager *self,
     query = g_string_new ("SELECT ?url tracker:id(?urn) "
                           "WHERE { ?urn nie:url ?url ; nao:hasTag " STARRED_TAG "}");
 
-    start_query_or_update (query,
+    start_query_or_update (self->connection,
+                           query,
                            on_get_starred_files_query_callback,
                            self,
                            TRUE,
@@ -484,7 +470,7 @@ gboolean
 nautilus_tag_manager_file_is_starred (NautilusTagManager *self,
                                       const gchar        *file_name)
 {
-    return g_hash_table_contains (self->starred_files, file_name);
+    return g_hash_table_contains (self->starred_file_uris, file_name);
 }
 
 static void
@@ -560,9 +546,9 @@ on_get_file_ids_for_urls_query_callback (GObject      *object,
 }
 
 static void
-nautilus_tag_manager_get_file_ids_for_urls (GObject *object,
-                                            GList   *selection,
-                                            GTask   *task)
+nautilus_tag_manager_get_file_ids_for_urls (NautilusTagManager *self,
+                                            GList              *selection,
+                                            GTask              *task)
 {
     GString *query;
 
@@ -572,7 +558,8 @@ nautilus_tag_manager_get_file_ids_for_urls (GObject *object,
 
     g_string_append (query, "}\n");
 
-    start_query_or_update (query,
+    start_query_or_update (self->connection,
+                           query,
                            on_get_file_ids_for_urls_query_callback,
                            task,
                            TRUE,
@@ -617,7 +604,8 @@ on_star_files_callback (GObject      *object,
      */
     destroy_insert_task_data (data);
 
-    start_query_or_update (query,
+    start_query_or_update (self->connection,
+                           query,
                            on_update_callback,
                            update_data,
                            FALSE,
@@ -651,7 +639,7 @@ nautilus_tag_manager_star_files (NautilusTagManager  *self,
                           data,
                           NULL);
 
-    nautilus_tag_manager_get_file_ids_for_urls (G_OBJECT (self), selection, task);
+    nautilus_tag_manager_get_file_ids_for_urls (self, selection, task);
 }
 
 void
@@ -679,7 +667,8 @@ nautilus_tag_manager_unstar_files (NautilusTagManager  *self,
     update_data->selection = nautilus_file_list_copy (selection);
     update_data->star = FALSE;
 
-    start_query_or_update (query,
+    start_query_or_update (self->connection,
+                           query,
                            on_update_callback,
                            update_data,
                            FALSE,
@@ -699,13 +688,13 @@ on_tracker_notifier_events (TrackerNotifier *notifier,
     const gchar *location_uri;
     const gchar *new_location_uri;
     GError *error = NULL;
-    TrackerSparqlConnection *connection;
     TrackerSparqlCursor *cursor;
     GString *query;
     gboolean query_has_results;
-    gint64 *id;
+    gboolean is_starred;
+    gint64 id, *new_id;
     GList *changed_files;
-    NautilusFile *file;
+    NautilusFile *changed_file;
 
     self = NAUTILUS_TAG_MANAGER (user_data);
 
@@ -713,52 +702,18 @@ on_tracker_notifier_events (TrackerNotifier *notifier,
     {
         event = g_ptr_array_index (events, i);
 
-        location_uri = tracker_notifier_event_get_location (event);
-
         query = g_string_new ("");
         g_string_append_printf (query,
-                                "SELECT ?url WHERE { ?urn nie:url ?url; nao:hasTag " STARRED_TAG " . FILTER 
(tracker:id(?urn) = %" G_GINT64_FORMAT ")}",
+                                "SELECT ?url EXISTS{ ?urn nao:hasTag " STARRED_TAG "} AS ?starred "
+                                "WHERE { ?urn nie:url ?url . FILTER (tracker:id(?urn) = %" G_GINT64_FORMAT 
")}",
                                 tracker_notifier_event_get_id (event));
 
-        /* check if the file changed it's location and update hash table if so */
-        new_location_uri = nautilus_tag_manager_file_with_id_changed_url (self->starred_files,
-                                                                          tracker_notifier_event_get_id 
(event),
-                                                                          location_uri);
-        if (new_location_uri)
-        {
-            id = g_new0 (gint64, 1);
-            *id = tracker_notifier_event_get_id (event);
-
-            g_hash_table_remove (self->starred_files, new_location_uri);
-            g_hash_table_insert (self->starred_files,
-                                 g_strdup (location_uri),
-                                 id);
-
-            file = nautilus_file_get_by_uri (location_uri);
-            changed_files = g_list_prepend (NULL, file);
-
-            g_signal_emit_by_name (self, "starred-changed", changed_files);
-
-            nautilus_file_list_free (changed_files);
-        }
-
-        connection = tracker_sparql_connection_get (NULL, &error);
-
-        if (!connection)
-        {
-            g_printerr ("Couldn't obtain a direct connection to the Tracker store: %s",
-                        error ? error->message : "unknown error");
-            g_clear_error (&error);
-
-            return;
-        }
-
-        cursor = tracker_sparql_connection_query (connection,
+        cursor = tracker_sparql_connection_query (self->connection,
                                                   query->str,
                                                   NULL,
                                                   &error);
 
-        if (error)
+        if (error || !cursor)
         {
             g_printerr ("Couldn't query the Tracker Store: '%s'", error->message);
 
@@ -767,45 +722,75 @@ on_tracker_notifier_events (TrackerNotifier *notifier,
             return;
         }
 
-        if (cursor)
+        changed_file = NULL;
+
+        id = tracker_notifier_event_get_id (event);
+        location_uri = g_hash_table_lookup (self->starred_file_ids, &id);
+
+        query_has_results = tracker_sparql_cursor_next (cursor, NULL, &error);
+
+        if (!query_has_results && g_hash_table_contains (self->starred_file_ids, &id))
         {
-            query_has_results = tracker_sparql_cursor_next (cursor, NULL, &error);
+            /* The file must have been deleted from the Tracker index. */
+            location_uri = g_hash_table_lookup (self->starred_file_ids, &id);
 
-            /* if no results are found, then the file isn't marked as starred.
-             * If needed, update the hashtable.
-             */
-            if (!query_has_results && location_uri && g_hash_table_contains (self->starred_files, 
location_uri))
+            changed_file = nautilus_file_get_by_uri (location_uri);
+
+            g_hash_table_remove (self->starred_file_ids, &id);
+            g_hash_table_remove (self->starred_file_uris, location_uri);
+        }
+        else
+        {
+            new_location_uri = tracker_sparql_cursor_get_string (cursor, 0, NULL);
+            is_starred = tracker_sparql_cursor_get_boolean (cursor, 1);
+
+            if (g_hash_table_contains (self->starred_file_ids, &id))
             {
-                g_hash_table_remove (self->starred_files, location_uri);
+                if (is_starred && strcmp (location_uri, new_location_uri) != 0)
+                {
+                    new_id = g_new0 (gint64, 1);
+                    *new_id = id;
 
-                file = nautilus_file_get_by_uri (location_uri);
-                changed_files = g_list_prepend (NULL, file);
+                    /* File URI changed. */
+                    g_hash_table_remove (self->starred_file_uris, location_uri);
 
-                g_signal_emit_by_name (self, "starred-changed", changed_files);
+                    g_hash_table_insert (self->starred_file_ids, &id, g_strdup (new_location_uri));
+                    g_hash_table_insert (self->starred_file_uris, g_strdup (new_location_uri), new_id);
 
-                nautilus_file_list_free (changed_files);
+                    changed_file = nautilus_file_get_by_uri (new_location_uri);
+                }
+                else if (!is_starred)
+                {
+                    /* File is no longer starred */
+                    g_hash_table_remove (self->starred_file_uris, location_uri);
+                    g_hash_table_remove (self->starred_file_ids, &id);
+
+                    changed_file = nautilus_file_get_by_uri (new_location_uri);
+                }
             }
-            else if (query_has_results && location_uri && !g_hash_table_contains (self->starred_files, 
location_uri))
+            else
             {
-                id = g_new0 (gint64, 1);
-                *id = tracker_notifier_event_get_id (event);
+                /* File is newly starred */
+                new_id = g_new0 (gint64, 1);
+                *new_id = id;
 
-                g_hash_table_insert (self->starred_files,
-                                     g_strdup (location_uri),
-                                     id);
+                g_hash_table_insert (self->starred_file_ids, &id, g_strdup (new_location_uri));
+                g_hash_table_insert (self->starred_file_uris, g_strdup (new_location_uri), new_id);
 
-                file = nautilus_file_get_by_uri (location_uri);
-                changed_files = g_list_prepend (NULL, file);
+                changed_file = nautilus_file_get_by_uri (new_location_uri);
+            }
+        }
 
-                g_signal_emit_by_name (self, "starred-changed", changed_files);
+        if (changed_file)
+        {
+            changed_files = g_list_prepend (NULL, changed_file);
 
-                nautilus_file_list_free (changed_files);
-            }
+            g_signal_emit_by_name (self, "starred-changed", changed_files);
 
-            g_object_unref (cursor);
+            nautilus_file_list_free (changed_files);
         }
 
-        g_object_unref (connection);
+        g_object_unref (cursor);
 
         g_string_free (query, TRUE);
     }
@@ -826,8 +811,10 @@ nautilus_tag_manager_finalize (GObject *object)
     }
 
     g_clear_object (&self->notifier);
+    g_clear_object (&self->connection);
 
-    g_hash_table_destroy (self->starred_files);
+    g_hash_table_destroy (self->starred_file_ids);
+    g_hash_table_destroy (self->starred_file_uris);
 
     G_OBJECT_CLASS (nautilus_tag_manager_parent_class)->finalize (object);
 }
@@ -869,30 +856,41 @@ nautilus_tag_manager_get (void)
     return tag_manager;
 }
 
+/* Initialize the tag mananger. */
 void
 nautilus_tag_manager_set_cancellable (NautilusTagManager *self,
                                       GCancellable       *cancellable)
 {
-    nautilus_tag_manager_query_starred_files (self, cancellable);
+    GError *error = NULL;
 
-    self->notifier = tracker_notifier_new (NULL,
-                                           TRACKER_NOTIFIER_FLAG_QUERY_LOCATION,
-                                           cancellable,
-                                           &self->notifier_error);
-    if (self->notifier != NULL)
-    {
-        g_signal_connect (self->notifier,
-                          "events",
-                          G_CALLBACK (on_tracker_notifier_events),
-                          self);
+    self->connection = tracker_sparql_connection_bus_new (
+            TRACKER_MINER_FS_BUSNAME, NULL, NULL, &error);
+
+    if (error) {
+        g_warning ("Unable to initialize tag manager: %s", error->message);
+        g_error_free (error);
+        return;
     }
+
+    nautilus_tag_manager_query_starred_files (self, cancellable);
+
+    self->notifier = tracker_sparql_connection_create_notifier (self->connection,
+                                                                TRACKER_NOTIFIER_FLAG_NONE);
+    g_signal_connect (self->notifier,
+                      "events",
+                      G_CALLBACK (on_tracker_notifier_events),
+                      self);
 }
 
 static void
 nautilus_tag_manager_init (NautilusTagManager *self)
 {
-    self->starred_files = g_hash_table_new_full (g_str_hash,
-                                                 g_str_equal,
-                                                 (GDestroyNotify) g_free,
-                                                 (GDestroyNotify) g_free);
+    self->starred_file_uris = g_hash_table_new_full (g_str_hash,
+                                                     g_str_equal,
+                                                     (GDestroyNotify) g_free,
+                                                     (GDestroyNotify) g_free);
+    self->starred_file_ids = g_hash_table_new_full (g_int_hash,
+                                                    g_int_equal,
+                                                    (GDestroyNotify) g_free,
+                                                    (GDestroyNotify) g_free);
 }
diff --git a/test/automated/displayless/test-nautilus-search-engine-tracker.c 
b/test/automated/displayless/test-nautilus-search-engine-tracker.c
index 0de2d404b..ba3f2e21a 100644
--- a/test/automated/displayless/test-nautilus-search-engine-tracker.c
+++ b/test/automated/displayless/test-nautilus-search-engine-tracker.c
@@ -1,5 +1,7 @@
 #include "test-utilities.h"
 
+TrackerSparqlConnection *connection;
+
 static void
 hits_added_cb (NautilusSearchEngine *engine,
                GSList               *hits)
@@ -16,14 +18,12 @@ finished_cb (NautilusSearchEngine         *engine,
              NautilusSearchProviderStatus  status,
              gpointer                      user_data)
 {
-    TrackerSparqlConnection *connection;
     g_autofree gchar *sparql_query = NULL;
 
     nautilus_search_provider_stop (NAUTILUS_SEARCH_PROVIDER (engine));
 
     g_print ("\nNautilus search engine tracker finished!\n");
 
-    connection = tracker_sparql_connection_get (NULL, NULL);
     sparql_query = g_strdup_printf ("DELETE WHERE { <nautilus-test-tracker> ?p ?o }");
     tracker_sparql_connection_update (connection,
                                       sparql_query,
@@ -43,10 +43,18 @@ main (int   argc,
     g_autoptr (NautilusDirectory) directory = NULL;
     g_autoptr (NautilusQuery) query = NULL;
     g_autoptr (GFile) location = NULL;
-    TrackerSparqlConnection *connection;
     g_autofree gchar *sparql_query = NULL;
+    TrackerSparqlConnectionFlags fts_flags;
+    GError *error = NULL;
+
+    /* Keep these in sync with Tracker's default FTS settings:
+     * 
https://gitlab.gnome.org/GNOME/tracker-miners/-/blob/master/data/org.freedesktop.Tracker.FTS.gschema.xml */
+    fts_flags = TRACKER_SPARQL_CONNECTION_FLAGS_FTS_ENABLE_UNACCENT |
+            TRACKER_SPARQL_CONNECTION_FLAGS_FTS_ENABLE_STOP_WORDS |
+            TRACKER_SPARQL_CONNECTION_FLAGS_FTS_IGNORE_NUMBERS;
 
-    connection = tracker_sparql_connection_get (NULL, NULL);
+    connection = tracker_sparql_connection_new (fts_flags, NULL, NULL, NULL, &error);
+    g_assert_no_error (error);
 
     loop = g_main_loop_new (NULL, FALSE);
 


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