diff --git a/desktop/gnome/apps/gitg/actions.py b/desktop/gnome/apps/gitg/actions.py new file mode 100644 index 0000000000..cc6214d303 --- /dev/null +++ b/desktop/gnome/apps/gitg/actions.py @@ -0,0 +1,18 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 2. +# See the file http://www.gnu.org/copyleft/gpl.txt. + +from pisi.actionsapi import mesontools, pisitools + +def setup(): + mesontools.configure() + +def build(): + mesontools.build() + +def install(): + mesontools.install() + + pisitools.dodoc("AUTHORS", "ChangeLog", "README*", "NEWS") diff --git a/desktop/gnome/apps/gitg/files/vala.patch b/desktop/gnome/apps/gitg/files/vala.patch new file mode 100644 index 0000000000..15cefa4944 --- /dev/null +++ b/desktop/gnome/apps/gitg/files/vala.patch @@ -0,0 +1,29 @@ +--- libgitg/gitg-diff-view-file-selectable.vala 2019-07-25 13:13:01.000000000 +0200 ++++ libgitg/gitg-diff-view-file-selectable.vala 2020-09-06 14:36:26.374965220 +0200 +@@ -54,7 +54,7 @@ + + buffer.get_start_iter(out iter); + +- while (buffer.forward_iter_to_source_mark(ref iter, d_selection_category)) ++ while (buffer.forward_iter_to_source_mark(iter, d_selection_category)) + { + ret += iter.get_line(); + } +@@ -321,7 +321,7 @@ + + var buffer = source_view.buffer as Gtk.SourceBuffer; + +- if (!buffer.forward_iter_to_source_mark(ref iter, "header")) ++ if (!buffer.forward_iter_to_source_mark(iter, "header")) + { + iter.forward_to_end(); + } +@@ -493,7 +493,7 @@ + } + else + { +- something_selected = (buffer as Gtk.SourceBuffer).forward_iter_to_source_mark(ref iter, d_selection_category); ++ something_selected = (buffer as Gtk.SourceBuffer).forward_iter_to_source_mark(iter, d_selection_category); + } + + if (something_selected != has_selection) diff --git a/desktop/gnome/apps/gitg/pspec.xml b/desktop/gnome/apps/gitg/pspec.xml new file mode 100644 index 0000000000..34bf177d75 --- /dev/null +++ b/desktop/gnome/apps/gitg/pspec.xml @@ -0,0 +1,81 @@ + + + + + gitg + https://wiki.gnome.org/Apps/Gitg + + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + GPLv2 + gitg + app:gui + GTK+ graphical interface for the git revision control system + GTK+ graphical interface for the git revision control system + mirrors://gnome/gitg/3.32/gitg-3.32.1.tar.xz + + gettext-devel + python-pygobject3-devel + python3-pygobject3-devel + glib2-devel + gobject-introspection-devel + gsettings-desktop-schemas-devel + gtk3-devel + gtksourceview3-devel + gtkspell3-devel + json-glib-devel + meson + libdazzle-devel + libgee-devel + libgit2-devel + libgit2-glib-devel + libpeas-devel + libsecret-devel + libsoup-devel + python3-devel + vala-devel + webkit2gtk-devel + + + vala.patch + + + + + gitg + + vala + + + /usr/bin + /usr/lib + /usr/share + /usr/share/local + + + + + gitg-devel + Development files for gitg + + gitg + vala + + + /usr/include + /usr/lib/pkgconfig + /usr/share/gir-1.0 + + + + + + 2021-06-08 + 3.32.1 + First release + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + + diff --git a/desktop/gnome/apps/gitg/translations.xml b/desktop/gnome/apps/gitg/translations.xml new file mode 100644 index 0000000000..06a00a4568 --- /dev/null +++ b/desktop/gnome/apps/gitg/translations.xml @@ -0,0 +1,13 @@ + + + + gitg + Git sürüm kontrol sistemi için bir GTK tabanlı bir arayüz + Git sürüm kontrol sistemi için bir GTK tabanlı bir arayüz + + + + gitg-devel + devhelp için geliştirme dosyaları + + diff --git a/desktop/gnome/apps/gnome-books/actions.py b/desktop/gnome/apps/gnome-books/actions.py new file mode 100644 index 0000000000..cb466a0763 --- /dev/null +++ b/desktop/gnome/apps/gnome-books/actions.py @@ -0,0 +1,18 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 2. +# See the file http://www.gnu.org/copyleft/gpl.txt. + +from pisi.actionsapi import mesontools, pisitools, shelltools + +def setup(): + mesontools.configure() + +def build(): + mesontools.build() + +def install(): + mesontools.install() + + pisitools.dodoc("AUTHORS", "ChangeLog", "README*", "NEWS") diff --git a/desktop/gnome/apps/gnome-books/files/51.patch b/desktop/gnome/apps/gnome-books/files/51.patch new file mode 100644 index 0000000000..b256cbb5e0 --- /dev/null +++ b/desktop/gnome/apps/gnome-books/files/51.patch @@ -0,0 +1,1238 @@ +From 87623fc7161855a8ae67764c61a91384baf1f25d Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Sun, 17 Jan 2021 16:21:26 +0100 +Subject: [PATCH 01/12] 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 | 34 ---------------------------------- + 1 file changed, 34 deletions(-) + +diff --git a/src/search.js b/src/search.js +index b8e9b593..1a25f3ed 100644 +--- a/src/search.js ++++ b/src/search.js +@@ -286,9 +286,6 @@ var SearchSourceStock = { + LOCAL: 'local' + }; + +-const TRACKER_SCHEMA = 'org.freedesktop.Tracker.Miner.Files'; +-const TRACKER_KEY_RECURSIVE_DIRECTORIES = 'index-recursive-directories'; +- + const Source = new Lang.Class({ + Name: 'Source', + +@@ -303,36 +300,6 @@ const Source = new Lang.Class({ + this.builtin = params.builtin; + }, + +- _getTrackerLocations: function() { +- let settings = new Gio.Settings({ schema_id: TRACKER_SCHEMA }); +- let locations = settings.get_strv(TRACKER_KEY_RECURSIVE_DIRECTORIES); +- let files = []; +- +- locations.forEach(Lang.bind(this, +- function(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: function() { + let files = []; + let xdgDirs = [GLib.UserDirectory.DIRECTORY_DESKTOP, +@@ -351,7 +318,6 @@ const Source = new Lang.Class({ + + _buildFilterLocal: function() { + let locations = this._getBuiltinLocations(); +- locations = locations.concat(this._getTrackerLocations()); + + let filters = []; + locations.forEach(Lang.bind(this, +-- +GitLab + + +From 26597b99b69529b8bb733664ce8904ac5ebcd630 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Sun, 17 Jan 2021 16:26:05 +0100 +Subject: [PATCH 02/12] 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 07af5471..67b87247 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 853664968e82d00dadc356cf6c4ec3ead924a988 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Sun, 17 Jan 2021 16:41:57 +0100 +Subject: [PATCH 03/12] 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 | 122 ------------------------------------------- + 1 file changed, 122 deletions(-) + +diff --git a/src/notifications.js b/src/notifications.js +index cc46bdcd..32d7c1a6 100644 +--- a/src/notifications.js ++++ b/src/notifications.js +@@ -22,7 +22,6 @@ + const Gd = imports.gi.Gd; + const Gettext = imports.gettext; + const Gtk = imports.gi.Gtk; +-const TrackerControl = imports.gi.TrackerControl; + const _ = imports.gettext.gettext; + + const Application = imports.application; +@@ -166,124 +165,6 @@ var PrintNotification = new Lang.Class({ + } + }); + +-const REMOTE_MINER_TIMEOUT = 10; // seconds +-const TRACKER_MINER_FILES_NAME = 'org.freedesktop.Tracker1.Miner.Files'; +- +-const IndexingNotification = new Lang.Class({ +- Name: 'IndexingNotification', +- +- _init: function() { +- this._closed = false; +- +- try { +- this._manager = TrackerControl.MinerManager.new_full(false); +- this._manager.connect('miner-progress', Lang.bind(this, this._checkNotification)); +- } catch(e) { +- logError(e, 'Unable to create a TrackerMinerManager, indexing progress ' + +- 'notification won\'t work'); +- return; +- } +- +- Application.application.connect('miners-changed', Lang.bind(this, this._checkNotification)); +- Application.modeController.connect('window-mode-changed', Lang.bind(this, this._checkNotification)); +- }, +- +- _checkNotification: function() { +- if (Application.modeController.getWindowMode() == WindowMode.WindowMode.PREVIEW_EV) { +- this._destroy(false); +- return; +- } +- +- let isIndexingLocal = 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 (isIndexingLocal) { +- this._display(_("Your documents are being indexed"), +- _("Some documents might not be available during this process")); +- } else { +- this._destroy(false); +- } +- }, +- +- _buildWidget: function() { +- 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', Lang.bind(this, +- function() { +- this._destroy(true); +- })); +- this.widget.add(close); +- +- Application.notificationManager.addNotification(this); +- }, +- +- _update: function(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: function(primaryText, secondaryText) { +- if (this._closed) { +- return; +- } +- +- if (!this.widget) +- this._buildWidget(); +- +- this._update(primaryText, secondaryText); +- }, +- +- _destroy: function(closed) { +- if (this.widget) { +- this.widget.destroy(); +- this.widget = null; +- } +- +- this._closed = closed; +- } +-}); +- + var NotificationManager = new Lang.Class({ + Name: 'NotificationManager', + Extends: Gtk.Revealer, +@@ -300,9 +181,6 @@ var NotificationManager = new Lang.Class({ + row_spacing: 6 }); + + frame.add(this._grid); +- +- // add indexing monitor notification +- this._indexingNotification = new IndexingNotification(); + }, + + addNotification: function(notification) { +-- +GitLab + + +From 058389819f9a5ea2f633e4097db3cc444b7270db Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Sun, 17 Jan 2021 16:54:46 +0100 +Subject: [PATCH 04/12] 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 | 31 +++++++++++++++---------------- + 1 file changed, 15 insertions(+), 16 deletions(-) + +diff --git a/src/application.js b/src/application.js +index 67b87247..a6ac6f0f 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -69,20 +69,21 @@ var trackerCollectionsController = null; + var trackerDocumentsController = null; + var trackerSearchController = null; + +-const TrackerExtractPriorityIface = ' \ +- \ +- \ +- \ +- \ ++const TrackerMinerFilesIndexIface = ' \ ++ \ ++ \ ++ \ ++ \ ++ \ + \ + \ + '; + +-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 */ +@@ -97,7 +98,7 @@ var Application = new Lang.Class({ + _init: function() { + this.minersRunning = []; + this._activationTimestamp = Gdk.CURRENT_TIME; +- this._extractPriority = null; ++ this._minerControl = null; + + let appid; + GLib.set_application_name(_("Books")); +@@ -219,8 +220,9 @@ var Application = new Lang.Class({ + this._mainWindow.connect('destroy', Lang.bind(this, this._onWindowDestroy)); + + try { +- this._extractPriority = TrackerExtractPriority(); +- this._extractPriority.SetRdfTypesRemote(['nfo:Document']); ++ 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'); + } +@@ -264,9 +266,6 @@ var Application = new Lang.Class({ + modeController.setWindowMode(WindowMode.WindowMode.NONE); + selectionController.setSelection(null); + notificationManager = null; +- +- if (this._extractPriority) +- this._extractPriority.ClearRdfTypesRemote(); + }, + + _onWindowDestroy: function(window) { +-- +GitLab + + +From d51f0d4eecd83e5f4c73668bf2577afaeaa16b96 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Sun, 17 Jan 2021 17:02:04 +0100 +Subject: [PATCH 05/12] 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 | 160 +++++-------------------------------------- + 1 file changed, 19 insertions(+), 141 deletions(-) + +diff --git a/src/changeMonitor.js b/src/changeMonitor.js +index a9e3a5ba..0172cd65 100644 +--- a/src/changeMonitor.js ++++ b/src/changeMonitor.js +@@ -23,176 +23,54 @@ 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 = ' \ +- \ +- \ +- \ +- \ +- \ +- \ +- \ +-'; +- +-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 = new Lang.Class({ + Name: 'ChangeEvent', + +- _init: function(urnId, predicateId, isDelete) { +- this.urnId = urnId; +- this.predicateId = predicateId; +- +- if (isDelete) +- this.type = ChangeEventType.DELETED; +- else +- this.type = ChangeEventType.CREATED; +- }, +- +- setResolvedValues: function(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: function(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 = new Lang.Class({ + Name: 'TrackerChangeMonitor', + + _init: function() { +- this._pendingChanges = {}; +- this._unresolvedIds = {}; +- +- this._pendingEvents = []; +- this._pendingEventsId = 0; +- +- this._resourceService = new TrackerResourcesService(); +- this._resourceService.connectSignal('GraphUpdated', Lang.bind(this, this._onGraphUpdated)); +- }, +- +- _onGraphUpdated: function(proxy, senderName, [className, deleteEvents, insertEvents]) { +- deleteEvents.forEach(Lang.bind(this, +- function(event) { +- this._addPendingEvent(event, true); +- })); +- +- insertEvents.forEach(Lang.bind(this, +- function(event) { +- this._addPendingEvent(event, false); +- })); +- }, +- +- _addPendingEvent: function(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, Lang.bind(this, this._processEvents)); +- }, +- +- _processEvents: function() { +- let events = this._pendingEvents; +- let idTable = this._unresolvedIds; +- +- this._pendingEventsId = 0; +- this._pendingEvents = []; +- this._unresolvedIds = {}; +- +- let sparql = 'SELECT'; +- Object.keys(idTable).forEach(Lang.bind(this, +- function(unresolvedId) { +- sparql += (' tracker:uri(%d)').format(unresolvedId); +- })); +- sparql += ' {}'; +- +- // resolve all the unresolved IDs we got so far +- Application.connectionQueue.add(sparql, null, Lang.bind(this, +- function(object, res) { +- let cursor = object.query_finish(res); +- +- cursor.next_async(null, Lang.bind(this, +- function(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(Lang.bind(this, +- function(unresolvedId) { +- idTable[unresolvedId] = cursor.get_string(idx)[0]; +- idx++; +- })); +- +- this._sendEvents(events, idTable); +- } +- +- cursor.close(); +- })); +- })); +- +- return false; ++ 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)); + }, + +- _addEvent: function(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; +- } +- }, ++ _onNotifierEvents: function(notifier, service, graph, events) { ++ let pendingChanges = {}; + +- _sendEvents: function(events, idTable) { + events.forEach(Lang.bind(this, + function(event) { +- event.setResolvedValues(idTable[event.urnId], idTable[event.predicateId]); +- this._addEvent(event); ++ let urn = event.get_urn(); ++ let changeEvent = new ChangeEvent(event.get_event_type(), urn); ++ pendingChanges[urn] = changeEvent; + })); + +- this.emit('changes-pending', this._pendingChanges); +- this._pendingChanges = {}; ++ this.emit('changes-pending', pendingChanges); + } + }); + Signals.addSignalMethods(TrackerChangeMonitor.prototype); +-- +GitLab + + +From 3e066e63742f88eab0f131faa6bc7e70fc78da3b Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Sun, 17 Jan 2021 17:03:14 +0100 +Subject: [PATCH 06/12] 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 + +All queries happen on the local connection, optionally including data +from tracker-miner-fs via SERVICE{} clauses, this is just not the case +for collection queries, since collections are stored in the private +books database. +--- + meson.build | 4 +- + src/application.js | 8 +++- + src/documents.js | 2 +- + src/main.js | 3 +- + src/query.js | 99 ++++++++++++++++++++++++++++++---------- + src/search.js | 8 ++-- + src/trackerController.js | 4 +- + src/trackerUtils.js | 2 +- + 8 files changed, 92 insertions(+), 38 deletions(-) + +diff --git a/meson.build b/meson.build +index afd97aa4..f608bfc1 100644 +--- a/meson.build ++++ b/meson.build +@@ -50,7 +50,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') +@@ -63,8 +62,7 @@ books_deps = [ + dependency('gnome-desktop-3.0'), + dependency('gobject-introspection-1.0', version: '>= 1.31.6'), + dependency('gtk+-3.0', version: '>= 3.22.15'), +- 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 a6ac6f0f..c3ebf933 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -175,9 +175,13 @@ var Application = new Lang.Class({ + + // connect to tracker + try { +- connection = Tracker.SparqlConnection.get(null); ++ let cacheDir = GLib.build_filenamev([GLib.get_user_cache_dir(), 'org.gnome.Books', '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 b6aea652..a2f15c6b 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -803,7 +803,7 @@ const DocCommon = new Lang.Class({ + 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 57f62019..d6624940 100644 +--- a/src/main.js ++++ b/src/main.js +@@ -33,8 +33,7 @@ pkg.require({ 'EvinceDocument': '3.0', + 'GLib': '2.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 ce7928cd..fa7c5ca1 100644 +--- a/src/query.js ++++ b/src/query.js +@@ -94,9 +94,6 @@ var QueryBuilder = new Lang.Class({ + part += this._buildOptional(); + + if ((flags & QueryFlags.UNFILTERED) == 0) { +- if (global) +- part += this._context.documentManager.getWhere(); +- + part += this._buildFilterString(currentType, flags, ftsQuery.length > 0); + } + +@@ -139,12 +136,25 @@ var QueryBuilder = new Lang.Class({ + + // put all the clauses in an UNION + whereSparql += whereParts.join(' UNION '); ++ + whereSparql += ' }'; + + return whereSparql; + }, + + _buildQueryInternal: function(global, flags, offsetController, sortBy) { ++ let selectClauses = ++ ' (nie:isStoredAs(?urn) AS ?uri) ' + ++ ' (nfo:fileName(?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 = ''; + +@@ -179,19 +189,44 @@ var QueryBuilder = new Lang.Class({ + } + + 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) ' + ++ ' ?author ' + ++ ' ?mtime ' + ++ ' ?identifier ' + ++ ' ?type ' + ++ ' ?datasource ' + ++ ' ?shared ' + ++ ' ?created ' + ++ 'WHERE { '; ++ ++ // Collections queries are local ++ if (flags & QueryFlags.COLLECTIONS) { ++ sparql += ++ 'SELECT DISTINCT ?urn ' + ++ selectClauses + ++ whereSparql + ++ tailSparql; ++ } else { ++ sparql += ++ 'SERVICE {' + ++ ' GRAPH tracker:Documents { ' + ++ ' SELECT DISTINCT ?urn ' + ++ selectClauses + ++ whereSparql + ++ tailSparql + ++ ' }' + ++ '}' + ++ 'OPTIONAL { ?urn nie:title ?localTitle } . '; ++ ++ if (global && (flags & QueryFlags.UNFILTERED) == 0) ++ sparql += this._context.documentManager.getWhere(); ++ } ++ ++ sparql += '}'; + + return sparql; + }, +@@ -208,8 +243,18 @@ var QueryBuilder = new Lang.Class({ + }, + + buildCountQuery: function(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 { ++ sparql = 'SELECT ?c {' + ++ ' SERVICE { ' + ++ ' SELECT DISTINCT COUNT(?urn) AS ?c ' + ++ this._buildWhere(true, flags) + ++ ' }' + ++ '}'; ++ } + + return this._createQuery(sparql); + }, +@@ -219,8 +264,8 @@ var QueryBuilder = new Lang.Class({ + 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 + '>'); + +@@ -232,7 +277,7 @@ var QueryBuilder = new Lang.Class({ + 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); +@@ -240,15 +285,21 @@ var QueryBuilder = new Lang.Class({ + + // adds or removes the given item to the given collection + buildSetCollectionQuery: function(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: function(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 1a25f3ed..0bcc6d2c 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; +@@ -126,11 +128,11 @@ const SearchTypeManager = new Lang.Class({ + this.addItem(new SearchType({ id: SearchTypeStock.EBOOKS, + name: _("e-Books"), + filter: '(nie:mimeType(?urn) IN (\"application/epub+zip\", \"application/x-mobipocket-ebook\", \"application/vnd.amazon.mobi8-ebook\", \"application/x-fictionbook+xml\", \"application/x-zip-compressed-fb2\", \"image/vnd.djvu+multipage\"))', +- where: '?urn rdf:type nfo:FileDataObject .' })); ++ where: '?urn rdf:type nfo:EBook .' })); + this.addItem(new SearchType({ id: SearchTypeStock.COMICS, + name: _("Comics"), + filter: '(nie:mimeType(?urn) IN (\"application/x-cbr\", \"application/vnd.comicbook-rar\", \"application/x-cbz\", \"application/vnd.comicbook+zip\", \"application/x-cbt\", \"application/x-cb7\"))', +- where: '?urn rdf:type nfo:FileDataObject .' })); ++ where: '?urn rdf:type nfo:EBook .' })); + + + this.setActiveItemById(SearchTypeStock.ALL); +@@ -322,7 +324,7 @@ const Source = new Lang.Class({ + let filters = []; + locations.forEach(Lang.bind(this, + function(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), "gb:collection:local:"))'); +diff --git a/src/trackerController.js b/src/trackerController.js +index e45f3a7f..17507e03 100644 +--- a/src/trackerController.js ++++ b/src/trackerController.js +@@ -89,10 +89,10 @@ var TrackerConnectionQueue = new Lang.Class({ + Application.connection.query_async(params.query, params.cancellable, + Lang.bind(this, this._queueCollector, 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, + Lang.bind(this, this._queueCollector, 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, + Lang.bind(this, this._queueCollector, params)); + }, + +diff --git a/src/trackerUtils.js b/src/trackerUtils.js +index a1653fed..c98a3345 100644 +--- a/src/trackerUtils.js ++++ b/src/trackerUtils.js +@@ -24,7 +24,7 @@ const Lang = imports.lang; + 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 1e915784f2009f280757eb0601446fa44ec38926 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 26 Jan 2021 14:18:53 +0100 +Subject: [PATCH 07/12] 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.Books.json | 37 ++++++++++-------------------------- + src/application.js | 32 +++++++++++++++++++++++-------- + src/query.js | 4 ++-- + 3 files changed, 36 insertions(+), 37 deletions(-) + +diff --git a/flatpak/org.gnome.Books.json b/flatpak/org.gnome.Books.json +index cac5df46..6c625776 100644 +--- a/flatpak/org.gnome.Books.json ++++ b/flatpak/org.gnome.Books.json +@@ -17,10 +17,8 @@ + "--filesystem=xdg-documents:ro", "--filesystem=xdg-download:ro", + /* Needs to talk to the network: */ + "--share=network", +- /* Tracker D-Bus access */ +- "--talk-name=org.freedesktop.Tracker1", +- "--talk-name=org.freedesktop.Tracker1.Miner.Extract", +- "--env=TRACKER_SPARQL_BACKEND=bus", ++ /* Tracker3 graph access */ ++ "--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Documents", + /* For the WebP loader */ + "--env=GDK_PIXBUF_MODULE_FILE=/app/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache", + /* Needed for dconf to work */ +@@ -125,19 +123,6 @@ + } + ] + }, +- { +- "name": "tracker", +- "buildsystem": "meson", +- "cleanup": [ "/bin", "/etc", "/lib/systemd", "/libexec", "/share/dbus-1/services" ], +- "config-opts": [ "--default-library=shared", "-Dbash-completion=no", "-Ddocs=false", "-Dsystemd_user_services=no" ], +- "sources": [ +- { +- "type": "git", +- "url": "https://gitlab.gnome.org/GNOME/tracker.git", +- "branch": "tracker-2.3" +- } +- ] +- }, + { + "name": "intltool", + "cleanup": [ "*" ], +@@ -152,20 +137,18 @@ + { + "name": "tracker-miners", + "buildsystem": "meson", +- "cleanup": [ "/bin", "/etc", "/lib/systemd", "/libexec" ], +- "config-opts": [ "--default-library=shared", +- "-Dminer_apps=false", +- "-Dminer_rss=false", +- "-Dextract=false", +- "-Dgeneric_media_extractor=none", +- "-Dwriteback=false", ++ "config-opts": [ "-Ddefault_index_single_directories=&DOWNLOADS", ++ "-Ddefault_index_recursive_directories=&DOCUMENTS", ++ "-Ddomain_prefix=org.gnome.Books", ++ "-Dman=false", + "-Dminer_fs=true", +- "-Ddbus_services=/app/share/dbus-1/services/" ], ++ "-Dminer_fs_cache_location=$XDG_CACHE_HOME/org.gnome.Books/miner/files", ++ "-Dminer_rss=false", ++ "-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 c3ebf933..7d7493d4 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -68,6 +68,7 @@ var sourceManager = null; + var trackerCollectionsController = null; + var trackerDocumentsController = null; + var trackerSearchController = null; ++var trackerMinerService = null; + + const TrackerMinerFilesIndexIface = ' \ + \ +@@ -160,6 +161,11 @@ var Application = new Lang.Class({ + } + }, + ++ _isSandboxed: function() { ++ file = Gio.File.new_for_path("/.flatpak-info"); ++ return file.query_exists(null); ++ }, ++ + vfunc_startup: function() { + this.parent(); + String.prototype.format = Format.format; +@@ -185,6 +191,24 @@ var Application = new Lang.Class({ + return; + } + ++ if (this._isSandboxed()) { ++ // if the daemon is not available, run our own copy (for the sandboxed case) ++ trackerMinerService = this.get_application_id() + '.Tracker3.Miner.Files'; ++ } else { ++ // use global tracker daemon ++ let busConn = Tracker.SparqlConnection.bus_new('org.freedesktop.Tracker3.Miner.Files', ++ null, Gio.DBus.session); ++ trackerMinerService = 'org.freedesktop.Tracker3.Miner.Files'; ++ ++ 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'); ++ } ++ } ++ + connectionQueue = new TrackerController.TrackerConnectionQueue(); + changeMonitor = new ChangeMonitor.TrackerChangeMonitor(); + +@@ -222,14 +246,6 @@ var Application = new Lang.Class({ + notificationManager = new Notifications.NotificationManager(); + this._mainWindow = new MainWindow.MainWindow(this); + this._mainWindow.connect('destroy', Lang.bind(this, this._onWindowDestroy)); +- +- 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'); +- } + }, + + vfunc_handle_local_options: function(options) { +diff --git a/src/query.js b/src/query.js +index fa7c5ca1..4fc94b6b 100644 +--- a/src/query.js ++++ b/src/query.js +@@ -212,7 +212,7 @@ var QueryBuilder = new Lang.Class({ + tailSparql; + } else { + sparql += +- 'SERVICE {' + ++ 'SERVICE {' + + ' GRAPH tracker:Documents { ' + + ' SELECT DISTINCT ?urn ' + + selectClauses + +@@ -249,7 +249,7 @@ var QueryBuilder = new Lang.Class({ + this._buildWhere(true, flags); + } else { + sparql = 'SELECT ?c {' + +- ' SERVICE { ' + ++ ' SERVICE { ' + + ' SELECT DISTINCT COUNT(?urn) AS ?c ' + + this._buildWhere(true, flags) + + ' }' + +-- +GitLab + + +From df74c08221003d63ef486f5aa7b33b9d2cd01697 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Tue, 16 Feb 2021 11:37:16 +0100 +Subject: [PATCH 08/12] flatpak: Use WIP gjs patch to fix signal reception + +See https://gitlab.gnome.org/GNOME/gjs/-/merge_requests/569 +--- + flatpak/org.gnome.Books.json | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/flatpak/org.gnome.Books.json b/flatpak/org.gnome.Books.json +index 6c625776..a80bab77 100644 +--- a/flatpak/org.gnome.Books.json ++++ b/flatpak/org.gnome.Books.json +@@ -180,6 +180,17 @@ + } + ] + }, ++ { ++ "name": "gjs", ++ "buildsystem": "meson", ++ "sources": [ ++ { ++ "type": "git", ++ "url": "https://gitlab.gnome.org/GNOME/gjs.git", ++ "branch": "wip/carlosg/arrays-in-signals" ++ } ++ ] ++ }, + { + "name": "gnome-books", + "buildsystem": "meson", +-- +GitLab + + +From ed61ff9d0689378a0fe39856fed454565c97cb2e Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 16 Feb 2021 13:04:45 +0100 +Subject: [PATCH 09/12] query: Fix filename lookup in queries + +Coalesce the nfo:fileName of the resource (if we have access to +it) with runtime function call (if we only have the URI at hand +but no access to the nfo:FileDataObject) +--- + src/query.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/query.js b/src/query.js +index 4fc94b6b..3600f1c4 100644 +--- a/src/query.js ++++ b/src/query.js +@@ -145,7 +145,7 @@ var QueryBuilder = new Lang.Class({ + _buildQueryInternal: function(global, flags, offsetController, sortBy) { + let selectClauses = + ' (nie:isStoredAs(?urn) AS ?uri) ' + +- ' (nfo:fileName(?urn) AS ?filename) ' + ++ ' (COALESCE (nfo:fileName(nie:isStoredAs(?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) ' + +-- +GitLab + + +From 935a5a3d63807668af94c40d12bc778d702e48e9 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 16 Feb 2021 13:16:52 +0100 +Subject: [PATCH 10/12] flatpak: Add libgsf dependency + +This is needed by tracker-miners for epub documents. +--- + flatpak/org.gnome.Books.json | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/flatpak/org.gnome.Books.json b/flatpak/org.gnome.Books.json +index a80bab77..aefbba7a 100644 +--- a/flatpak/org.gnome.Books.json ++++ b/flatpak/org.gnome.Books.json +@@ -104,6 +104,18 @@ + } + ] + }, ++ { ++ "name" : "libgsf", ++ "cleanup" : [ ++ "/bin" ++ ], ++ "sources": [ ++ { ++ "type": "git", ++ "url": "https://gitlab.gnome.org/GNOME/libgsf.git" ++ } ++ ] ++ }, + { + "name": "evince", + "buildsystem": "meson", +-- +GitLab + + +From 17ad73a79f292f0b9852c43985c349c5549b644a Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 16 Feb 2021 13:21:24 +0100 +Subject: [PATCH 11/12] flatpak: Disable tracker-miners writeback service + +This is unused, and unnecessary. +--- + flatpak/org.gnome.Books.json | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/flatpak/org.gnome.Books.json b/flatpak/org.gnome.Books.json +index aefbba7a..a4859489 100644 +--- a/flatpak/org.gnome.Books.json ++++ b/flatpak/org.gnome.Books.json +@@ -156,6 +156,7 @@ + "-Dminer_fs=true", + "-Dminer_fs_cache_location=$XDG_CACHE_HOME/org.gnome.Books/miner/files", + "-Dminer_rss=false", ++ "-Dwriteback=false", + "-Dsystemd_user_services=false" ], + "sources": [ + { +-- +GitLab + + +From b5875b2d435be067b5affc7e01c6e85574846cf6 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Tue, 16 Feb 2021 18:42:48 +0100 +Subject: [PATCH 12/12] query: Make nfo:fileName extraction more reliable + +Nesting properties with multiple cardinality don't result in the +desired effect here. Get the nfo:FileDataObject inside the WHERE +block, and use it in the select clause for this. +--- + src/query.js | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/query.js b/src/query.js +index 3600f1c4..f753d3ae 100644 +--- a/src/query.js ++++ b/src/query.js +@@ -79,6 +79,7 @@ var QueryBuilder = new Lang.Class({ + + _buildOptional: function() { + let sparql = ++ 'OPTIONAL { ?urn nie:isStoredAs ?file . } '; + 'OPTIONAL { ?urn nco:creator ?creator . } ' + + 'OPTIONAL { ?urn nco:publisher ?publisher . } '; + +@@ -145,7 +146,7 @@ var QueryBuilder = new Lang.Class({ + _buildQueryInternal: function(global, flags, offsetController, sortBy) { + let selectClauses = + ' (nie:isStoredAs(?urn) AS ?uri) ' + +- ' (COALESCE (nfo:fileName(nie:isStoredAs(?urn)), tracker:string-from-filename(nie:isStoredAs(?urn))) AS ?filename) ' + ++ ' (COALESCE (nfo:fileName(?file), 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) ' + +-- +GitLab + diff --git a/desktop/gnome/apps/gnome-books/pspec.xml b/desktop/gnome/apps/gnome-books/pspec.xml new file mode 100644 index 0000000000..be04d060ce --- /dev/null +++ b/desktop/gnome/apps/gnome-books/pspec.xml @@ -0,0 +1,75 @@ + + + + + gnome-books + https://wiki.gnome.org/Apps/Books + + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + GPLv2 + gnome-books + app:gui + E-Book Manager + E-Book Manager + mirrors://gnome/gnome-books/40/gnome-books-40.0.tar.xz + + appstream-glib-devel + desktop-file-utils + docbook-xsl + librsvg-devel + gjs-devel + evince-devel + git + glib2-devel + gnome-desktop-devel + gobject-introspection-devel + gtk3-devel + libxslt-devel + libgepub-devel + libseccomp-devel + meson + tracker-devel + webkit2gtk-devel + + + + + + + + gnome-books + + gtk3 + + + /usr/bin + /usr/lib + /usr/share + /usr/share/local + + + + + gnome-books-devel + + gnome-books + + + /usr/include + /usr/lib/pkgconfig + /usr/share/gir-1.0 + + + + + + 2021-06-08 + 40.0 + First release + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + + diff --git a/desktop/gnome/apps/gnome-books/translations.xml b/desktop/gnome/apps/gnome-books/translations.xml new file mode 100644 index 0000000000..c8f4ad121a --- /dev/null +++ b/desktop/gnome/apps/gnome-books/translations.xml @@ -0,0 +1,13 @@ + + + + gnome-books + E-kitap yöneticisi + E-kitap yöneticisi + + + + gnome-books-devel + gnome-books için geliştirme dosyaları + +