[gnome-music/carlosg/tracker3: 2/2] Bundle Tracker 3 in the Flatpak for systems which don't have it




commit 104f2b016abcf801851e4fec8ec0132c18337680
Author: Sam Thursfield <sam afuera me uk>
Date:   Tue Jun 30 00:38:57 2020 +0200

    Bundle Tracker 3 in the Flatpak for systems which don't have it
    
    This commit allows the tracker3 version of GNOME Music to run on systems
    which don't have a suitable version of Tracker in the base OS. It does
    this by running tracker-miner-fs-3 inside the Flatpak sandbox. This will
    lead to increased resource consumption as it'll duplicate the work of
    any indexer in the host OS, but it's better than a broken app.

 data/meson.build                                   |   2 +
 data/tracker/meson.build                           |  31 +++++
 ...g.gnome.Music.Tracker3.Miner.Extract.service.in |   7 ++
 ...org.gnome.Music.Tracker3.Miner.Files.service.in |   7 ++
 data/tracker/org.gnome.Music.domain.rule.in        |  20 ++++
 gnomemusic/coregrilo.py                            |   5 +-
 gnomemusic/grilowrappers/grltrackerplaylists.py    |  39 ++++---
 gnomemusic/grilowrappers/grltrackerwrapper.py      |  62 ++++++----
 gnomemusic/trackerwrapper.py                       | 127 ++++++++++++++++-----
 meson.build                                        |   2 +-
 org.gnome.Music.json                               |  20 ++--
 11 files changed, 240 insertions(+), 82 deletions(-)
---
diff --git a/data/meson.build b/data/meson.build
index 25ff1e10..a093f1e2 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -81,3 +81,5 @@ install_data(
     install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'icons/hicolor/symbolic/apps'),
     rename: '@0 -symbolic svg'.format(APPLICATION_ID)
 )
+
+subdir('tracker')
diff --git a/data/tracker/meson.build b/data/tracker/meson.build
new file mode 100644
index 00000000..588d5c9a
--- /dev/null
+++ b/data/tracker/meson.build
@@ -0,0 +1,31 @@
+# Files needed for running Tracker inside the Flatpak sandbox, for systems
+# which don't have a suitable version of Tracker in the host OS.
+#
+# We must export the .service files from the sandbox so they work on the
+# session bus. This means the Tracker domain name must correspond with the
+# application ID.
+
+domain_ontologies_dir = get_option('datadir') / 'tracker3' / 'domain-ontologies'
+dbus_services_dir = get_option('datadir') / 'dbus-1' / 'services'
+
+tracker_domain_config = configuration_data()
+tracker_domain_config.set('application_id', APPLICATION_ID)
+tracker_domain_config.set('domain_rule', get_option('prefix') / domain_ontologies_dir / APPLICATION_ID + 
'.domain.rule')
+
+configure_file(
+  input: 'org.gnome.Music.domain.rule.in',
+  output: APPLICATION_ID + '.domain.rule',
+  configuration: tracker_domain_config,
+  install_dir: domain_ontologies_dir)
+
+configure_file(
+  input: 'org.gnome.Music.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.Music.Tracker3.Miner.Files.service.in',
+  output: APPLICATION_ID + '.Tracker3.Miner.Files.service',
+  configuration: tracker_domain_config,
+  install_dir: dbus_services_dir)
diff --git a/data/tracker/org.gnome.Music.Tracker3.Miner.Extract.service.in 
b/data/tracker/org.gnome.Music.Tracker3.Miner.Extract.service.in
new file mode 100644
index 00000000..eb7a87aa
--- /dev/null
+++ b/data/tracker/org.gnome.Music.Tracker3.Miner.Extract.service.in
@@ -0,0 +1,7 @@
+[D-BUS Service]
+Name=@application_id@.Tracker3.Miner.Extract
+Exec=/app/libexec/tracker-extract-3 --domain-ontology @domain_rule@
+
+# Miner details needed for tracker-control
+Path=/org/freedesktop/Tracker3/Miner/Extract
+NameSuffix=Miner.Files
diff --git a/data/tracker/org.gnome.Music.Tracker3.Miner.Files.service.in 
b/data/tracker/org.gnome.Music.Tracker3.Miner.Files.service.in
new file mode 100644
index 00000000..4fa7371d
--- /dev/null
+++ b/data/tracker/org.gnome.Music.Tracker3.Miner.Files.service.in
@@ -0,0 +1,7 @@
+[D-BUS Service]
+Name=@application_id@.Tracker3.Miner.Files
+Exec=/app/libexec/tracker-miner-fs-3 --domain-ontology @domain_rule@ --initial-sleep 0
+
+# Miner details needed for tracker-control
+Path=/org/freedesktop/Tracker3/Miner/Files
+NameSuffix=Miner.Files
diff --git a/data/tracker/org.gnome.Music.domain.rule.in b/data/tracker/org.gnome.Music.domain.rule.in
new file mode 100644
index 00000000..6119cfc5
--- /dev/null
+++ b/data/tracker/org.gnome.Music.domain.rule.in
@@ -0,0 +1,20 @@
+# This defines a private Tracker domain for GNOME Music.
+#
+# It's used to run the Tracker indexer inside a Flatpak sandbox, when Music 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/gnome-music/miner/files
+
+# Name of the ontology to use, must be one located in
+# $(sharedir)/tracker/ontologies
+OntologyName=nepomuk
+
+# DBus name for the owner (not optional). Tracker will use
+# the domain as the prefix of the DBus name for all the
+# services related to this domain ontology.
+Domain=@application_id@
+
+# List of miners we expect to run in this domain.
+Miners=Miner.Files;Miner.Extract
diff --git a/gnomemusic/coregrilo.py b/gnomemusic/coregrilo.py
index 0dd53a84..636b5165 100644
--- a/gnomemusic/coregrilo.py
+++ b/gnomemusic/coregrilo.py
@@ -74,7 +74,8 @@ class CoreGrilo(GObject.GObject):
         self._wrappers = {}
         self._mb_wrappers = {}
 
