summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam@afuera.me.uk>2020-08-29 21:10:48 +0200
committerSam Thursfield <sam@afuera.me.uk>2020-09-02 18:50:17 +0200
commit7cf268ab73f71c09ed85f917c5c5f2703d71e400 (patch)
treee593b20b334e2a6da8f33cddde3b3d7569ac639e
parentbd30a21a0ce1b40ca59814f731bd761670601aaa (diff)
downloadnautilus-7cf268ab73f71c09ed85f917c5c5f2703d71e400.tar.gz
Import starred files data from Tracker 2.x
Starred files data is now migrated from the Tracker 2.x database if found. This depends on the `tracker3` CLI tool, which should be present anywhere that we find libtracker-sparql 3.0. The --2to3 export functionality was added in https://gitlab.gnome.org/GNOME/tracker/-/merge_requests/308 If/when the migration completes successfully, a stamp file named `~/.local/share/nautilus/tracker2-migration-complete` is created.
-rw-r--r--src/nautilus-application.c2
-rw-r--r--src/nautilus-search-engine-tracker.c2
-rw-r--r--src/nautilus-tag-manager.c173
-rw-r--r--src/nautilus-tag-manager.h2
4 files changed, 178 insertions, 1 deletions
diff --git a/src/nautilus-application.c b/src/nautilus-application.c
index 17f1da59a..10478da9c 100644
--- a/src/nautilus-application.c
+++ b/src/nautilus-application.c
@@ -1351,6 +1351,8 @@ nautilus_application_startup_common (NautilusApplication *self)
nautilus_init_application_actions (self);
+ nautilus_tag_manager_maybe_migrate_tracker2_data (priv->tag_manager);
+
nautilus_profile_end (NULL);
g_signal_connect (self, "notify::active-window", G_CALLBACK (on_application_active_window_changed), NULL);
diff --git a/src/nautilus-search-engine-tracker.c b/src/nautilus-search-engine-tracker.c
index a0e0d638c..9ebac0b28 100644
--- a/src/nautilus-search-engine-tracker.c
+++ b/src/nautilus-search-engine-tracker.c
@@ -393,7 +393,7 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
" nie:mimeType ?mime");
}
- if (tracker->fts_enabled)
+ if (tracker->fts_enabled && *search_text)
{
/* Use fts:match only for content search to not lose some filename results due to stop words. */
g_autofree gchar *filtered_search_text;
diff --git a/src/nautilus-tag-manager.c b/src/nautilus-tag-manager.c
index f41b3ec8f..fbd8571e5 100644
--- a/src/nautilus-tag-manager.c
+++ b/src/nautilus-tag-manager.c
@@ -25,6 +25,7 @@
#define DEBUG_FLAG NAUTILUS_DEBUG_TAG_MANAGER
#include "nautilus-debug.h"
+#include <gio/gunixinputstream.h>
#include <tracker-sparql.h>
#include "config.h"
@@ -84,6 +85,14 @@ enum
static guint signals[LAST_SIGNAL];
+/* Limit to 10MB output from Tracker -- surely, nobody has over a million starred files. */
+#define TRACKER2_MAX_IMPORT_BYTES 10 * 1024 * 1024
+
+static const gchar *tracker2_migration_stamp (void)
+{
+ return g_build_filename (g_get_user_data_dir (), "nautilus", "tracker2-migration-complete", NULL);
+}
+
static void
start_query_or_update (TrackerSparqlConnection *db,
GString *query,
@@ -690,3 +699,167 @@ nautilus_tag_manager_can_star_contents (NautilusTagManager *tag_manager,
*/
return g_file_has_prefix (directory, tag_manager->home) || g_file_equal (directory, tag_manager->home);
}
+
+static void
+process_tracker2_data_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ NautilusTagManager *self = NAUTILUS_TAG_MANAGER (source_object);
+ const gchar *path = tracker2_migration_stamp ();
+ g_autoptr (GError) error = NULL;
+
+ tracker_sparql_connection_update_finish (self->db, res, &error);
+
+ if (!error)
+ {
+ DEBUG ("Data migration was successful. Creating stamp %s", path);
+
+ g_file_set_contents (path, "", -1, &error);
+ if (error)
+ {
+ g_warning ("Failed to create %s after migration: %s", path, error->message);
+ }
+ }
+ else
+ {
+ g_warning ("Error during data migration: %s", error->message);
+ }
+}
+
+static void
+process_tracker2_data (NautilusTagManager *self,
+ GBytes *key_file_data)
+{
+ g_autoptr (GKeyFile) key_file = NULL;
+ g_autoptr (GError) error = NULL;
+ gchar **groups, **group;
+ GList *selection = NULL;
+ NautilusFile *file;
+
+ key_file = g_key_file_new ();
+ g_key_file_load_from_bytes (key_file,
+ key_file_data,
+ G_KEY_FILE_NONE,
+ &error);
+ g_bytes_unref (key_file_data);
+
+ if (error)
+ {
+ g_warning ("Tracker 2 migration: Failed to parse key file data: %s", error->message);
+ return;
+ }
+
+ groups = g_key_file_get_groups (key_file, NULL);
+
+ for (group = groups; *group != NULL; group++)
+ {
+ file = nautilus_file_get_by_uri (*group);
+
+ if (file)
+ {
+ DEBUG ("Tracker 2 migration: starring %s", *group);
+ selection = g_list_prepend (selection, file);
+ }
+ else
+ {
+ DEBUG ("Tracker 2 migration: couldn't get NautilusFile for %s", *group);
+ }
+ }
+
+ nautilus_tag_manager_star_files (self,
+ G_OBJECT (self),
+ selection,
+ process_tracker2_data_cb,
+ self->cancellable);
+
+ g_free (groups);
+}
+
+static void
+export_tracker2_data_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GInputStream *stream = G_INPUT_STREAM (source_object);
+ NautilusTagManager *self = NAUTILUS_TAG_MANAGER (user_data);
+ g_autoptr (GError) error = NULL;
+ GBytes *key_file_data;
+
+ key_file_data = g_input_stream_read_bytes_finish (stream, res, &error);
+
+ if (key_file_data)
+ {
+ process_tracker2_data (self, key_file_data);
+ }
+ else
+ {
+ g_warning ("Tracker2 migration: Failed to read data from pipe: %s", error->message);
+ }
+}
+
+static void
+child_watch_cb (GPid pid,
+ gint status,
+ gpointer user_data)
+{
+ DEBUG ("Child %" G_PID_FORMAT " exited %s", pid,
+ g_spawn_check_exit_status (status, NULL) ? "normally" : "abnormally");
+ g_spawn_close_pid (pid);
+}
+
+static void
+export_tracker2_data (NautilusTagManager *self)
+{
+ gchar *argv[] = {"tracker3", "export", "--2to3", "files-starred", "--keyfile", NULL};
+ gint stdout_fd;
+ GPid child_pid;
+ g_autoptr (GError) error = NULL;
+ gboolean success;
+ g_autoptr (GInputStream) stream = NULL;
+ GSpawnFlags flags;
+
+ flags = G_SPAWN_DO_NOT_REAP_CHILD |
+ G_SPAWN_STDERR_TO_DEV_NULL |
+ G_SPAWN_SEARCH_PATH_FROM_ENVP;
+ success = g_spawn_async_with_pipes (NULL,
+ argv,
+ NULL,
+ flags,
+ NULL,
+ NULL,
+ &child_pid,
+ NULL,
+ &stdout_fd,
+ NULL,
+ &error);
+ if (!success)
+ {
+ g_warning ("Tracker 2 migration: Couldn't run `tracker3`: %s", error->message);
+ return;
+ }
+
+ g_child_watch_add (child_pid, child_watch_cb, NULL);
+
+ stream = g_unix_input_stream_new (stdout_fd, TRUE);
+ g_input_stream_read_bytes_async (stream,
+ TRACKER2_MAX_IMPORT_BYTES,
+ G_PRIORITY_LOW,
+ self->cancellable,
+ export_tracker2_data_cb,
+ self);
+}
+
+void
+nautilus_tag_manager_maybe_migrate_tracker2_data (NautilusTagManager *self)
+{
+ if (g_file_test (tracker2_migration_stamp (), G_FILE_TEST_EXISTS))
+ {
+ DEBUG ("Tracker 2 migration: already completed.");
+ }
+ else
+ {
+ DEBUG ("Tracker 2 migration: starting.");
+ export_tracker2_data (self);
+ }
+}
diff --git a/src/nautilus-tag-manager.h b/src/nautilus-tag-manager.h
index c0d793adc..2e926ae75 100644
--- a/src/nautilus-tag-manager.h
+++ b/src/nautilus-tag-manager.h
@@ -54,4 +54,6 @@ gboolean nautilus_tag_manager_file_is_starred (NautilusTagManager *
gboolean nautilus_tag_manager_can_star_contents (NautilusTagManager *self,
GFile *directory);
+void nautilus_tag_manager_maybe_migrate_tracker2_data (NautilusTagManager *self);
+
G_END_DECLS