diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches/revert_tracker_update.patch | 2516 |
1 files changed, 2516 insertions, 0 deletions
diff --git a/debian/patches/revert_tracker_update.patch b/debian/patches/revert_tracker_update.patch new file mode 100644 index 0000000..b04ad2b --- /dev/null +++ b/debian/patches/revert_tracker_update.patch @@ -0,0 +1,2516 @@ +Index: nautilus/data/meson.build +=================================================================== +--- nautilus.orig/data/meson.build ++++ nautilus/data/meson.build +@@ -137,6 +137,3 @@ if appstream_util.found() + ] + ) + endif +- +-subdir('ontology') +-subdir('tracker') +Index: nautilus/data/ontology/meson.build +=================================================================== +--- nautilus.orig/data/ontology/meson.build ++++ /dev/null +@@ -1,8 +0,0 @@ +-ontology_data = files( +- 'nautilus.description', +- 'nautilus.ontology', +-) +- +-install_data(ontology_data, +- install_dir: join_paths(datadir, 'nautilus', 'ontology') +-) +Index: nautilus/data/ontology/nautilus.description +=================================================================== +--- nautilus.orig/data/ontology/nautilus.description ++++ /dev/null +@@ -1,9 +0,0 @@ +-@prefix dsc: <http://tracker.api.gnome.org/ontology/v3/dsc#> . +- +-<virtual-ontology-uri:nautilus.ontology> a dsc:Ontology ; +- dsc:title "Nautilus ontology" ; +- dsc:description "Tracker database schema for Nautilus private data." ; +- +- dsc:localPrefix "nautilus" ; +- dsc:baseUrl "https://gitlab.gnome.org/GNOME/nautilus#" ; +- dsc:relativePath "./nautilus.ontology" ; +Index: nautilus/data/ontology/nautilus.ontology +=================================================================== +--- nautilus.orig/data/ontology/nautilus.ontology ++++ /dev/null +@@ -1,20 +0,0 @@ +-@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . +-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +-@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . +-@prefix nrl: <http://tracker.api.gnome.org/ontology/v3/nrl#> . +-@prefix nautilus: <https://gitlab.gnome.org/GNOME/nautilus#> . +- +-nautilus: a nrl:Namespace, nrl:Ontology ; +- nrl:prefix "nautilus" ; +- nrl:lastModified "2020-05-01T10:00:00Z" . +- +-nautilus:File a rdfs:Class ; +- rdfs:comment "Represents a file on disk by its URL. Equivalent to http://tracker.api.gnome.org/ontology/v3/nfo#FileDataObject" ; +- rdfs:subClassOf rdfs:Resource ; +- nrl:notify true . +- +-nautilus:starred a rdf:Property ; +- rdfs:comment "Marks files that are starred in Nautilus." ; +- rdfs:domain nautilus:File ; +- rdfs:range xsd:boolean ; +- nrl:maxCardinality 1 . +Index: nautilus/data/tracker/meson.build +=================================================================== +--- nautilus.orig/data/tracker/meson.build ++++ /dev/null +@@ -1,31 +0,0 @@ +-# 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) +Index: nautilus/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Extract.service.in +=================================================================== +--- nautilus.orig/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Extract.service.in ++++ /dev/null +@@ -1,7 +0,0 @@ +-[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 +Index: nautilus/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Files.service.in +=================================================================== +--- nautilus.orig/data/tracker/org.gnome.Nautilus.Tracker3.Miner.Files.service.in ++++ /dev/null +@@ -1,7 +0,0 @@ +-[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 +Index: nautilus/data/tracker/org.gnome.Nautilus.domain.rule.in +=================================================================== +--- nautilus.orig/data/tracker/org.gnome.Nautilus.domain.rule.in ++++ /dev/null +@@ -1,21 +0,0 @@ +-# 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 +Index: nautilus/meson.build +=================================================================== +--- nautilus.orig/meson.build ++++ nautilus/meson.build +@@ -6,7 +6,7 @@ project('nautilus', 'c', + # * Update GTK-based codes over src/gtk/gtk-code-generator.sh + version: '3.38.2', + +- meson_version: '>= 0.49.0', ++ meson_version: '>= 0.47.0', + license: 'GPL3+' + ) + +@@ -124,7 +124,7 @@ selinux = [] + if get_option('selinux') + selinux = dependency('libselinux', version: '>= 2.0') + endif +-tracker_sparql = dependency('tracker-sparql-3.0') ++tracker_sparql = dependency('tracker-sparql-2.0') + xml = dependency('libxml-2.0', version: '>= 2.7.8') + + #################### +Index: nautilus/src/nautilus-application.c +=================================================================== +--- nautilus.orig/src/nautilus-application.c ++++ nautilus/src/nautilus-application.c +@@ -1351,8 +1351,6 @@ nautilus_application_startup_common (Nau + + 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); +Index: nautilus/src/nautilus-batch-rename-utilities.c +=================================================================== +--- nautilus.orig/src/nautilus-batch-rename-utilities.c ++++ nautilus/src/nautilus-batch-rename-utilities.c +@@ -19,7 +19,6 @@ + #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> +@@ -1057,21 +1056,21 @@ check_metadata_for_selection (NautilusBa + + query = g_string_new ("SELECT " + "nfo:fileName(?file) " +- "nie:contentCreated(?content) " +- "year(nie:contentCreated(?content)) " +- "month(nie:contentCreated(?content)) " +- "day(nie:contentCreated(?content)) " +- "hours(nie:contentCreated(?content)) " +- "minutes(nie:contentCreated(?content)) " +- "seconds(nie:contentCreated(?content)) " +- "nfo:model(nfo:equipment(?content)) " +- "nmm:seasonNumber(?content) " +- "nmm:episodeNumber(?content) " +- "nmm:trackNumber(?content) " +- "nmm:artistName(nmm:performer(?content)) " +- "nie:title(?content) " +- "nie:title(nmm:musicAlbum(?content)) " +- "WHERE { ?file a nfo:FileDataObject. ?file nie:url ?url. ?content nie:isStoredAs ?file. "); ++ "nie:contentCreated(?file) " ++ "year(nie:contentCreated(?file)) " ++ "month(nie:contentCreated(?file)) " ++ "day(nie:contentCreated(?file)) " ++ "hours(nie:contentCreated(?file)) " ++ "minutes(nie:contentCreated(?file)) " ++ "seconds(nie:contentCreated(?file)) " ++ "nfo:model(nfo:equipment(?file)) " ++ "nmm:season(?file) " ++ "nmm:episodeNumber(?file) " ++ "nmm:trackNumber(?file) " ++ "nmm:artistName(nmm:performer(?file)) " ++ "nie:title(?file) " ++ "nmm:albumTitle(nmm:musicAlbum(?file)) " ++ "WHERE { ?file a nfo:FileDataObject. ?file nie:url ?url. "); + + parent_uri = nautilus_file_get_parent_uri (NAUTILUS_FILE (selection->data)); + +@@ -1116,9 +1115,9 @@ check_metadata_for_selection (NautilusBa + + selection_metadata = g_list_reverse (selection_metadata); + +- g_string_append (query, "} ORDER BY ASC(nie:contentCreated(?content))"); ++ g_string_append (query, "} ORDER BY ASC(nie:contentCreated(?file))"); + +- connection = nautilus_tracker_get_miner_fs_connection (&error); ++ connection = tracker_sparql_connection_get (NULL, &error); + if (!connection) + { + if (error) +Index: nautilus/src/nautilus-file-changes-queue.c +=================================================================== +--- nautilus.orig/src/nautilus-file-changes-queue.c ++++ nautilus/src/nautilus-file-changes-queue.c +@@ -21,7 +21,6 @@ + #include "nautilus-file-changes-queue.h" + + #include "nautilus-directory-notify.h" +-#include "nautilus-tag-manager.h" + + typedef enum + { +@@ -207,7 +206,6 @@ pairs_list_free (GList *pairs) + void + nautilus_file_changes_consume_changes (gboolean consume_all) + { +- g_autoptr (NautilusTagManager) tag_manager = nautilus_tag_manager_get (); + NautilusFileChange *change; + GList *additions, *changes, *deletions, *moves; + GFilePair *pair; +@@ -323,10 +321,6 @@ nautilus_file_changes_consume_changes (g + + case CHANGE_FILE_MOVED: + { +- nautilus_tag_manager_update_moved_uris (tag_manager, +- change->from, +- change->to); +- + pair = g_new (GFilePair, 1); + pair->from = change->from; + pair->to = change->to; +Index: nautilus/src/nautilus-file.c +=================================================================== +--- nautilus.orig/src/nautilus-file.c ++++ nautilus/src/nautilus-file.c +@@ -1853,10 +1853,6 @@ rename_get_info_callback (GObject * + new_info = g_file_query_info_finish (G_FILE (source_object), res, &error); + if (new_info != NULL) + { +- g_autoptr (NautilusTagManager) tag_manager = nautilus_tag_manager_get (); +- g_autoptr (GFile) old_location = NULL; +- g_autoptr (GFile) new_location = NULL; +- + directory = op->file->details->directory; + + new_name = g_file_info_get_name (new_info); +@@ -1872,17 +1868,12 @@ rename_get_info_callback (GObject * + nautilus_file_changed (existing_file); + } + +- old_location = nautilus_file_get_location (op->file); +- old_uri = g_file_get_uri (old_location); ++ old_uri = nautilus_file_get_uri (op->file); + + update_info_and_name (op->file, new_info); + +- new_location = nautilus_file_get_location (op->file); +- new_uri = g_file_get_uri (new_location); +- ++ new_uri = nautilus_file_get_uri (op->file); + nautilus_directory_moved (old_uri, new_uri); +- nautilus_tag_manager_update_moved_uris (tag_manager, old_location, new_location); +- + g_free (new_uri); + g_free (old_uri); + +Index: nautilus/src/nautilus-files-view.c +=================================================================== +--- nautilus.orig/src/nautilus-files-view.c ++++ nautilus/src/nautilus-files-view.c +@@ -7450,7 +7450,7 @@ real_update_actions_state (NautilusFiles + GDriveStartStopType start_stop_type; + g_autoptr (GFile) current_location = NULL; + g_autofree gchar *current_uri = NULL; +- gboolean can_star_current_directory; ++ gboolean current_directory_tracked; + gboolean show_star; + gboolean show_unstar; + gchar *uri; +@@ -7784,12 +7784,12 @@ real_update_actions_state (NautilusFiles + + current_location = nautilus_file_get_location (nautilus_files_view_get_directory_as_file (view)); + current_uri = g_file_get_uri (current_location); +- can_star_current_directory = nautilus_tag_manager_can_star_contents (priv->tag_manager, current_location); ++ current_directory_tracked = nautilus_tracker_directory_is_tracked (current_location); + + show_star = (selection != NULL) && +- (can_star_current_directory || selection_contains_starred); ++ (current_directory_tracked || selection_contains_starred); + show_unstar = (selection != NULL) && +- (can_star_current_directory || selection_contains_starred); ++ (current_directory_tracked || selection_contains_starred); + for (l = selection; l != NULL; l = l->next) + { + NautilusFile *file; +Index: nautilus/src/nautilus-global-preferences.c +=================================================================== +--- nautilus.orig/src/nautilus-global-preferences.c ++++ nautilus/src/nautilus-global-preferences.c +@@ -66,5 +66,5 @@ nautilus_global_preferences_init (void) + gnome_lockdown_preferences = g_settings_new ("org.gnome.desktop.lockdown"); + gnome_background_preferences = g_settings_new ("org.gnome.desktop.background"); + gnome_interface_preferences = g_settings_new ("org.gnome.desktop.interface"); +- tracker_preferences = g_settings_new ("org.freedesktop.Tracker3.Miner.Files"); ++ tracker_preferences = g_settings_new ("org.freedesktop.Tracker.Miner.Files"); + } +Index: nautilus/src/nautilus-list-view.c +=================================================================== +--- nautilus.orig/src/nautilus-list-view.c ++++ nautilus/src/nautilus-list-view.c +@@ -2494,15 +2494,14 @@ get_visible_columns (NautilusListView *l + GPtrArray *res; + GList *l; + g_autofree gchar *uri = NULL; +- gboolean can_star_current_directory; ++ gboolean in_tracked_dir; + gboolean is_starred; + + file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (list_view)); + uri = nautilus_file_get_uri (file); + + location = g_file_new_for_uri (uri); +- can_star_current_directory = nautilus_tag_manager_can_star_contents (list_view->details->tag_manager, +- location); ++ in_tracked_dir = nautilus_tracker_directory_is_tracked (location); + is_starred = eel_uri_is_starred (uri); + + visible_columns = nautilus_file_get_metadata_list (file, +@@ -2516,7 +2515,7 @@ get_visible_columns (NautilusListView *l + for (l = visible_columns; l != NULL; l = l->next) + { + if (g_strcmp0 (l->data, "starred") != 0 || +- (g_strcmp0 (l->data, "starred") == 0 && (can_star_current_directory || is_starred))) ++ (g_strcmp0 (l->data, "starred") == 0 && (in_tracked_dir || is_starred))) + { + g_ptr_array_add (res, l->data); + } +Index: nautilus/src/nautilus-search-engine-tracker.c +=================================================================== +--- nautilus.orig/src/nautilus-search-engine-tracker.c ++++ nautilus/src/nautilus-search-engine-tracker.c +@@ -25,7 +25,6 @@ + #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" + +@@ -78,9 +77,8 @@ 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); + } +@@ -294,31 +292,6 @@ search_finished_idle (gpointer user_data + */ + #define FILENAME_RANK "5.0" + +-static gchar * +-filter_alnum_strdup (gchar *string) +-{ +- GString *filtered; +- gchar *c; +- +- filtered = g_string_new (""); +- for (c = string; *c; c = g_utf8_next_char (c)) +- { +- gunichar uc; +- +- uc = g_utf8_get_char (c); +- if (g_unichar_isalnum (uc)) +- { +- g_string_append_unichar (filtered, uc); +- } +- else +- { +- g_string_append_c (filtered, ' '); +- } +- } +- +- return g_string_free (filtered, FALSE); +-} +- + static void + nautilus_search_engine_tracker_start (NautilusSearchProvider *provider) + { +@@ -361,56 +334,43 @@ nautilus_search_engine_tracker_start (Na + mimetypes = nautilus_query_get_mime_types (tracker->query); + + sparql = g_string_new ("SELECT DISTINCT" +- " ?url" ++ " nie:url(?urn)" + " xsd:double(COALESCE(?rank2, ?rank1)) AS ?rank" +- " nfo:fileLastModified(?file)" +- " nfo:fileLastAccessed(?file)"); +- +- if (tracker->fts_enabled && *search_text) +- { +- g_string_append (sparql, " fts:snippet(?content)"); +- } +- +- g_string_append (sparql, "FROM tracker:FileSystem "); ++ " nfo:fileLastModified(?urn)" ++ " nfo:fileLastAccessed(?urn)"); + + if (tracker->fts_enabled) + { +- g_string_append (sparql, "FROM tracker:Documents "); ++ g_string_append (sparql, " fts:snippet(?urn)"); + } + + g_string_append (sparql, + "\nWHERE {" +- " ?file a nfo:FileDataObject;" ++ " ?urn a nfo:FileDataObject;" + " nfo:fileLastModified ?mtime;" + " nfo:fileLastAccessed ?atime;" +- " nie:dataSource/tracker:available true;" +- " nie:url ?url."); ++ " tracker:available true;" ++ " nie:url ?url"); + + if (mimetypes->len > 0) + { +- g_string_append (sparql, +- " ?content nie:isStoredAs ?file;" +- " nie:mimeType ?mime"); ++ g_string_append (sparql, "; nie:mimeType ?mime"); + } + +- if (tracker->fts_enabled && *search_text) ++ if (tracker->fts_enabled) + { + /* Use fts:match only for content search to not lose some filename results due to stop words. */ +- g_autofree gchar *filtered_search_text; +- +- filtered_search_text = filter_alnum_strdup (search_text); + g_string_append_printf (sparql, +- " { " +- " ?content nie:isStoredAs ?file ." +- " ?content fts:match \"%s*\" ." +- " BIND(fts:rank(?content) AS ?rank1) ." ++ " {" ++ " ?urn fts:match '\"nie:plainTextContent\" : \"%s\"*' ." ++ " BIND(fts:rank(?urn) AS ?rank1) ." + " } UNION", +- filtered_search_text); ++ search_text); + } + + g_string_append_printf (sparql, + " {" +- " ?file nfo:fileName ?filename ." ++ " ?urn nfo:fileName ?filename ." + " FILTER(fn:contains(fn:lower-case(?filename), '%s')) ." + " BIND(" FILENAME_RANK " AS ?rank2) ." + " }", +@@ -601,7 +561,8 @@ nautilus_search_engine_tracker_init (Nau + + engine->hits_pending = g_queue_new (); + +- engine->connection = nautilus_tracker_get_miner_fs_connection (&error); ++ engine->connection = tracker_sparql_connection_get (NULL, &error); ++ + if (error) + { + g_warning ("Could not establish a connection to Tracker: %s", error->message); +Index: nautilus/src/nautilus-starred-directory.c +=================================================================== +--- nautilus.orig/src/nautilus-starred-directory.c ++++ nautilus/src/nautilus-starred-directory.c +@@ -510,6 +510,7 @@ nautilus_starred_directory_dispose (GObj + { + NautilusFavoriteDirectory *starred; + GList *l; ++ NautilusFile *file; + + starred = NAUTILUS_STARRED_DIRECTORY (object); + +Index: nautilus/src/nautilus-tag-manager.c +=================================================================== +--- nautilus.orig/src/nautilus-tag-manager.c ++++ nautilus/src/nautilus-tag-manager.c +@@ -1,7 +1,6 @@ + /* nautilus-tag-manager.c + * + * Copyright (C) 2017 Alexandru Pandelea <alexandru.pandelea@gmail.com> +- * Copyright (C) 2020 Sam Thursfield <sam@afuera.me.uk> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -21,29 +20,17 @@ + #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" + +-#include <gio/gunixinputstream.h> + #include <tracker-sparql.h> + +-#include "config.h" +- + struct _NautilusTagManager + { + GObject object; + +- gboolean database_ok; +- TrackerSparqlConnection *db; + TrackerNotifier *notifier; ++ GError *notifier_error; + +- TrackerSparqlStatement *query_starred_files; +- TrackerSparqlStatement *query_file_is_starred; +- +- GHashTable *starred_file_uris; +- GFile *home; +- ++ GHashTable *starred_files; + GCancellable *cancellable; + }; + +@@ -57,10 +44,21 @@ typedef enum + + typedef struct + { ++ GTask *task; ++ GList *selection; ++ GHashTable *ids; ++ GObject *object; ++ GAsyncReadyCallback callback; ++ GCancellable *cancellable; ++} InsertTaskData; ++ ++typedef struct ++{ + NautilusTagManager *tag_manager; + GTask *task; + GList *selection; + gboolean star; ++ GHashTable *ids; + } UpdateData; + + enum +@@ -69,49 +67,96 @@ enum + LAST_SIGNAL + }; + +-#define QUERY_STARRED_FILES \ +- "SELECT ?file " \ +- "{ " \ +- " ?file a nautilus:File ; " \ +- " nautilus:starred true . " \ +- "}" +- +-#define QUERY_FILE_IS_STARRED \ +- "ASK " \ +- "{ " \ +- " ~file a nautilus:File ; " \ +- " nautilus:starred true . " \ +- "}" ++#define STARRED_TAG "<urn:gnome:nautilus:starred>" + + 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 * ++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 const gchar *tracker2_migration_stamp (void) ++static void ++destroy_insert_task_data (gpointer data) + { +- return g_build_filename (g_get_user_data_dir (), "nautilus", "tracker2-migration-complete", NULL); ++ InsertTaskData *task_data; ++ ++ task_data = data; ++ ++ nautilus_file_list_free (task_data->selection); ++ g_free (data); ++} ++ ++static GString * ++add_selection_filter (GList *selection, ++ GString *query) ++{ ++ NautilusFile *file; ++ GList *l; ++ ++ g_string_append (query, " FILTER(?url IN ("); ++ ++ for (l = selection; l != NULL; l = l->next) ++ { ++ g_autofree gchar *uri = NULL; ++ g_autofree gchar *escaped_uri = NULL; ++ ++ file = l->data; ++ ++ uri = nautilus_file_get_uri (file); ++ escaped_uri = tracker_sparql_escape_string (uri); ++ g_string_append_printf (query, "'%s'", escaped_uri); ++ ++ if (l->next != NULL) ++ { ++ g_string_append (query, ", "); ++ } ++ } ++ ++ g_string_append (query, "))"); ++ ++ return query; + } + + static void +-start_query_or_update (TrackerSparqlConnection *db, +- GString *query, +- GAsyncReadyCallback callback, +- gpointer user_data, +- gboolean is_query, +- GCancellable *cancellable) ++start_query_or_update (GString *query, ++ GAsyncReadyCallback callback, ++ gpointer user_data, ++ gboolean is_query, ++ GCancellable *cancellable) + { + g_autoptr (GError) error = NULL; ++ TrackerSparqlConnection *connection; + +- if (!db) ++ connection = tracker_sparql_connection_get (cancellable, &error); ++ if (!connection) + { +- g_message ("nautilus-tag-manager: No Tracker connection"); ++ if (error) ++ { ++ g_warning ("Error on getting connection: %s", error->message); ++ } ++ + return; + } + + if (is_query) + { +- tracker_sparql_connection_query_async (db, ++ tracker_sparql_connection_query_async (connection, + query->str, + cancellable, + callback, +@@ -119,12 +164,65 @@ start_query_or_update (TrackerSparqlConn + } + else + { +- tracker_sparql_connection_update_async (db, ++ tracker_sparql_connection_update_async (connection, + query->str, ++ G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data); + } ++ ++ g_object_unref (connection); ++} ++ ++static void ++on_query_callback (GObject *object, ++ GAsyncResult *result, ++ gpointer user_data, ++ GAsyncReadyCallback callback, ++ OperationType op_type, ++ GCancellable *cancellable) ++{ ++ TrackerSparqlCursor *cursor; ++ g_autoptr (GError) error = NULL; ++ TrackerSparqlConnection *connection; ++ GTask *task; ++ ++ task = user_data; ++ ++ connection = TRACKER_SPARQL_CONNECTION (object); ++ ++ cursor = tracker_sparql_connection_query_finish (connection, ++ result, ++ &error); ++ ++ if (error != NULL) ++ { ++ if (error->code != G_IO_ERROR_CANCELLED) ++ { ++ if (op_type == GET_STARRED_FILES) ++ { ++ g_warning ("Error on getting starred files: %s", error->message); ++ } ++ else if (op_type == GET_IDS_FOR_URLS) ++ { ++ g_warning ("Error on getting id for url: %s", error->message); ++ g_task_return_pointer (task, g_task_get_task_data (task), NULL); ++ g_object_unref (task); ++ } ++ else ++ { ++ g_warning ("Error on getting query callback: %s", error->message); ++ } ++ } ++ } ++ else ++ { ++ tracker_sparql_cursor_next_async (cursor, ++ cancellable, ++ callback, ++ user_data); ++ } + } + + static void +@@ -132,21 +230,46 @@ on_update_callback (GObject *object + GAsyncResult *result, + gpointer user_data) + { +- TrackerSparqlConnection *db; ++ TrackerSparqlConnection *connection; + GError *error; + UpdateData *data; ++ gint64 *id; ++ GList *l; ++ gchar *uri; + + data = user_data; + + error = NULL; + +- db = TRACKER_SPARQL_CONNECTION (object); ++ connection = TRACKER_SPARQL_CONNECTION (object); + +- tracker_sparql_connection_update_finish (db, result, &error); ++ tracker_sparql_connection_update_finish (connection, result, &error); + + if (error == NULL) + { +- /* FIXME: make sure data->tag_manager->starred_file_uris is up to date */ ++ for (l = data->selection; l != NULL; l = l->next) ++ { ++ uri = nautilus_file_get_uri (NAUTILUS_FILE (l->data)); ++ ++ if (data->star) ++ { ++ if (g_hash_table_contains (data->ids, uri)) ++ { ++ id = g_new0 (gint64, 1); ++ ++ *id = (gint64) g_hash_table_lookup (data->ids, uri); ++ g_hash_table_insert (data->tag_manager->starred_files, ++ nautilus_file_get_uri (NAUTILUS_FILE (l->data)), ++ id); ++ } ++ } ++ else ++ { ++ g_hash_table_remove (data->tag_manager->starred_files, uri); ++ } ++ ++ g_free (uri); ++ } + + if (!nautilus_file_undo_manager_is_operating ()) + { +@@ -169,11 +292,15 @@ on_update_callback (GObject *object + } + else + { +- g_warning ("error updating tags: %s", error->message); + g_task_return_error (data->task, error); + g_object_unref (data->task); ++ g_warning ("error updating tags: %s", error->message); + } + ++ if (data->ids) ++ { ++ g_hash_table_destroy (data->ids); ++ } + nautilus_file_list_free (data->selection); + g_free (data); + } +@@ -224,24 +351,7 @@ get_query_status (TrackerSparqlCursor *c + GList * + nautilus_tag_manager_get_starred_files (NautilusTagManager *self) + { +- GHashTableIter starred_iter; +- gchar *starred_uri; +- GList *starred_file_uris = NULL; +- +- g_hash_table_iter_init (&starred_iter, self->starred_file_uris); +- while (g_hash_table_iter_next (&starred_iter, (gpointer *) &starred_uri, NULL)) +- { +- g_autoptr (GFile) file = g_file_new_for_uri (starred_uri); +- +- /* Skip files ouside $HOME, because we don't support starring these yet. +- * See comment on nautilus_tag_manager_can_star_contents() */ +- if (g_file_has_prefix (file, self->home)) +- { +- starred_file_uris = g_list_prepend (starred_file_uris, starred_uri); +- } +- } +- +- return starred_file_uris; ++ return g_hash_table_get_keys (self->starred_files); + } + + static void +@@ -251,6 +361,7 @@ on_get_starred_files_cursor_callback (GO + { + TrackerSparqlCursor *cursor; + const gchar *url; ++ gint64 *id; + gboolean success; + NautilusTagManager *self; + GList *changed_files; +@@ -266,24 +377,21 @@ on_get_starred_files_cursor_callback (GO + return; + } + ++ id = g_new0 (gint64, 1); ++ + url = tracker_sparql_cursor_get_string (cursor, 0, NULL); ++ *id = tracker_sparql_cursor_get_integer (cursor, 1); + +- g_hash_table_add (self->starred_file_uris, g_strdup (url)); ++ g_hash_table_insert (self->starred_files, ++ g_strdup (url), ++ id); + + file = nautilus_file_get_by_uri (url); ++ changed_files = g_list_prepend (NULL, file); + +- if (file) +- { +- changed_files = g_list_prepend (NULL, file); ++ g_signal_emit_by_name (self, "starred-changed", changed_files); + +- g_signal_emit_by_name (self, "starred-changed", changed_files); +- +- nautilus_file_list_free (changed_files); +- } +- else +- { +- DEBUG ("File %s is starred but not found", url); +- } ++ nautilus_file_list_free (changed_files); + + tracker_sparql_cursor_next_async (cursor, + self->cancellable, +@@ -296,150 +404,256 @@ on_get_starred_files_query_callback (GOb + GAsyncResult *result, + gpointer user_data) + { +- TrackerSparqlCursor *cursor; +- g_autoptr (GError) error = NULL; +- TrackerSparqlStatement *statement; + NautilusTagManager *self; + + self = NAUTILUS_TAG_MANAGER (user_data); +- statement = TRACKER_SPARQL_STATEMENT (object); +- +- cursor = tracker_sparql_statement_execute_finish (statement, +- result, +- &error); + +- if (error != NULL) +- { +- if (error->code != G_IO_ERROR_CANCELLED) +- { +- g_warning ("Error on getting starred files: %s", error->message); +- } +- } +- else +- { +- tracker_sparql_cursor_next_async (cursor, +- self->cancellable, +- on_get_starred_files_cursor_callback, +- user_data); +- } ++ on_query_callback (object, ++ result, ++ user_data, ++ on_get_starred_files_cursor_callback, ++ GET_STARRED_FILES, ++ self->cancellable); + } + + static void + nautilus_tag_manager_query_starred_files (NautilusTagManager *self, + GCancellable *cancellable) + { +- if (!self->database_ok) +- { +- g_message ("nautilus-tag-manager: No Tracker connection"); +- return; +- } ++ GString *query; + + self->cancellable = cancellable; + +- tracker_sparql_statement_execute_async (self->query_starred_files, +- cancellable, +- on_get_starred_files_query_callback, +- self); ++ query = g_string_new ("SELECT ?url tracker:id(?urn) " ++ "WHERE { ?urn nie:url ?url ; nao:hasTag " STARRED_TAG "}"); ++ ++ start_query_or_update (query, ++ on_get_starred_files_query_callback, ++ self, ++ TRUE, ++ cancellable); ++ ++ g_string_free (query, TRUE); ++} ++ ++static gpointer ++nautilus_tag_manager_gpointer_task_finish (GObject *source_object, ++ GAsyncResult *res, ++ GError **error) ++{ ++ g_return_val_if_fail (g_task_is_valid (res, source_object), FALSE); ++ ++ return g_task_propagate_pointer (G_TASK (res), error); + } + + static GString * + nautilus_tag_manager_delete_tag (NautilusTagManager *self, +- GList *selection) ++ GList *selection, ++ GString *query) + { +- GString *query; +- NautilusFile *file; +- GList *l; ++ g_string_append (query, ++ "DELETE { ?urn nao:hasTag " STARRED_TAG " }" ++ "WHERE { ?urn a nfo:FileDataObject ; nie:url ?url ."); + +- query = g_string_new ("DELETE DATA {"); ++ query = add_selection_filter (selection, query); + +- for (l = selection; l != NULL; l = l->next) +- { +- g_autofree gchar *uri = NULL; ++ g_string_append (query, "}\n"); + +- file = l->data; ++ return query; ++} + +- uri = nautilus_file_get_uri (file); +- g_string_append_printf (query, +- " <%s> a nautilus:File ; " +- " nautilus:starred true . ", +- uri); +- } ++static GString * ++nautilus_tag_manager_insert_tag (NautilusTagManager *self, ++ GList *selection, ++ GString *query) ++{ ++ g_string_append (query, ++ "INSERT DATA { " STARRED_TAG " a nao:Tag .}\n" ++ "INSERT { ?urn nao:hasTag " STARRED_TAG " }" ++ "WHERE { ?urn a nfo:FileDataObject ; nie:url ?url ."); ++ ++ query = add_selection_filter (selection, query); + +- g_string_append (query, "}"); ++ g_string_append (query, "}\n"); + + return query; + } + +-static GString * +-nautilus_tag_manager_insert_tag (NautilusTagManager *self, +- GList *selection) ++gboolean ++nautilus_tag_manager_file_is_starred (NautilusTagManager *self, ++ const gchar *file_name) + { +- GString *query; +- NautilusFile *file; ++ return g_hash_table_contains (self->starred_files, file_name); ++} ++ ++static void ++on_get_file_ids_for_urls_cursor_callback (GObject *object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ TrackerSparqlCursor *cursor; ++ GTask *task; ++ gint64 *id; ++ const gchar *url; ++ gboolean success; + GList *l; ++ gchar *file_url; ++ InsertTaskData *data; + +- query = g_string_new ("INSERT DATA {"); ++ task = user_data; ++ data = g_task_get_task_data (task); + +- for (l = selection; l != NULL; l = l->next) ++ cursor = TRACKER_SPARQL_CURSOR (object); ++ ++ success = get_query_status (cursor, result, GET_IDS_FOR_URLS, task); ++ if (!success) + { +- g_autofree gchar *uri = NULL; ++ return; ++ } + +- file = l->data; ++ id = g_new0 (gint64, 1); + +- uri = nautilus_file_get_uri (file); +- g_string_append_printf (query, +- " <%s> a nautilus:File ; " +- " nautilus:starred true . ", +- uri); ++ url = tracker_sparql_cursor_get_string (cursor, 0, NULL); ++ *id = tracker_sparql_cursor_get_integer (cursor, 1); ++ ++ for (l = data->selection; l != NULL; l = l->next) ++ { ++ file_url = nautilus_file_get_uri (NAUTILUS_FILE (l->data)); ++ ++ if (g_strcmp0 (file_url, url) == 0) ++ { ++ g_hash_table_insert (data->ids, ++ g_strdup (url), ++ id); ++ ++ g_free (file_url); ++ ++ break; ++ } ++ ++ g_free (file_url); + } + +- g_string_append (query, "}"); ++ tracker_sparql_cursor_next_async (cursor, ++ g_task_get_cancellable (task), ++ on_get_file_ids_for_urls_cursor_callback, ++ task); ++} + +- return query; ++ ++static void ++on_get_file_ids_for_urls_query_callback (GObject *object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ GTask *task; ++ ++ task = user_data; ++ ++ on_query_callback (object, ++ result, ++ user_data, ++ on_get_file_ids_for_urls_cursor_callback, ++ GET_IDS_FOR_URLS, ++ g_task_get_cancellable (task)); + } + +-gboolean +-nautilus_tag_manager_file_is_starred (NautilusTagManager *self, +- const gchar *file_uri) ++static void ++nautilus_tag_manager_get_file_ids_for_urls (GObject *object, ++ GList *selection, ++ GTask *task) + { +- return g_hash_table_contains (self->starred_file_uris, file_uri); ++ GString *query; ++ ++ query = g_string_new ("SELECT ?url tracker:id(?urn) WHERE { ?urn nie:url ?url; ."); ++ ++ query = add_selection_filter (selection, query); ++ ++ g_string_append (query, "}\n"); ++ ++ start_query_or_update (query, ++ on_get_file_ids_for_urls_query_callback, ++ task, ++ TRUE, ++ g_task_get_cancellable (task)); ++ ++ g_string_free (query, TRUE); + } + +-void +-nautilus_tag_manager_star_files (NautilusTagManager *self, +- GObject *object, +- GList *selection, +- GAsyncReadyCallback callback, +- GCancellable *cancellable) ++static void ++on_star_files_callback (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) + { ++ NautilusTagManager *self; + GString *query; ++ InsertTaskData *data; + g_autoptr (GError) error = NULL; + GTask *task; + UpdateData *update_data; + +- DEBUG ("Starring %i files", g_list_length (selection)); ++ self = NAUTILUS_TAG_MANAGER (object); + +- task = g_task_new (object, cancellable, callback, NULL); ++ data = nautilus_tag_manager_gpointer_task_finish (object, res, &error); + +- query = nautilus_tag_manager_insert_tag (self, selection); ++ task = g_task_new (data->object, data->cancellable, data->callback, NULL); ++ ++ query = g_string_new (""); ++ ++ query = nautilus_tag_manager_insert_tag (self, ++ data->selection, ++ query); + + update_data = g_new0 (UpdateData, 1); + update_data->task = task; + update_data->tag_manager = self; +- update_data->selection = nautilus_file_list_copy (selection); ++ update_data->selection = nautilus_file_list_copy (data->selection); + update_data->star = TRUE; ++ update_data->ids = data->ids; + +- start_query_or_update (self->db, +- query, ++ /* the ids hash table is now owned by the update_data, ++ * so it will be freed by it. ++ */ ++ destroy_insert_task_data (data); ++ ++ start_query_or_update (query, + on_update_callback, + update_data, + FALSE, +- cancellable); ++ g_task_get_cancellable (task)); + + g_string_free (query, TRUE); + } + + void ++nautilus_tag_manager_star_files (NautilusTagManager *self, ++ GObject *object, ++ GList *selection, ++ GAsyncReadyCallback callback, ++ GCancellable *cancellable) ++{ ++ GTask *task; ++ InsertTaskData *data; ++ ++ data = g_new0 (InsertTaskData, 1); ++ data->selection = nautilus_file_list_copy (selection); ++ data->ids = g_hash_table_new_full (g_str_hash, ++ g_str_equal, ++ (GDestroyNotify) g_free, ++ (GDestroyNotify) g_free); ++ data->callback = callback; ++ data->object = object; ++ data->cancellable = cancellable; ++ ++ task = g_task_new (self, cancellable, on_star_files_callback, NULL); ++ g_task_set_task_data (task, ++ data, ++ NULL); ++ ++ nautilus_tag_manager_get_file_ids_for_urls (G_OBJECT (self), selection, task); ++} ++ ++void + nautilus_tag_manager_unstar_files (NautilusTagManager *self, + GObject *object, + GList *selection, +@@ -450,11 +664,13 @@ nautilus_tag_manager_unstar_files (Nauti + GTask *task; + UpdateData *update_data; + +- DEBUG ("Unstarring %i files", g_list_length (selection)); +- + task = g_task_new (object, cancellable, callback, NULL); + +- query = nautilus_tag_manager_delete_tag (self, selection); ++ query = g_string_new (""); ++ ++ query = nautilus_tag_manager_delete_tag (self, ++ selection, ++ query); + + update_data = g_new0 (UpdateData, 1); + update_data->task = task; +@@ -462,8 +678,7 @@ nautilus_tag_manager_unstar_files (Nauti + update_data->selection = nautilus_file_list_copy (selection); + update_data->star = FALSE; + +- start_query_or_update (self->db, +- query, ++ start_query_or_update (query, + on_update_callback, + update_data, + FALSE, +@@ -474,21 +689,22 @@ nautilus_tag_manager_unstar_files (Nauti + + static void + on_tracker_notifier_events (TrackerNotifier *notifier, +- gchar *service, +- gchar *graph, + GPtrArray *events, + gpointer user_data) + { + TrackerNotifierEvent *event; + NautilusTagManager *self; + int i; +- const gchar *file_url; ++ const gchar *location_uri; ++ const gchar *new_location_uri; + GError *error = NULL; ++ TrackerSparqlConnection *connection; + TrackerSparqlCursor *cursor; +- gboolean query_has_results = FALSE; +- gboolean starred; ++ GString *query; ++ gboolean query_has_results; ++ gint64 *id; + GList *changed_files; +- NautilusFile *changed_file; ++ NautilusFile *file; + + self = NAUTILUS_TAG_MANAGER (user_data); + +@@ -496,60 +712,101 @@ on_tracker_notifier_events (TrackerNotif + { + event = g_ptr_array_index (events, i); + +- file_url = tracker_notifier_event_get_urn (event); +- changed_file = NULL; ++ location_uri = tracker_notifier_event_get_location (event); + +- DEBUG ("Got event for file %s", file_url); ++ 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 ")}", ++ tracker_notifier_event_get_id (event)); + +- tracker_sparql_statement_bind_string (self->query_file_is_starred, "file", file_url); +- cursor = tracker_sparql_statement_execute (self->query_file_is_starred, +- NULL, +- &error); ++ /* 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); + +- if (cursor) +- { +- query_has_results = tracker_sparql_cursor_next (cursor, NULL, &error); ++ 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); + } + +- if (error || !cursor || !query_has_results) ++ connection = tracker_sparql_connection_get (NULL, &error); ++ ++ if (!connection) + { +- g_warning ("Couldn't query the starred files database: '%s'", error ? error->message : "(null error)"); ++ g_printerr ("Couldn't obtain a direct connection to the Tracker store: %s", ++ error ? error->message : "unknown error"); + g_clear_error (&error); ++ + return; + } + +- starred = tracker_sparql_cursor_get_boolean (cursor, 0); +- if (starred) ++ cursor = tracker_sparql_connection_query (connection, ++ query->str, ++ NULL, ++ &error); ++ ++ if (error) + { +- gboolean inserted = g_hash_table_add (self->starred_file_uris, g_strdup (file_url)); ++ g_printerr ("Couldn't query the Tracker Store: '%s'", error->message); + +- if (inserted) +- { +- DEBUG ("Added %s to starred files list", file_url); +- changed_file = nautilus_file_get_by_uri (file_url); +- } ++ g_clear_error (&error); ++ ++ return; + } +- else ++ ++ if (cursor) + { +- gboolean removed = g_hash_table_remove (self->starred_file_uris, file_url); ++ query_has_results = tracker_sparql_cursor_next (cursor, NULL, &error); + +- if (removed) ++ /* 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)) + { +- DEBUG ("Removed %s from starred files list", file_url); +- changed_file = nautilus_file_get_by_uri (file_url); ++ g_hash_table_remove (self->starred_files, location_uri); ++ ++ 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); + } +- } ++ else if (query_has_results && location_uri && !g_hash_table_contains (self->starred_files, location_uri)) ++ { ++ id = g_new0 (gint64, 1); ++ *id = tracker_notifier_event_get_id (event); + +- if (changed_file) +- { +- changed_files = g_list_prepend (NULL, changed_file); ++ g_hash_table_insert (self->starred_files, ++ g_strdup (location_uri), ++ id); + +- g_signal_emit_by_name (self, "starred-changed", changed_files); ++ file = nautilus_file_get_by_uri (location_uri); ++ changed_files = g_list_prepend (NULL, file); + +- nautilus_file_list_free (changed_files); ++ g_signal_emit_by_name (self, "starred-changed", changed_files); ++ ++ nautilus_file_list_free (changed_files); ++ } ++ ++ g_object_unref (cursor); + } + +- g_object_unref (cursor); ++ g_object_unref (connection); ++ ++ g_string_free (query, TRUE); + } + } + +@@ -568,11 +825,8 @@ nautilus_tag_manager_finalize (GObject * + } + + g_clear_object (&self->notifier); +- g_clear_object (&self->db); +- g_clear_object (&self->query_file_is_starred); +- g_clear_object (&self->query_starred_files); + +- g_hash_table_destroy (self->starred_file_uris); ++ g_hash_table_destroy (self->starred_files); + + G_OBJECT_CLASS (nautilus_tag_manager_parent_class)->finalize (object); + } +@@ -614,403 +868,30 @@ nautilus_tag_manager_get (void) + return tag_manager; + } + +-static gboolean +-setup_database (NautilusTagManager *self, +- GCancellable *cancellable, +- GError **error) +-{ +- const gchar *datadir; +- g_autofree gchar *store_path = NULL; +- g_autofree gchar *ontology_path = NULL; +- g_autoptr (GFile) store = NULL; +- g_autoptr (GFile) ontology = NULL; +- +- /* Open private database to store nautilus:starred property. */ +- +- datadir = NAUTILUS_DATADIR; +- +- store_path = g_build_filename (g_get_user_data_dir (), "nautilus", "tags", NULL); +- ontology_path = g_build_filename (datadir, "ontology", NULL); +- +- store = g_file_new_for_path (store_path); +- ontology = g_file_new_for_path (ontology_path); +- +- self->db = tracker_sparql_connection_new (TRACKER_SPARQL_CONNECTION_FLAGS_NONE, +- store, +- ontology, +- cancellable, +- error); +- +- if (*error) +- { +- return FALSE; +- } +- +- /* Prepare reusable queries. */ +- self->query_file_is_starred = tracker_sparql_connection_query_statement (self->db, +- QUERY_FILE_IS_STARRED, +- cancellable, +- error); +- +- if (*error) +- { +- return FALSE; +- } +- +- self->query_starred_files = tracker_sparql_connection_query_statement (self->db, +- QUERY_STARRED_FILES, +- cancellable, +- error); +- +- if (*error) +- { +- return FALSE; +- } +- +- return TRUE; +-} +- +-/* Initialize the tag mananger. */ + void + nautilus_tag_manager_set_cancellable (NautilusTagManager *self, + GCancellable *cancellable) + { +- g_autoptr (GError) error = NULL; +- +- self->database_ok = setup_database (self, cancellable, &error); +- +- if (error) +- { +- g_warning ("Unable to initialize tag manager: %s", error->message); +- return; +- } +- +- self->notifier = tracker_sparql_connection_create_notifier (self->db); +- + nautilus_tag_manager_query_starred_files (self, cancellable); + +- g_signal_connect (self->notifier, +- "events", +- G_CALLBACK (on_tracker_notifier_events), +- self); +-} +- +-static void +-nautilus_tag_manager_init (NautilusTagManager *self) +-{ +- self->starred_file_uris = g_hash_table_new_full (g_str_hash, +- g_str_equal, +- (GDestroyNotify) g_free, +- /* values are keys */ +- NULL); +- self->home = g_file_new_for_path (g_get_home_dir ()); +-} +- +-gboolean +-nautilus_tag_manager_can_star_contents (NautilusTagManager *tag_manager, +- GFile *directory) +-{ +- /* We only allow files to be starred inside the home directory for now. +- * This avoids the starred files database growing too big. +- * See https://gitlab.gnome.org/GNOME/nautilus/-/merge_requests/553#note_903108 +- */ +- return g_file_has_prefix (directory, tag_manager->home) || g_file_equal (directory, tag_manager->home); +-} +- +-static void +-update_moved_uris_callback (GObject *object, +- GAsyncResult *result, +- gpointer user_data) +-{ +- g_autoptr (GError) error = NULL; +- g_autoptr (GPtrArray) new_uris = user_data; +- +- tracker_sparql_connection_update_finish (TRACKER_SPARQL_CONNECTION (object), +- result, +- &error); +- +- if (error != NULL && error->code != G_IO_ERROR_CANCELLED) +- { +- g_warning ("Error updating moved uris: %s", error->message); +- } +- else +- { +- g_autolist (NautilusFile) updated_files = NULL; +- g_autoptr (NautilusTagManager) tag_manager = NULL; +- +- for (guint i = 0; i < new_uris->len; i++) +- { +- gchar *new_uri = g_ptr_array_index (new_uris, i); +- +- updated_files = g_list_prepend (updated_files, nautilus_file_get_by_uri (new_uri)); +- } +- +- tag_manager = nautilus_tag_manager_get (); +- g_signal_emit_by_name (tag_manager, "starred-changed", updated_files); +- } +-} +- +-/** +- * nautilus_tag_manager_update_moved_uris: +- * @self: The tag manager singleton +- * @src: The original location as a #GFile +- * @dest: The new location as a #GFile +- * +- * Checks whether the rename/move operation (@src to @dest) has modified +- * the URIs of any starred files, and updates the database accordingly. +- */ +-void +-nautilus_tag_manager_update_moved_uris (NautilusTagManager *self, +- GFile *src, +- GFile *dest) +-{ +- GHashTableIter starred_iter; +- gchar *starred_uri; +- g_autoptr (GPtrArray) old_uris = NULL; +- g_autoptr (GPtrArray) new_uris = NULL; +- g_autoptr (GString) query = NULL; +- +- if (!self->database_ok) +- { +- g_message ("nautilus-tag-manager: No Tracker connection"); +- return; +- } +- +- old_uris = g_ptr_array_new (); +- new_uris = g_ptr_array_new_with_free_func (g_free); +- +- g_hash_table_iter_init (&starred_iter, self->starred_file_uris); +- while (g_hash_table_iter_next (&starred_iter, (gpointer *) &starred_uri, NULL)) +- { +- g_autoptr (GFile) starred_location = NULL; +- g_autofree gchar *relative_path = NULL; +- +- starred_location = g_file_new_for_uri (starred_uri); +- +- if (g_file_equal (starred_location, src)) +- { +- /* The moved file/folder is starred */ +- g_ptr_array_add (old_uris, starred_uri); +- g_ptr_array_add (new_uris, g_file_get_uri (dest)); +- continue; +- } +- +- relative_path = g_file_get_relative_path (src, starred_location); +- if (relative_path != NULL) +- { +- /* The starred file/folder is descendant of the moved/renamed directory */ +- g_autoptr (GFile) new_location = NULL; +- +- new_location = g_file_resolve_relative_path (dest, relative_path); +- +- g_ptr_array_add (old_uris, starred_uri); +- g_ptr_array_add (new_uris, g_file_get_uri (new_location)); +- } +- } +- +- if (new_uris->len == 0) +- { +- /* No starred files are affected by this move/rename */ +- return; +- } +- +- DEBUG ("Updating moved URI for %i starred files", new_uris->len); +- +- query = g_string_new ("DELETE DATA {"); +- +- for (guint i = 0; i < old_uris->len; i++) +- { +- gchar *old_uri = g_ptr_array_index (old_uris, i); +- g_string_append_printf (query, +- " <%s> a nautilus:File ; " +- " nautilus:starred true . ", +- old_uri); +- } +- +- g_string_append (query, "} ; INSERT DATA {"); +- +- for (guint i = 0; i < new_uris->len; i++) +- { +- gchar *new_uri = g_ptr_array_index (new_uris, i); +- g_string_append_printf (query, +- " <%s> a nautilus:File ; " +- " nautilus:starred true . ", +- new_uri); +- } +- +- g_string_append (query, "}"); +- +- /* Forward the new_uris list to later pass in the ::files-changed signal. +- * There is no need to pass the old_uris because the file model is updated +- * independently; we need only inform the view where to display stars now. +- */ +- tracker_sparql_connection_update_async (self->db, +- query->str, +- self->cancellable, +- update_moved_uris_callback, +- g_steal_pointer (&new_uris)); +-} +- +-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 ++ self->notifier = tracker_notifier_new (NULL, ++ TRACKER_NOTIFIER_FLAG_QUERY_LOCATION, ++ cancellable, ++ &self->notifier_error); ++ if (self->notifier != NULL) + { +- g_warning ("Tracker2 migration: Failed to read data from pipe: %s", error->message); ++ g_signal_connect (self->notifier, ++ "events", ++ G_CALLBACK (on_tracker_notifier_events), ++ self); + } + } + + 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; +- 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) ++nautilus_tag_manager_init (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); +- } ++ self->starred_files = g_hash_table_new_full (g_str_hash, ++ g_str_equal, ++ (GDestroyNotify) g_free, ++ (GDestroyNotify) g_free); + } +Index: nautilus/src/nautilus-tag-manager.h +=================================================================== +--- nautilus.orig/src/nautilus-tag-manager.h ++++ nautilus/src/nautilus-tag-manager.h +@@ -49,14 +49,6 @@ void nautilus_tag_manager + + + gboolean nautilus_tag_manager_file_is_starred (NautilusTagManager *self, +- const gchar *file_uri); ++ const gchar *file_name); + +-gboolean nautilus_tag_manager_can_star_contents (NautilusTagManager *self, +- GFile *directory); +-void nautilus_tag_manager_update_moved_uris (NautilusTagManager *tag_manager, +- GFile *src, +- GFile *dest); +- +-void nautilus_tag_manager_maybe_migrate_tracker2_data (NautilusTagManager *self); +- +-G_END_DECLS ++G_END_DECLS +\ No newline at end of file +Index: nautilus/src/nautilus-tracker-utilities.c +=================================================================== +--- nautilus.orig/src/nautilus-tracker-utilities.c ++++ nautilus/src/nautilus-tracker-utilities.c +@@ -18,128 +18,141 @@ + * 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) ++static GFile * ++location_from_tracker_dir (const gchar *value) + { +- const gchar *busname = "org.freedesktop.Tracker3.Miner.Files"; ++ const gchar *special_dir; ++ g_autoptr (GFile) home = NULL; ++ GFile *location; ++ ++ home = g_file_new_for_path (g_get_home_dir ()); + +- g_message ("Connecting to %s", busname); +- tracker_miner_fs_connection = tracker_sparql_connection_bus_new (busname, NULL, NULL, error); +- if (*error) ++ if (g_strcmp0 (value, "$HOME") == 0) + { +- g_warning ("Unable to create connection for session-wide Tracker indexer: %s", (*error)->message); +- return FALSE; ++ return g_steal_pointer (&home); + } + +- tracker_miner_fs_busname = busname; +- return TRUE; +-} ++ special_dir = NULL; ++ if (g_strcmp0 (value, "&DESKTOP") == 0) ++ { ++ special_dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); ++ } ++ else if (g_strcmp0 (value, "&DOCUMENTS") == 0) ++ { ++ special_dir = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); ++ } ++ else if (g_strcmp0 (value, "&DOWNLOAD") == 0) ++ { ++ special_dir = g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD); ++ } ++ else if (g_strcmp0 (value, "&MUSIC") == 0) ++ { ++ special_dir = g_get_user_special_dir (G_USER_DIRECTORY_MUSIC); ++ } ++ else if (g_strcmp0 (value, "&PICTURES") == 0) ++ { ++ special_dir = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES); ++ } ++ else if (g_strcmp0 (value, "&PUBLIC_SHARE") == 0) ++ { ++ special_dir = g_get_user_special_dir (G_USER_DIRECTORY_PUBLIC_SHARE); ++ } ++ else if (g_strcmp0 (value, "&TEMPLATES") == 0) ++ { ++ special_dir = g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES); ++ } ++ else if (g_strcmp0 (value, "&VIDEOS") == 0) ++ { ++ special_dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS); ++ } + +-static gboolean +-start_local_tracker_miner_fs (GError **error) +-{ +- const gchar *busname = APPLICATION_ID ".Tracker3.Miner.Files"; ++ if (special_dir != NULL) ++ { ++ location = g_file_new_for_commandline_arg (special_dir); + +- g_message ("Starting %s", busname); +- tracker_miner_fs_connection = tracker_sparql_connection_bus_new (busname, NULL, NULL, error); +- if (*error) ++ /* Ignore XDG directories set to $HOME, like the miner does */ ++ if (g_file_equal (location, home)) ++ { ++ g_clear_object (&location); ++ } ++ } ++ else + { +- g_critical ("Could not start local Tracker indexer at %s: %s", busname, (*error)->message); +- return FALSE; ++ location = g_file_new_for_commandline_arg (value); + } + +- tracker_miner_fs_busname = busname; +- return TRUE; ++ return location; + } + +-static gboolean +-inside_flatpak (void) ++static GList * ++get_tracker_locations (const gchar *key) + { +- return g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS); +-} ++ g_auto (GStrv) locations = NULL; ++ GList *list = NULL; ++ gint idx; ++ GFile *location; + +-static void +-setup_tracker_miner_fs_connection (void) +-{ +- static gsize tried_tracker_init = FALSE; ++ locations = g_settings_get_strv (tracker_preferences, key); + +- if (g_once_init_enter (&tried_tracker_init)) ++ for (idx = 0; locations[idx] != NULL; idx++) + { +- gboolean success; +- +- success = get_host_tracker_miner_fs (&tracker_miner_fs_error); +- +- if (!success && inside_flatpak ()) ++ location = location_from_tracker_dir (locations[idx]); ++ if (location != NULL) + { +- g_clear_error (&tracker_miner_fs_error); +- success = start_local_tracker_miner_fs (&tracker_miner_fs_error); ++ list = g_list_prepend (list, location); + } +- +- g_once_init_leave (&tried_tracker_init, TRUE); + } ++ ++ return list; + } + + /** +- * nautilus_tracker_get_miner_fs_connection: +- * @error: return location for a #GError ++ * nautilus_tracker_directory_is_tracked: ++ * @directory: a #GFile representing a directory + * +- * This function returns a global singleton #TrackerSparqlConnection, or %NULL +- * if we couldn't connect to Tracker Miner FS. ++ * This function reads the "index-recursive-directories" and ++ * "index-single-directories" keys from the org.freedesktop.tracker.miner.files ++ * schema, and assumes the listed directories (and their descendants for the ++ * former key) are tracked. + * +- * 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. ++ * Exception: XDG user dirs set to $HOME are ignored. + * +- * The returned object is a globally shared singleton which should NOT be +- * unreffed. ++ * FIXME: Tracker's files miner's logic is actually a lot more complex, ++ * including configurable ignore patterns, but we are overlooking that. + * +- * Returns: a #TrackerSparqlConnection, or %NULL ++ * Returns: $TRUE if the @directory is, in principle, tracked. $FALSE otherwise. + */ +-TrackerSparqlConnection * +-nautilus_tracker_get_miner_fs_connection (GError **error) ++gboolean ++nautilus_tracker_directory_is_tracked (GFile *directory) + { +- setup_tracker_miner_fs_connection (); ++ g_autolist (GFile) recursive_locations = NULL; ++ g_autolist (GFile) single_locations = NULL; ++ GList *l; + +- if (tracker_miner_fs_error && error) ++ recursive_locations = get_tracker_locations (TRACKER_KEY_RECURSIVE_DIRECTORIES); ++ for (l = recursive_locations; l != NULL; l = l->next) + { +- *error = g_error_copy (tracker_miner_fs_error); ++ if (g_file_equal (directory, G_FILE (l->data)) || ++ g_file_has_prefix (directory, G_FILE (l->data))) ++ { ++ return TRUE; ++ } + } + +- 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) ++ single_locations = get_tracker_locations (TRACKER_KEY_SINGLE_DIRECTORIES); ++ for (l = single_locations; l != NULL; l = l->next) + { +- *error = g_error_copy (tracker_miner_fs_error); ++ if (g_file_equal (directory, G_FILE (l->data))) ++ { ++ return TRUE; ++ } + } + +- return tracker_miner_fs_busname; ++ return FALSE; + } +Index: nautilus/src/nautilus-tracker-utilities.h +=================================================================== +--- nautilus.orig/src/nautilus-tracker-utilities.h ++++ nautilus/src/nautilus-tracker-utilities.h +@@ -22,7 +22,5 @@ + #pragma once + + #include <gio/gio.h> +-#include <libtracker-sparql/tracker-sparql.h> + +-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); +Index: nautilus/test/automated/displayless/meson.build +=================================================================== +--- nautilus.orig/test/automated/displayless/meson.build ++++ nautilus/test/automated/displayless/meson.build +@@ -1,7 +1,3 @@ +-trackertestutils = dependency('tracker-testutils-3.0') +- +-tracker_sandbox = find_program(trackertestutils.get_pkgconfig_variable('command')) +- + tests = [ + ['test-file-utilities-get-common-filename-prefix', [ + 'test-file-utilities-get-common-filename-prefix.c' +@@ -27,6 +23,9 @@ tests = [ + ['test-nautilus-search-engine-model', [ + 'test-nautilus-search-engine-model.c' + ]], ++ ['test-nautilus-search-engine-tracker', [ ++ 'test-nautilus-search-engine-tracker.c' ++ ]], + ['test-file-operations-copy-files', [ + 'test-file-operations-copy-files.c' + ]], +@@ -35,12 +34,6 @@ tests = [ + ]] + ] + +-tracker_tests = [ +- ['test-nautilus-search-engine-tracker', [ +- 'test-nautilus-search-engine-tracker.c', +- ]], +-] +- + foreach t: tests + test( + t[0], +@@ -48,25 +41,6 @@ foreach t: tests + env: [ + test_env, + 'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()), +- 'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()) +- ], +- timeout: 480 +- ) +-endforeach +- +- +- +-# Tests that read and write from the Tracker index are run using 'tracker-sandbox' +-# script to use a temporary instance of tracker-miner-fs instead of the session one. +-foreach t: tracker_tests +- test_exe = executable(t[0], t[1], files('test-utilities.c'), dependencies: libnautilus_dep) +- test( +- t[0], +- tracker_sandbox, +- args: ['--store-tmpdir', '--index-recursive-tmpdir', test_exe], +- env: [ +- test_env, +- 'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()), + 'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()) + ], + timeout: 480 +Index: nautilus/test/automated/displayless/test-nautilus-search-engine-model.c +=================================================================== +--- nautilus.orig/test/automated/displayless/test-nautilus-search-engine-model.c ++++ nautilus/test/automated/displayless/test-nautilus-search-engine-model.c +@@ -1,7 +1,5 @@ + #include "test-utilities.h" + +-static guint total_hits = 0; +- + static void + hits_added_cb (NautilusSearchEngine *engine, + GSList *hits) +@@ -10,8 +8,6 @@ hits_added_cb (NautilusSearchEngine *eng + for (gint hit_number = 0; hits != NULL; hits = hits->next, hit_number++) + { + g_print ("Hit %i: %s\n", hit_number, nautilus_search_hit_get_uri (hits->data)); +- +- total_hits += 1; + } + } + +@@ -72,8 +68,5 @@ main (int argc, + NAUTILUS_SEARCH_ENGINE_MODEL_ENGINE); + + g_main_loop_run (loop); +- +- g_assert_cmpint (total_hits, ==, 3); +- + return 0; + } +Index: nautilus/test/automated/displayless/test-nautilus-search-engine-simple.c +=================================================================== +--- nautilus.orig/test/automated/displayless/test-nautilus-search-engine-simple.c ++++ nautilus/test/automated/displayless/test-nautilus-search-engine-simple.c +@@ -1,7 +1,5 @@ + #include "test-utilities.h" + +-static guint total_hits = 0; +- + static void + hits_added_cb (NautilusSearchEngine *engine, + GSList *hits) +@@ -10,7 +8,6 @@ hits_added_cb (NautilusSearchEngine *eng + for (gint hit_number = 0; hits != NULL; hits = hits->next, hit_number++) + { + g_print ("Hit %i: %s\n", hit_number, nautilus_search_hit_get_uri (hits->data)); +- total_hits += 1; + } + } + +@@ -67,8 +64,5 @@ main (int argc, + NAUTILUS_SEARCH_ENGINE_SIMPLE_ENGINE); + + g_main_loop_run (loop); +- +- g_assert_cmpint (total_hits, ==, 3); +- + return 0; + } +Index: nautilus/test/automated/displayless/test-nautilus-search-engine-tracker.c +=================================================================== +--- nautilus.orig/test/automated/displayless/test-nautilus-search-engine-tracker.c ++++ nautilus/test/automated/displayless/test-nautilus-search-engine-tracker.c +@@ -1,106 +1,5 @@ + #include "test-utilities.h" + +-/* Time in seconds we allow for Tracker Miners to index the file */ +-#define TRACKER_MINERS_AWAIT_TIMEOUT 1000 +- +-static guint total_hits = 0; +- +-typedef struct +-{ +- GMainLoop *main_loop; +- gchar *uri; +- gboolean created; +-} TrackerAwaitFileData; +- +-static TrackerAwaitFileData * +-tracker_await_file_data_new (const char *uri, +- GMainLoop *main_loop) +-{ +- TrackerAwaitFileData *data; +- +- data = g_slice_new0 (TrackerAwaitFileData); +- data->uri = g_strdup (uri); +- data->main_loop = g_main_loop_ref (main_loop); +- +- return data; +-} +- +-static void +-tracker_await_file_data_free (TrackerAwaitFileData *data) +-{ +- g_free (data->uri); +- g_main_loop_unref (data->main_loop); +- g_slice_free (TrackerAwaitFileData, data); +-} +- +-static gboolean timeout_cb (gpointer user_data) +-{ +- TrackerAwaitFileData *data = user_data; +- g_error ("Timeout waiting for %s to be indexed by Tracker.", data->uri); +- return G_SOURCE_REMOVE; +-} +- +-static void +-tracker_events_cb (TrackerNotifier *self, +- gchar *service, +- gchar *graph, +- GPtrArray *events, +- gpointer user_data) +-{ +- TrackerAwaitFileData *data = user_data; +- int i; +- +- for (i = 0; i < events->len; i++) +- { +- TrackerNotifierEvent *event = g_ptr_array_index (events, i); +- +- if (tracker_notifier_event_get_event_type (event) == TRACKER_NOTIFIER_EVENT_CREATE) +- { +- const gchar *urn = tracker_notifier_event_get_urn (event); +- g_debug ("Got CREATED event for %s", urn); +- if (strcmp (urn, data->uri) == 0) +- { +- data->created = TRUE; +- g_main_loop_quit (data->main_loop); +- } +- } +- } +-} +- +-/* Create data that the Tracker indexer will find, and wait for the database to be updated. */ +-static void +-create_test_data (TrackerSparqlConnection *connection, +- const gchar *indexed_tmpdir) +-{ +- g_autoptr (GFile) test_file = NULL; +- g_autoptr (GMainLoop) main_loop = NULL; +- g_autoptr (GError) error = NULL; +- g_autoptr (TrackerNotifier) notifier = NULL; +- TrackerAwaitFileData *await_data; +- gulong signal_id, timeout_id; +- +- test_file = g_file_new_build_filename (indexed_tmpdir, "target_file.txt", NULL); +- +- main_loop = g_main_loop_new (NULL, 0); +- await_data = tracker_await_file_data_new (g_file_get_uri (test_file), main_loop); +- +- notifier = tracker_sparql_connection_create_notifier (connection); +- +- signal_id = g_signal_connect (notifier, "events", G_CALLBACK (tracker_events_cb), await_data); +- timeout_id = g_timeout_add_seconds (TRACKER_MINERS_AWAIT_TIMEOUT, timeout_cb, await_data); +- +- g_file_set_contents (g_file_peek_path (test_file), "Please show me in the search results", -1, &error); +- g_assert_no_error (error); +- +- g_main_loop_run (main_loop); +- +- g_assert (await_data->created); +- g_source_remove (timeout_id); +- g_clear_signal_handler (&signal_id, notifier); +- +- tracker_await_file_data_free (await_data); +-} +- + static void + hits_added_cb (NautilusSearchEngine *engine, + GSList *hits) +@@ -109,7 +8,6 @@ hits_added_cb (NautilusSearchEngine *eng + for (gint hit_number = 0; hits != NULL; hits = hits->next, hit_number++) + { + g_print ("Hit %i: %s\n", hit_number, nautilus_search_hit_get_uri (hits->data)); +- total_hits += 1; + } + } + +@@ -118,10 +16,21 @@ finished_cb (NautilusSearchEngine + 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, ++ 0, ++ NULL, ++ NULL); ++ + g_main_loop_quit (user_data); + } + +@@ -130,24 +39,14 @@ main (int argc, + char *argv[]) + { + g_autoptr (GMainLoop) loop = NULL; +- g_autoptr (TrackerSparqlConnection) connection = NULL; + NautilusSearchEngine *engine; + g_autoptr (NautilusDirectory) directory = NULL; + g_autoptr (NautilusQuery) query = NULL; + g_autoptr (GFile) location = NULL; +- g_autoptr (GError) error = NULL; +- const gchar *indexed_tmpdir; +- +- indexed_tmpdir = g_getenv ("TRACKER_INDEXED_TMPDIR"); +- if (!indexed_tmpdir) +- { +- g_error ("This test must be inside the `tracker-sandbox` script " +- "to ensure a private Tracker indexer daemon is used."); +- } +- +- connection = tracker_sparql_connection_bus_new ("org.freedesktop.Tracker3.Miner.Files", NULL, NULL, &error); ++ TrackerSparqlConnection *connection; ++ g_autofree gchar *sparql_query = NULL; + +- g_assert_no_error (error); ++ connection = tracker_sparql_connection_get (NULL, NULL); + + loop = g_main_loop_new (NULL, FALSE); + +@@ -158,8 +57,6 @@ main (int argc, + */ + nautilus_global_preferences_init (); + +- create_test_data (connection, indexed_tmpdir); +- + engine = nautilus_search_engine_new (); + g_signal_connect (engine, "hits-added", + G_CALLBACK (hits_added_cb), NULL); +@@ -170,16 +67,40 @@ main (int argc, + nautilus_query_set_text (query, "target"); + nautilus_search_provider_set_query (NAUTILUS_SEARCH_PROVIDER (engine), query); + +- location = g_file_new_for_path (indexed_tmpdir); ++ location = g_file_new_for_path (g_get_tmp_dir ()); + directory = nautilus_directory_get (location); + nautilus_query_set_location (query, location); + ++ /* This sparql query with the update call create a virtual file ++ * in tracker, so it sees a file named "target_file" in /tmp. ++ * The file's MIME type is text/plain and the name tracker is ++ * using for search is "target". For the engine tracker to hit, ++ * we also need to set the last time the file was accessed and modified, ++ * which we set to 2001-01-01, at 00:00:01 (the date needs to be a full ++ * ISO 8601 date string) and tracker:available be set to true (in order ++ * for the file to be accessible). ++ */ ++ ++ sparql_query = g_strdup_printf ("INSERT DATA {\n<nautilus-test-tracker> "); ++ sparql_query = g_strconcat (sparql_query, "a nfo:FileDataObject ;", NULL); ++ sparql_query = g_strconcat (sparql_query, "\na nie:InformationElement ;", NULL); ++ sparql_query = g_strconcat (sparql_query, "\nnie:url 'file:///tmp/target_file';", NULL); ++ sparql_query = g_strconcat (sparql_query, "\nnie:mimeType 'text/plain';", NULL); ++ sparql_query = g_strconcat (sparql_query, "\nnfo:fileName 'target';", NULL); ++ sparql_query = g_strconcat (sparql_query, "\nnfo:fileLastModified '2001-01-01T00:00:01Z';", NULL); ++ sparql_query = g_strconcat (sparql_query, "\nnfo:fileLastAccessed '2001-01-01T00:00:01Z';", NULL); ++ sparql_query = g_strconcat (sparql_query, "\ntracker:available true", NULL); ++ sparql_query = g_strconcat (sparql_query, ".\n}\n", NULL); ++ ++ tracker_sparql_connection_update (connection, ++ sparql_query, ++ 0, ++ NULL, ++ NULL); ++ + nautilus_search_engine_start_by_target (NAUTILUS_SEARCH_PROVIDER (engine), + NAUTILUS_SEARCH_ENGINE_TRACKER_ENGINE); + + g_main_loop_run (loop); +- +- g_assert_cmpint (total_hits, ==, 1); +- + return 0; + } +Index: nautilus/test/automated/displayless/test-nautilus-search-engine.c +=================================================================== +--- nautilus.orig/test/automated/displayless/test-nautilus-search-engine.c ++++ nautilus/test/automated/displayless/test-nautilus-search-engine.c +@@ -1,7 +1,5 @@ + #include "test-utilities.h" + +-static guint total_hits = 0; +- + static void + hits_added_cb (NautilusSearchEngine *engine, + GSList *hits) +@@ -10,7 +8,6 @@ hits_added_cb (NautilusSearchEngine *eng + for (gint hit_number = 0; hits != NULL; hits = hits->next, hit_number++) + { + g_print ("Hit %i: %s\n", hit_number, nautilus_search_hit_get_uri (hits->data)); +- total_hits += 1; + } + } + +@@ -67,8 +64,5 @@ main (int argc, + nautilus_search_provider_start (NAUTILUS_SEARCH_PROVIDER (engine)); + + g_main_loop_run (loop); +- +- g_assert_cmpint (total_hits, ==, 3); +- + return 0; + } |