-        self._tracker_wrapper = TrackerWrapper()
+        application_id = application.get_application_id()
+        self._tracker_wrapper = TrackerWrapper(application_id)
         self._tracker_wrapper.bind_property(
             "tracker-available", self, "tracker-available",
             GObject.BindingFlags.SYNC_CREATE)
@@ -96,6 +97,8 @@ class CoreGrilo(GObject.GObject):
         self._registry.add_config(config)
 
         config = Grl.Config.new("grl-tracker3", "grl-tracker3-source")
+        config.set_string(
+            "miner-service", self._tracker_wrapper.miner_fs_busname())
         config.set_string(
             "store-path", self._tracker_wrapper.cache_directory())
         self._registry.add_config(config)
diff --git a/gnomemusic/grilowrappers/grltrackerplaylists.py b/gnomemusic/grilowrappers/grltrackerplaylists.py
index 422f0516..d4951f3b 100644
--- a/gnomemusic/grilowrappers/grltrackerplaylists.py
+++ b/gnomemusic/grilowrappers/grltrackerplaylists.py
@@ -74,7 +74,7 @@ class GrlTrackerPlaylists(GObject.GObject):
         self._user_model_filter = self._coremodel.props.user_playlists_filter
         self._pls_todelete = []
         self._songs_hash = songs_hash
-        self._tracker = tracker_wrapper.props.tracker
+        self._tracker = tracker_wrapper.props.local_db
         self._tracker_wrapper = tracker_wrapper
         self._window = application.props.window
 
@@ -323,7 +323,7 @@ class Playlist(GObject.GObject):
         self._coreselection = application.props.coreselection
         self._log = application.props.log
         self._songs_hash = songs_hash
-        self._tracker = tracker_wrapper.props.tracker
+        self._tracker = tracker_wrapper.props.local_db
         self._tracker_wrapper = tracker_wrapper
         self._window = application.props.window
 
