File 35.patch of Package gnome-documents
From 38fc56ab890c9272498ad3c5043147e537dc6575 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 17 Jan 2021 16:21:26 +0100
Subject: [PATCH 1/8] search: Don't inspect Tracker settings
In a sandboxed environment it's no possible (or shouldn't be!) to
inspect tracker settings. This is just used to include results from
custom folders in addition to Documents/Downloads/Desktop folders,
however these are not accessible within the sandbox anymore.
Drop this code, and stick to the given XDG folders, if support for
custom folders is desirable, should go through the
org.freedesktop.Tracker3.Miner.Files.Index interface.
---
src/search.js | 36 +-----------------------------------
1 file changed, 1 insertion(+), 35 deletions(-)
diff --git a/src/search.js b/src/search.js
index df5907c5..738ca336 100644
--- a/src/search.js
+++ b/src/search.js
@@ -279,9 +279,6 @@ var SearchSourceStock = {
LOCAL: 'local'
};
-const TRACKER_SCHEMA = 'org.freedesktop.Tracker.Miner.Files';
-const TRACKER_KEY_RECURSIVE_DIRECTORIES = 'index-recursive-directories';
-
const Source = class Source {
constructor(params) {
this.id = null;
@@ -310,35 +307,6 @@ const Source = class Source {
return [];
}
- _getTrackerLocations() {
- let settings = new Gio.Settings({ schema_id: TRACKER_SCHEMA });
- let locations = settings.get_strv(TRACKER_KEY_RECURSIVE_DIRECTORIES);
- let files = [];
-
- locations.forEach((location) => {
- // ignore special XDG placeholders, since we handle those internally
- if (location[0] == '&' || location[0] == '$')
- return;
-
- let trackerFile = Gio.file_new_for_commandline_arg(location);
-
- // also ignore XDG locations if they are present with their full path
- for (let idx = 0; idx < GLib.UserDirectory.N_DIRECTORIES; idx++) {
- let path = GLib.get_user_special_dir(idx);
- if (!path)
- continue;
-
- let file = Gio.file_new_for_path(path);
- if (trackerFile.equal(file))
- return;
- }
-
- files.push(trackerFile);
- });
-
- return files;
- }
-
_getBuiltinLocations() {
let files = [];
let xdgDirs = [GLib.UserDirectory.DIRECTORY_DESKTOP,
@@ -356,9 +324,7 @@ const Source = class Source {
_buildFilterLocal() {
let locations = this._getBuiltinLocations();
- locations = locations.concat(
- this._getTrackerLocations(),
- this._getGettingStartedLocations());
+ locations = locations.concat(this._getGettingStartedLocations());
let filters = [];
locations.forEach((location) => {
--
GitLab
From 613c214f98451a756b819c0da0b239c69253fecc Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 17 Jan 2021 16:26:05 +0100
Subject: [PATCH 2/8] application: Drop unused import
This library does not exist anymore in Tracker3, and is besides unused
here.
---
src/application.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/application.js b/src/application.js
index eadcd43f..86bb1eff 100644
--- a/src/application.js
+++ b/src/application.js
@@ -30,7 +30,6 @@ const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Tracker = imports.gi.Tracker;
-const TrackerControl = imports.gi.TrackerControl;
const ChangeMonitor = imports.changeMonitor;
const Format = imports.format;
--
GitLab
From f4a6d68538b2efead616d2e2d26e5c037878d1ad Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 17 Jan 2021 16:41:57 +0100
Subject: [PATCH 3/8] notification: Delete indexing notification
This relies on libtracker-control, which is no longer a thing. It
might make sense to track indexing state, but that goes together
with requests to index specific locations.
---
src/notifications.js | 159 -------------------------------------------
1 file changed, 159 deletions(-)
diff --git a/src/notifications.js b/src/notifications.js
index 4629b832..7d77f40b 100644
--- a/src/notifications.js
+++ b/src/notifications.js
@@ -23,7 +23,6 @@ const Gd = imports.gi.Gd;
const Gettext = imports.gettext;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
-const TrackerControl = imports.gi.TrackerControl;
const _ = imports.gettext.gettext;
const Application = imports.application;
@@ -155,161 +154,6 @@ var PrintNotification = class PrintNotification {
}
}
-const REMOTE_MINER_TIMEOUT = 10; // seconds
-const TRACKER_MINER_FILES_NAME = 'org.freedesktop.Tracker1.Miner.Files';
-
-const IndexingNotification = class IndexingNotification {
- constructor() {
- this._closed = false;
- this._timeoutId = 0;
-
- try {
- this._manager = TrackerControl.MinerManager.new_full(false);
- this._manager.connect('miner-progress', this._checkNotification.bind(this));
- } catch(e) {
- logError(e, 'Unable to create a TrackerMinerManager, indexing progress ' +
- 'notification won\'t work');
- return;
- }
-
- Application.application.connect('miners-changed', this._checkNotification.bind(this));
- Application.modeController.connect('window-mode-changed', this._checkNotification.bind(this));
- }
-
- _checkNotification() {
- if (Application.modeController.getWindowMode() == WindowMode.WindowMode.PREVIEW_EV) {
- this._destroy(false);
- return;
- }
-
- let isIndexingLocal = false;
- let isIndexingRemote = false;
-
- if (this._manager) {
- let running = this._manager.get_running();
- if (running.indexOf(TRACKER_MINER_FILES_NAME) != -1) {
- let [res, status, progress, time] = this._manager.get_status(TRACKER_MINER_FILES_NAME);
-
- if (progress < 1)
- isIndexingLocal = true;
- }
- }
-
- if (Application.application.minersRunning.length > 0)
- isIndexingRemote = true;
-
- if (isIndexingLocal) {
- this._display(_("Your documents are being indexed"),
- _("Some documents might not be available during this process"));
- } else if (isIndexingRemote) {
- this._removeTimeout();
- this._timeoutId = Mainloop.timeout_add_seconds(REMOTE_MINER_TIMEOUT, this._onTimeoutExpired.bind(this));
- } else {
- this._destroy(false);
- }
- }
-
- _onTimeoutExpired() {
- this._timeoutId = 0;
-
- let primary = null;
- let miner = null;
-
- if (Application.application.minersRunning.length == 1) {
- miner = Application.application.minersRunning[0];
- }
-
- if (miner && miner.DisplayName) {
- // Translators: %s refers to an online account provider, e.g.
- // "Google", or "Windows Live".
- primary = _("Fetching documents from %s").format(miner.DisplayName);
- } else {
- primary = _("Fetching documents from online accounts");
- }
-
- this._display(primary, null);
-
- return false;
- }
-
- _removeTimeout() {
- if (this._timeoutId != 0) {
- Mainloop.source_remove(this._timeoutId);
- this._timeoutId = 0;
- }
- }
-
- _buildWidget() {
- this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
- column_spacing: 12 });
-
- let spinner = new Gtk.Spinner({ width_request: 16,
- height_request: 16 });
- spinner.start();
- this.widget.add(spinner);
-
- let labels = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL,
- row_spacing: 3 });
- this.widget.add(labels);
-
- this._primaryLabel = new Gtk.Label({ halign: Gtk.Align.START });
- labels.add(this._primaryLabel);
-
- this._secondaryLabel = new Gtk.Label({ halign: Gtk.Align.START });
- this._secondaryLabel.get_style_context().add_class('dim-label');
- labels.add(this._secondaryLabel);
-
- let close = new Gtk.Button({ image: new Gtk.Image({ icon_name: 'window-close-symbolic',
- pixel_size: 16,
- margin_top: 2,
- margin_bottom: 2 }),
- valign: Gtk.Align.CENTER,
- focus_on_click: false,
- relief: Gtk.ReliefStyle.NONE });
- close.connect('clicked', () => {
- this._destroy(true);
- });
- this.widget.add(close);
-
- Application.notificationManager.addNotification(this);
- }
-
- _update(primaryText, secondaryText) {
- this._primaryLabel.label = primaryText;
- this._secondaryLabel.label = secondaryText;
-
- if (secondaryText) {
- this._primaryLabel.vexpand = false;
- this._secondaryLabel.show();
- } else {
- this._primaryLabel.vexpand = true;
- this._secondaryLabel.hide();
- }
- }
-
- _display(primaryText, secondaryText) {
- if (this._closed) {
- return;
- }
-
- if (!this.widget)
- this._buildWidget();
-
- this._update(primaryText, secondaryText);
- }
-
- _destroy(closed) {
- this._removeTimeout();
-
- if (this.widget) {
- this.widget.destroy();
- this.widget = null;
- }
-
- this._closed = closed;
- }
-}
-
var NotificationManager = GObject.registerClass(class NotificationManager extends Gtk.Revealer {
_init() {
super._init({ halign: Gtk.Align.CENTER,
@@ -323,9 +167,6 @@ var NotificationManager = GObject.registerClass(class NotificationManager extend
row_spacing: 6 });
frame.add(this._grid);
-
- // add indexing monitor notification
- this._indexingNotification = new IndexingNotification();
}
addNotification(notification) {
--
GitLab
From 442616018c83c620619e7ea1b462b08cb664f930 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 17 Jan 2021 16:54:46 +0100
Subject: [PATCH 4/8] application: Use
org.freedesktop.Tracker3.Miner.Files.Control for index control
This new request allows prioritising graphs on index folders, so request
the tracker:Documents graph on the Documents folder here.
---
src/application.js | 44 +++++++++++++++++++++-----------------------
1 file changed, 21 insertions(+), 23 deletions(-)
diff --git a/src/application.js b/src/application.js
index 86bb1eff..d1a1d454 100644
--- a/src/application.js
+++ b/src/application.js
@@ -71,20 +71,21 @@ var trackerCollectionsController = null;
var trackerDocumentsController = null;
var trackerSearchController = null;
-const TrackerExtractPriorityIface = '<node> \
-<interface name="org.freedesktop.Tracker1.Extract.Priority"> \
- <method name="ClearRdfTypes" /> \
- <method name="SetRdfTypes"> \
- <arg name="rdf_types" type="as" /> \
+const TrackerMinerFilesIndexIface = '<node> \
+<interface name="org.freedesktop.Tracker3.Miner.Files.Index"> \
+ <method name="IndexLocation"> \
+ <arg name="file_uri" type="s" /> \
+ <arg name="graphs" type="as" /> \
+ <arg name="flags" type="as" /> \
</method> \
</interface> \
</node>';
-var TrackerExtractPriorityProxy = Gio.DBusProxy.makeProxyWrapper(TrackerExtractPriorityIface);
-function TrackerExtractPriority() {
- return new TrackerExtractPriorityProxy(Gio.DBus.session,
- 'org.freedesktop.Tracker1.Miner.Extract',
- '/org/freedesktop/Tracker1/Extract/Priority');
+var TrackerMinerFilesControlProxy = Gio.DBusProxy.makeProxyWrapper(TrackerMinerFilesIndexIface);
+function TrackerMinerFilesControl() {
+ return new TrackerMinerFilesControlProxy(Gio.DBus.session,
+ 'org.freedesktop.Tracker3.Miner.Files.Control',
+ '/org/freedesktop/Tracker3/Miner/Files/Index');
}
const MINER_REFRESH_TIMEOUT = 60; /* seconds */
@@ -99,6 +100,7 @@ var Application = GObject.registerClass({
this._activationTimestamp = Gdk.CURRENT_TIME;
this._extractPriority = null;
this._searchProvider = null;
+ this._minerControl = null;
let appid;
GLib.set_application_name(_("Documents"));
@@ -115,8 +117,6 @@ var Application = GObject.registerClass({
}
_initGettingStarted() {
- let manager = TrackerControl.MinerManager.new_full(false);
-
let languages = GLib.get_language_names();
let files = languages.map(
function(language) {
@@ -138,7 +138,7 @@ var Application = GObject.registerClass({
this.gettingStartedLocation = files[i].get_parent();
try {
- manager.index_file(files[i], null);
+ this._minerControl.IndexLocationRemote(files[i].get_path(), ['tracker:Documents'], []);
} catch (e) {
logError(e, 'Error indexing the getting started PDF');
}
@@ -388,19 +388,20 @@ var Application = GObject.registerClass({
if (this._mainWindow)
return;
+ try {
+ this._minerControl = TrackerMinerFilesControl();
+ this._minerControl.IndexLocationRemote(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOCUMENTS),
+ ['tracker:Documents'], []);
+ } catch (e) {
+ logError(e, 'Unable to connect to the tracker extractor');
+ }
+
this._initGettingStarted();
notificationManager = new Notifications.NotificationManager();
this._mainWindow = new MainWindow.MainWindow(this);
this._mainWindow.connect('destroy', this._onWindowDestroy.bind(this));
- try {
- this._extractPriority = TrackerExtractPriority();
- this._extractPriority.SetRdfTypesRemote(['nfo:Document']);
- } catch (e) {
- logError(e, 'Unable to connect to the tracker extractor');
- }
-
// start miners
this._startMiners();
}
@@ -475,9 +476,6 @@ var Application = GObject.registerClass({
// stop miners
this._stopMiners();
-
- if (this._extractPriority)
- this._extractPriority.ClearRdfTypesRemote();
}
_onWindowDestroy(window) {
--
GitLab
From e4b48b1227b7cdff28abfc77dfafe6a83e286aa9 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 17 Jan 2021 17:02:04 +0100
Subject: [PATCH 5/8] changeMonitor: Rewrite to use TrackerNotifier
The GraphUpdated DBus signal became superseded by TrackerNotifier
in 2.x, and completely removed on 3.x. Use TrackerNotifier here
for event tracking.
---
src/changeMonitor.js | 182 +++++++++----------------------------------
1 file changed, 36 insertions(+), 146 deletions(-)
diff --git a/src/changeMonitor.js b/src/changeMonitor.js
index 5308b042..0172cd65 100644
--- a/src/changeMonitor.js
+++ b/src/changeMonitor.js
@@ -20,167 +20,57 @@
*/
const Gio = imports.gi.Gio;
+const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
+const Tracker = imports.gi.Tracker;
const Application = imports.application;
-const TrackerResourcesServiceIface = '<node> \
-<interface name="org.freedesktop.Tracker1.Resources"> \
- <signal name="GraphUpdated"> \
- <arg name="className" type="s" /> \
- <arg name="deleteEvents" type="a(iiii)" /> \
- <arg name="insertEvents" type="a(iiii)" /> \
- </signal> \
-</interface> \
-</node>';
-
-var TrackerResourcesServiceProxy = Gio.DBusProxy.makeProxyWrapper(TrackerResourcesServiceIface);
-function TrackerResourcesService() {
- return new TrackerResourcesServiceProxy(Gio.DBus.session,
- 'org.freedesktop.Tracker1',
- '/org/freedesktop/Tracker1/Resources');
-}
-
var ChangeEventType = {
CHANGED: 0,
CREATED: 1,
DELETED: 2
};
-const _RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
-
-const ChangeEvent = class ChangeEvent {
- constructor(urnId, predicateId, isDelete) {
- this.urnId = urnId;
- this.predicateId = predicateId;
-
- if (isDelete)
- this.type = ChangeEventType.DELETED;
- else
- this.type = ChangeEventType.CREATED;
- }
+const ChangeEvent = new Lang.Class({
+ Name: 'ChangeEvent',
- setResolvedValues(urn, predicate) {
+ _init: function(type, urn) {
this.urn = urn;
- this.predicate = predicate;
- if (predicate != _RDF_TYPE)
+ if (type == Tracker.NotifierEventType.CREATE)
+ this.type = ChangeEventType.CREATED;
+ else if (type == Tracker.NotifierEventType.DELETE)
+ this.type = ChangeEventType.DELETED;
+ else if (type == Tracker.NotifierEventType.UPDATE)
this.type = ChangeEventType.CHANGED;
}
-
- merge(event) {
- // deletions or creations override the current type
- if (event.type == ChangeEventType.DELETED ||
- event.type == ChangeEventType.CREATED) {
- this.type = event.type;
- }
- }
-}
-
-const CHANGE_MONITOR_TIMEOUT = 500; // msecs
-const CHANGE_MONITOR_MAX_ITEMS = 500; // items
-
-var TrackerChangeMonitor = class TrackerChangeMonitor {
- constructor() {
- this._pendingChanges = {};
- this._unresolvedIds = {};
-
- this._pendingEvents = [];
- this._pendingEventsId = 0;
-
- this._resourceService = new TrackerResourcesService();
- this._resourceService.connectSignal('GraphUpdated', this._onGraphUpdated.bind(this));
- }
-
- _onGraphUpdated(proxy, senderName, [className, deleteEvents, insertEvents]) {
- deleteEvents.forEach((event) => {
- this._addPendingEvent(event, true);
- });
-
- insertEvents.forEach((event) => {
- this._addPendingEvent(event, false);
- });
- }
-
- _addPendingEvent(event, isDelete) {
- if (this._pendingEventsId != 0)
- Mainloop.source_remove(this._pendingEventsId);
-
- this._unresolvedIds[event[1]] = event[1];
- this._unresolvedIds[event[2]] = event[2];
- this._pendingEvents.push(new ChangeEvent(event[1], event[2], isDelete));
-
- if (this._pendingEvents.length >= CHANGE_MONITOR_MAX_ITEMS)
- this._processEvents();
- else
- this._pendingEventsId =
- Mainloop.timeout_add(CHANGE_MONITOR_TIMEOUT, this._processEvents.bind(this));
- }
-
- _processEvents() {
- let events = this._pendingEvents;
- let idTable = this._unresolvedIds;
-
- this._pendingEventsId = 0;
- this._pendingEvents = [];
- this._unresolvedIds = {};
-
- let sparql = 'SELECT';
- Object.keys(idTable).forEach((unresolvedId) => {
- sparql += (' tracker:uri(%d)').format(unresolvedId);
- });
- sparql += ' {}';
-
- // resolve all the unresolved IDs we got so far
- Application.connectionQueue.add(sparql, null, (object, res) => {
- let cursor = object.query_finish(res);
-
- cursor.next_async(null, (object, res) => {
- let valid = false;
- try {
- valid = cursor.next_finish(res);
- } catch(e) {
- logError(e, 'Unable to resolve item URNs for graph changes');
- }
-
- if (valid) {
- let idx = 0;
- Object.keys(idTable).forEach((unresolvedId) => {
- idTable[unresolvedId] = cursor.get_string(idx)[0];
- idx++;
- });
-
- this._sendEvents(events, idTable);
- }
-
- cursor.close();
- });
- });
-
- return false;
- }
-
- _addEvent(event) {
- let urn = event.urn;
- let oldEvent = this._pendingChanges[urn];
-
- if (oldEvent != null) {
- oldEvent.merge(event);
- this._pendingChanges[urn] = oldEvent;
- } else {
- this._pendingChanges[urn] = event;
- }
- }
-
- _sendEvents(events, idTable) {
- events.forEach((event) => {
- event.setResolvedValues(idTable[event.urnId], idTable[event.predicateId]);
- this._addEvent(event);
- });
-
- this.emit('changes-pending', this._pendingChanges);
- this._pendingChanges = {};
+});
+
+var TrackerChangeMonitor = new Lang.Class({
+ Name: 'TrackerChangeMonitor',
+
+ _init: function() {
+ this._notifier = Application.connection.create_notifier();
+ this._notifier.signal_subscribe(Gio.DBus.session,
+ 'org.freedesktop.Tracker3.Miner.Files',
+ null,
+ 'http://tracker.api.gnome.org/ontology/v3/tracker#Documents');
+ this._notifier.connect('events', Lang.bind(this, this._onNotifierEvents));
+ },
+
+ _onNotifierEvents: function(notifier, service, graph, events) {
+ let pendingChanges = {};
+
+ events.forEach(Lang.bind(this,
+ function(event) {
+ let urn = event.get_urn();
+ let changeEvent = new ChangeEvent(event.get_event_type(), urn);
+ pendingChanges[urn] = changeEvent;
+ }));
+
+ this.emit('changes-pending', pendingChanges);
}
-}
+});
Signals.addSignalMethods(TrackerChangeMonitor.prototype);
--
GitLab
From 3296833675ff48f7c578ac766aeac346e7911d68 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 17 Jan 2021 17:03:14 +0100
Subject: [PATCH 6/8] Port queries to Tracker3
Use new Tracker.SparqlConnection constructors, and rework the queries
so that it:
1) Observes the data layout in use in Tracker Miners 3.x
2) Uses a private database for the data considered writeable:
- collections
- titles
3) Queries g-o-m miners specifically, alongside local data
All queries happen on the local connection, optionally including data
from tracker-miner-fs and g-o-m miners via SERVICE{} clauses, this is
just not the case for collection queries, since collections are stored
in the private documents database.
---
meson.build | 4 +-
src/application.js | 8 ++-
src/documents.js | 2 +-
src/main.js | 3 +-
src/query.js | 136 ++++++++++++++++++++++++++++++++-------
src/search.js | 4 +-
src/trackerController.js | 4 +-
src/trackerUtils.js | 2 +-
8 files changed, 127 insertions(+), 36 deletions(-)
diff --git a/meson.build b/meson.build
index 7a6d1ad0..1f63b310 100644
--- a/meson.build
+++ b/meson.build
@@ -54,7 +54,6 @@ endforeach
add_project_arguments('-DHAVE_CONFIG_H', language: 'c')
evince_req_version = '>= 3.13.3'
-tracker_req_version = '>= 0.17.3'
gjs_dep = dependency('gjs-1.0', version: '>= 1.48.0')
gjs_console = gjs_dep.get_pkgconfig_variable('gjs_console')
@@ -68,8 +67,7 @@ documents_deps = [
dependency('gobject-introspection-1.0', version: '>= 1.31.6'),
dependency('gtk+-3.0', version: '>= 3.22.15'),
dependency('libsoup-2.4', version: '>= 2.41.3'),
- dependency('tracker-control-2.0', version: tracker_req_version),
- dependency('tracker-sparql-2.0', version: tracker_req_version),
+ dependency('tracker-sparql-3.0'),
dependency('webkit2gtk-4.0', version: '>= 2.6.0'),
cc.find_library('m')
]
diff --git a/src/application.js b/src/application.js
index d1a1d454..73cd2da1 100644
--- a/src/application.js
+++ b/src/application.js
@@ -337,9 +337,13 @@ var Application = GObject.registerClass({
// connect to tracker
try {
- connection = Tracker.SparqlConnection.get(null);
+ let cacheDir = GLib.build_filenamev([GLib.get_user_cache_dir(), 'org.gnome.Documents', 'db']);
+ let nepomuk = Tracker.sparql_get_ontology_nepomuk();
+ connection = Tracker.SparqlConnection.new(Tracker.SparqlConnectionFlags.NONE,
+ Gio.File.new_for_path(cacheDir),
+ nepomuk, null);
} catch (e) {
- logError(e, 'Unable to connect to the tracker database');
+ logError(e, 'Unable to set up the tracker database');
return;
}
diff --git a/src/documents.js b/src/documents.js
index 752b5714..d2ad55f9 100644
--- a/src/documents.js
+++ b/src/documents.js
@@ -776,7 +776,7 @@ const DocCommon = class DocCommon {
let retval = '';
if (this.collection)
- retval = '{ ?urn nie:isPartOf <' + this.id + '> }';
+ retval = '{ ?urn nie:isLogicalPartOf <' + this.id + '> }';
return retval;
}
diff --git a/src/main.js b/src/main.js
index b4afb261..9094f889 100644
--- a/src/main.js
+++ b/src/main.js
@@ -33,8 +33,7 @@ pkg.require({ 'EvinceDocument': '3.0',
'Goa': '1.0',
'Gtk': '3.0',
'GObject': '2.0',
- 'Tracker': '2.0',
- 'TrackerControl': '2.0',
+ 'Tracker': '3.0',
'WebKit2': '4.0' });
const Application = imports.application;
diff --git a/src/query.js b/src/query.js
index 6ab1a462..4f5142ea 100644
--- a/src/query.js
+++ b/src/query.js
@@ -90,9 +90,6 @@ var QueryBuilder = class QueryBuilder {
part += this._buildOptional();
if ((flags & QueryFlags.UNFILTERED) == 0) {
- if (global)
- part += this._context.documentManager.getWhere();
-
part += this._buildFilterString(currentType, flags, ftsQuery.length > 0);
}
@@ -141,6 +138,18 @@ var QueryBuilder = class QueryBuilder {
}
_buildQueryInternal(global, flags, offsetController, sortBy) {
+ let selectClauses =
+ ' (COALESCE (nie:url(?urn), nie:isStoredAs(?urn)) AS ?uri) ' +
+ ' (COALESCE (nfo:fileName(?urn), tracker:string-from-filename(nie:isStoredAs(?urn))) AS ?filename) ' +
+ ' (nie:mimeType(?urn) AS ?mimetype) ' +
+ ' (nie:title(?urn) AS ?title) ' +
+ ' (tracker:coalesce(nco:fullname(?creator), nco:fullname(?publisher), \'\') AS ?author) ' +
+ ' (nie:contentLastModified(?urn) AS ?mtime) ' +
+ ' (nao:identifier(?urn) AS ?identifier) ' +
+ ' (rdf:type(?urn) AS ?type) ' +
+ ' (nie:dataSource(?urn) AS ?datasource ) ' +
+ ' (( EXISTS { ?urn nco:contributor ?contributor FILTER ( ?contributor != ?creator ) } ) AS ?shared) ' +
+ ' (nie:contentCreated(?urn) AS ?created) ';
let whereSparql = this._buildWhere(global, flags);
let tailSparql = '';
@@ -175,19 +184,61 @@ var QueryBuilder = class QueryBuilder {
}
let sparql =
- 'SELECT DISTINCT ?urn ' + // urn
- 'nie:url(?urn) ' + // uri
- 'nfo:fileName(?urn) AS ?filename ' + // filename
- 'nie:mimeType(?urn)' + // mimetype
- 'nie:title(?urn) AS ?title ' + // title
- 'tracker:coalesce(nco:fullname(?creator), nco:fullname(?publisher), \'\') AS ?author ' + // author
- 'tracker:coalesce(nfo:fileLastModified(?urn), nie:contentLastModified(?urn)) AS ?mtime ' + // mtime
- 'nao:identifier(?urn) ' + // identifier
- 'rdf:type(?urn) ' + // type
- 'nie:dataSource(?urn) ' + // resource URN
- '( EXISTS { ?urn nco:contributor ?contributor FILTER ( ?contributor != ?creator ) } ) ' + // shared
- 'tracker:coalesce(nfo:fileCreated(?urn), nie:contentCreated(?urn)) ' + // date created
- whereSparql + tailSparql;
+ 'SELECT ?urn ' +
+ ' ?uri ' +
+ ' ?filename ' +
+ ' ?mimetype ' +
+ ' COALESCE (?localTitle, ?title, ?filename) AS ?t ' +
+ ' ?author ' +
+ ' ?mtime ' +
+ ' ?identifier ' +
+ ' ?type ' +
+ ' ?datasource ' +
+ ' ?shared ' +
+ ' ?created ' +
+ 'WHERE { ';
+
+ // Collections queries are local
+ if (flags & QueryFlags.COLLECTIONS) {
+ sparql +=
+ 'SELECT DISTINCT ?urn ' +
+ selectClauses +
+ whereSparql;
+ } else {
+ let services = ['org.freedesktop.Tracker3.Miner.Files'];
+ let serviceQueries = [];
+
+ if (this._context.sourceManager.hasProviderType('google'))
+ services.push('org.gnome.OnlineMiners.GData');
+ if (this._context.sourceManager.hasProviderType('owncloud'))
+ services.push('org.gnome.OnlineMiners.Owncloud');
+ if (this._context.sourceManager.hasProviderType('windows_live'))
+ services.push('org.gnome.OnlineMiners.Zpj');
+
+ services.forEach((service) => {
+ let serviceQuery =
+ '{' +
+ ' SERVICE SILENT <dbus:' + service + '> {' +
+ ' GRAPH tracker:Documents { ' +
+ ' SELECT DISTINCT ?urn ' +
+ selectClauses +
+ whereSparql +
+ ' }' +
+ ' }' +
+ '}';
+
+ serviceQueries.push(serviceQuery);
+ });
+
+ sparql += serviceQueries.join(' UNION ');
+ sparql += 'OPTIONAL { ?urn nie:title ?localTitle } . ';
+
+ if (global && (flags & QueryFlags.UNFILTERED) == 0)
+ sparql += this._context.documentManager.getWhere();
+ }
+
+ sparql += '}';
+ sparql += tailSparql;
return sparql;
}
@@ -204,8 +255,39 @@ var QueryBuilder = class QueryBuilder {
}
buildCountQuery(flags) {
- let sparql = 'SELECT DISTINCT COUNT(?urn) ' +
- this._buildWhere(true, flags);
+ let sparql;
+ if (flags & QueryFlags.COLLECTIONS) {
+ sparql = 'SELECT DISTINCT COUNT(?urn) AS ?c ' +
+ this._buildWhere(true, flags);
+ } else {
+ let services = ['org.freedesktop.Tracker3.Miner.Files'];
+ let countQueries = [];
+
+ if (this._context.sourceManager.hasProviderType('google'))
+ services.push('org.gnome.OnlineMiners.GData');
+ if (this._context.sourceManager.hasProviderType('owncloud'))
+ services.push('org.gnome.OnlineMiners.Owncloud');
+ if (this._context.sourceManager.hasProviderType('windows_live'))
+ services.push('org.gnome.OnlineMiners.Zpj');
+
+ sparql = 'SELECT SUM(?c) {';
+
+ services.forEach((service) => {
+ let countQuery =
+ '{ ' +
+ ' SERVICE SILENT <dbus:' + service + '> { ' +
+ ' GRAPH tracker:Documents { ' +
+ ' SELECT DISTINCT COUNT(?urn) AS ?c ' +
+ this._buildWhere(true, flags) +
+ ' }' +
+ ' }' +
+ '}';
+ countQueries.push(countQuery);
+ });
+
+ sparql += countQueries.join(' UNION ');
+ sparql += '}';
+ }
return this._createQuery(sparql);
}
@@ -215,8 +297,8 @@ var QueryBuilder = class QueryBuilder {
let sparql =
('SELECT ' +
'?urn ' +
- 'tracker:coalesce(nfo:fileLastModified(?urn), nie:contentLastModified(?urn)) AS ?mtime ' +
- 'WHERE { ?urn nie:isPartOf ?collUrn } ' +
+ 'nie:contentLastModified(?urn) AS ?mtime ' +
+ 'WHERE { ?urn nie:isLogicalPartOf ?collUrn } ' +
'ORDER BY DESC (?mtime)' +
'LIMIT 4').replace(/\?collUrn/, '<' + resource + '>');
@@ -228,7 +310,7 @@ var QueryBuilder = class QueryBuilder {
let sparql =
('SELECT ' +
'?urn ' +
- 'WHERE { ?urn a nfo:DataContainer . ?docUrn nie:isPartOf ?urn }'
+ 'WHERE { ?urn a nfo:DataContainer . ?docUrn nie:isLogicalPartOf ?urn }'
).replace(/\?docUrn/, '<' + resource + '>');
return this._createQuery(sparql);
@@ -236,15 +318,21 @@ var QueryBuilder = class QueryBuilder {
// adds or removes the given item to the given collection
buildSetCollectionQuery(itemUrn, collectionUrn, setting) {
- let sparql = ('%s { <%s> nie:isPartOf <%s> }'
- ).format((setting ? 'INSERT' : 'DELETE'), itemUrn, collectionUrn);
+ let sparql;
+ if (setting) {
+ sparql = ('INSERT DATA { <%s> a nie:InformationElement; nie:isLogicalPartOf <%s> }'
+ ).format(itemUrn, collectionUrn);
+ } else {
+ sparql = ('DELETE DATA { <%s> nie:isLogicalPartOf <%s> }'
+ ).format(itemUrn, collectionUrn);
+ }
return this._createQuery(sparql);
}
// bumps the mtime to current time for the given resource
buildUpdateMtimeQuery(resource) {
let time = GdPrivate.iso8601_from_timestamp(GLib.get_real_time() / GLib.USEC_PER_SEC);
- let sparql = ('INSERT OR REPLACE { <%s> nie:contentLastModified \"%s\" }'
+ let sparql = ('INSERT OR REPLACE { <%s> a nie:InformationElement; nie:contentLastModified \"%s\" }'
).format(resource, time);
return this._createQuery(sparql);
diff --git a/src/search.js b/src/search.js
index 738ca336..557c7a0a 100644
--- a/src/search.js
+++ b/src/search.js
@@ -19,6 +19,8 @@
*
*/
+imports.gi.versions.Tracker = '3.0';
+
const Application = imports.application;
const Documents = imports.documents;
const Manager = imports.manager;
@@ -328,7 +330,7 @@ const Source = class Source {
let filters = [];
locations.forEach((location) => {
- filters.push('(fn:contains (nie:url(?urn), "%s"))'.format(location.get_uri()));
+ filters.push('(fn:contains (nie:isStoredAs(?urn), "%s"))'.format(location.get_uri()));
});
filters.push('(fn:starts-with (nao:identifier(?urn), "gd:collection:local:"))');
diff --git a/src/trackerController.js b/src/trackerController.js
index 23e1c137..169ddcb5 100644
--- a/src/trackerController.js
+++ b/src/trackerController.js
@@ -86,10 +86,10 @@ var TrackerConnectionQueue = class TrackerConnectionQueue {
Application.connection.query_async(params.query, params.cancellable,
this._queueCollector.bind(this, params));
else if (params.queryType == QueryType.UPDATE)
- Application.connection.update_async(params.query, GLib.PRIORITY_DEFAULT, params.cancellable,
+ Application.connection.update_async(params.query, params.cancellable,
this._queueCollector.bind(this, params));
else if (params.queryType == QueryType.UPDATE_BLANK)
- Application.connection.update_blank_async(params.query, GLib.PRIORITY_DEFAULT, params.cancellable,
+ Application.connection.update_blank_async(params.query, params.cancellable,
this._queueCollector.bind(this, params));
}
diff --git a/src/trackerUtils.js b/src/trackerUtils.js
index 007568c1..1ed63f2e 100644
--- a/src/trackerUtils.js
+++ b/src/trackerUtils.js
@@ -22,7 +22,7 @@
const Application = imports.application;
function setEditedName(newTitle, docId, callback) {
- let sparql = ('INSERT OR REPLACE { <%s> nie:title \"%s\" }'.format(docId, newTitle));
+ let sparql = ('INSERT OR REPLACE { <%s> a nie:InformationElement ; nie:title \"%s\" }'.format(docId, newTitle));
Application.connectionQueue.update(sparql, null,
function(object, res) {
--
GitLab
From f2721143344fbb0f1836a70a0efbaa7c246ae8dc Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 22 Jan 2021 18:00:55 +0100
Subject: [PATCH 7/8] flatpak: Update reference to use Tracker3
Use the Tracker3 policy to specify the accessed graph, drop
the builtin tracker copy, and change tracker-miners build parameters
so we can run our own internal copy.
In code, first check whether there is access to the stock miner,
then attempt this internal miner. This is a fallback for systems that
do not have tracker3 installed.
---
flatpak/org.gnome.Documents.json | 35 +++++++++-----------------------
src/application.js | 11 ++++++++++
src/query.js | 4 ++--
3 files changed, 23 insertions(+), 27 deletions(-)
diff --git a/flatpak/org.gnome.Documents.json b/flatpak/org.gnome.Documents.json
index 5c2e3116..325d1e73 100644
--- a/flatpak/org.gnome.Documents.json
+++ b/flatpak/org.gnome.Documents.json
@@ -17,9 +17,8 @@
/* Needs to talk to the network: */
"--share=network",
"--talk-name=org.gnome.Mutter.DisplayConfig",
- /* Tracker access */
- "--talk-name=org.freedesktop.Tracker1",
- "--talk-name=org.freedesktop.Tracker1.Miner.Extract",
+ /* Tracker3 graph access */
+ "--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Documents",
/* Needed for dconf to work */
"--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro",
"--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
@@ -157,35 +156,21 @@
}
]
},
- {
- "name": "tracker",
- "buildsystem": "meson",
- "cleanup": [ "/bin", "/etc", "/lib/systemd", "/libexec", "/share/dbus-1/services" ],
- "config-opts": [ "--default-library=shared", "-Dbash-completion=no", "-Ddocs=false" ],
- "sources": [
- {
- "type": "git",
- "url": "https://gitlab.gnome.org/GNOME/tracker.git",
- "branch": "tracker-2.3"
- }
- ]
- },
{
"name": "tracker-miners",
"buildsystem": "meson",
- "cleanup": [ "/bin", "/etc", "/lib/systemd", "/libexec" ],
- "config-opts": [ "--default-library=shared",
- "-Dminer_apps=false",
+ "config-opts": [ "-Ddefault_index_single_directories=&DOWNLOADS",
+ "-Ddefault_index_recursive_directories=&DOCUMENTS",
+ "-Ddomain_prefix=org.gnome.Documents",
+ "-Dman=false",
+ "-Dminer_fs=true",
+ "-Dminer_fs_cache_location=$XDG_CACHE_HOME/org.gnome.Documents/miner/files",
"-Dminer_rss=false",
- "-Dextract=false",
- "-Dgeneric_media_extractor=none",
- "-Dwriteback=false",
- "-Dminer_fs=true" ],
+ "-Dsystemd_user_services=false" ],
"sources": [
{
"type": "git",
- "url": "https://gitlab.gnome.org/GNOME/tracker-miners.git",
- "branch": "tracker-miners-2.3"
+ "url": "https://gitlab.gnome.org/GNOME/tracker-miners.git"
}
]
},
diff --git a/src/application.js b/src/application.js
index 73cd2da1..1fa75b79 100644
--- a/src/application.js
+++ b/src/application.js
@@ -70,6 +70,7 @@ var sourceManager = null;
var trackerCollectionsController = null;
var trackerDocumentsController = null;
var trackerSearchController = null;
+var trackerMinerService = null;
const TrackerMinerFilesIndexIface = '<node> \
<interface name="org.freedesktop.Tracker3.Miner.Files.Index"> \
@@ -347,6 +348,16 @@ var Application = GObject.registerClass({
return;
}
+ // test access to global tracker daemon
+ try {
+ let busConn = Tracker.SparqlConnection.bus_new('org.freedesktop.Tracker3.Miner.Files',
+ null, Gio.DBus.session);
+ trackerMinerService = 'org.freedesktop.Tracker3.Miner.Files';
+ } catch (e) {
+ // if the daemon is not available, run our own copy (for the sandboxed case)
+ trackerMinerService = this.get_application_id() + '.Tracker3.Miner.Files';
+ }
+
try {
goaClient = Goa.Client.new_sync(null);
} catch (e) {
diff --git a/src/query.js b/src/query.js
index 4f5142ea..ef90754e 100644
--- a/src/query.js
+++ b/src/query.js
@@ -205,7 +205,7 @@ var QueryBuilder = class QueryBuilder {
selectClauses +
whereSparql;
} else {
- let services = ['org.freedesktop.Tracker3.Miner.Files'];
+ let services = [this._context.trackerMinerService];
let serviceQueries = [];
if (this._context.sourceManager.hasProviderType('google'))
@@ -260,7 +260,7 @@ var QueryBuilder = class QueryBuilder {
sparql = 'SELECT DISTINCT COUNT(?urn) AS ?c ' +
this._buildWhere(true, flags);
} else {
- let services = ['org.freedesktop.Tracker3.Miner.Files'];
+ let services = [this._context.trackerMinerService];
let countQueries = [];
if (this._context.sourceManager.hasProviderType('google'))
--
GitLab
From 912235ec6243eb34c27517f119e88ce8eb495a55 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 26 Jan 2021 16:48:29 +0100
Subject: [PATCH 8/8] flatpak: Update flatpak reference
Drop gspell, and update to meson build in evince. Just needed
for CI to pass, and build flatpaks.
---
.gitlab-ci.yml | 1 -
flatpak/org.gnome.Documents.json | 23 ++++++-----------------
2 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e2d7ce78..774a9834 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -4,7 +4,6 @@ variables:
GIT_SUBMODULE_STRATEGY: normal
flatpak-documents:
- image: 'registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.32'
variables:
BUNDLE: "gnome-documents-dev.flatpak"
MANIFEST_PATH: "flatpak/org.gnome.Documents.json"
diff --git a/flatpak/org.gnome.Documents.json b/flatpak/org.gnome.Documents.json
index 325d1e73..309cf6cb 100644
--- a/flatpak/org.gnome.Documents.json
+++ b/flatpak/org.gnome.Documents.json
@@ -1,7 +1,7 @@
{
"app-id": "org.gnome.Documents",
"runtime": "org.gnome.Platform",
- "runtime-version": "3.32",
+ "runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "gnome-documents",
"tags": [ "nightly" ],
@@ -130,25 +130,14 @@
}
]
},
- {
- "name": "gspell",
- "cleanup": [
- "/bin"
- ],
- "sources": [
- {
- "type": "git",
- "url": "https://gitlab.gnome.org/GNOME/gspell.git"
- }
- ]
- },
{
"name": "evince",
+ "buildsystem": "meson",
"cleanup": [ "/share/GConf", "/share/help" ],
- "config-opts": [ "--disable-nautilus", "--disable-viewer",
- "--disable-previewer", "--disable-dbus",
- "--disable-browser-plugin", "--enable-introspection",
- "--disable-comics" ],
+ "config-opts": [ "-Dnautilus=false", "-Dviewer=false",
+ "-Dpreviewer=false", "-Ddbus=false",
+ "-Dbrowser-plugin=false", "-Dintrospection=true",
+ "-Dcomics=disabled" ],
"sources": [
{
"type": "git",
--
GitLab