summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam@afuera.me.uk>2020-08-01 17:25:27 +0200
committerSam Thursfield <sam@afuera.me.uk>2020-09-02 18:50:17 +0200
commitf9c79fce6d90e7e5842f2c56a1ec98a151126874 (patch)
tree86f3ab12aa2c5e2e49ed81c046fdd18201b299fb
parent034a6a3394d9de5da743f9e62f6019ca37b50f1d (diff)
downloadnautilus-f9c79fce6d90e7e5842f2c56a1ec98a151126874.tar.gz
Use Tracker Miners inside Flatpak when not available on the host
This means the Nautilus flatpak will be able to use Tracker on systems which don't have Tracker 3 available on the host. It comes at a cost of increased resource consumption inside the Flatpak due running an extra indexer process there.
-rw-r--r--data/meson.build1
-rw-r--r--data/tracker/meson.build31
-rw-r--r--data/tracker/org.gnome.Nautilus.Tracker3.Miner.Extract.service.in7
-rw-r--r--data/tracker/org.gnome.Nautilus.Tracker3.Miner.Files.service.in7
-rw-r--r--data/tracker/org.gnome.Nautilus.domain.rule.in21
-rw-r--r--meson.build2
-rw-r--r--src/nautilus-batch-rename-utilities.c5
-rw-r--r--src/nautilus-search-engine-tracker.c9
-rw-r--r--src/nautilus-tag-manager.c68
-rw-r--r--src/nautilus-tracker-utilities.c120
-rw-r--r--src/nautilus-tracker-utilities.h6
11 files changed, 236 insertions, 41 deletions
diff --git a/data/meson.build b/data/meson.build
index e51ed50b1..9a4e2ff52 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -139,3 +139,4 @@ if appstream_util.found()
endif
subdir('ontology')
+subdir('tracker')
diff --git a/data/tracker/meson.build b/data/tracker/meson.build
new file mode 100644
index 000000000..5320af164
--- /dev/null
+++ b/data/tracker/meson.build
@@ -0,0 +1,31 @@
+# Files needed for running Tracker inside the Flatpak sandbox, for systems
+# which don't have a suitable version of Tracker in the host OS.
+#
+# We must export the .service files from the sandbox so they work on the
+# session bus. This means the Tracker domain name must correspond with the
+# application ID.
+
+domain_ontologies_dir = get_option('datadir') / 'tracker3' / 'domain-ontologies'
+dbus_services_dir = get_option('datadir') / 'dbus-1' / 'services'
+
+tracker_domain_config = configuration_data()
+tracker_domain_config.set('application_id', application_id)
+tracker_domain_config.set('domain_rule', get_option('prefix') / domain_ontologies_dir / application_id + '.domain.rule')
+
+configure_file(
+ input: 'org.gnome.Nautilus.domain.rule.in',
+ output: application_id + '.domain.rule',
+ configuration: tracker_domain_config,
+ install_dir: domain_ontologies_dir)
+
+configure_file(
+ input: 'org.gnome.Nautilus.Tracker3.Miner.Extract.service.in',
+ output: application_id + '.Tracker3.Miner.Extract.service',
+ configuration: tracker_domain_config,
+ install_dir: dbus_services_dir)
+
+configure_file(
+ input: 'org.gnome.Nautilus.Tracker3.Miner.Files.service.in',
+ output: application_id + '.Tracker3.Miner.Files.service',
+ configuration: tracker_domain_config,
+ install_dir: dbus_services_dir)
diff --git a/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Extract.service.in b/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Extract.service.in
new file mode 100644
index 000000000..eb7a87aa6
--- /dev/null
+++ b/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Extract.service.in
@@ -0,0 +1,7 @@
+[D-BUS Service]
+Name=@application_id@.Tracker3.Miner.Extract
+Exec=/app/libexec/tracker-extract-3 --domain-ontology @domain_rule@
+
+# Miner details needed for tracker-control
+Path=/org/freedesktop/Tracker3/Miner/Extract
+NameSuffix=Miner.Files
diff --git a/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Files.service.in b/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Files.service.in
new file mode 100644
index 000000000..4fa7371d1
--- /dev/null
+++ b/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Files.service.in
@@ -0,0 +1,7 @@
+[D-BUS Service]
+Name=@application_id@.Tracker3.Miner.Files
+Exec=/app/libexec/tracker-miner-fs-3 --domain-ontology @domain_rule@ --initial-sleep 0
+
+# Miner details needed for tracker-control
+Path=/org/freedesktop/Tracker3/Miner/Files
+NameSuffix=Miner.Files
diff --git a/data/tracker/org.gnome.Nautilus.domain.rule.in b/data/tracker/org.gnome.Nautilus.domain.rule.in
new file mode 100644
index 000000000..ec0808e30
--- /dev/null
+++ b/data/tracker/org.gnome.Nautilus.domain.rule.in
@@ -0,0 +1,21 @@
+# This defines a private Tracker domain for Nautilus.
+#
+# It's used to run the Tracker indexer inside a Flatpak sandbox, when Nautilus
+# is running on a host that doesn't have a suitable version of Tracker
+# installed.
+
+[DomainOntology]
+# Location for the Tracker database
+CacheLocation=$XDG_CACHE_HOME/nautilus/miner/files
+
+# Name of the ontology to use, must be one located in
+# $(sharedir)/tracker/ontologies
+OntologyName=nepomuk
+
+# DBus name for the owner (not optional). Tracker will use
+# the domain as the prefix of the DBus name for all the
+# services related to this domain ontology.
+Domain=@application_id@
+
+# List of miners we expect to run in this domain.
+Miners=Miner.Files;Miner.Extract
diff --git a/meson.build b/meson.build
index bb36b8a20..c33c0c5e7 100644
--- a/meson.build
+++ b/meson.build
@@ -6,7 +6,7 @@ project('nautilus', 'c',
# * Update GTK-based codes over src/gtk/gtk-code-generator.sh
version: '3.37.91',
- meson_version: '>= 0.47.0',
+ meson_version: '>= 0.49.0',
license: 'GPL3+'
)
diff --git a/src/nautilus-batch-rename-utilities.c b/src/nautilus-batch-rename-utilities.c
index b6cea25fa..0412a172e 100644
--- a/src/nautilus-batch-rename-utilities.c
+++ b/src/nautilus-batch-rename-utilities.c
@@ -19,6 +19,7 @@
#include "nautilus-batch-rename-dialog.h"
#include "nautilus-batch-rename-utilities.h"
#include "nautilus-file.h"
+#include "nautilus-tracker-utilities.h"
#include <glib.h>
#include <gtk/gtk.h>
@@ -63,8 +64,6 @@ 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);
@@ -1119,7 +1118,7 @@ check_metadata_for_selection (NautilusBatchRenameDialog *dialog,
g_string_append (query, "} ORDER BY ASC(nie:contentCreated(?content))");
- connection = tracker_sparql_connection_bus_new (TRACKER_MINER_FS_BUSNAME, NULL, NULL, &error);
+ connection = nautilus_tracker_get_miner_fs_connection (&error);
if (!connection)
{
if (error)
diff --git a/src/nautilus-search-engine-tracker.c b/src/nautilus-search-engine-tracker.c
index dde3cab26..a0e0d638c 100644
--- a/src/nautilus-search-engine-tracker.c
+++ b/src/nautilus-search-engine-tracker.c
@@ -25,6 +25,7 @@
#include "nautilus-search-engine-private.h"
#include "nautilus-search-hit.h"
#include "nautilus-search-provider.h"
+#include "nautilus-tracker-utilities.h"
#define DEBUG_FLAG NAUTILUS_DEBUG_SEARCH
#include "nautilus-debug.h"
@@ -55,8 +56,6 @@ 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,
@@ -79,8 +78,9 @@ finalize (GObject *object)
}
g_clear_object (&tracker->query);
- g_clear_object (&tracker->connection);
g_queue_free_full (tracker->hits_pending, g_object_unref);
+ /* This is a singleton, no need to unref. */
+ tracker->connection = NULL;
G_OBJECT_CLASS (nautilus_search_engine_tracker_parent_class)->finalize (object);
}
@@ -601,8 +601,7 @@ nautilus_search_engine_tracker_init (NautilusSearchEngineTracker *engine)
engine->hits_pending = g_queue_new ();
- engine->connection = tracker_sparql_connection_bus_new (TRACKER_MINER_FS_BUSNAME, NULL, NULL, &error);
-
+ engine->connection = nautilus_tracker_get_miner_fs_connection (&error);
if (error)
{
g_warning ("Could not establish a connection to Tracker: %s", error->message);
diff --git a/src/nautilus-tag-manager.c b/src/nautilus-tag-manager.c
index 8009e6ca9..e21749a10 100644
--- a/src/nautilus-tag-manager.c
+++ b/src/nautilus-tag-manager.c
@@ -21,6 +21,7 @@
#include "nautilus-file.h"
#include "nautilus-file-undo-operations.h"
#include "nautilus-file-undo-manager.h"
+#include "nautilus-tracker-utilities.h"
#define DEBUG_FLAG NAUTILUS_DEBUG_TAG_MANAGER
#include "nautilus-debug.h"
@@ -35,6 +36,7 @@ struct _NautilusTagManager
gboolean tracker_ok;
TrackerSparqlConnection *local;
TrackerSparqlConnection *miner_fs;
+ const gchar *miner_fs_busname;
TrackerNotifier *notifier;
TrackerSparqlStatement *query_starred_files;
@@ -81,14 +83,12 @@ enum
LAST_SIGNAL
};
-#define TRACKER_MINER_FS_BUSNAME "org.freedesktop.Tracker3.Miner.Files"
-
#define QUERY_STARRED_FILES \
"SELECT ?file_url ?content_id " \
"{ " \
" ?content_urn a nautilus:FileReference ; " \
" nautilus:starred true . " \
- " SERVICE <dbus:" TRACKER_MINER_FS_BUSNAME "> { " \
+ " SERVICE <dbus:%s> { " \
" ?content_urn nie:isStoredAs ?file_url . " \
" BIND (tracker:id (?content_urn) AS ?content_id) " \
" } " \
@@ -97,7 +97,7 @@ enum
#define QUERY_UPDATED_FILE_URL \
"SELECT ?file_url EXISTS { ?content_urn nautilus:starred true } AS ?starred" \
"{ " \
- " SERVICE <dbus:" TRACKER_MINER_FS_BUSNAME "> { " \
+ " SERVICE <dbus:%s> { " \
" ?content_urn nie:isStoredAs ?file_url . " \
" FILTER (tracker:id(?content_urn) = ~id) " \
" }" \
@@ -432,14 +432,15 @@ nautilus_tag_manager_delete_tag (NautilusTagManager *self,
GList *selection,
GString *query)
{
- g_string_append (query,
- "DELETE { "
- " ?content_urn a nautilus:FileReference ; "
- " nautilus:starred true . "
- "} "
- "WHERE { "
- " SERVICE <dbus:" TRACKER_MINER_FS_BUSNAME "> { "
- " ?content_urn nie:isStoredAs ?file_url . ");
+ g_string_append_printf (query,
+ "DELETE { "
+ " ?content_urn a nautilus:FileReference ; "
+ " nautilus:starred true . "
+ "} "
+ "WHERE { "
+ " SERVICE <dbus:%s> { "
+ " ?content_urn nie:isStoredAs ?file_url . ",
+ self->miner_fs_busname);
query = add_selection_filter (selection, query);
@@ -453,13 +454,14 @@ nautilus_tag_manager_insert_tag (NautilusTagManager *self,
GList *selection,
GString *query)
{
- g_string_append (query,
- "INSERT { "
- " ?content_urn a nautilus:FileReference . "
- " ?content_urn nautilus:starred true . "
- "} WHERE { "
- " SERVICE <dbus:" TRACKER_MINER_FS_BUSNAME "> { "
- " ?content_urn nie:isStoredAs ?file_url . ");
+ g_string_append_printf (query,
+ "INSERT { "
+ " ?content_urn a nautilus:FileReference . "
+ " ?content_urn nautilus:starred true . "
+ "} WHERE { "
+ " SERVICE <dbus:%s> { "
+ " ?content_urn nie:isStoredAs ?file_url . ",
+ self->miner_fs_busname);
query = add_selection_filter (selection, query);
@@ -570,11 +572,13 @@ nautilus_tag_manager_get_file_ids_for_urls (NautilusTagManager *self,
{
GString *query;
- query = g_string_new ("SELECT ?file_url ?content_id "
- "WHERE { "
- " SERVICE <dbus:" TRACKER_MINER_FS_BUSNAME "> { "
- " ?content_urn nie:isStoredAs ?file_url . "
- " BIND (tracker:id (?content_urn) AS ?content_id) ");
+ query = g_string_new ("");
+ g_string_append_printf (query, "SELECT ?file_url ?content_id "
+ "WHERE { "
+ " SERVICE <dbus:%s> { "
+ " ?content_urn nie:isStoredAs ?file_url . "
+ " BIND (tracker:id (?content_urn) AS ?content_id) ",
+ self->miner_fs_busname);
query = add_selection_filter (selection, query);
@@ -890,6 +894,7 @@ setup_tracker_connections (NautilusTagManager *self,
GError **error)
{
const gchar *datadir;
+ gchar *query_with_busname;
g_autofree gchar *store_path = NULL;
g_autofree gchar *ontology_path = NULL;
g_autoptr (GFile) store = NULL;
@@ -917,31 +922,32 @@ setup_tracker_connections (NautilusTagManager *self,
}
/* Connect to Tracker filesystem index to follow file renames. */
- self->miner_fs = tracker_sparql_connection_bus_new (TRACKER_MINER_FS_BUSNAME,
- NULL,
- NULL,
- error);
-
+ self->miner_fs = nautilus_tracker_get_miner_fs_connection (error);
if (*error)
{
return FALSE;
}
+ self->miner_fs_busname = nautilus_tracker_get_miner_fs_busname (NULL);
/* Prepare reusable queries. */
+ query_with_busname = g_strdup_printf (QUERY_UPDATED_FILE_URL, self->miner_fs_busname);
self->query_updated_file_url = tracker_sparql_connection_query_statement (self->local,
- QUERY_UPDATED_FILE_URL,
+ query_with_busname,
cancellable,
error);
+ g_free (query_with_busname);
if (*error)
{
return FALSE;
}
+ query_with_busname = g_strdup_printf (QUERY_STARRED_FILES, self->miner_fs_busname);
self->query_starred_files = tracker_sparql_connection_query_statement (self->local,
- QUERY_STARRED_FILES,
+ query_with_busname,
cancellable,
error);
+ g_free (query_with_busname);
if (*error)
{
diff --git a/src/nautilus-tracker-utilities.c b/src/nautilus-tracker-utilities.c
index b220df4bd..4c408942e 100644
--- a/src/nautilus-tracker-utilities.c
+++ b/src/nautilus-tracker-utilities.c
@@ -18,12 +18,132 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
+#include "config.h"
#include "nautilus-tracker-utilities.h"
#include "nautilus-global-preferences.h"
#define TRACKER_KEY_RECURSIVE_DIRECTORIES "index-recursive-directories"
#define TRACKER_KEY_SINGLE_DIRECTORIES "index-single-directories"
+/* Shared global connection to Tracker Miner FS */
+static const gchar *tracker_miner_fs_busname = NULL;
+static TrackerSparqlConnection *tracker_miner_fs_connection = NULL;
+static GError *tracker_miner_fs_error = NULL;
+
+static gboolean
+get_host_tracker_miner_fs (GError **error)
+{
+ const gchar *busname = "org.freedesktop.Tracker3.Miner.Files";
+
+ g_message ("Connecting to %s", busname);
+ tracker_miner_fs_connection = tracker_sparql_connection_bus_new (busname, NULL, NULL, error);
+ if (*error)
+ {
+ g_warning ("Unable to create connection for session-wide Tracker indexer: %s", (*error)->message);
+ return FALSE;
+ }
+
+ tracker_miner_fs_busname = busname;
+ return TRUE;
+}
+
+static gboolean
+start_local_tracker_miner_fs (GError **error)
+{
+ const gchar *busname = APPLICATION_ID ".Tracker3.Miner.Files";
+
+ g_message ("Starting %s", busname);
+ tracker_miner_fs_connection = tracker_sparql_connection_bus_new (busname, NULL, NULL, error);
+ if (*error)
+ {
+ g_critical ("Could not start local Tracker indexer at %s: %s", busname, (*error)->message);
+ return FALSE;
+ }
+
+ tracker_miner_fs_busname = busname;
+ return TRUE;
+}
+
+static gboolean
+inside_flatpak (void)
+{
+ return g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS);
+}
+
+static void
+setup_tracker_miner_fs_connection (void)
+{
+ static gsize tried_tracker_init = FALSE;
+
+ if (g_once_init_enter (&tried_tracker_init))
+ {
+ gboolean success;
+
+ success = get_host_tracker_miner_fs (&tracker_miner_fs_error);
+
+ if (!success && inside_flatpak ())
+ {
+ g_clear_error (&tracker_miner_fs_error);
+ success = start_local_tracker_miner_fs (&tracker_miner_fs_error);
+ }
+
+ g_once_init_leave (&tried_tracker_init, TRUE);
+ }
+}
+
+/**
+ * nautilus_tracker_get_miner_fs_connection:
+ * @error: return location for a #GError
+ *
+ * This function returns a global singleton #TrackerSparqlConnection, or %NULL
+ * if we couldn't connect to Tracker Miner FS.
+ *
+ * The first time you call it, this function will block while trying to connect.
+ * This may take some time if starting Tracker Miners from a Flatpak bundle.
+ *
+ * The returned object is a globally shared singleton which should NOT be
+ * unreffed.
+ *
+ * Returns: a #TrackerSparqlConnection, or %NULL
+ */
+TrackerSparqlConnection *
+nautilus_tracker_get_miner_fs_connection (GError **error)
+{
+ setup_tracker_miner_fs_connection ();
+
+ if (tracker_miner_fs_error && error)
+ {
+ *error = g_error_copy (tracker_miner_fs_error);
+ }
+
+ return tracker_miner_fs_connection;
+}
+
+/**
+ * nautilus_tracker_get_miner_fs_busname:
+ * @error: return location for a #GError
+ *
+ * This function returns a DBus name that can be used to talk to
+ * tracker-miner-fs, or %NULL if there is no Tracker Miner FS available.
+ *
+ * The first time you call it, this function will block while trying to connect.
+ * This may take some time if starting Tracker Miners from a Flatpak bundle.
+ *
+ * Returns: a string
+ */
+const gchar *
+nautilus_tracker_get_miner_fs_busname (GError **error)
+{
+ setup_tracker_miner_fs_connection ();
+
+ if (tracker_miner_fs_error && error)
+ {
+ *error = g_error_copy (tracker_miner_fs_error);
+ }
+
+ return tracker_miner_fs_busname;
+}
+
static GFile *
location_from_tracker_dir (const gchar *value)
{
diff --git a/src/nautilus-tracker-utilities.h b/src/nautilus-tracker-utilities.h
index f509c3005..d4b2eba0c 100644
--- a/src/nautilus-tracker-utilities.h
+++ b/src/nautilus-tracker-utilities.h
@@ -22,5 +22,9 @@
#pragma once
#include <gio/gio.h>
+#include <libtracker-sparql/tracker-sparql.h>
-gboolean nautilus_tracker_directory_is_tracked (GFile *directory);
+TrackerSparqlConnection * nautilus_tracker_get_miner_fs_connection (GError **error);
+const gchar * nautilus_tracker_get_miner_fs_busname (GError **error);
+
+gboolean nautilus_tracker_directory_is_tracked (GFile *directory);