@@ -367,7 +367,7 @@ class Playlist(GObject.GObject):
                         nfo:hasMediaFileListEntry ?entry .
             ?entry a nfo:MediaFileListEntry ;
                      nfo:entryUrl ?url .
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         ?song
@@ -394,7 +394,8 @@ class Playlist(GObject.GObject):
         """.replace('\n', ' ').strip() % {
             'media_type': int(Grl.MediaType.AUDIO),
             "filter_clause": 'tracker:id(?playlist) = ' + self.props.pl_id,
-            "location_filter": self._tracker_wrapper.location_filter()
+            "location_filter": self._tracker_wrapper.location_filter(),
+            "miner_fs_busname": self._tracker_wrapper.miner_fs_busname(),
         }
 
         def _add_to_playlist_cb(
@@ -624,7 +625,7 @@ class Playlist(GObject.GObject):
                             nfo:hasMediaFileListEntry ?entry .
                 ?entry a nfo:MediaFileListEntry ;
                          nfo:entryUrl ?url .
-                SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+                SERVICE <dbus:%(miner_fs_busname)s> {
                     GRAPH tracker:Audio {
                         SELECT
                             ?song
@@ -650,7 +651,8 @@ class Playlist(GObject.GObject):
             """.replace("\n", " ").strip() % {
                 'media_type': int(Grl.MediaType.AUDIO),
                 "filter_clause": "tracker:id(?song) = " + media_id,
-                "location_filter": self._tracker_wrapper.location_filter()
+                "location_filter": self._tracker_wrapper.location_filter(),
+                "miner_fs_busname": self._tracker_wrapper.miner_fs_busname(),
             }
 
             options = self._fast_options.copy()
@@ -839,7 +841,7 @@ class MostPlayed(SmartPlaylist):
             ?playCount
             ?tag AS ?favorite
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         ?song
@@ -864,7 +866,8 @@ class MostPlayed(SmartPlaylist):
         ORDER BY DESC(?playCount) LIMIT 50
         """.replace('\n', ' ').strip() % {
             'media_type': int(Grl.MediaType.AUDIO),
-            "location_filter": self._tracker_wrapper.location_filter()
+            "location_filter": self._tracker_wrapper.location_filter(),
+            "miner_fs_busname": self._tracker_wrapper.miner_fs_busname(),
         }
 
 
@@ -891,7 +894,7 @@ class NeverPlayed(SmartPlaylist):
             nie:usageCounter(?song) AS ?playCount
             ?tag AS ?favorite
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         ?song
@@ -915,7 +918,8 @@ class NeverPlayed(SmartPlaylist):
         } ORDER BY nfo:fileLastAccessed(?song) LIMIT 50
         """.replace('\n', ' ').strip() % {
             'media_type': int(Grl.MediaType.AUDIO),
-            "location_filter": self._tracker_wrapper.location_filter()
+            "location_filter": self._tracker_wrapper.location_filter(),
+            "miner_fs_busname": self._tracker_wrapper.miner_fs_busname(),
         }
 
 
@@ -949,7 +953,7 @@ class RecentlyPlayed(SmartPlaylist):
             nie:usageCounter(?song) AS ?playCount
             ?tag AS ?favorite
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         ?song
@@ -976,7 +980,8 @@ class RecentlyPlayed(SmartPlaylist):
         """.replace('\n', ' ').strip() % {
             'media_type': int(Grl.MediaType.AUDIO),
             'compare_date': compare_date,
-            "location_filter": self._tracker_wrapper.location_filter()
+            "location_filter": self._tracker_wrapper.location_filter(),
+            "miner_fs_busname": self._tracker_wrapper.miner_fs_busname(),
         }
 
 
@@ -1010,7 +1015,7 @@ class RecentlyAdded(SmartPlaylist):
             nie:usageCounter(?song) AS ?playCount
             ?tag AS ?favorite
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         ?song
@@ -1037,7 +1042,8 @@ class RecentlyAdded(SmartPlaylist):
         """.replace('\n', ' ').strip() % {
             'media_type': int(Grl.MediaType.AUDIO),
             'compare_date': compare_date,
-            "location_filter": self._tracker_wrapper.location_filter()
+            "location_filter": self._tracker_wrapper.location_filter(),
+            "miner_fs_busname": self._tracker_wrapper.miner_fs_busname(),
         }
 
 
@@ -1064,7 +1070,7 @@ class Favorites(SmartPlaylist):
                 nie:usageCounter(?song) AS ?playCount
                 nao:predefined-tag-favorite AS ?favorite
             WHERE {
-                SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+                SERVICE <dbus:%(miner_fs_busname)s> {
                     GRAPH tracker:Audio {
                         SELECT
                             ?song
@@ -1087,5 +1093,6 @@ class Favorites(SmartPlaylist):
             } ORDER BY DESC(?added)
         """.replace('\n', ' ').strip() % {
             "media_type": int(Grl.MediaType.AUDIO),
-            "location_filter": self._tracker_wrapper.location_filter()
+            "location_filter": self._tracker_wrapper.location_filter(),
+            "miner_fs_busname": self._tracker_wrapper.miner_fs_busname(),
         }
diff --git a/gnomemusic/grilowrappers/grltrackerwrapper.py b/gnomemusic/grilowrappers/grltrackerwrapper.py
index e00a164a..10cd5b8c 100644
--- a/gnomemusic/grilowrappers/grltrackerwrapper.py
+++ b/gnomemusic/grilowrappers/grltrackerwrapper.py
@@ -178,7 +178,7 @@ class GrlTrackerWrapper(GObject.GObject):
             ?type ?id ?title ?composer ?albumArtist
             ?artist ?url ?creationDate
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         %(media_type)s AS ?type
@@ -204,8 +204,9 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
-            'location_filter': self._tracker_wrapper.location_filter()
+            'location_filter': self._tracker_wrapper.location_filter(),
         }
 
         def check_album_cb(source, op_id, media, remaining, error):
@@ -250,7 +251,7 @@ class GrlTrackerWrapper(GObject.GObject):
         query = """
         SELECT ?type ?id ?artist
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         %(media_type)s AS ?type
@@ -273,8 +274,9 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
-            'location_filter': self._tracker_wrapper.location_filter()
+            'location_filter': self._tracker_wrapper.location_filter(),
         }
 
         def check_artist_cb(source, op_id, media, remaining, error):
@@ -340,7 +342,7 @@ class GrlTrackerWrapper(GObject.GObject):
             nie:usageCounter(?urn) AS ?playCount
             ?tag AS ?favorite
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -411,9 +413,10 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.AUDIO),
             'location_filter': self._tracker_wrapper.location_filter(),
-            'media_ids': media_ids
+            'media_ids': media_ids,
         }
 
         return query
@@ -488,7 +491,7 @@ class GrlTrackerWrapper(GObject.GObject):
             nie:usageCounter(?urn) AS ?playCount
             ?tag AS ?favorite
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         %(media_type)s AS ?type
@@ -559,8 +562,9 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.AUDIO),
-            'location_filter': self._tracker_wrapper.location_filter()
+            'location_filter': self._tracker_wrapper.location_filter(),
         }
 
         options = self._fast_options.copy()
@@ -597,7 +601,7 @@ class GrlTrackerWrapper(GObject.GObject):
             ?artist ?url ?creationDate
         WHERE
         {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                         %(media_type)s AS ?type
@@ -626,8 +630,9 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
-            'location_filter': self._tracker_wrapper.location_filter()
+            'location_filter': self._tracker_wrapper.location_filter(),
         }
 
         options = self._fast_options.copy()
@@ -662,7 +667,7 @@ class GrlTrackerWrapper(GObject.GObject):
         query = """
         SELECT ?type ?id ?albumArtist
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT
                        %(media_type)s AS ?type
@@ -686,8 +691,9 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
-            'location_filter': self._tracker_wrapper.location_filter()
+            'location_filter': self._tracker_wrapper.location_filter(),
         }
 
         options = self._fast_options.copy()
@@ -708,7 +714,7 @@ class GrlTrackerWrapper(GObject.GObject):
         SELECT
             ?type ?id ?title ?creationDate
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -731,9 +737,10 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
             'artist_id': artist_id,
-            'location_filter': self._tracker_wrapper.location_filter()
+            'location_filter': self._tracker_wrapper.location_filter(),
         }
 
         albums = []
@@ -775,7 +782,7 @@ class GrlTrackerWrapper(GObject.GObject):
         SELECT
             ?type ?id ?albumDiscNumber
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -793,9 +800,10 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
             'album_id': album_id,
-            'location_filter': self._tracker_wrapper.location_filter()
+            'location_filter': self._tracker_wrapper.location_filter(),
         }
 
         def _disc_nr_cb(source, op_id, media, remaining, error):
@@ -837,7 +845,7 @@ class GrlTrackerWrapper(GObject.GObject):
             nie:usageCounter(?id) AS ?playCount
             ?tag AS ?favorite
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -911,7 +919,8 @@ class GrlTrackerWrapper(GObject.GObject):
             'media_type': int(Grl.MediaType.AUDIO),
             'album_id': album_id,
             'disc_nr': disc_nr,
-            'location_filter': self._tracker_wrapper.location_filter()
+            'location_filter': self._tracker_wrapper.location_filter(),
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
         }
 
         options = self._fast_options.copy()
@@ -934,7 +943,7 @@ class GrlTrackerWrapper(GObject.GObject):
         SELECT
             ?type ?id
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -975,9 +984,10 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.AUDIO),
             'location_filter': self._tracker_wrapper.location_filter(),
-            'name': term
+            'name': term,
         }
 
         artist_filter_ids = []
@@ -1009,7 +1019,7 @@ class GrlTrackerWrapper(GObject.GObject):
         SELECT
             ?type ?id
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -1042,6 +1052,7 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
             'location_filter': self._tracker_wrapper.location_filter(),
             'name': term
@@ -1076,7 +1087,7 @@ class GrlTrackerWrapper(GObject.GObject):
         SELECT
             ?type ?id
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -1114,6 +1125,7 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace('\n', ' ').strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.AUDIO),
             'location_filter': self._tracker_wrapper.location_filter(),
             'name': term
@@ -1169,7 +1181,7 @@ class GrlTrackerWrapper(GObject.GObject):
         SELECT
             ?type ?id ?mbReleaseGroup ?mbRelease ?artist ?album
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -1207,6 +1219,7 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace("\n", " ").strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
             'album_id': album_id,
             'location_filter': self._tracker_wrapper.location_filter()
@@ -1220,7 +1233,7 @@ class GrlTrackerWrapper(GObject.GObject):
         SELECT
             ?type ?id ?mbReleaseGroup ?mbRelease ?artist ?album
         WHERE {
-            SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> {
+            SERVICE <dbus:%(miner_fs_busname)s> {
                 GRAPH tracker:Audio {
                     SELECT DISTINCT
                         %(media_type)s AS ?type
@@ -1261,6 +1274,7 @@ class GrlTrackerWrapper(GObject.GObject):
             }
         }
         """.replace("\n", " ").strip() % {
+            'miner_fs_busname': self._tracker_wrapper.miner_fs_busname(),
             'media_type': int(Grl.MediaType.CONTAINER),
             'location_filter': self._tracker_wrapper.location_filter(),
             'song_id': song_id
diff --git a/gnomemusic/trackerwrapper.py b/gnomemusic/trackerwrapper.py
index a99e4c86..471c8a2a 100644
--- a/gnomemusic/trackerwrapper.py
+++ b/gnomemusic/trackerwrapper.py
@@ -53,19 +53,95 @@ class MbReference(Enum):
         self.method = method
 
 
+def in_flatpak():
+    if os.path.exists('/.flatpak-info'):
+        return True
+    return False
+
+
 class TrackerWrapper(GObject.GObject):
     """Create a connection to an instance of Tracker"""
 
-    def __init__(self):
+    def __init__(self, application_id):
         super().__init__()
 
         self._log = MusicLogger()
+        self._application_id = application_id
+
+        self._local_db = None
+        self._local_db_available = TrackerState.UNAVAILABLE
+
+        self._miner_fs = None
+        self._miner_fs_busname = None
+        self._miner_fs_available = TrackerState.UNAVAILABLE
+
+        self._setup_local_db()
+        self._setup_host_miner_fs()
+
+    def _setup_host_miner_fs(self):
+        self._miner_fs_busname = 'org.freedesktop.Tracker3.Miner.Files'
 
-        self._tracker = None
-        self._tracker_available = TrackerState.UNAVAILABLE
+        self._log.debug("Connecting to session-wide Tracker indexer at {}"
+                        .format(self._miner_fs_busname))
+
+        try:
+            self._miner_fs = Tracker.SparqlConnection.bus_new(
+                self._miner_fs_busname, None, None)
+            self._log.info("Using session-wide tracker-miner-fs-3")
+            self._miner_fs_available = TrackerState.AVAILABLE
+            self.notify('tracker-available')
+        except GLib.Error as error:
+            self._log.warning(
+                "Could not connect to host Tracker miner-fs at {}: {}"
+                .format(self._miner_fs_busname, error))
+            if in_flatpak():
+                self._setup_local_miner_fs()
+            else:
+                self._miner_fs_busname = None
+                self.notify('tracker-available')
+
+    def _setup_local_miner_fs(self):
+        self._miner_fs_busname = self._application_id + '.Tracker3.Miner.Files'
+        self._log.debug("Connecting to bundled Tracker indexer at {}"
+                        .format(self._miner_fs_busname))
+
+        # Calling self._application.get_dbus_connection() seems to return None
+        # here, so get the bus directly from Gio.
+        Gio.bus_get(Gio.BusType.SESSION, None,
+                    self._setup_local_bus_connection_cb)
+
+    def _setup_local_bus_connection_cb(self, klass, result):
+        # Query callback for _setup_local_miner_fs() to connect to session bus
+        bus = Gio.bus_get_finish(result)
+
+        miner_fs_startup_timeout_msec = 30 * 1000
+        miner_fs_object_path = '/org/freedesktop/Tracker3/Miner/Files'
+
+        bus.call(self._miner_fs_busname, miner_fs_object_path,
+                 'org.freedesktop.DBus.Peer', 'Ping', None, None,
+                 Gio.DBusCallFlags.NONE,
+                 miner_fs_startup_timeout_msec, None,
+                 self._setup_local_miner_fs_ping_cb)
+
+    def _setup_local_miner_fs_ping_cb(self, klass, result):
+        try:
+            klass.call_finish(result)
+            self._log.info("Using bundled tracker-miner-fs-3")
+            self._miner_fs = Tracker.SparqlConnection.bus_new(
+                self._miner_fs_busname, None, None)
+            self._miner_fs_available = TrackerState.AVAILABLE
+            self.notify('tracker-available')
+        except GLib.Error as error:
+            self._log.warning(
+                "Could not start local Tracker miner-fs at {}: {}"
+                .format(self._miner_fs_busname, error))
+            self._miner_fs_busname = None
+            self.notify('tracker-available')
 
+    def _setup_local_db(self):
+        # Open a local Tracker database.
         try:
-            self._tracker = Tracker.SparqlConnection.new(
+            self._local_db = Tracker.SparqlConnection.new(
                 Tracker.SparqlConnectionFlags.NONE,
                 Gio.File.new_for_path(self.cache_directory()),
                 Tracker.sparql_get_ontology_nepomuk(),
@@ -76,34 +152,21 @@ class TrackerWrapper(GObject.GObject):
             self.notify("tracker-available")
             return
 
-        query = """
-        SELECT
-            ?e
-        {
-            GRAPH tracker:Audio {
-                ?e a tracker:ExternalReference .
-            }
-        }""".replace("\n", "").strip()
-
-        self._tracker.query_async(query, None, self._query_version_check)
-
-    def _query_version_check(self, klass, result):
-        try:
-            klass.query_finish(result)
-            self._tracker_available = TrackerState.AVAILABLE
-        except GLib.Error as error:
-            self._log.warning(
-                "Error: {}, {}".format(error.domain, error.message))
-            self._tracker_available = TrackerState.OUTDATED
-
+        # Version checks against the local version of Tracker can be done
+        # here, set `self._tracker_available = TrackerState.OUTDATED` if the
+        # checks fail.
+        self._local_db_available = TrackerState.AVAILABLE
         self.notify("tracker-available")
 
     def cache_directory(self):
         return os.path.join(GLib.get_user_cache_dir(), 'gnome-music', 'db')
 
+    def miner_fs_busname(self):
+        return self._miner_fs_busname
+
     @GObject.Property(type=object, flags=GObject.ParamFlags.READABLE)
-    def tracker(self):
-        return self._tracker
+    def local_db(self):
+        return self._local_db
 
     @GObject.Property(
         type=int, default=TrackerState.UNAVAILABLE,
@@ -111,13 +174,17 @@ class TrackerWrapper(GObject.GObject):
     def tracker_available(self):
         """Get Tracker availability.
 
-        Tracker is available if a SparqlConnection has been opened and
-        if a query can be performed.
-
         :returns: tracker availability
         :rtype: TrackerState
         """
-        return self._tracker_available
+        if (self._local_db_available == TrackerState.AVAILABLE
+                and self._miner_fs_available == TrackerState.AVAILABLE):
+            return TrackerState.AVAILABLE
+        elif (self._local_db_available == TrackerState.OUTDATED
+                or self._miner_fs_available == TrackerState.OUTDATED):
+            return TrackerState.OUTDATED
+        else:
+            return TrackerState.UNAVAILABLE
 
     def location_filter(self):
         try:
diff --git a/meson.build b/meson.build
index a3208f59..a3e2feec 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project('gnome-music',
     version: '3.37.2',
-    meson_version: '>= 0.46.0'
+    meson_version: '>= 0.49.0'
 )
 
 # Importing modules
diff --git a/org.gnome.Music.json b/org.gnome.Music.json
index ab18436d..e511328e 100644
--- a/org.gnome.Music.json
+++ b/org.gnome.Music.json
@@ -59,20 +59,20 @@
             ]
         },
         {
-            "name": "tracker",
+            "name": "tracker-miners",
             "buildsystem": "meson",
-            "cleanup": [ "/bin", "/etc", "/libexec" ],
-            "config-opts": [ "-Ddocs=false",
-                             "-Dman=false",
-                             "-Dfunctional_tests=false",
-                             "-Dnetwork_manager=disabled",
-                             "-Dstemmer=disabled",
-                             "-Dunicode_support=icu",
-                             "-Dbash_completion=false" ],
+            "cleanup": [ "/share/dbus-1/services/org.freedesktop.Tracker3.Miner.Extract.service",
+                         "/share/dbus-1/services/org.freedesktop.Tracker3.Miner.Files.service",
+                         "/share/dbus-1/services/org.freedesktop.Tracker3.Writeback.service" ],
+            "config-opts": [ "-Dman=false",
+                             "-Dminer_fs=true",
+                             "-Dminer_rss=false",
+                             "-Dsystemd_user_services=false"],
             "sources": [
                 {
                     "type": "git",
-                    "url": "https://gitlab.gnome.org/GNOME/tracker.git";
+                    "url": "https://gitlab.gnome.org/GNOME/tracker-miners.git";,
+                    "branch": "master"
                 }
             ]
         },


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]