From e09bbc1aa8b36ae15cfe2cac2d7cf42d20425427 Mon Sep 17 00:00:00 2001 From: Enno Boland Date: Tue, 20 Apr 2021 13:21:08 +0200 Subject: [PATCH] gnome-photos: update to 40.0. --- .../patches/fix-double-declaration.diff | 11 + srcpkgs/gnome-photos/patches/tracker3.patch | 4151 ----------------- srcpkgs/gnome-photos/template | 7 +- 3 files changed, 14 insertions(+), 4155 deletions(-) create mode 100644 srcpkgs/gnome-photos/patches/fix-double-declaration.diff delete mode 100644 srcpkgs/gnome-photos/patches/tracker3.patch diff --git a/srcpkgs/gnome-photos/patches/fix-double-declaration.diff b/srcpkgs/gnome-photos/patches/fix-double-declaration.diff new file mode 100644 index 000000000000..0162e13db42d --- /dev/null +++ b/srcpkgs/gnome-photos/patches/fix-double-declaration.diff @@ -0,0 +1,11 @@ +--- src/photos-base-manager.h.orig 2021-04-20 13:16:07.042348375 +0200 ++++ src/photos-base-manager.h 2021-04-20 13:16:16.974347953 +0200 +@@ -78,8 +78,6 @@ guint photos_base_manager_ + + GObject *photos_base_manager_get_previous_object (PhotosBaseManager *self, GObject *object); + +-PhotosSparqlTemplate *photos_base_manager_get_sparql_template (PhotosBaseManager *self, gint flags); +- + const gchar *photos_base_manager_get_title (PhotosBaseManager *self); + + gchar *photos_base_manager_get_where (PhotosBaseManager *self, gint flags); diff --git a/srcpkgs/gnome-photos/patches/tracker3.patch b/srcpkgs/gnome-photos/patches/tracker3.patch deleted file mode 100644 index 6062fac2b263..000000000000 --- a/srcpkgs/gnome-photos/patches/tracker3.patch +++ /dev/null @@ -1,4151 +0,0 @@ -From 4673c40a7c006ccb6de203ec2b25ca39a74782d9 Mon Sep 17 00:00:00 2001 -From: Sam Thursfield -Date: Wed, 27 May 2020 13:07:58 +0200 -Subject: [PATCH 1/3] Fix build failure due to undefined M_PI constant - -The header needs to be included. - -Previously I suppose libtracker-sparql.h pulled this in. ---- - src/photos-utils.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/photos-utils.c b/src/photos-utils.c -index 1d7be577..d659b47d 100644 ---- a/src/photos-utils.c -+++ b/src/photos-utils.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - #include "photos-application.h" - #include "photos-device-item.h" --- -GitLab - - -From 18f126a67a37d1f6efe546e42eef22ae15da7642 Mon Sep 17 00:00:00 2001 -From: Sam Thursfield -Date: Sun, 7 Jun 2020 21:53:20 +0200 -Subject: [PATCH 2/3] Generate queries using SPARQL templates - -The code to generate SPARQL queries was split across many different -source files, making it difficult to make big changes. Now the -queries are written out as templates and we use template substitution -to build the SPARQL that we send to Tracker. ---- - src/meson.build | 5 + - src/photos-base-manager.c | 15 ++ - src/photos-base-manager.h | 4 + - src/photos-filterable.c | 8 - - src/photos-filterable.h | 3 - - src/photos-query-builder.c | 207 +++++++++----------- - src/photos-search-type-manager.c | 59 +----- - src/photos-search-type.c | 67 +++---- - src/photos-search-type.h | 6 +- - src/photos-sparql-template.c | 187 ++++++++++++++++++ - src/photos-sparql-template.h | 38 ++++ - src/photos.gresource.xml | 4 + - src/queries/all.sparql.template | 31 +++ - src/queries/collections.sparql.template | 14 ++ - src/queries/favorite-photos.sparql.template | 12 ++ - src/queries/photos.sparql.template | 11 ++ - 16 files changed, 446 insertions(+), 225 deletions(-) - create mode 100644 src/photos-sparql-template.c - create mode 100644 src/photos-sparql-template.h - create mode 100644 src/queries/all.sparql.template - create mode 100644 src/queries/collections.sparql.template - create mode 100644 src/queries/favorite-photos.sparql.template - create mode 100644 src/queries/photos.sparql.template - -diff --git a/src/meson.build b/src/meson.build -index 9919f0cf..b5b2759c 100644 ---- a/src/meson.build -+++ b/src/meson.build -@@ -195,6 +195,7 @@ sources = common_sources + files( - 'photos-source.c', - 'photos-source-manager.c', - 'photos-source-notification.c', -+ 'photos-sparql-template.c', - 'photos-spinner-box.c', - 'photos-thumbnail-factory.c', - 'photos-tool.c', -@@ -290,6 +291,10 @@ resource_data = files( - 'photos-selection-toolbar.ui', - 'photos-share-dialog.ui', - 'photos-zoom-controls.ui', -+ 'queries/all.sparql.template', -+ 'queries/collections.sparql.template', -+ 'queries/favorite-photos.sparql.template', -+ 'queries/photos.sparql.template', - ) - - sources += gnome.compile_resources( -diff --git a/src/photos-base-manager.c b/src/photos-base-manager.c -index d49d19a5..052638d5 100644 ---- a/src/photos-base-manager.c -+++ b/src/photos-base-manager.c -@@ -250,6 +250,12 @@ photos_base_manager_default_get_where (PhotosBaseManager *self, gint flags) - } - - -+static PhotosSparqlTemplate * -+photos_base_manager_default_get_sparql_template (PhotosBaseManager *self, gint flags) -+{ -+ return NULL; -+} -+ - static void - photos_base_manager_default_remove_object_by_id (PhotosBaseManager *self, const gchar *id) - { -@@ -438,6 +444,7 @@ photos_base_manager_class_init (PhotosBaseManagerClass *class) - class->get_object_by_id = photos_base_manager_default_get_object_by_id; - class->get_previous_object = photos_base_manager_default_get_previous_object; - class->get_where = photos_base_manager_default_get_where; -+ class->get_sparql_template = photos_base_manager_default_get_sparql_template; - class->remove_object_by_id = photos_base_manager_default_remove_object_by_id; - class->set_active_object = photos_base_manager_default_set_active_object; - -@@ -714,6 +721,14 @@ photos_base_manager_get_where (PhotosBaseManager *self, gint flags) - } - - -+PhotosSparqlTemplate * -+photos_base_manager_get_sparql_template (PhotosBaseManager *self, gint flags) -+{ -+ g_return_val_if_fail (PHOTOS_IS_BASE_MANAGER (self), NULL); -+ return PHOTOS_BASE_MANAGER_GET_CLASS (self)->get_sparql_template (self, flags); -+} -+ -+ - void - photos_base_manager_process_new_objects (PhotosBaseManager *self, GHashTable *new_objects) - { -diff --git a/src/photos-base-manager.h b/src/photos-base-manager.h -index 99d203e9..04cfa7db 100644 ---- a/src/photos-base-manager.h -+++ b/src/photos-base-manager.h -@@ -24,6 +24,7 @@ - #define PHOTOS_BASE_MANAGER_H - - #include -+#include "photos-sparql-template.h" - - G_BEGIN_DECLS - -@@ -46,6 +47,7 @@ struct _PhotosBaseManagerClass - gchar *(*get_where) (PhotosBaseManager *self, gint flags); - void (*remove_object_by_id) (PhotosBaseManager *self, const gchar *id); - gboolean (*set_active_object) (PhotosBaseManager *self, GObject *object); -+ PhotosSparqlTemplate *(*get_sparql_template) (PhotosBaseManager *self, gint flags); - - /* signals */ - void (*active_changed) (PhotosBaseManager *self, GObject *object); -@@ -80,6 +82,8 @@ const gchar *photos_base_manager_get_title (PhotosBaseMana - - gchar *photos_base_manager_get_where (PhotosBaseManager *self, gint flags); - -+PhotosSparqlTemplate *photos_base_manager_get_sparql_template (PhotosBaseManager *self, gint flags); -+ - void photos_base_manager_process_new_objects (PhotosBaseManager *self, GHashTable *new_objects); - - void photos_base_manager_remove_object (PhotosBaseManager *self, GObject *object); -diff --git a/src/photos-filterable.c b/src/photos-filterable.c -index 361b1c29..aaa4109c 100644 ---- a/src/photos-filterable.c -+++ b/src/photos-filterable.c -@@ -69,14 +69,6 @@ photos_filterable_get_id (PhotosFilterable *self) - } - - --gchar * --photos_filterable_get_where (PhotosFilterable *self) --{ -- g_return_val_if_fail (PHOTOS_IS_FILTERABLE (self), NULL); -- return PHOTOS_FILTERABLE_GET_IFACE (self)->get_where (self); --} -- -- - gboolean - photos_filterable_is_search_criterion (PhotosFilterable *self) - { -diff --git a/src/photos-filterable.h b/src/photos-filterable.h -index e768bca0..8a3415fc 100644 ---- a/src/photos-filterable.h -+++ b/src/photos-filterable.h -@@ -37,7 +37,6 @@ struct _PhotosFilterableInterface - gboolean (*get_builtin) (PhotosFilterable *self); - gchar *(*get_filter) (PhotosFilterable *self); - const gchar *(*get_id) (PhotosFilterable *self); -- gchar *(*get_where) (PhotosFilterable *self); - gboolean (*is_search_criterion) (PhotosFilterable *self); - }; - -@@ -47,8 +46,6 @@ gchar *photos_filterable_get_filter (PhotosFilterable *self - - const gchar *photos_filterable_get_id (PhotosFilterable *self); - --gchar *photos_filterable_get_where (PhotosFilterable *self); -- - gboolean photos_filterable_is_search_criterion (PhotosFilterable *self); - - G_END_DECLS -diff --git a/src/photos-query-builder.c b/src/photos-query-builder.c -index 2c52a130..5d9d8a5a 100644 ---- a/src/photos-query-builder.c -+++ b/src/photos-query-builder.c -@@ -26,112 +26,76 @@ - #include - - #include "photos-base-manager.h" -+#include "photos-query.h" - #include "photos-query-builder.h" - #include "photos-search-type.h" - #include "photos-source-manager.h" - #include "photos-search-match-manager.h" - #include "photos-search-type-manager.h" - -+#define PHOTOS_QUERY_COLLECTIONS_IDENTIFIER "photos:collection:" -+#define PHOTOS_QUERY_LOCAL_COLLECTIONS_IDENTIFIER "photos:collection:local:" - --static gchar * --photos_query_builder_filter (PhotosSearchContextState *state, gint flags) --{ -- gchar *sparql; -- g_autofree gchar *src_mngr_filter = NULL; -- g_autofree gchar *srch_mtch_mngr_filter = NULL; -- g_autofree gchar *srch_typ_mngr_filter = NULL; -+const gchar *collections_default_filter = \ -+ "(fn:starts-with (nao:identifier (?urn), '" PHOTOS_QUERY_COLLECTIONS_IDENTIFIER "')" -+ " || (?urn = nfo:image-category-screenshot))"; - -- src_mngr_filter = photos_base_manager_get_filter (state->src_mngr, flags); -- srch_mtch_mngr_filter = photos_base_manager_get_filter (state->srch_mtch_mngr, flags); -- srch_typ_mngr_filter = photos_base_manager_get_filter (state->srch_typ_mngr, flags); - -- sparql = g_strdup_printf ("FILTER (%s && %s && %s)", -- src_mngr_filter, -- srch_mtch_mngr_filter, -- srch_typ_mngr_filter); -- -- return sparql; --} -+/* This includes mimetype blocklist */ -+const gchar *photos_default_filter = \ -+ "(nie:mimeType(?urn) != 'image/gif' && nie:mimeType(?urn) != 'image/x-eps')"; - - - static gchar * --photos_query_builder_optional (void) --{ -- return g_strdup ("OPTIONAL { ?urn nco:creator ?creator . } " -- "OPTIONAL { ?urn nco:publisher ?publisher . }"); --} -- -- --static gchar * --photos_query_builder_inner_where (PhotosSearchContextState *state, gboolean global, gint flags) -+photos_query_builder_query (PhotosSearchContextState *state, -+ gboolean global, -+ gint flags, -+ PhotosOffsetController *offset_cntrlr) - { -- g_autofree gchar *item_mngr_where = NULL; -+ PhotosSparqlTemplate *template; -+ const gchar *projection = NULL; -+ g_autofree gchar *item_pattern = NULL; -+ g_autofree gchar *search_filter = NULL; -+ g_autofree gchar *source_filter = NULL; -+ const gchar *order = NULL; -+ g_autofree gchar *offset_limit = NULL; - gchar *sparql; -- g_autofree gchar *srch_typ_mngr_where = NULL; - -- srch_typ_mngr_where = photos_base_manager_get_where (state->srch_typ_mngr, flags); -+ template = photos_base_manager_get_sparql_template (state->srch_typ_mngr, flags); -+ -+ projection = "?urn " -+ "nie:url (?urn) " -+ "nfo:fileName (?urn) " -+ "nie:mimeType (?urn) " -+ "nie:title (?urn) " -+ "tracker:coalesce (nco:fullname (?creator), nco:fullname (?publisher), '') " -+ "tracker:coalesce (nfo:fileLastModified (?urn), nie:contentLastModified (?urn)) AS ?mtime " -+ "nao:identifier (?urn) " -+ "rdf:type (?urn) " -+ "nie:dataSource(?urn) " -+ "( EXISTS { ?urn nao:hasTag nao:predefined-tag-favorite } ) " -+ "( EXISTS { ?urn nco:contributor ?contributor FILTER ( ?contributor != ?creator ) } ) " -+ "tracker:coalesce(nfo:fileCreated (?urn), nie:contentCreated (?urn)) " -+ "nfo:width (?urn) " -+ "nfo:height (?urn) " -+ "nfo:equipment (?urn) " -+ "nfo:orientation (?urn) " -+ "nmm:exposureTime (?urn) " -+ "nmm:fnumber (?urn) " -+ "nmm:focalLength (?urn) " -+ "nmm:isoSpeed (?urn) " -+ "nmm:flash (?urn) " -+ "slo:location (?urn) "; -+ -+ item_pattern = photos_base_manager_get_where (state->item_mngr, flags); - - if (!(flags & PHOTOS_QUERY_FLAGS_UNFILTERED)) - { -- if (global) -- { -- /* TODO: SearchCategoryManager */ -- -- item_mngr_where = photos_base_manager_get_where (state->item_mngr, flags); -- } -+ source_filter = photos_base_manager_get_filter (state->src_mngr, flags); -+ search_filter = photos_base_manager_get_filter (state->srch_mtch_mngr, flags); - } - -- sparql = g_strdup_printf ("WHERE { %s %s }", -- srch_typ_mngr_where, -- (item_mngr_where != NULL) ? item_mngr_where : ""); -- -- return sparql; --} -- -- --static gchar * --photos_query_builder_where (PhotosSearchContextState *state, gboolean global, gint flags) --{ -- const gchar *count_items = "COUNT (?item) AS ?count"; -- gboolean item_defined; -- g_autofree gchar *filter = NULL; -- g_autofree gchar *optional = NULL; -- gchar *sparql; -- g_autofree gchar *where_sparql = NULL; -- -- where_sparql = photos_query_builder_inner_where (state, global, flags); -- item_defined = strstr (where_sparql, "?item") != NULL; -- -- optional = photos_query_builder_optional (); -- -- if (!(flags & PHOTOS_QUERY_FLAGS_UNFILTERED)) -- filter = photos_query_builder_filter (state, flags); -- -- sparql = g_strdup_printf ("WHERE {{" -- " SELECT ?urn rdf:type (?urn) AS ?type %s %s GROUP BY (?urn)" -- " }" -- " %s %s" -- "}", -- item_defined ? count_items : "", -- where_sparql, -- optional, -- (filter != NULL) ? filter : ""); -- -- return sparql; --} -- -- --static gchar * --photos_query_builder_query (PhotosSearchContextState *state, -- gboolean global, -- gint flags, -- PhotosOffsetController *offset_cntrlr) --{ -- gchar *sparql; -- g_autofree gchar *tail_sparql = NULL; -- g_autofree gchar *where_sparql = NULL; -- -- where_sparql = photos_query_builder_where (state, global, flags); -+ order = "ORDER BY DESC (?mtime)"; - - if (global && (flags & PHOTOS_QUERY_FLAGS_UNLIMITED) == 0) - { -@@ -144,35 +108,19 @@ photos_query_builder_query (PhotosSearchContextState *state, - step = photos_offset_controller_get_step (offset_cntrlr); - } - -- tail_sparql = g_strdup_printf ("ORDER BY DESC (?mtime) LIMIT %d OFFSET %d", step, offset); -+ offset_limit = g_strdup_printf ("LIMIT %d OFFSET %d", step, offset); - } - -- sparql = g_strconcat ("SELECT ?urn " -- "nie:url (?urn) " -- "nfo:fileName (?urn) " -- "nie:mimeType (?urn) " -- "nie:title (?urn) " -- "tracker:coalesce (nco:fullname (?creator), nco:fullname (?publisher), '') " -- "tracker:coalesce (nfo:fileLastModified (?urn), nie:contentLastModified (?urn)) AS ?mtime " -- "nao:identifier (?urn) " -- "rdf:type (?urn) " -- "nie:dataSource(?urn) " -- "( EXISTS { ?urn nao:hasTag nao:predefined-tag-favorite } ) " -- "( EXISTS { ?urn nco:contributor ?contributor FILTER ( ?contributor != ?creator ) } ) " -- "tracker:coalesce(nfo:fileCreated (?urn), nie:contentCreated (?urn)) " -- "nfo:width (?urn) " -- "nfo:height (?urn) " -- "nfo:equipment (?urn) " -- "nfo:orientation (?urn) " -- "nmm:exposureTime (?urn) " -- "nmm:fnumber (?urn) " -- "nmm:focalLength (?urn) " -- "nmm:isoSpeed (?urn) " -- "nmm:flash (?urn) " -- "slo:location (?urn) ", -- where_sparql, -- tail_sparql, -- NULL); -+ sparql = photos_sparql_template_get_sparql (template, -+ "projection", projection, -+ "collections_default_filter", collections_default_filter, -+ "item_pattern", item_pattern, -+ "photos_default_filter", photos_default_filter, -+ "source_filter", source_filter ? source_filter : "", -+ "search_filter", search_filter ? search_filter : "", -+ "order", order, -+ "offset_limit", offset_limit ? offset_limit : "", -+ NULL); - - return sparql; - } -@@ -234,12 +182,37 @@ photos_query_builder_collection_icon_query (PhotosSearchContextState *state, con - PhotosQuery * - photos_query_builder_count_query (PhotosSearchContextState *state, gint flags) - { -- PhotosQuery *query; -+ PhotosSparqlTemplate *template; -+ const gchar *projection = NULL; -+ g_autofree gchar *item_pattern = NULL; -+ g_autofree gchar *search_filter = NULL; -+ g_autofree gchar *source_filter = NULL; - g_autofree gchar *sparql = NULL; -- g_autofree gchar *where_sparql = NULL; -+ PhotosQuery *query; -+ -+ template = photos_base_manager_get_sparql_template (state->srch_typ_mngr, flags); -+ -+ projection = "COUNT(?urn) "; -+ -+ item_pattern = photos_base_manager_get_where (state->item_mngr, flags); -+ -+ if (! (flags & PHOTOS_QUERY_FLAGS_UNFILTERED)) -+ { -+ source_filter = photos_base_manager_get_filter (state->src_mngr, flags); -+ search_filter = photos_base_manager_get_filter (state->srch_mtch_mngr, flags); -+ } -+ -+ sparql = photos_sparql_template_get_sparql (template, -+ "projection", projection, -+ "collections_default_filter", collections_default_filter, -+ "item_pattern", item_pattern, -+ "photos_default_filter", photos_default_filter, -+ "source_filter", source_filter ? source_filter : "", -+ "search_filter", search_filter ? search_filter : "", -+ "order", "", -+ "offset_limit", "", -+ NULL); - -- where_sparql = photos_query_builder_where (state, TRUE, flags); -- sparql = g_strconcat ("SELECT DISTINCT COUNT(?urn) ", where_sparql, NULL); - query = photos_query_new (state, sparql); - - return query; -diff --git a/src/photos-search-type-manager.c b/src/photos-search-type-manager.c -index 87f441ed..5c87d4a4 100644 ---- a/src/photos-search-type-manager.c -+++ b/src/photos-search-type-manager.c -@@ -41,13 +41,6 @@ struct _PhotosSearchTypeManager - G_DEFINE_TYPE (PhotosSearchTypeManager, photos_search_type_manager, PHOTOS_TYPE_BASE_MANAGER); - - --static const gchar *BLACKLISTED_MIME_TYPES[] = --{ -- "image/gif", -- "image/x-eps" --}; -- -- - static gchar * - photos_search_type_manager_get_filter (PhotosBaseManager *mngr, gint flags) - { -@@ -69,9 +62,8 @@ photos_search_type_manager_get_filter (PhotosBaseManager *mngr, gint flags) - return filter; - } - -- --static gchar * --photos_search_type_manager_get_where (PhotosBaseManager *mngr, gint flags) -+static PhotosSparqlTemplate * -+photos_search_type_manager_get_sparql_template (PhotosBaseManager *mngr, gint flags) - { - GObject *search_type; - -@@ -86,74 +78,39 @@ photos_search_type_manager_get_where (PhotosBaseManager *mngr, gint flags) - else - search_type = photos_base_manager_get_object_by_id (mngr, PHOTOS_SEARCH_TYPE_STOCK_ALL); - -- return photos_filterable_get_where (PHOTOS_FILTERABLE (search_type)); -+ return photos_search_type_get_sparql_template (PHOTOS_SEARCH_TYPE (search_type)); - } - -- - static void - photos_search_type_manager_init (PhotosSearchTypeManager *self) - { - PhotosSearchType *search_type; -- gchar *item_filter; -- gchar *all_filter; -- gchar *blacklisted_mime_types_filter; -- gchar *col_filter; -- gchar **strv; -- guint i; -- guint n_elements; -- -- n_elements = G_N_ELEMENTS (BLACKLISTED_MIME_TYPES); -- strv = (gchar **) g_malloc0_n (n_elements + 1, sizeof (gchar *)); -- for (i = 0; i < n_elements; i++) -- strv[i] = g_strdup_printf ("nie:mimeType(?urn) != '%s'", BLACKLISTED_MIME_TYPES[i]); -- -- blacklisted_mime_types_filter = g_strjoinv (" && ", strv); -- -- item_filter = g_strdup_printf ("(fn:contains (?type, 'nmm#Photo') && %s)", blacklisted_mime_types_filter); -- col_filter = g_strdup_printf ("(fn:contains (?type, 'nfo#DataContainer')" -- " && ?count > 0" -- " && (fn:starts-with (nao:identifier (?urn), '%s')" -- " || (?urn = nfo:image-category-screenshot)))", -- PHOTOS_QUERY_COLLECTIONS_IDENTIFIER); -- all_filter = g_strdup_printf ("(%s || %s)", col_filter, item_filter); - - search_type = photos_search_type_new_full (PHOTOS_SEARCH_TYPE_STOCK_ALL, - _("All"), -- "?urn a rdfs:Resource. " -- "OPTIONAL {?item a nmm:Photo; nie:isPartOf ?urn}", -- all_filter); -+ "resource:///org/gnome/Photos/all.sparql.template"); - photos_base_manager_add_object (PHOTOS_BASE_MANAGER (self), G_OBJECT (search_type)); - g_object_unref (search_type); - - search_type = photos_search_type_new_full (PHOTOS_SEARCH_TYPE_STOCK_COLLECTIONS, - _("Albums"), -- "?urn a nfo:DataContainer. " -- "?item a nmm:Photo; nie:isPartOf ?urn.", -- col_filter); -+ "resource:///org/gnome/Photos/collections.sparql.template"); - photos_base_manager_add_object (PHOTOS_BASE_MANAGER (self), G_OBJECT (search_type)); - g_object_unref (search_type); - - search_type = photos_search_type_new_full (PHOTOS_SEARCH_TYPE_STOCK_FAVORITES, - _("Favorites"), -- "?urn a nmm:Photo; nao:hasTag nao:predefined-tag-favorite. ", -- blacklisted_mime_types_filter); -+ "resource:///org/gnome/Photos/favorite-photos.sparql.template"); - photos_base_manager_add_object (PHOTOS_BASE_MANAGER (self), G_OBJECT (search_type)); - g_object_unref (search_type); - - search_type = photos_search_type_new_full (PHOTOS_SEARCH_TYPE_STOCK_PHOTOS, - _("Photos"), -- "?urn a nmm:Photo", -- blacklisted_mime_types_filter); -+ "resource:///org/gnome/Photos/photos.sparql.template"); - photos_base_manager_add_object (PHOTOS_BASE_MANAGER (self), G_OBJECT (search_type)); - g_object_unref (search_type); - - photos_base_manager_set_active_object_by_id (PHOTOS_BASE_MANAGER (self), PHOTOS_SEARCH_TYPE_STOCK_ALL); -- -- g_free (item_filter); -- g_free (all_filter); -- g_free (blacklisted_mime_types_filter); -- g_free (col_filter); -- g_strfreev (strv); - } - - -@@ -163,7 +120,7 @@ photos_search_type_manager_class_init (PhotosSearchTypeManagerClass *class) - PhotosBaseManagerClass *base_manager_class = PHOTOS_BASE_MANAGER_CLASS (class); - - base_manager_class->get_filter = photos_search_type_manager_get_filter; -- base_manager_class->get_where = photos_search_type_manager_get_where; -+ base_manager_class->get_sparql_template = photos_search_type_manager_get_sparql_template; - } - - -diff --git a/src/photos-search-type.c b/src/photos-search-type.c -index 44dc60eb..f3bbae15 100644 ---- a/src/photos-search-type.c -+++ b/src/photos-search-type.c -@@ -25,24 +25,23 @@ - - #include "photos-filterable.h" - #include "photos-search-type.h" -+#include "photos-sparql-template.h" - - - struct _PhotosSearchType - { - GObject parent_instance; -- gchar *filter; - gchar *id; - gchar *name; -- gchar *where; -+ PhotosSparqlTemplate *sparql_template; - }; - - enum - { - PROP_0, -- PROP_FILTER, - PROP_ID, - PROP_NAME, -- PROP_WHERE, -+ PROP_SPARQL_TEMPLATE, - }; - - static void photos_search_type_filterable_iface_init (PhotosFilterableInterface *iface); -@@ -53,14 +52,6 @@ G_DEFINE_TYPE_WITH_CODE (PhotosSearchType, photos_search_type, G_TYPE_OBJECT, - photos_search_type_filterable_iface_init)); - - --static gchar * --photos_search_type_get_filter (PhotosFilterable *iface) --{ -- PhotosSearchType *self = PHOTOS_SEARCH_TYPE (iface); -- return g_strdup (self->filter); --} -- -- - static const gchar * - photos_search_type_get_id (PhotosFilterable *filterable) - { -@@ -69,14 +60,6 @@ photos_search_type_get_id (PhotosFilterable *filterable) - } - - --static gchar * --photos_search_type_get_where (PhotosFilterable *iface) --{ -- PhotosSearchType *self = PHOTOS_SEARCH_TYPE (iface); -- return g_strdup (self->where); --} -- -- - static gboolean - photos_search_type_is_search_criterion (PhotosFilterable *iface) - { -@@ -84,15 +67,20 @@ photos_search_type_is_search_criterion (PhotosFilterable *iface) - } - - -+PhotosSparqlTemplate * -+photos_search_type_get_sparql_template (PhotosSearchType *self) -+{ -+ return self->sparql_template; -+} -+ - static void - photos_search_type_finalize (GObject *object) - { - PhotosSearchType *self = PHOTOS_SEARCH_TYPE (object); - -- g_free (self->filter); - g_free (self->id); - g_free (self->name); -- g_free (self->where); -+ g_clear_object (&self->sparql_template); - - G_OBJECT_CLASS (photos_search_type_parent_class)->finalize (object); - } -@@ -113,6 +101,10 @@ photos_search_type_get_property (GObject *object, guint prop_id, GValue *value, - g_value_set_string (value, self->name); - break; - -+ case PROP_SPARQL_TEMPLATE: -+ g_value_set_object (value, self->sparql_template); -+ break; -+ - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; -@@ -127,10 +119,6 @@ photos_search_type_set_property (GObject *object, guint prop_id, const GValue *v - - switch (prop_id) - { -- case PROP_FILTER: -- self->filter = g_value_dup_string (value); -- break; -- - case PROP_ID: - self->id = g_value_dup_string (value); - break; -@@ -139,8 +127,8 @@ photos_search_type_set_property (GObject *object, guint prop_id, const GValue *v - self->name = g_value_dup_string (value); - break; - -- case PROP_WHERE: -- self->where = g_value_dup_string (value); -+ case PROP_SPARQL_TEMPLATE: -+ self->sparql_template = g_object_ref (g_value_get_object (value)); - break; - - default: -@@ -165,14 +153,6 @@ photos_search_type_class_init (PhotosSearchTypeClass *class) - object_class->get_property = photos_search_type_get_property; - object_class->set_property = photos_search_type_set_property; - -- g_object_class_install_property (object_class, -- PROP_FILTER, -- g_param_spec_string ("filter", -- "", -- "", -- "(true)", -- G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE)); -- - g_object_class_install_property (object_class, - PROP_ID, - g_param_spec_string ("id", -@@ -190,11 +170,11 @@ photos_search_type_class_init (PhotosSearchTypeClass *class) - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, -- PROP_WHERE, -- g_param_spec_string ("where", -- "", -+ PROP_SPARQL_TEMPLATE, -+ g_param_spec_object ("sparql-template", - "", - "", -+ PHOTOS_TYPE_SPARQL_TEMPLATE, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE)); - } - -@@ -202,9 +182,7 @@ photos_search_type_class_init (PhotosSearchTypeClass *class) - static void - photos_search_type_filterable_iface_init (PhotosFilterableInterface *iface) - { -- iface->get_filter = photos_search_type_get_filter; - iface->get_id = photos_search_type_get_id; -- iface->get_where = photos_search_type_get_where; - iface->is_search_criterion = photos_search_type_is_search_criterion; - } - -@@ -217,12 +195,13 @@ photos_search_type_new (const gchar *id, const gchar *name) - - - PhotosSearchType * --photos_search_type_new_full (const gchar *id, const gchar *name, const gchar *where, const gchar *filter) -+photos_search_type_new_full (const gchar *id, const gchar *name, const gchar *template_path) - { -+ g_autoptr (PhotosSparqlTemplate) template = photos_sparql_template_new (template_path); -+ - return g_object_new (PHOTOS_TYPE_SEARCH_TYPE, - "id", id, - "name", name, -- "filter", filter, -- "where", where, -+ "sparql-template", template, - NULL); - } -diff --git a/src/photos-search-type.h b/src/photos-search-type.h -index 2f7135bd..7d699dd4 100644 ---- a/src/photos-search-type.h -+++ b/src/photos-search-type.h -@@ -24,6 +24,7 @@ - #define PHOTOS_SEARCH_TYPE_H - - #include -+#include "photos-sparql-template.h" - - G_BEGIN_DECLS - -@@ -39,8 +40,9 @@ PhotosSearchType *photos_search_type_new (const gchar *id, con - - PhotosSearchType *photos_search_type_new_full (const gchar *id, - const gchar *name, -- const gchar *where, -- const gchar *filter); -+ const gchar *template_path); -+ -+PhotosSparqlTemplate *photos_search_type_get_sparql_template (PhotosSearchType *self); - - G_END_DECLS - -diff --git a/src/photos-sparql-template.c b/src/photos-sparql-template.c -new file mode 100644 -index 00000000..b32437c0 ---- /dev/null -+++ b/src/photos-sparql-template.c -@@ -0,0 +1,187 @@ -+/* -+ * Photos - access, organize and share your photos on GNOME -+ * Copyright © 2020 Sam Thursfield -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+ -+#include "photos-sparql-template.h" -+ -+#define MAX_SPARQL_TEMPLATE_SIZE (1024 * 10) -+ -+struct _PhotosSparqlTemplate { -+ GObject parent_instance; -+ gchar *template_path; -+ gchar *template_text; -+}; -+ -+G_DEFINE_TYPE (PhotosSparqlTemplate, photos_sparql_template, G_TYPE_OBJECT) -+ -+enum { -+ PROP_0, -+ PROP_TEMPLATE_PATH, -+ N_PROPS -+}; -+ -+PhotosSparqlTemplate * -+photos_sparql_template_new (const gchar *template_path) -+{ -+ return g_object_new (PHOTOS_TYPE_SPARQL_TEMPLATE, "template-path", template_path, NULL); -+} -+ -+static void -+photos_sparql_template_constructed (GObject *object) -+{ -+ PhotosSparqlTemplate *self = PHOTOS_SPARQL_TEMPLATE (object); -+ g_autoptr (GFile) file = NULL; -+ g_autoptr (GFileInputStream) stream = NULL; -+ gchar buffer[MAX_SPARQL_TEMPLATE_SIZE + 1]; -+ gsize bytes_read; -+ g_autoptr (GError) error = NULL; -+ -+ G_OBJECT_CLASS (photos_sparql_template_parent_class)->constructed (object); -+ -+ file = g_file_new_for_uri (self->template_path); -+ -+ stream = g_file_read (file, NULL, &error); -+ -+ if (!stream) -+ { -+ g_critical ("Failed to open template %s: %s", self->template_path, error->message); -+ } -+ -+ g_input_stream_read_all (G_INPUT_STREAM (stream), buffer, MAX_SPARQL_TEMPLATE_SIZE, &bytes_read, NULL, &error); -+ -+ if (error) -+ { -+ g_critical ("Failed to read template %s: %s", self->template_path, error->message); -+ } -+ -+ buffer[bytes_read] = '\0'; -+ -+ self->template_text = g_strdup (buffer); -+} -+ -+static void -+photos_sparql_template_finalize (GObject *object) -+{ -+ G_OBJECT_CLASS (photos_sparql_template_parent_class)->finalize (object); -+} -+ -+static void -+photos_sparql_template_get_property (GObject *object, -+ guint prop_id, -+ GValue *value, -+ GParamSpec *pspec) -+{ -+ PhotosSparqlTemplate *self = PHOTOS_SPARQL_TEMPLATE (object); -+ -+ switch (prop_id) -+ { -+ case PROP_TEMPLATE_PATH: -+ g_value_set_string (value, self->template_path); -+ break; -+ -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ } -+} -+ -+static void -+photos_sparql_template_set_property (GObject *object, -+ guint prop_id, -+ const GValue *value, -+ GParamSpec *pspec) -+{ -+ PhotosSparqlTemplate *self = PHOTOS_SPARQL_TEMPLATE (object); -+ -+ switch (prop_id) -+ { -+ case PROP_TEMPLATE_PATH: -+ self->template_path = g_value_dup_string (value); -+ break; -+ -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ } -+} -+ -+static void -+photos_sparql_template_class_init (PhotosSparqlTemplateClass *klass) -+{ -+ GObjectClass *object_class = G_OBJECT_CLASS (klass); -+ -+ object_class->constructed = photos_sparql_template_constructed; -+ object_class->finalize = photos_sparql_template_finalize; -+ object_class->get_property = photos_sparql_template_get_property; -+ object_class->set_property = photos_sparql_template_set_property; -+ -+ g_object_class_install_property (object_class, -+ PROP_TEMPLATE_PATH, -+ g_param_spec_string ("template-path", -+ "Template path", -+ "Path to the template file.", -+ NULL, -+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); -+} -+ -+static void -+photos_sparql_template_init (PhotosSparqlTemplate *self) -+{ -+} -+ -+ -+gchar * -+photos_sparql_template_get_sparql (PhotosSparqlTemplate *self, -+ const gchar *first_binding_name, ...) -+{ -+ va_list va; -+ gchar *sparql; -+ -+ sparql = self->template_text; -+ -+ /* FIXME: this is an inefficent way to do template substitutions -+ * because we allocate and free a copy of the string for each binding. -+ * We should check https://gitlab.gnome.org/GNOME/template-glib/ -+ */ -+ if (first_binding_name) -+ { -+ GRegex *regex; -+ gchar *name_regex; -+ const gchar *name; -+ const gchar *value; -+ -+ va_start (va, first_binding_name); -+ name = first_binding_name; -+ do { -+ value = va_arg (va, const gchar *); -+ -+ if (value == NULL) -+ { -+ g_critical ("Missing value for argument \"%s\"", name); -+ break; -+ } -+ -+ name_regex = g_strdup_printf ("{{\\s?%s\\s?}}", name); -+ regex = g_regex_new (name_regex, 0, 0, NULL); -+ sparql = g_regex_replace_literal (regex, sparql, -1, 0, value, 0, NULL) ; -+ } while ((name = va_arg (va, const gchar *))); -+ -+ va_end (va); -+ } -+ -+ return sparql; -+} -diff --git a/src/photos-sparql-template.h b/src/photos-sparql-template.h -new file mode 100644 -index 00000000..66351b38 ---- /dev/null -+++ b/src/photos-sparql-template.h -@@ -0,0 +1,38 @@ -+/* -+ * Photos - access, organize and share your photos on GNOME -+ * Copyright © 2020 Sam Thursfield -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#pragma once -+ -+#include -+ -+G_BEGIN_DECLS -+ -+#define PHOTOS_TYPE_SPARQL_TEMPLATE (photos_sparql_template_get_type()) -+ -+G_DECLARE_FINAL_TYPE (PhotosSparqlTemplate, photos_sparql_template, PHOTOS, SPARQL_TEMPLATE, GObject) -+ -+struct _PhotosSparqlTemplateClass -+{ -+ GObjectClass parent_class; -+}; -+ -+PhotosSparqlTemplate *photos_sparql_template_new (const gchar *template_path); -+ -+gchar *photos_sparql_template_get_sparql (PhotosSparqlTemplate *self, const gchar *first_binding_name, ...) G_GNUC_NULL_TERMINATED; -+ -+G_END_DECLS -diff --git a/src/photos.gresource.xml b/src/photos.gresource.xml -index 1015b11d..39e6d842 100644 ---- a/src/photos.gresource.xml -+++ b/src/photos.gresource.xml -@@ -35,6 +35,10 @@ - photos-selection-toolbar.ui - photos-share-dialog.ui - photos-zoom-controls.ui -+ queries/all.sparql.template -+ queries/collections.sparql.template -+ queries/favorite-photos.sparql.template -+ queries/photos.sparql.template - - - -diff --git a/src/queries/all.sparql.template b/src/queries/all.sparql.template -new file mode 100644 -index 00000000..1cef98e8 ---- /dev/null -+++ b/src/queries/all.sparql.template -@@ -0,0 +1,31 @@ -+SELECT {{projection}} -+{ -+ { -+ SELECT {{projection}} -+ { -+ { -+ SELECT ?urn COUNT(?item) AS ?count -+ { -+ ?urn a nfo:DataContainer. -+ ?item a nmm:Photo; nie:isPartOf ?urn. -+ } GROUP BY ?urn -+ } -+ FILTER (?count > 0 && {{collections_default_filter}} && {{search_filter}}) -+ } -+ GROUP BY ?urn -+ } -+ UNION -+ { -+ SELECT {{projection}} -+ { -+ ?urn a nmm:Photo . -+ OPTIONAL { ?urn nco:creator ?creator . } -+ OPTIONAL { ?urn nco:publisher ?publisher . } -+ {{item_pattern}} -+ FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+ } -+ GROUP BY ?urn -+ } -+} -+{{order}} -+{{offset_limit}} -diff --git a/src/queries/collections.sparql.template b/src/queries/collections.sparql.template -new file mode 100644 -index 00000000..20b35cd6 ---- /dev/null -+++ b/src/queries/collections.sparql.template -@@ -0,0 +1,14 @@ -+SELECT {{projection}} -+{ -+ { -+ SELECT ?urn COUNT(?item) AS ?count -+ { -+ ?urn a nfo:DataContainer. -+ ?item a nmm:Photo; nie:isPartOf ?urn. -+ } GROUP BY ?urn -+ } -+ FILTER (?count > 0 && {{collections_default_filter}} && {{search_filter}}) -+} -+GROUP BY ?urn -+{{order}} -+{{offset_limit}} -diff --git a/src/queries/favorite-photos.sparql.template b/src/queries/favorite-photos.sparql.template -new file mode 100644 -index 00000000..0885a08a ---- /dev/null -+++ b/src/queries/favorite-photos.sparql.template -@@ -0,0 +1,12 @@ -+SELECT {{projection}} -+{ -+ ?urn a nmm:Photo . -+ ?urn a nmm:Photo; nao:hasTag nao:predefined-tag-favorite . -+ OPTIONAL { ?urn nco:creator ?creator . } -+ OPTIONAL { ?urn nco:publisher ?publisher . } -+ {{item_pattern}} -+ FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+} -+GROUP BY ?urn -+{{order}} -+{{offset_limit}} -diff --git a/src/queries/photos.sparql.template b/src/queries/photos.sparql.template -new file mode 100644 -index 00000000..4eb10b74 ---- /dev/null -+++ b/src/queries/photos.sparql.template -@@ -0,0 +1,11 @@ -+SELECT {{projection}} -+{ -+ ?urn a nmm:Photo . -+ OPTIONAL { ?urn nco:creator ?creator . } -+ OPTIONAL { ?urn nco:publisher ?publisher . } -+ {{item_pattern}} -+ FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+} -+GROUP BY ?urn -+{{order}} -+{{offset_limit}} --- -GitLab - - -From dbbb76f228bad33334e0574784c34efb7071f950 Mon Sep 17 00:00:00 2001 -From: Sam Thursfield -Date: Sat, 23 May 2020 13:36:25 +0200 -Subject: [PATCH 3/3] Port to Tracker 3 - -Notable changes: - - * User data (favourites, albums) is now stored in a private database in - ~/.local/share/gnome-photos. This is combined with the Tracker Miner - FS index of photos at query time. - * Inside Flatpak, the app connects to Tracker via the new - xdg-tracker-portal instead of talking directly over D-Bus. Access is - limited by the portal so the app can only see the Pictures graph. - * The Flatpak build can use a bundled version of Tracker Miners, if a - suitable version is not available on the host. - * Change detection is done using TrackerNotifier instead of watching - the GraphUpdated D-Bus signal directly. - -Closes https://gitlab.gnome.org/GNOME/gnome-photos/-/issues/59 -Closes https://gitlab.gnome.org/GNOME/gnome-photos/-/issues/152 ---- - data/meson.build | 2 + - data/tracker/meson.build | 33 ++ - ...e.Photos.Tracker3.Miner.Extract.service.in | 7 + - ...ome.Photos.Tracker3.Miner.Files.service.in | 7 + - data/tracker/org.gnome.Photos.domain.rule.in | 20 + - flatpak/org.gnome.Photos.json | 49 +- - meson.build | 3 +- - src/meson.build | 19 +- - ...freedesktop.Tracker3.Miner.Files.Index.xml | 11 + - src/org.freedesktop.Tracker3.Miner.xml | 56 +++ - src/photos-application.c | 176 ++----- - src/photos-base-item.c | 10 + - src/photos-indexing-notification.c | 53 +- - src/photos-item-manager.c | 69 +-- - src/photos-quarks.c | 20 +- - src/photos-query-builder.c | 148 ++++-- - src/photos-search-context.c | 3 + - src/photos-search-context.h | 1 + - src/photos-search-match-manager.c | 2 +- - src/photos-source.c | 14 +- - src/photos-tracker-change-event.c | 136 ----- - src/photos-tracker-change-event.h | 64 --- - src/photos-tracker-change-monitor.c | 468 ------------------ - src/photos-tracker-change-monitor.h | 42 -- - src/photos-tracker-controller.c | 12 +- - src/photos-tracker-extract-priority.xml | 2 +- - src/photos-tracker-import-controller.c | 85 ++-- - src/photos-tracker-queue.c | 206 +++++++- - src/photos-tracker-queue.h | 7 + - src/photos-tracker-resources.xml | 31 -- - src/photos-utils.c | 24 +- - src/photos-utils.h | 2 +- - src/queries/all.sparql.template | 34 +- - src/queries/collections.sparql.template | 20 +- - src/queries/favorite-photos.sparql.template | 20 +- - src/queries/photos.sparql.template | 22 +- - 36 files changed, 736 insertions(+), 1142 deletions(-) - create mode 100644 data/tracker/meson.build - create mode 100644 data/tracker/org.gnome.Photos.Tracker3.Miner.Extract.service.in - create mode 100644 data/tracker/org.gnome.Photos.Tracker3.Miner.Files.service.in - create mode 100644 data/tracker/org.gnome.Photos.domain.rule.in - create mode 100644 src/org.freedesktop.Tracker3.Miner.Files.Index.xml - create mode 100644 src/org.freedesktop.Tracker3.Miner.xml - delete mode 100644 src/photos-tracker-change-event.c - delete mode 100644 src/photos-tracker-change-event.h - delete mode 100644 src/photos-tracker-change-monitor.c - delete mode 100644 src/photos-tracker-change-monitor.h - delete mode 100644 src/photos-tracker-resources.xml - -diff --git a/data/meson.build b/data/meson.build -index f51a4511..9b528c96 100644 ---- a/data/meson.build -+++ b/data/meson.build -@@ -83,3 +83,5 @@ install_data( - photos_namespace.to_lower() + '.gschema.xml', - install_dir: join_paths(photos_datadir, 'glib-2.0', 'schemas'), - ) -+ -+subdir('tracker') -diff --git a/data/tracker/meson.build b/data/tracker/meson.build -new file mode 100644 -index 00000000..accc99c2 ---- /dev/null -+++ b/data/tracker/meson.build -@@ -0,0 +1,33 @@ -+# 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', photos_namespace) -+tracker_domain_config.set('domain_rule', get_option('prefix') / domain_ontologies_dir / photos_namespace + '.domain.rule') -+ -+configure_file( -+ input: 'org.gnome.Photos.domain.rule.in', -+ output: photos_namespace + '.domain.rule', -+ configuration: tracker_domain_config, -+ install_dir: domain_ontologies_dir) -+ -+configure_file( -+ input: 'org.gnome.Photos.Tracker3.Miner.Extract.service.in', -+ output: photos_namespace + '.Tracker3.Miner.Extract.service', -+ configuration: tracker_domain_config, -+ install_dir: dbus_services_dir) -+ -+configure_file( -+ input: 'org.gnome.Photos.Tracker3.Miner.Files.service.in', -+ output: photos_namespace + '.Tracker3.Miner.Files.service', -+ configuration: tracker_domain_config, -+ install_dir: dbus_services_dir) -+ -diff --git a/data/tracker/org.gnome.Photos.Tracker3.Miner.Extract.service.in b/data/tracker/org.gnome.Photos.Tracker3.Miner.Extract.service.in -new file mode 100644 -index 00000000..eb7a87aa ---- /dev/null -+++ b/data/tracker/org.gnome.Photos.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.Photos.Tracker3.Miner.Files.service.in b/data/tracker/org.gnome.Photos.Tracker3.Miner.Files.service.in -new file mode 100644 -index 00000000..4fa7371d ---- /dev/null -+++ b/data/tracker/org.gnome.Photos.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.Photos.domain.rule.in b/data/tracker/org.gnome.Photos.domain.rule.in -new file mode 100644 -index 00000000..8f5fc4a1 ---- /dev/null -+++ b/data/tracker/org.gnome.Photos.domain.rule.in -@@ -0,0 +1,20 @@ -+# This defines a private Tracker domain for GNOME Photos. -+# -+# It's used to run the Tracker indexer inside a Flatpak sandbox, when Photos 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-photos/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/flatpak/org.gnome.Photos.json b/flatpak/org.gnome.Photos.json -index 4d3ac2a8..adfdaf34 100644 ---- a/flatpak/org.gnome.Photos.json -+++ b/flatpak/org.gnome.Photos.json -@@ -7,7 +7,7 @@ - "tags": [ "nightly" ], - "desktop-file-name-prefix": "(Nightly) ", - "finish-args": [ -- "--env=TRACKER_SPARQL_BACKEND=bus", -+ "--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Pictures", - "--filesystem=xdg-download", - "--filesystem=xdg-pictures", - "--metadata=X-DConf=migrate-path=/org/gnome/photos/", -@@ -17,8 +17,8 @@ - "--socket=wayland", - "--socket=x11", - "--talk-name=org.freedesktop.FileManager1", -- "--talk-name=org.freedesktop.Tracker1", -- "--talk-name=org.freedesktop.Tracker1.Miner.Extract", -+ "--talk-name=org.freedesktop.Tracker3.Miner.Files", -+ "--talk-name=org.freedesktop.Tracker3.Miner.Files.Index", - "--talk-name=com.intel.dleyna-renderer", - "--talk-name=org.gnome.ControlCenter", - "--talk-name=org.gnome.SettingsDaemon", -@@ -248,50 +248,22 @@ - } - ] - }, -- { -- "name": "tracker", -- "buildsystem": "meson", -- "cleanup": [ "/bin", "/etc", "/lib/girepository-1.0", "/share/dbus-1", "/share/gir-1.0" ], -- "config-opts": [ "-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": [ "*" ], -- "sources": [ -- { -- "type": "archive", -- "url": "https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz", -- "sha256": "67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd" -- } -- ] -- }, - { - "name": "tracker-miners", - "buildsystem": "meson", -- "cleanup": [ "/etc", -- "/share/dbus-1/services/org.freedesktop.Tracker1.Miner.Extract.service", -- "/share/dbus-1/services/org.freedesktop.Tracker1.Writeback.service", -- "/share/tracker/miners/org.freedesktop.Tracker1.Miner.Applications.service", -- "/share/tracker/miners/org.freedesktop.Tracker1.Miner.Extract.service", -- "/share/tracker/miners/org.freedesktop.Tracker1.Miner.RSS.service", -- "/share/glib-2.0/schemas/org.freedesktop.Tracker.Writeback.gschema.xml" ], -- "config-opts": [ "-Dextract=true", -+ "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=no", -+ "-Dsystemd_user_services=false", - "-Dwriteback=false" ], - "sources": [ - { - "type": "git", - "url": "https://gitlab.gnome.org/GNOME/tracker-miners.git", -- "branch": "tracker-miners-2.3" -+ "branch": "master" - } - ] - }, -@@ -303,7 +275,8 @@ - { - "type": "git", - "url": "https://gitlab.gnome.org/GNOME/gnome-photos.git", -- "disable-shallow-clone": "true" -+ "disable-shallow-clone": "true", -+ "branch": "sam/tracker3" - } - ] - } -diff --git a/meson.build b/meson.build -index ead63250..d20e1289 100644 ---- a/meson.build -+++ b/meson.build -@@ -172,8 +172,7 @@ libgdata_dep = dependency('libgdata', version: '>= 0.15.2') - libgfgraph_dep = dependency('libgfbgraph-0.2', version: '>= 0.2.1') - libjpeg_dep = dependency('libjpeg') - libpng_dep = dependency('libpng16') --tracker_control_dep = dependency('tracker-control-2.0') --tracker_sparql_dep = dependency('tracker-sparql-2.0') -+tracker_sparql_dep = dependency('tracker-sparql-3.0') - - dbus_dep = dependency('dbus-1') - dbus_services_dir = dbus_dep.get_pkgconfig_variable( -diff --git a/src/meson.build b/src/meson.build -index b5b2759c..6b3b7f01 100644 ---- a/src/meson.build -+++ b/src/meson.build -@@ -205,8 +205,6 @@ sources = common_sources + files( - 'photos-tool-enhance.c', - 'photos-tool-filter-button.c', - 'photos-tool-filters.c', -- 'photos-tracker-change-event.c', -- 'photos-tracker-change-monitor.c', - 'photos-tracker-collection-view-controller.c', - 'photos-tracker-collections-controller.c', - 'photos-tracker-controller.c', -@@ -367,22 +365,18 @@ sources += gnome.gdbus_codegen( - autocleanup: 'all', - ) - --tracker_extract_priority = 'photos-tracker-extract-priority' -- - sources += gnome.gdbus_codegen( -- tracker_extract_priority, -- tracker_extract_priority + '.xml', -- interface_prefix: 'org.freedesktop.Tracker1.', -+ 'photos-tracker-miner', -+ 'org.freedesktop.Tracker3.Miner.xml', -+ interface_prefix: 'org.freedesktop.Tracker3.', - namespace: 'Tracker', - autocleanup: 'all', - ) - --tracker_resources = 'photos-tracker-resources' -- - sources += gnome.gdbus_codegen( -- tracker_resources, -- tracker_resources + '.xml', -- interface_prefix: 'org.freedesktop.Tracker1.', -+ 'photos-tracker-miner-index', -+ 'org.freedesktop.Tracker3.Miner.Files.Index.xml', -+ interface_prefix: 'org.freedesktop.Tracker3.', - namespace: 'Tracker', - autocleanup: 'all', - ) -@@ -401,7 +395,6 @@ deps = common_deps + [ - libgdata_dep, - libgfgraph_dep, - m_dep, -- tracker_control_dep, - tracker_sparql_dep, - ] - -diff --git a/src/org.freedesktop.Tracker3.Miner.Files.Index.xml b/src/org.freedesktop.Tracker3.Miner.Files.Index.xml -new file mode 100644 -index 00000000..e368f1e2 ---- /dev/null -+++ b/src/org.freedesktop.Tracker3.Miner.Files.Index.xml -@@ -0,0 +1,11 @@ -+ -+ -+ -+ -+ -+ " -+ Extension flags, no allowed values at the moment -+ -+ -+ -+ -diff --git a/src/org.freedesktop.Tracker3.Miner.xml b/src/org.freedesktop.Tracker3.Miner.xml -new file mode 100644 -index 00000000..6fe09c84 ---- /dev/null -+++ b/src/org.freedesktop.Tracker3.Miner.xml -@@ -0,0 +1,56 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/src/photos-application.c b/src/photos-application.c -index f7b4b56e..7d6758cd 100644 ---- a/src/photos-application.c -+++ b/src/photos-application.c -@@ -36,7 +36,6 @@ - #include - #include - #include --#include - - #include "photos-application.h" - #include "photos-base-item.h" -@@ -68,7 +67,8 @@ - #include "photos-share-notification.h" - #include "photos-share-point-manager.h" - #include "photos-thumbnail-factory.h" --#include "photos-tracker-extract-priority.h" -+#include "photos-tracker-miner-index.h" -+#include "photos-tracker-queue.h" - #include "photos-utils.h" - - -@@ -127,8 +127,7 @@ struct _PhotosApplication - PhotosSearchProvider *search_provider; - PhotosSelectionController *sel_cntrlr; - PhotosThumbnailFactory *factory; -- TrackerMinerManager *miner_manager; -- TrackerExtractPriority *extract_priority; -+ TrackerMinerFilesIndex *miner_control_proxy; - gboolean empty_results; - gboolean main_window_deleted; - guint create_miners_count; -@@ -149,7 +148,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; - - static void photos_application_search_context_iface_init (PhotosSearchContextInterface *iface); - -- - G_DEFINE_TYPE_WITH_CODE (PhotosApplication, photos_application, GTK_TYPE_APPLICATION, - G_IMPLEMENT_INTERFACE (PHOTOS_TYPE_SEARCH_CONTEXT, - photos_application_search_context_iface_init)); -@@ -174,7 +172,6 @@ static const gchar *DESKTOP_KEY_PICTURE_OPTIONS = "picture-options"; - static const gchar *DESKTOP_KEY_COLOR_SHADING_TYPE = "color-shading-type"; - static const gchar *DESKTOP_KEY_PRIMARY_COLOR = "primary-color"; - static const gchar *DESKTOP_KEY_SECONDARY_COLOR = "secondary-color"; --static const gchar *MINER_FILES = "org.gnome.Photos.Tracker1.Miner.Files"; - - typedef struct _PhotosApplicationCreateData PhotosApplicationCreateData; - typedef struct _PhotosApplicationImportData PhotosApplicationImportData; -@@ -582,27 +579,6 @@ photos_application_actions_update (PhotosApplication *self) - } - - --static void --photos_application_tracker_clear_rdf_types (GObject *source_object, GAsyncResult *res, gpointer user_data) --{ -- PhotosApplication *self = PHOTOS_APPLICATION (user_data); -- TrackerExtractPriority *extract_priority = TRACKER_EXTRACT_PRIORITY (source_object); -- -- { -- g_autoptr (GError) error = NULL; -- -- if (!tracker_extract_priority_call_clear_rdf_types_finish (extract_priority, res, &error)) -- { -- g_warning ("Unable to call ClearRdfTypes: %s", error->message); -- goto out; -- } -- } -- -- out: -- g_application_release (G_APPLICATION (self)); --} -- -- - static gboolean - photos_application_delete_event (PhotosApplication *self) - { -@@ -639,16 +615,6 @@ photos_application_destroy (PhotosApplication *self) - self->create_window_cancellable = g_cancellable_new (); - - photos_application_stop_miners (self); -- -- if (self->extract_priority != NULL) -- { -- g_application_hold (G_APPLICATION (self)); -- tracker_extract_priority_call_clear_rdf_types (self->extract_priority, -- NULL, -- photos_application_tracker_clear_rdf_types, -- self); -- g_clear_object (&self->extract_priority); -- } - } - - -@@ -738,57 +704,34 @@ photos_application_gegl_init_fishes_idle (gpointer user_data) - } - - --static void --photos_application_tracker_set_rdf_types (GObject *source_object, GAsyncResult *res, gpointer user_data) -+static TrackerMinerFilesIndex * -+photos_application_get_miner_fs_control_proxy (GCancellable *cancellable) - { -- PhotosApplication *self = PHOTOS_APPLICATION (user_data); -- TrackerExtractPriority *extract_priority = TRACKER_EXTRACT_PRIORITY (source_object); -- -- { -- g_autoptr (GError) error = NULL; -+ g_autoptr (PhotosTrackerQueue) tracker_queue = NULL; -+ const gchar *miner_fs_control_busname; -+ g_autoptr (GError) error = NULL; -+ TrackerMinerFilesIndex *miner_control_proxy; - -- if (!tracker_extract_priority_call_set_rdf_types_finish (extract_priority, res, &error)) -- { -- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- g_warning ("Unable to call SetRdfTypes: %s", error->message); -+ tracker_queue = photos_tracker_queue_dup_singleton (cancellable, &error); - -- goto out; -- } -+ if (!tracker_queue) { -+ g_warning ("Error getting Tracker queue: %s. Import will not work.", error->message); -+ return NULL; - } - -- out: -- g_application_release (G_APPLICATION (self)); --} -- -- --static void --photos_application_tracker_extract_priority (GObject *source_object, GAsyncResult *res, gpointer user_data) --{ -- PhotosApplication *self = PHOTOS_APPLICATION (user_data); -- const gchar *const rdf_types[] = {"nfo:Image", NULL}; -- -- { -- g_autoptr (GError) error = NULL; -- -- self->extract_priority = tracker_extract_priority_proxy_new_for_bus_finish (res, &error); -- if (error != NULL) -- { -- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- g_warning ("Unable to create TrackerExtractPriority proxy: %s", error->message); -- -- goto out; -- } -+ miner_fs_control_busname = photos_tracker_queue_get_miner_fs_control_busname (tracker_queue); -+ miner_control_proxy = tracker_miner_files_index_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, -+ G_DBUS_PROXY_FLAGS_NONE, -+ miner_fs_control_busname, -+ "/org/freedesktop/Tracker3/Miner/Files/Control", -+ NULL, -+ &error); -+ if (!miner_control_proxy) { -+ g_warning ("Error getting Tracker Miner FS control proxy: %s. Import will not work", error->message); -+ return NULL; - } - -- g_application_hold (G_APPLICATION (self)); -- tracker_extract_priority_call_set_rdf_types (self->extract_priority, -- rdf_types, -- self->create_window_cancellable, -- photos_application_tracker_set_rdf_types, -- self); -- -- out: -- g_application_release (G_APPLICATION (self)); -+ return miner_control_proxy; - } - - -@@ -826,15 +769,10 @@ photos_application_create_window (PhotosApplication *self) - self->init_fishes_id = g_idle_add (photos_application_gegl_init_fishes_idle, self); - - g_application_hold (G_APPLICATION (self)); -- tracker_extract_priority_proxy_new_for_bus (G_BUS_TYPE_SESSION, -- G_DBUS_PROXY_FLAGS_NONE, -- "org.gnome.Photos.Tracker1.Miner.Extract", -- "/org/freedesktop/Tracker1/Extract/Priority", -- self->create_window_cancellable, -- photos_application_tracker_extract_priority, -- self); - - photos_application_start_miners (self); -+ -+ self->miner_control_proxy = photos_application_get_miner_fs_control_proxy (NULL); - return TRUE; - } - -@@ -1111,18 +1049,18 @@ photos_application_get_state (PhotosSearchContext *context) - - - static void --photos_application_import_index_file (GObject *source_object, GAsyncResult *res, gpointer user_data) -+photos_application_import_index_location (GObject *source_object, GAsyncResult *res, gpointer user_data) - { - PhotosApplication *self; - g_autoptr (GFile) file = G_FILE (user_data); -- TrackerMinerManager *manager = TRACKER_MINER_MANAGER (source_object); -+ TrackerMinerFilesIndex *miner_control_proxy = TRACKER_MINER_FILES_INDEX (source_object); - - self = PHOTOS_APPLICATION (g_application_get_default ()); - - { - g_autoptr (GError) error = NULL; - -- if (!tracker_miner_manager_index_file_for_process_finish (manager, res, &error)) -+ if (!tracker_miner_files_index_call_index_location_finish (miner_control_proxy, res, &error)) - { - g_autofree gchar *uri = NULL; - -@@ -1345,6 +1283,8 @@ photos_application_import_file_copy (GObject *source_object, GAsyncResult *res, - else - { - g_autofree gchar *destination_uri = NULL; -+ const gchar *tracker_priority_graphs[] = { TRACKER_PICTURES_GRAPH }; -+ const gchar *tracker_index_location_flags[] = { "for-process" }; - - g_assert_true (G_IS_FILE (destination)); - g_set_object (&data->destination, destination); -@@ -1361,11 +1301,13 @@ photos_application_import_file_copy (GObject *source_object, GAsyncResult *res, - - g_application_hold (G_APPLICATION (self)); - g_application_mark_busy (G_APPLICATION (self)); -- tracker_miner_manager_index_file_for_process_async (self->miner_manager, -- destination, -- NULL, -- photos_application_import_index_file, -- g_object_ref (destination)); -+ tracker_miner_files_index_call_index_location (self->miner_control_proxy, -+ destination_uri, -+ tracker_priority_graphs, -+ tracker_index_location_flags, -+ NULL, -+ photos_application_import_index_location, -+ g_object_ref (destination)); - } - - out: -@@ -1529,9 +1471,9 @@ photos_application_import (PhotosApplication *self) - selection = photos_selection_controller_get_selection (self->sel_cntrlr); - g_return_if_fail (selection != NULL); - -- if (self->miner_manager == NULL) -+ if (!self->miner_control_proxy) - { -- g_warning ("No TrackerMinerManager, importing from attached devices won't work"); -+ g_warning ("No Tracker3.Miner.Files.Index proxy, importing from attached devices won't work"); - goto out; - } - -@@ -1563,6 +1505,7 @@ photos_application_import (PhotosApplication *self) - gtk_widget_show_all (dialog); - - data = photos_application_import_data_new (self, files, ctime_latest); -+ - g_signal_connect (dialog, - "response", - G_CALLBACK (photos_application_import_response), -@@ -2234,35 +2177,7 @@ photos_application_share_current (PhotosApplication *self) - static void - photos_application_start_miners (PhotosApplication *self) - { -- { -- g_autoptr (GError) error = NULL; -- -- self->miner_manager = tracker_miner_manager_new_full (TRUE, &error); -- if (error != NULL) -- g_warning ("Unable to create a TrackerMinerManager: %s", error->message); -- } -- -- if (self->miner_manager != NULL) -- { -- GSList *available = NULL; -- GSList *miner_files = NULL; -- -- available = tracker_miner_manager_get_available (self->miner_manager); -- miner_files = g_slist_find_custom (available, MINER_FILES, (GCompareFunc) strcmp); -- if (miner_files == NULL) -- { -- g_warning ("Unable to find miner %s", MINER_FILES); -- } -- else -- { -- if (!tracker_miner_manager_is_active (self->miner_manager, MINER_FILES)) -- g_warning ("Unable to activate miner %s", MINER_FILES); -- } -- -- g_slist_free_full (available, g_free); -- } -- -- photos_application_create_online_miners (self); -+ photos_application_create_online_miners (self); - } - - -@@ -2991,6 +2906,7 @@ photos_application_dispose (GObject *object) - g_clear_object (&self->insta_action); - g_clear_object (&self->load_next_action); - g_clear_object (&self->load_previous_action); -+ g_clear_object (&self->miner_control_proxy); - g_clear_object (&self->open_action); - g_clear_object (&self->preview_menu_action); - g_clear_object (&self->primary_menu_action); -@@ -3019,8 +2935,7 @@ photos_application_dispose (GObject *object) - g_clear_object (&self->camera_cache); - g_clear_object (&self->sel_cntrlr); - g_clear_object (&self->factory); -- g_clear_object (&self->extract_priority); -- g_clear_object (&self->miner_manager); -+ g_clear_object (&self->miner_control_proxy); - - if (self->state != NULL) - { -@@ -3148,8 +3063,7 @@ photos_application_get_miners_running (PhotosApplication *self) - return self->miners_running; - } - -- --gint -+int - photos_application_get_scale_factor (PhotosApplication *self) - { - GList *windows; -diff --git a/src/photos-base-item.c b/src/photos-base-item.c -index 0d72f9c5..4ef69224 100644 ---- a/src/photos-base-item.c -+++ b/src/photos-base-item.c -@@ -2756,6 +2756,16 @@ photos_base_item_update_info_from_type (PhotosBaseItem *self) - } - - -+static gdouble -+get_double_with_default (TrackerSparqlCursor *cursor, PhotosQueryColumns column, gdouble default_value) -+{ -+ if (tracker_sparql_cursor_is_bound (cursor, column)) { -+ return tracker_sparql_cursor_get_double (cursor, column); -+ } else { -+ return default_value; -+ } -+} -+ - static void - photos_base_item_populate_from_cursor (PhotosBaseItem *self, TrackerSparqlCursor *cursor) - { -diff --git a/src/photos-indexing-notification.c b/src/photos-indexing-notification.c -index 72394983..122d0d91 100644 ---- a/src/photos-indexing-notification.c -+++ b/src/photos-indexing-notification.c -@@ -26,12 +26,13 @@ - #include - #include - #include --#include - - #include "photos-application.h" - #include "photos-gom-miner.h" - #include "photos-indexing-notification.h" - #include "photos-notification-manager.h" -+#include "photos-tracker-queue.h" -+#include "photos-tracker-miner.h" - - - struct _PhotosIndexingNotification -@@ -41,7 +42,7 @@ struct _PhotosIndexingNotification - GtkWidget *primary_label; - GtkWidget *secondary_label; - GtkWidget *spinner; -- TrackerMinerManager *manager; -+ TrackerMiner *miner_fs_proxy; - gboolean closed; - gboolean on_display; - guint timeout_id; -@@ -56,8 +57,6 @@ enum - REMOTE_MINER_TIMEOUT = 10 /* s */ - }; - --static const gchar *MINER_FILES = "org.gnome.Photos.Tracker1.Miner.Files"; -- - - static void - photos_indexing_notification_remove_timeout (PhotosIndexingNotification *self) -@@ -180,16 +179,18 @@ photos_indexing_notification_check_notification (PhotosIndexingNotification *sel - GSList *running = NULL; - gboolean is_indexing_local = FALSE; - gboolean is_indexing_remote = FALSE; -+ GError *error = NULL; -+ gdouble progress; - -- running = tracker_miner_manager_get_running (self->manager); -- if (g_slist_find_custom (running, (gconstpointer) MINER_FILES, (GCompareFunc) g_strcmp0) != NULL) -- { -- gdouble progress; -+ tracker_miner_call_get_progress_sync (self->miner_fs_proxy, &progress, NULL, &error); -+ if (error) { -+ g_warning ("Couldn't get indexing progress from Tracker Miner FS: %s", error->message); - -- tracker_miner_manager_get_status (self->manager, MINER_FILES, NULL, &progress, NULL); -- if (progress < 1) -- is_indexing_local = TRUE; -- } -+ g_clear_error (&error); -+ } else { -+ if (progress < 1) -+ is_indexing_local = TRUE; -+ } - - app = g_application_get_default (); - miners_running = photos_application_get_miners_running (PHOTOS_APPLICATION (app)); -@@ -222,7 +223,6 @@ photos_indexing_notification_dispose (GObject *object) - photos_indexing_notification_remove_timeout (self); - - g_clear_object (&self->ntfctn_mngr); -- g_clear_object (&self->manager); - - G_OBJECT_CLASS (photos_indexing_notification_parent_class)->dispose (object); - } -@@ -240,13 +240,25 @@ photos_indexing_notification_init (PhotosIndexingNotification *self) - app = g_application_get_default (); - - { -+ g_autoptr (PhotosTrackerQueue) tracker_queue; - g_autoptr (GError) error = NULL; -+ const gchar *miner_fs_busname; -+ -+ tracker_queue = photos_tracker_queue_dup_singleton (NULL, &error); -+ -+ if (tracker_queue) { -+ miner_fs_busname = photos_tracker_queue_get_miner_fs_busname (tracker_queue); -+ self->miner_fs_proxy = tracker_miner_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, -+ G_DBUS_PROXY_FLAGS_NONE, -+ miner_fs_busname, -+ "/org/freedesktop/Tracker3/Miner/Files", -+ NULL, -+ &error); -+ } - -- self->manager = tracker_miner_manager_new_full (TRUE, &error); - if (error != NULL) - { -- g_warning ("Unable to create a TrackerMinerManager, indexing progress notification won't work: %s", -- error->message); -+ g_warning ("Unable to create proxy for Tracker Miner FS, indexing progress notification won't work"); - return; - } - } -@@ -293,10 +305,11 @@ photos_indexing_notification_init (PhotosIndexingNotification *self) - self, - G_CONNECT_SWAPPED); - -- g_signal_connect_swapped (self->manager, -- "miner-progress", -- G_CALLBACK (photos_indexing_notification_check_notification), -- self); -+ g_signal_connect_object (self->miner_fs_proxy, -+ "progress", -+ G_CALLBACK (photos_indexing_notification_check_notification), -+ self, -+ G_CONNECT_SWAPPED); - } - - -diff --git a/src/photos-item-manager.c b/src/photos-item-manager.c -index 337891c1..4dfe3c7e 100644 ---- a/src/photos-item-manager.c -+++ b/src/photos-item-manager.c -@@ -41,12 +41,9 @@ - #include "photos-query.h" - #include "photos-search-context.h" - #include "photos-single-item-job.h" --#include "photos-tracker-change-event.h" --#include "photos-tracker-change-monitor.h" - #include "photos-tracker-queue.h" - #include "photos-utils.h" - -- - struct _PhotosItemManager - { - PhotosBaseManager parent_instance; -@@ -60,7 +57,7 @@ struct _PhotosItemManager - PhotosBaseItem *active_collection; - PhotosBaseManager **item_mngr_chldrn; - PhotosLoadState load_state; -- PhotosTrackerChangeMonitor *monitor; -+ TrackerNotifier *notifier; - PhotosTrackerQueue *queue; - PhotosWindowMode mode; - gboolean fullscreen; -@@ -311,7 +308,7 @@ photos_item_manager_add_cursor_for_mode (PhotosItemManager *self, - g_return_if_fail (base_item_type == G_TYPE_NONE - || (base_item_type != PHOTOS_TYPE_BASE_ITEM - && g_type_is_a (base_item_type, PHOTOS_TYPE_BASE_ITEM))); -- g_return_if_fail (TRACKER_SPARQL_IS_CURSOR (cursor)); -+ g_return_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor)); - g_return_if_fail (mode != PHOTOS_WINDOW_MODE_NONE); - g_return_if_fail (mode != PHOTOS_WINDOW_MODE_EDIT); - g_return_if_fail (mode != PHOTOS_WINDOW_MODE_PREVIEW); -@@ -529,21 +526,23 @@ photos_item_manager_item_created (PhotosItemManager *self, const gchar *urn) - - - static void --photos_item_manager_changes_pending_foreach (gpointer key, gpointer value, gpointer user_data) -+photos_item_manager_changes_pending_foreach (gpointer data, -+ gpointer user_data) - { - PhotosItemManager *self = PHOTOS_ITEM_MANAGER (user_data); -- PhotosTrackerChangeEvent *change_event = (PhotosTrackerChangeEvent *) value; -- PhotosTrackerChangeEventType change_type; -+ TrackerNotifierEvent *event = (TrackerNotifierEvent *) data; -+ TrackerNotifierEventType change_type; - const gchar *change_urn; - -- change_type = photos_tracker_change_event_get_type (change_event); -- change_urn = photos_tracker_change_event_get_urn (change_event); -+ change_type = tracker_notifier_event_get_event_type (event); -+ change_urn = tracker_notifier_event_get_urn (event); - -- if (change_type == PHOTOS_TRACKER_CHANGE_EVENT_CHANGED) -+ if (change_type == TRACKER_NOTIFIER_EVENT_UPDATE) - { - GObject *object; - - object = photos_base_manager_get_object_by_id (PHOTOS_BASE_MANAGER (self), change_urn); -+ g_message ("UPDATE event for %s, object %p", change_urn, object); - if (object != NULL) - { - photos_base_item_refresh (PHOTOS_BASE_ITEM (object)); -@@ -557,15 +556,17 @@ photos_item_manager_changes_pending_foreach (gpointer key, gpointer value, gpoin - } - } - } -- else if (change_type == PHOTOS_TRACKER_CHANGE_EVENT_CREATED) -+ else if (change_type == TRACKER_NOTIFIER_EVENT_CREATE) - { -+ g_message ("CREATE event for %s", change_urn); - photos_item_manager_item_created (self, change_urn); - } -- else if (change_type == PHOTOS_TRACKER_CHANGE_EVENT_DELETED) -+ else if (change_type == TRACKER_NOTIFIER_EVENT_DELETE) - { - GObject *object; - - object = photos_base_manager_get_object_by_id (PHOTOS_BASE_MANAGER (self), change_urn); -+ g_message ("DELETE event for %s, object %p", change_urn, object); - if (object != NULL) - { - photos_base_item_destroy (PHOTOS_BASE_ITEM (object)); -@@ -577,9 +578,15 @@ photos_item_manager_changes_pending_foreach (gpointer key, gpointer value, gpoin - - - static void --photos_item_manager_changes_pending (PhotosItemManager *self, GHashTable *changes) --{ -- g_hash_table_foreach (changes, photos_item_manager_changes_pending_foreach, self); -+photos_item_manager_changes_pending (PhotosItemManager *self, -+ const gchar *service, -+ const gchar *graph, -+ GPtrArray *events, -+ gpointer user_data) -+{ -+ if (g_str_equal (graph, TRACKER_PICTURES_GRAPH)) { -+ g_ptr_array_foreach (events, photos_item_manager_changes_pending_foreach, self); -+ } - } - - -@@ -717,7 +724,7 @@ photos_item_manager_wait_for_changes_timeout (gpointer user_data) - g_autoptr (PhotosQuery) query = NULL; - g_autofree gchar *sparql = NULL; - -- sparql = g_strdup_printf ("SELECT ?urn nie:url (?urn) WHERE { ?urn nie:url '%s' }", uri); -+ sparql = g_strdup_printf ("SELECT ?urn nie:isStoredAs (?urn) WHERE { ?urn nie:isStoredAs '%s' }", uri); - query = photos_query_new (NULL, sparql); - photos_tracker_queue_select (self->queue, - query, -@@ -1038,7 +1045,7 @@ photos_item_manager_dispose (GObject *object) - g_clear_object (&self->active_object); - g_clear_object (&self->loader_cancellable); - g_clear_object (&self->active_collection); -- g_clear_object (&self->monitor); -+ g_clear_object (&self->notifier); - g_clear_object (&self->queue); - - G_OBJECT_CLASS (photos_item_manager_parent_class)->dispose (object); -@@ -1093,20 +1100,24 @@ photos_item_manager_init (PhotosItemManager *self) - - self->mode = PHOTOS_WINDOW_MODE_NONE; - -- self->monitor = photos_tracker_change_monitor_dup_singleton (NULL, NULL); -- if (G_LIKELY (self->monitor != NULL)) -- g_signal_connect_object (self->monitor, -- "changes-pending", -- G_CALLBACK (photos_item_manager_changes_pending), -- self, -- G_CONNECT_SWAPPED); -- - { - g_autoptr (GError) error = NULL; - - self->queue = photos_tracker_queue_dup_singleton (NULL, &error); - if (G_UNLIKELY (error != NULL)) -- g_warning ("Unable to create PhotosTrackerQueue: %s", error->message); -+ { -+ g_warning ("Unable to create PhotosTrackerQueue: %s", error->message); -+ self->notifier = NULL; -+ } -+ else -+ { -+ self->notifier = photos_tracker_queue_get_notifier (self->queue); -+ g_signal_connect_object (self->notifier, -+ "events", -+ G_CALLBACK (photos_item_manager_changes_pending), -+ self, -+ G_CONNECT_SWAPPED); -+ } - } - - self->fullscreen = FALSE; -@@ -1241,7 +1252,7 @@ photos_item_manager_add_item (PhotosItemManager *self, - g_return_if_fail (base_item_type == G_TYPE_NONE - || (base_item_type != PHOTOS_TYPE_BASE_ITEM - && g_type_is_a (base_item_type, PHOTOS_TYPE_BASE_ITEM))); -- g_return_if_fail (TRACKER_SPARQL_IS_CURSOR (cursor)); -+ g_return_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor)); - - id = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URN, NULL); - g_return_if_fail (id != NULL && id[0] != '\0'); -@@ -1370,7 +1381,7 @@ photos_item_manager_create_item (PhotosItemManager *self, - g_return_val_if_fail (base_item_type == G_TYPE_NONE - || (base_item_type != PHOTOS_TYPE_BASE_ITEM - && g_type_is_a (base_item_type, PHOTOS_TYPE_BASE_ITEM)), NULL); -- g_return_val_if_fail (TRACKER_SPARQL_IS_CURSOR (cursor), NULL); -+ g_return_val_if_fail (TRACKER_IS_SPARQL_CURSOR (cursor), NULL); - - id = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URN, NULL); - item = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (PHOTOS_BASE_MANAGER (self), id)); -diff --git a/src/photos-quarks.c b/src/photos-quarks.c -index 0870ef62..5ee25745 100644 ---- a/src/photos-quarks.c -+++ b/src/photos-quarks.c -@@ -25,68 +25,68 @@ - GQuark - photos_quarks_flash_off_quark (void) - { -- return g_quark_from_static_string ("http://www.tracker-project.org/temp/nmm#flash-off"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nmm#flash-off"); - } - - - GQuark - photos_quarks_flash_on_quark (void) - { -- return g_quark_from_static_string ("http://www.tracker-project.org/temp/nmm#flash-on"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nmm#flash-on"); - } - - - GQuark - photos_quarks_orientation_bottom_quark (void) - { -- return g_quark_from_static_string ("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#orientation-bottom"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nfo#orientation-bottom"); - } - - - GQuark - photos_quarks_orientation_bottom_mirror_quark (void) - { -- return g_quark_from_static_string ("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#orientation-bottom-mirror"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nfo#orientation-bottom-mirror"); - } - - - GQuark - photos_quarks_orientation_left_quark (void) - { -- return g_quark_from_static_string ("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#orientation-left"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nfo#orientation-left"); - } - - - GQuark - photos_quarks_orientation_left_mirror_quark (void) - { -- return g_quark_from_static_string ("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#orientation-left-mirror"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nfo#orientation-left-mirror"); - } - - - GQuark - photos_quarks_orientation_right_quark (void) - { -- return g_quark_from_static_string ("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#orientation-right"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nfo#orientation-right"); - } - - - GQuark - photos_quarks_orientation_right_mirror_quark (void) - { -- return g_quark_from_static_string ("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#orientation-right-mirror"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nfo#orientation-right-mirror"); - } - - - GQuark - photos_quarks_orientation_top_quark (void) - { -- return g_quark_from_static_string ("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#orientation-top"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nfo#orientation-top"); - } - - - GQuark - photos_quarks_orientation_top_mirror_quark (void) - { -- return g_quark_from_static_string ("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#orientation-top-mirror"); -+ return g_quark_from_static_string ("http://tracker.api.gnome.org/ontology/v3/nfo#orientation-top-mirror"); - } -diff --git a/src/photos-query-builder.c b/src/photos-query-builder.c -index 5d9d8a5a..9b1baf29 100644 ---- a/src/photos-query-builder.c -+++ b/src/photos-query-builder.c -@@ -25,6 +25,7 @@ - - #include - -+#include "photos-application.h" - #include "photos-base-manager.h" - #include "photos-query.h" - #include "photos-query-builder.h" -@@ -32,6 +33,7 @@ - #include "photos-source-manager.h" - #include "photos-search-match-manager.h" - #include "photos-search-type-manager.h" -+#include "photos-tracker-queue.h" - - #define PHOTOS_QUERY_COLLECTIONS_IDENTIFIER "photos:collection:" - #define PHOTOS_QUERY_LOCAL_COLLECTIONS_IDENTIFIER "photos:collection:local:" -@@ -48,12 +50,14 @@ const gchar *photos_default_filter = \ - - static gchar * - photos_query_builder_query (PhotosSearchContextState *state, -- gboolean global, -+ const gchar *values, - gint flags, - PhotosOffsetController *offset_cntrlr) - { - PhotosSparqlTemplate *template; -- const gchar *projection = NULL; -+ const gchar *miner_fs_busname = NULL; -+ const gchar *main_projection = NULL; -+ const gchar *second_projection = NULL; - g_autofree gchar *item_pattern = NULL; - g_autofree gchar *search_filter = NULL; - g_autofree gchar *source_filter = NULL; -@@ -63,29 +67,35 @@ photos_query_builder_query (PhotosSearchContextState *state, - - template = photos_base_manager_get_sparql_template (state->srch_typ_mngr, flags); - -- projection = "?urn " -- "nie:url (?urn) " -- "nfo:fileName (?urn) " -- "nie:mimeType (?urn) " -- "nie:title (?urn) " -- "tracker:coalesce (nco:fullname (?creator), nco:fullname (?publisher), '') " -- "tracker:coalesce (nfo:fileLastModified (?urn), nie:contentLastModified (?urn)) AS ?mtime " -- "nao:identifier (?urn) " -- "rdf:type (?urn) " -- "nie:dataSource(?urn) " -- "( EXISTS { ?urn nao:hasTag nao:predefined-tag-favorite } ) " -- "( EXISTS { ?urn nco:contributor ?contributor FILTER ( ?contributor != ?creator ) } ) " -- "tracker:coalesce(nfo:fileCreated (?urn), nie:contentCreated (?urn)) " -- "nfo:width (?urn) " -- "nfo:height (?urn) " -- "nfo:equipment (?urn) " -- "nfo:orientation (?urn) " -- "nmm:exposureTime (?urn) " -- "nmm:fnumber (?urn) " -- "nmm:focalLength (?urn) " -- "nmm:isoSpeed (?urn) " -- "nmm:flash (?urn) " -- "slo:location (?urn) "; -+ miner_fs_busname = photos_tracker_queue_get_miner_fs_busname (state->queue); -+ -+ main_projection = "?urn " -+ "?file " -+ "nfo:fileName (?file) AS ?filename " -+ "nie:mimeType (?urn) AS ?mimetype " -+ "nie:title (?urn) AS ?title " -+ "tracker:coalesce (nco:fullname (?creator), nco:fullname (?publisher), '') AS ?author_name " -+ "tracker:coalesce (nfo:fileLastModified (?file), 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 ?has_contributor " -+ "tracker:coalesce(nfo:fileCreated (?file), nie:contentCreated (?urn)) AS ?ctime " -+ "nfo:width (?urn) AS ?width " -+ "nfo:height (?urn) AS ?height " -+ "nfo:equipment (?urn) AS ?equipment " -+ "nfo:orientation (?urn) AS ?orientation " -+ "nmm:exposureTime (?urn) AS ?exposure_time " -+ "nmm:fnumber (?urn) AS ?fnumber " -+ "nmm:focalLength (?urn) AS ?focal_length " -+ "nmm:isoSpeed (?urn) AS ?isospeed " -+ "nmm:flash (?urn) AS ?flash " -+ "slo:location (?urn) AS ?location "; -+ -+ second_projection = "?urn ?file ?filename ?mimetype ?title ?author_name ?mtime ?identifier ?type ?datasource " -+ "( EXISTS { ?urn nao:hasTag nao:predefined-tag-favorite } ) AS ?is_favorite " -+ "?has_contributor ?ctime ?width ?height ?equipment ?orientation ?exposure_time ?fnumber " -+ "?focal_length ?isospeed ?flash ?location "; - - item_pattern = photos_base_manager_get_where (state->item_mngr, flags); - -@@ -97,7 +107,7 @@ photos_query_builder_query (PhotosSearchContextState *state, - - order = "ORDER BY DESC (?mtime)"; - -- if (global && (flags & PHOTOS_QUERY_FLAGS_UNLIMITED) == 0) -+ if (values == NULL && (flags & PHOTOS_QUERY_FLAGS_UNLIMITED) == 0) - { - gint offset = 0; - gint step = 60; -@@ -112,12 +122,16 @@ photos_query_builder_query (PhotosSearchContextState *state, - } - - sparql = photos_sparql_template_get_sparql (template, -- "projection", projection, -+ "miner_fs_busname", miner_fs_busname, -+ "main_projection", main_projection, -+ "second_projection", second_projection, -+ "final_projection", second_projection, -+ "values", values ? values : "", - "collections_default_filter", collections_default_filter, - "item_pattern", item_pattern, - "photos_default_filter", photos_default_filter, -- "source_filter", source_filter ? source_filter : "", -- "search_filter", search_filter ? search_filter : "", -+ "source_filter", source_filter ? source_filter : "(true)", -+ "search_filter", search_filter ? search_filter : "(true)", - "order", order, - "offset_limit", offset_limit ? offset_limit : "", - NULL); -@@ -133,6 +147,7 @@ photos_query_builder_create_collection_query (PhotosSearchContextState *state, - { - GTimeVal tv; - PhotosQuery *query; -+ g_autoptr (TrackerResource) collection = NULL; - g_autofree gchar *identifier = NULL; - g_autofree gchar *sparql = NULL; - g_autofree gchar *time = NULL; -@@ -147,13 +162,14 @@ photos_query_builder_create_collection_query (PhotosSearchContextState *state, - tv.tv_usec = 0; - time = g_time_val_to_iso8601 (&tv); - -- sparql = g_strdup_printf ("INSERT { _:res a nfo:DataContainer ; a nie:DataObject ; " -- "nie:contentLastModified '%s' ; " -- "nie:title '%s' ; " -- "nao:identifier '%s' }", -- time, -- name, -- identifier); -+ collection = tracker_resource_new ("_:res"); -+ tracker_resource_add_uri (collection, "rdf:type", "nfo:DataContainer"); -+ tracker_resource_add_uri (collection, "rdf:type", "nie:DataObject"); -+ tracker_resource_set_string (collection, "nie:contentLastModified", time); -+ tracker_resource_set_string (collection, "nie:title", name); -+ tracker_resource_set_string (collection, "nao:identifier", identifier); -+ -+ sparql = tracker_resource_print_sparql_update (collection, NULL, "tracker:Pictures"); - - query = photos_query_new (state, sparql); - -@@ -183,7 +199,9 @@ PhotosQuery * - photos_query_builder_count_query (PhotosSearchContextState *state, gint flags) - { - PhotosSparqlTemplate *template; -- const gchar *projection = NULL; -+ const gchar *miner_fs_busname = NULL; -+ const gchar *count_projection = NULL; -+ const gchar *value_projection = NULL; - g_autofree gchar *item_pattern = NULL; - g_autofree gchar *search_filter = NULL; - g_autofree gchar *source_filter = NULL; -@@ -192,7 +210,10 @@ photos_query_builder_count_query (PhotosSearchContextState *state, gint flags) - - template = photos_base_manager_get_sparql_template (state->srch_typ_mngr, flags); - -- projection = "COUNT(?urn) "; -+ miner_fs_busname = photos_tracker_queue_get_miner_fs_busname (state->queue); -+ -+ value_projection = "?urn "; -+ count_projection = "COUNT(?urn) "; - - item_pattern = photos_base_manager_get_where (state->item_mngr, flags); - -@@ -203,12 +224,16 @@ photos_query_builder_count_query (PhotosSearchContextState *state, gint flags) - } - - sparql = photos_sparql_template_get_sparql (template, -- "projection", projection, -+ "miner_fs_busname", miner_fs_busname, -+ "main_projection", value_projection, -+ "second_projection", value_projection, -+ "final_projection", count_projection, -+ "values", "", - "collections_default_filter", collections_default_filter, - "item_pattern", item_pattern, - "photos_default_filter", photos_default_filter, -- "source_filter", source_filter ? source_filter : "", -- "search_filter", search_filter ? search_filter : "", -+ "source_filter", source_filter ? source_filter : "(true)", -+ "search_filter", search_filter ? search_filter : "(true)", - "order", "", - "offset_limit", "", - NULL); -@@ -267,7 +292,7 @@ photos_query_builder_fetch_collections_local (PhotosSearchContextState *state) - g_autofree gchar *sparql = NULL; - - sparql = photos_query_builder_query (state, -- TRUE, -+ NULL, - PHOTOS_QUERY_FLAGS_COLLECTIONS - | PHOTOS_QUERY_FLAGS_LOCAL - | PHOTOS_QUERY_FLAGS_UNLIMITED, -@@ -287,7 +312,7 @@ photos_query_builder_global_query (PhotosSearchContextState *state, - PhotosQuery *query; - g_autofree gchar *sparql = NULL; - -- sparql = photos_query_builder_query (state, TRUE, flags, offset_cntrlr); -+ sparql = photos_query_builder_query (state, NULL, flags, offset_cntrlr); - query = photos_query_new (state, sparql); - - return query; -@@ -316,10 +341,19 @@ photos_query_builder_set_collection_query (PhotosSearchContextState *state, - PhotosQuery *query; - g_autofree gchar *sparql = NULL; - -- sparql = g_strdup_printf ("%s { <%s> nie:isPartOf <%s> }", -- setting ? "INSERT" : "DELETE", -- item_urn, -- collection_urn); -+ if (setting) -+ sparql = g_strdup_printf ("INSERT DATA { " -+ " GRAPH tracker:Pictures {" -+ " <%s> a nie:DataObject , nmm:Photo ; " -+ " nie:isPartOf <%s> " -+ " }" -+ "}", item_urn, collection_urn); -+ else -+ sparql = g_strdup_printf ("DELETE DATA { " -+ " GRAPH tracker:Pictures {" -+ " <%s> nie:isPartOf <%s> " -+ " }" -+ "}", item_urn, collection_urn); - query = photos_query_new (state, sparql); - - return query; -@@ -329,17 +363,14 @@ photos_query_builder_set_collection_query (PhotosSearchContextState *state, - PhotosQuery * - photos_query_builder_single_query (PhotosSearchContextState *state, gint flags, const gchar *resource) - { -- g_autoptr (GRegex) regex = NULL; - PhotosQuery *query; -- g_autofree gchar *replacement = NULL; - g_autofree gchar *sparql = NULL; -- g_autofree gchar *tmp = NULL; -+ g_autofree gchar *values = NULL; -+ -+ values = g_strdup_printf ("VALUES ?urn { <%s> }", resource); - -- tmp = photos_query_builder_query (state, FALSE, flags, NULL); -+ sparql = photos_query_builder_query (state, values, flags, NULL); - -- regex = g_regex_new ("\\?urn", 0, 0, NULL); -- replacement = g_strconcat ("<", resource, ">", NULL); -- sparql = g_regex_replace (regex, tmp, -1, 0, replacement, 0, NULL); - query = photos_query_new (state, sparql); - - return query; -@@ -360,7 +391,14 @@ photos_query_builder_update_mtime_query (PhotosSearchContextState *state, const - tv.tv_usec = 0; - time = g_time_val_to_iso8601 (&tv); - -- sparql = g_strdup_printf ("INSERT OR REPLACE { <%s> nie:contentLastModified '%s' }", resource, time); -+ sparql = g_strdup_printf ("WITH tracker:Pictures " -+ "DELETE { <%s> nie:contentLastModified ?time } " -+ "INSERT { " -+ " <%s> a nmm:Photo ; " -+ " nie:contentLastModified '%s' " -+ "}" -+ "WHERE { <%s> nie:contentLastModified ?time }", -+ resource, resource, time, resource); - query = photos_query_new (state, sparql); - - return query; -diff --git a/src/photos-search-context.c b/src/photos-search-context.c -index 4b503798..6f8694bc 100644 ---- a/src/photos-search-context.c -+++ b/src/photos-search-context.c -@@ -31,6 +31,7 @@ - #include "photos-search-match-manager.h" - #include "photos-search-type-manager.h" - #include "photos-source-manager.h" -+#include "photos-tracker-queue.h" - - - G_DEFINE_INTERFACE (PhotosSearchContext, photos_search_context, G_TYPE_OBJECT); -@@ -54,6 +55,7 @@ photos_search_context_state_new (PhotosSearchContext *self) - state->srch_cntrlr = photos_search_controller_new (); - state->srch_mtch_mngr = photos_search_match_manager_new (state->srch_cntrlr); - state->srch_typ_mngr = photos_search_type_manager_new (); -+ state->queue = photos_tracker_queue_dup_singleton (NULL, NULL); - - return state; - } -@@ -68,6 +70,7 @@ photos_search_context_state_free (PhotosSearchContextState *state) - g_object_unref (state->srch_mtch_mngr); - g_object_unref (state->srch_typ_mngr); - g_object_unref (state->srch_cntrlr); -+ g_clear_object (&state->queue); - g_slice_free (PhotosSearchContextState, state); - } - -diff --git a/src/photos-search-context.h b/src/photos-search-context.h -index 2af6cf96..5a18d386 100644 ---- a/src/photos-search-context.h -+++ b/src/photos-search-context.h -@@ -41,6 +41,7 @@ struct _PhotosSearchContextState - gpointer srch_typ_mngr; - gpointer offset_cntrlr; - gpointer srch_cntrlr; -+ gpointer queue; - }; - - PhotosSearchContextState *photos_search_context_state_new (PhotosSearchContext *self); -diff --git a/src/photos-search-match-manager.c b/src/photos-search-match-manager.c -index e6dc429a..2ba1fd0f 100644 ---- a/src/photos-search-match-manager.c -+++ b/src/photos-search-match-manager.c -@@ -148,7 +148,7 @@ photos_search_match_manager_init (PhotosSearchMatchManager *self) - " tracker:case-fold (tracker:coalesce (nco:fullname (?creator), nco:fullname(?publisher)))," - " \"%s\")"; - title_filter = "fn:contains (" -- " tracker:case-fold (tracker:coalesce (nie:title (?urn), nfo:fileName(?urn)))," -+ " tracker:case-fold (tracker:coalesce (nie:title (?urn), nfo:fileName(?file)))," - " \"%s\")"; - - search_match = photos_search_match_new (PHOTOS_SEARCH_MATCH_STOCK_ALL, -diff --git a/src/photos-source.c b/src/photos-source.c -index db6f2de9..5219652c 100644 ---- a/src/photos-source.c -+++ b/src/photos-source.c -@@ -62,7 +62,7 @@ G_DEFINE_TYPE_WITH_CODE (PhotosSource, photos_source, G_TYPE_OBJECT, - DZL_DEFINE_COUNTER (instances, "PhotosSource", "Instances", "Number of PhotosSource instances") - - --static const gchar *TRACKER_SCHEMA = "org.freedesktop.Tracker.Miner.Files"; -+static const gchar *TRACKER_SCHEMA = "org.freedesktop.Tracker3.Miner.Files"; - static const gchar *TRACKER_KEY_RECURSIVE_DIRECTORIES = "index-recursive-directories"; - - -@@ -94,7 +94,7 @@ photos_source_build_filter_local (void) - continue; - - tracker_uri = photos_utils_convert_path_to_uri (tracker_dirs[i]); -- g_string_append_printf (tracker_filter, " || fn:contains (nie:url (?urn), '%s')", tracker_uri); -+ g_string_append_printf (tracker_filter, " || fn:contains (nie:isStoredAs (?urn), '%s')", tracker_uri); - } - - path = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); -@@ -109,11 +109,11 @@ photos_source_build_filter_local (void) - export_path = g_build_filename (path, PHOTOS_EXPORT_SUBPATH, NULL); - export_uri = photos_utils_convert_path_to_uri (export_path); - -- filter = g_strdup_printf ("(((fn:contains (nie:url (?urn), '%s')" -- " || fn:contains (nie:url (?urn), '%s')" -- " || fn:contains (nie:url (?urn), '%s')" -+ filter = g_strdup_printf ("(((fn:contains (nie:isStoredAs (?urn), '%s')" -+ " || fn:contains (nie:isStoredAs (?urn), '%s')" -+ " || fn:contains (nie:isStoredAs (?urn), '%s')" - " %s)" -- " && !fn:contains (nie:url (?urn), '%s'))" -+ " && !fn:contains (nie:isStoredAs (?urn), '%s'))" - " || fn:starts-with (nao:identifier (?urn), '%s')" - " || (?urn = nfo:image-category-screenshot))", - desktop_uri, -@@ -146,7 +146,7 @@ photos_source_build_filter_resource (PhotosSource *self) - - root = g_mount_get_root (self->mount); - uri = g_file_get_uri (root); -- filter = g_strdup_printf ("(fn:starts-with (nie:url (?urn), '%s'))", uri); -+ filter = g_strdup_printf ("(fn:starts-with (nie:isStoredAs (?urn), '%s'))", uri); - } - else - { -diff --git a/src/photos-tracker-change-event.c b/src/photos-tracker-change-event.c -deleted file mode 100644 -index d5c74ebc..00000000 ---- a/src/photos-tracker-change-event.c -+++ /dev/null -@@ -1,136 +0,0 @@ --/* -- * Photos - access, organize and share your photos on GNOME -- * Copyright © 2012 – 2019 Red Hat, Inc. -- * -- * This program is free software: you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation, either version 3 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . -- */ -- --/* Based on code from: -- * + Documents -- */ -- -- --#include "config.h" -- --#include "photos-tracker-change-event.h" -- -- --struct _PhotosTrackerChangeEvent --{ -- PhotosTrackerChangeEventType type; -- gchar *predicate; -- gchar *urn; -- gint32 predicate_id; -- gint32 urn_id; --}; -- -- --static const gchar *RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"; -- -- --void --photos_tracker_change_event_free (PhotosTrackerChangeEvent *self) --{ -- g_free (self->predicate); -- g_free (self->urn); -- g_slice_free (PhotosTrackerChangeEvent, self); --} -- -- --PhotosTrackerChangeEvent * --photos_tracker_change_event_new (gint32 urn_id, gint32 predicate_id, gboolean is_delete) --{ -- PhotosTrackerChangeEvent *self; -- -- self = g_slice_new0 (PhotosTrackerChangeEvent); -- self->urn_id = urn_id; -- self->predicate_id = predicate_id; -- -- if (is_delete) -- self->type = PHOTOS_TRACKER_CHANGE_EVENT_DELETED; -- else -- self->type = PHOTOS_TRACKER_CHANGE_EVENT_CREATED; -- -- return self; --} -- -- --PhotosTrackerChangeEvent * --photos_tracker_change_event_copy (PhotosTrackerChangeEvent *event) --{ -- PhotosTrackerChangeEvent *self; -- -- self = g_slice_new0 (PhotosTrackerChangeEvent); -- self->type = event->type; -- self->predicate = g_strdup (event->predicate); -- self->urn = g_strdup (event->urn); -- self->predicate_id = event->predicate_id; -- self->urn_id = event->urn_id; -- -- return self; --} -- -- --PhotosTrackerChangeEventType --photos_tracker_change_event_get_type (PhotosTrackerChangeEvent *self) --{ -- return self->type; --} -- -- --gint32 --photos_tracker_change_event_get_predicate_id (PhotosTrackerChangeEvent *self) --{ -- return self->predicate_id; --} -- -- --const gchar * --photos_tracker_change_event_get_urn (PhotosTrackerChangeEvent *self) --{ -- return self->urn; --} -- -- --gint32 --photos_tracker_change_event_get_urn_id (PhotosTrackerChangeEvent *self) --{ -- return self->urn_id; --} -- -- --void --photos_tracker_change_event_merge (PhotosTrackerChangeEvent *self, PhotosTrackerChangeEvent *event) --{ -- g_return_if_fail (g_strcmp0 (self->urn, event->urn) == 0); -- -- if (event->type == PHOTOS_TRACKER_CHANGE_EVENT_DELETED || event->type == PHOTOS_TRACKER_CHANGE_EVENT_CREATED) -- self->type = event->type; --} -- -- --void --photos_tracker_change_event_set_resolved_values (PhotosTrackerChangeEvent *self, -- const gchar *urn, -- const gchar *predicate) --{ -- g_return_if_fail (self->predicate == NULL); -- g_return_if_fail (self->urn == NULL); -- -- self->urn = g_strdup (urn); -- self->predicate = g_strdup (predicate); -- -- if (g_strcmp0 (predicate, RDF_TYPE) != 0) -- self->type = PHOTOS_TRACKER_CHANGE_EVENT_CHANGED; --} -diff --git a/src/photos-tracker-change-event.h b/src/photos-tracker-change-event.h -deleted file mode 100644 -index eee4f40c..00000000 ---- a/src/photos-tracker-change-event.h -+++ /dev/null -@@ -1,64 +0,0 @@ --/* -- * Photos - access, organize and share your photos on GNOME -- * Copyright © 2012 – 2019 Red Hat, Inc. -- * -- * This program is free software: you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation, either version 3 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . -- */ -- --/* Based on code from: -- * + Documents -- */ -- --#ifndef PHOTOS_TRACKER_CHANGE_EVENT_H --#define PHOTOS_TRACKER_CHANGE_EVENT_H -- --#include -- --G_BEGIN_DECLS -- --typedef enum --{ -- PHOTOS_TRACKER_CHANGE_EVENT_CHANGED, -- PHOTOS_TRACKER_CHANGE_EVENT_CREATED, -- PHOTOS_TRACKER_CHANGE_EVENT_DELETED --} PhotosTrackerChangeEventType; -- --typedef struct _PhotosTrackerChangeEvent PhotosTrackerChangeEvent; -- --PhotosTrackerChangeEvent *photos_tracker_change_event_new (gint32 urn_id, -- gint32 predicate_id, -- gboolean is_delete); -- --PhotosTrackerChangeEvent *photos_tracker_change_event_copy (PhotosTrackerChangeEvent *event); -- --void photos_tracker_change_event_free (PhotosTrackerChangeEvent *self); -- --PhotosTrackerChangeEventType photos_tracker_change_event_get_type (PhotosTrackerChangeEvent *self); -- --gint32 photos_tracker_change_event_get_predicate_id (PhotosTrackerChangeEvent *self); -- --const gchar *photos_tracker_change_event_get_urn (PhotosTrackerChangeEvent *self); -- --gint32 photos_tracker_change_event_get_urn_id (PhotosTrackerChangeEvent *self); -- --void photos_tracker_change_event_merge (PhotosTrackerChangeEvent *self, -- PhotosTrackerChangeEvent *event); -- --void photos_tracker_change_event_set_resolved_values (PhotosTrackerChangeEvent *self, -- const gchar *urn, -- const gchar *predicate); -- --G_END_DECLS -- --#endif /* PHOTOS_TRACKER_CHANGE_EVENT_H */ -diff --git a/src/photos-tracker-change-monitor.c b/src/photos-tracker-change-monitor.c -deleted file mode 100644 -index 44c9ffe7..00000000 ---- a/src/photos-tracker-change-monitor.c -+++ /dev/null -@@ -1,468 +0,0 @@ --/* -- * Photos - access, organize and share your photos on GNOME -- * Copyright © 2012 – 2019 Red Hat, Inc. -- * -- * This program is free software: you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation, either version 3 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . -- */ -- --/* Based on code from: -- * + Documents -- */ -- -- --#include "config.h" -- --#include --#include -- --#include "photos-tracker-change-event.h" --#include "photos-tracker-change-monitor.h" --#include "photos-tracker-queue.h" --#include "photos-tracker-resources.h" --#include "photos-query.h" -- -- --struct _PhotosTrackerChangeMonitor --{ -- GObject parent_instance; -- GHashTable *pending_changes; -- GHashTable *unresolved_ids; -- GQueue *pending_events; -- PhotosTrackerQueue *queue; -- TrackerResources *resource_service; -- guint outstanding_ops; -- guint pending_events_id; --}; -- --enum --{ -- CHANGES_PENDING, -- LAST_SIGNAL --}; -- --static guint signals[LAST_SIGNAL] = { 0 }; -- --static void photos_tracker_change_monitor_initable_iface_init (GInitableIface *iface); -- -- --G_DEFINE_TYPE_EXTENDED (PhotosTrackerChangeMonitor, photos_tracker_change_monitor, G_TYPE_OBJECT, 0, -- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, photos_tracker_change_monitor_initable_iface_init)); -- -- --enum --{ -- CHANGE_MONITOR_TIMEOUT = 500, /* ms */ -- CHANGE_MONITOR_MAX_ITEMS = 500 --}; -- -- --typedef struct _PhotosTrackerChangeMonitorQueryData PhotosTrackerChangeMonitorQueryData; --typedef struct _TrackerResourcesEvent TrackerResourcesEvent; -- --struct _PhotosTrackerChangeMonitorQueryData --{ -- PhotosTrackerChangeMonitor *self; -- GHashTable *id_table; -- GQueue *events; --}; -- --struct _TrackerResourcesEvent --{ -- gint32 graph; -- gint32 subject; -- gint32 predicate; -- gint32 object; --}; -- -- --static void --photos_tracker_change_monitor_query_data_free (PhotosTrackerChangeMonitorQueryData *data) --{ -- g_clear_object (&data->self); -- -- if (data->id_table != NULL) -- g_hash_table_unref (data->id_table); -- -- if (data->events != NULL) -- g_queue_free_full (data->events, (GDestroyNotify) photos_tracker_change_event_free); -- -- g_slice_free (PhotosTrackerChangeMonitorQueryData, data); --} -- -- --static PhotosTrackerChangeMonitorQueryData * --photos_tracker_change_monitor_query_data_new (PhotosTrackerChangeMonitor *self, -- GHashTable *id_table, -- GQueue *events) --{ -- PhotosTrackerChangeMonitorQueryData *data; -- -- data = g_slice_new0 (PhotosTrackerChangeMonitorQueryData); -- data->self = g_object_ref (self); -- data->id_table = id_table; -- data->events = events; -- -- return data; --} -- -- --static void --photos_tracker_change_monitor_add_event (PhotosTrackerChangeMonitor *self, PhotosTrackerChangeEvent *change_event) --{ -- PhotosTrackerChangeEvent *old_change_event; -- const gchar *urn; -- -- urn = photos_tracker_change_event_get_urn (change_event); -- old_change_event = (PhotosTrackerChangeEvent *) g_hash_table_lookup (self->pending_changes, urn); -- -- if (old_change_event != NULL) -- photos_tracker_change_event_merge (old_change_event, change_event); -- else -- g_hash_table_insert (self->pending_changes, g_strdup (urn), photos_tracker_change_event_copy (change_event)); --} -- -- --static void --photos_tracker_change_monitor_remove_timeout (PhotosTrackerChangeMonitor *self) --{ -- if (self->pending_events_id != 0) -- { -- g_source_remove (self->pending_events_id); -- self->pending_events_id = 0; -- } --} -- -- --static void --photos_tracker_change_monitor_send_events (PhotosTrackerChangeMonitor *self, GHashTable *id_table, GQueue *events) --{ -- GList *l; -- -- for (l = events->head; l != NULL; l = l->next) -- { -- PhotosTrackerChangeEvent *change_event = (PhotosTrackerChangeEvent *) l->data; -- const gchar *predicate; -- const gchar *urn; -- gint32 predicate_id; -- gint32 urn_id; -- -- predicate_id = photos_tracker_change_event_get_predicate_id (change_event); -- urn_id = photos_tracker_change_event_get_urn_id (change_event); -- -- predicate = (gchar *) g_hash_table_lookup (id_table, GINT_TO_POINTER (predicate_id)); -- if (G_UNLIKELY (predicate == NULL)) -- continue; -- -- urn = (gchar *) g_hash_table_lookup (id_table, GINT_TO_POINTER (urn_id)); -- if (G_UNLIKELY (urn == NULL)) -- continue; -- -- photos_tracker_change_event_set_resolved_values (change_event, urn, predicate); -- photos_tracker_change_monitor_add_event (self, change_event); -- } -- -- g_signal_emit (self, signals[CHANGES_PENDING], 0, self->pending_changes); -- g_hash_table_remove_all (self->pending_changes); --} -- -- --static void --photos_tracker_change_monitor_cursor_next (GObject *source_object, GAsyncResult *res, gpointer user_data) --{ -- PhotosTrackerChangeMonitorQueryData *data = (PhotosTrackerChangeMonitorQueryData *) user_data; -- PhotosTrackerChangeMonitor *self = data->self; -- TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source_object); -- GHashTableIter iter; -- gboolean valid; -- -- { -- g_autoptr (GError) error = NULL; -- -- valid = tracker_sparql_cursor_next_finish (cursor, res, &error); -- if (error != NULL) -- g_warning ("Unable to resolve item URNs for graph changes: %s", error->message); -- } -- -- if (valid) -- { -- guint idx; -- -- idx = 0; -- g_hash_table_iter_init (&iter, data->id_table); -- while (g_hash_table_iter_next (&iter, NULL, NULL)) -- { -- const gchar *str; -- -- str = tracker_sparql_cursor_get_string (cursor, idx, NULL); -- g_hash_table_iter_replace (&iter, g_strdup (str)); -- idx++; -- } -- -- photos_tracker_change_monitor_send_events (self, data->id_table, data->events); -- } -- -- tracker_sparql_cursor_close (cursor); -- photos_tracker_change_monitor_query_data_free (data); --} -- -- --static void --photos_tracker_change_monitor_query_executed (GObject *source_object, GAsyncResult *res, gpointer user_data) --{ -- PhotosTrackerChangeMonitorQueryData *data = (PhotosTrackerChangeMonitorQueryData *) user_data; -- TrackerSparqlConnection *connection = TRACKER_SPARQL_CONNECTION (source_object); -- TrackerSparqlCursor *cursor; /* TODO: Use g_autoptr */ -- -- { -- g_autoptr (GError) error = NULL; -- -- cursor = tracker_sparql_connection_query_finish (connection, res, &error); -- if (error != NULL) -- { -- g_warning ("Unable to resolve item URNs for graph changes: %s", error->message); -- photos_tracker_change_monitor_query_data_free (data); -- return; -- } -- } -- -- tracker_sparql_cursor_next_async (cursor, NULL, photos_tracker_change_monitor_cursor_next, data); -- g_object_unref (cursor); --} -- -- --static gboolean --photos_tracker_change_monitor_process_events (PhotosTrackerChangeMonitor *self) --{ -- GHashTable *id_table; -- GHashTableIter iter; -- GQueue *events; -- g_autoptr (GString) sparql = NULL; -- PhotosTrackerChangeMonitorQueryData *data; -- g_autoptr (PhotosQuery) query = NULL; -- gpointer id; -- -- events = self->pending_events; -- self->pending_events = g_queue_new (); -- -- id_table = self->unresolved_ids; -- self->unresolved_ids = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); -- -- self->pending_events_id = 0; -- -- sparql = g_string_new ("SELECT"); -- -- g_hash_table_iter_init (&iter, id_table); -- while (g_hash_table_iter_next (&iter, &id, NULL)) -- g_string_append_printf (sparql, " tracker:uri(%d)", GPOINTER_TO_INT (id)); -- -- g_string_append (sparql, " {}"); -- -- query = photos_query_new (NULL, sparql->str); -- -- data = photos_tracker_change_monitor_query_data_new (self, id_table, events); -- photos_tracker_queue_select (self->queue, -- query, -- NULL, -- photos_tracker_change_monitor_query_executed, -- data, -- NULL); -- -- return G_SOURCE_REMOVE; --} -- -- --static void --photos_tracker_change_monitor_add_pending_event (PhotosTrackerChangeMonitor *self, -- const TrackerResourcesEvent *event, -- gboolean is_delete) --{ -- PhotosTrackerChangeEvent *change_event; -- -- photos_tracker_change_monitor_remove_timeout (self); -- -- g_hash_table_insert (self->unresolved_ids, GINT_TO_POINTER (event->subject), NULL); -- g_hash_table_insert (self->unresolved_ids, GINT_TO_POINTER (event->predicate), NULL); -- -- change_event = photos_tracker_change_event_new (event->subject, event->predicate, is_delete); -- g_queue_push_tail (self->pending_events, change_event); -- -- if (self->pending_events->length >= CHANGE_MONITOR_MAX_ITEMS) -- photos_tracker_change_monitor_process_events (self); -- else -- self->pending_events_id = g_timeout_add (CHANGE_MONITOR_TIMEOUT, -- (GSourceFunc) photos_tracker_change_monitor_process_events, -- self); --} -- -- --static void --photos_tracker_change_monitor_graph_updated (TrackerResources *resource_service, -- const gchar *class_name, -- GVariant *delete_events, -- GVariant *insert_events, -- gpointer user_data) --{ -- PhotosTrackerChangeMonitor *self = PHOTOS_TRACKER_CHANGE_MONITOR (user_data); -- const TrackerResourcesEvent *events; -- gsize i; -- gsize n_elements; -- -- events = (const TrackerResourcesEvent *) g_variant_get_fixed_array (delete_events, -- &n_elements, -- sizeof (TrackerResourcesEvent)); -- for (i = 0; i < n_elements; i++) -- photos_tracker_change_monitor_add_pending_event (self, &events[i], TRUE); -- -- events = (const TrackerResourcesEvent *) g_variant_get_fixed_array (insert_events, -- &n_elements, -- sizeof (TrackerResourcesEvent)); -- for (i = 0; i < n_elements; i++) -- photos_tracker_change_monitor_add_pending_event (self, &events[i], FALSE); --} -- -- --static GObject * --photos_tracker_change_monitor_constructor (GType type, -- guint n_construct_params, -- GObjectConstructParam *construct_params) --{ -- static GObject *self = NULL; -- -- if (self == NULL) -- { -- self = G_OBJECT_CLASS (photos_tracker_change_monitor_parent_class)->constructor (type, -- n_construct_params, -- construct_params); -- g_object_add_weak_pointer (self, (gpointer) &self); -- return self; -- } -- -- return g_object_ref (self); --} -- -- --static void --photos_tracker_change_monitor_dispose (GObject *object) --{ -- PhotosTrackerChangeMonitor *self = PHOTOS_TRACKER_CHANGE_MONITOR (object); -- -- photos_tracker_change_monitor_remove_timeout (self); -- -- g_clear_object (&self->queue); -- g_clear_object (&self->resource_service); -- -- G_OBJECT_CLASS (photos_tracker_change_monitor_parent_class)->dispose (object); --} -- -- --static void --photos_tracker_change_monitor_finalize (GObject *object) --{ -- PhotosTrackerChangeMonitor *self = PHOTOS_TRACKER_CHANGE_MONITOR (object); -- -- g_hash_table_unref (self->pending_changes); -- g_hash_table_unref (self->unresolved_ids); -- -- g_queue_free_full (self->pending_events, (GDestroyNotify) photos_tracker_change_event_free); -- -- G_OBJECT_CLASS (photos_tracker_change_monitor_parent_class)->finalize (object); --} -- -- --static void --photos_tracker_change_monitor_init (PhotosTrackerChangeMonitor *self) --{ -- self->pending_changes = g_hash_table_new_full (g_str_hash, -- g_str_equal, -- g_free, -- (GDestroyNotify) photos_tracker_change_event_free); -- -- self->unresolved_ids = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); -- -- self->pending_events = g_queue_new (); --} -- -- --static void --photos_tracker_change_monitor_class_init (PhotosTrackerChangeMonitorClass *class) --{ -- GObjectClass *object_class = G_OBJECT_CLASS (class); -- -- object_class->constructor = photos_tracker_change_monitor_constructor; -- object_class->dispose = photos_tracker_change_monitor_dispose; -- object_class->finalize = photos_tracker_change_monitor_finalize; -- -- signals[CHANGES_PENDING] = g_signal_new ("changes-pending", -- G_TYPE_FROM_CLASS (class), -- G_SIGNAL_RUN_LAST, -- 0, -- NULL, /*accumulator */ -- NULL, /*accu_data */ -- g_cclosure_marshal_VOID__BOXED, -- G_TYPE_NONE, -- 1, -- G_TYPE_HASH_TABLE); --} -- -- --static gboolean --photos_tracker_change_monitor_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) --{ -- PhotosTrackerChangeMonitor *self = PHOTOS_TRACKER_CHANGE_MONITOR (initable); -- gboolean ret_val = TRUE; -- -- if (G_LIKELY (self->queue != NULL && self->resource_service != NULL)) -- goto out; -- -- self->queue = photos_tracker_queue_dup_singleton (cancellable, error); -- if (G_UNLIKELY (self->queue == NULL)) -- { -- ret_val = FALSE; -- goto out; -- } -- -- self->resource_service = tracker_resources_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, -- G_DBUS_PROXY_FLAGS_NONE, -- "org.gnome.Photos.Tracker1", -- "/org/freedesktop/Tracker1/Resources", -- cancellable, -- error); -- if (G_UNLIKELY (self->resource_service == NULL)) -- { -- ret_val = FALSE; -- goto out; -- } -- -- g_signal_connect (self->resource_service, -- "graph-updated", -- G_CALLBACK (photos_tracker_change_monitor_graph_updated), -- self); -- -- out: -- return ret_val; --} -- -- --static void --photos_tracker_change_monitor_initable_iface_init (GInitableIface *iface) --{ -- iface->init = photos_tracker_change_monitor_initable_init; --} -- -- --PhotosTrackerChangeMonitor * --photos_tracker_change_monitor_dup_singleton (GCancellable *cancellable, GError **error) --{ -- return g_initable_new (PHOTOS_TYPE_TRACKER_CHANGE_MONITOR, cancellable, error, NULL); --} -diff --git a/src/photos-tracker-change-monitor.h b/src/photos-tracker-change-monitor.h -deleted file mode 100644 -index 9740b046..00000000 ---- a/src/photos-tracker-change-monitor.h -+++ /dev/null -@@ -1,42 +0,0 @@ --/* -- * Photos - access, organize and share your photos on GNOME -- * Copyright © 2012 – 2019 Red Hat, Inc. -- * -- * This program is free software: you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation, either version 3 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . -- */ -- --/* Based on code from: -- * + Documents -- */ -- --#ifndef PHOTOS_TRACKER_CHANGE_MONITOR_H --#define PHOTOS_TRACKER_CHANGE_MONITOR_H -- --#include -- --G_BEGIN_DECLS -- --#define PHOTOS_TYPE_TRACKER_CHANGE_MONITOR (photos_tracker_change_monitor_get_type ()) --G_DECLARE_FINAL_TYPE (PhotosTrackerChangeMonitor, -- photos_tracker_change_monitor, -- PHOTOS, -- TRACKER_CHANGE_MONITOR, -- GObject); -- --PhotosTrackerChangeMonitor *photos_tracker_change_monitor_dup_singleton (GCancellable *cancellable, -- GError **error); -- --G_END_DECLS -- --#endif /* PHOTOS_TRACKER_CHANGE_MONITOR_H */ -diff --git a/src/photos-tracker-controller.c b/src/photos-tracker-controller.c -index a02db077..6d0053a1 100644 ---- a/src/photos-tracker-controller.c -+++ b/src/photos-tracker-controller.c -@@ -292,6 +292,12 @@ photos_tracker_controller_perform_current_query (PhotosTrackerController *self) - - priv = photos_tracker_controller_get_instance_private (self); - -+ if (G_UNLIKELY (priv->queue == NULL)) -+ { -+ photos_tracker_controller_query_error (self, priv->queue_error); -+ goto out; -+ } -+ - g_clear_object (&priv->current_query); - priv->current_query = PHOTOS_TRACKER_CONTROLLER_GET_CLASS (self)->get_query (self); - g_return_if_fail (priv->current_query != NULL); -@@ -303,12 +309,6 @@ photos_tracker_controller_perform_current_query (PhotosTrackerController *self) - g_object_unref (priv->cancellable); - priv->cancellable = g_cancellable_new (); - -- if (G_UNLIKELY (priv->queue == NULL)) -- { -- photos_tracker_controller_query_error (self, priv->queue_error); -- goto out; -- } -- - photos_tracker_queue_select (priv->queue, - priv->current_query, - priv->cancellable, -diff --git a/src/photos-tracker-extract-priority.xml b/src/photos-tracker-extract-priority.xml -index 7e3b9b0c..2b562299 100644 ---- a/src/photos-tracker-extract-priority.xml -+++ b/src/photos-tracker-extract-priority.xml -@@ -21,7 +21,7 @@ - --> - - -- -+ - - - -diff --git a/src/photos-tracker-import-controller.c b/src/photos-tracker-import-controller.c -index 9f130714..d7ed9b20 100644 ---- a/src/photos-tracker-import-controller.c -+++ b/src/photos-tracker-import-controller.c -@@ -24,7 +24,6 @@ - #include "config.h" - - #include --#include - - #include "photos-base-manager.h" - #include "photos-debug.h" -@@ -34,6 +33,8 @@ - #include "photos-query-builder.h" - #include "photos-search-context.h" - #include "photos-tracker-import-controller.h" -+#include "photos-tracker-miner-index.h" -+#include "photos-tracker-queue.h" - #include "photos-utils.h" - - -@@ -45,7 +46,7 @@ struct _PhotosTrackerImportController - PhotosBaseManager *item_mngr; - PhotosBaseManager *src_mngr; - PhotosOffsetController *offset_cntrlr; -- TrackerMinerManager *manager; -+ TrackerMinerFilesIndex *miner_control_proxy; - }; - - -@@ -76,12 +77,12 @@ static void - photos_tracker_import_controller_index (GObject *source_object, GAsyncResult *res, gpointer user_data) - { - g_autoptr (GFile) file = G_FILE (user_data); -- TrackerMinerManager *manager = TRACKER_MINER_MANAGER (source_object); -+ TrackerMinerFilesIndex *miner_control_proxy = TRACKER_MINER_FILES_INDEX (source_object); - - { - g_autoptr (GError) error = NULL; - -- if (!tracker_miner_manager_index_file_for_process_finish (manager, res, &error)) -+ if (!tracker_miner_files_index_call_index_location_finish (miner_control_proxy, res, &error)) - { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - { -@@ -102,6 +103,8 @@ photos_tracker_import_controller_next_files (GObject *source_object, GAsyncResul - GFileEnumerator *enumerator = G_FILE_ENUMERATOR (source_object); - GList *infos = NULL; - GList *l; -+ const gchar *tracker_priority_graphs[] = { TRACKER_PICTURES_GRAPH }; -+ const gchar *tracker_index_location_flags[] = { "for-process" }; - - { - g_autoptr (GError) error = NULL; -@@ -187,11 +190,13 @@ photos_tracker_import_controller_next_files (GObject *source_object, GAsyncResul - if (g_content_type_equals (mime_type, IMPORTABLE_MIME_TYPES[i]) - || g_content_type_is_a (mime_type, IMPORTABLE_MIME_TYPES[i])) - { -- tracker_miner_manager_index_file_for_process_async (self->manager, -- file, -- self->cancellable, -- photos_tracker_import_controller_index, -- g_object_ref (file)); -+ tracker_miner_files_index_call_index_location (self->miner_control_proxy, -+ uri, -+ tracker_priority_graphs, -+ tracker_index_location_flags, -+ self->cancellable, -+ photos_tracker_import_controller_index, -+ g_object_ref (file)); - indexing = TRUE; - } - } -@@ -291,28 +296,6 @@ photos_tracker_import_controller_source_active_changed (PhotosTrackerImportContr - { - g_return_if_fail (g_queue_is_empty (self->pending_directories)); - -- if (G_LIKELY (self->manager != NULL)) -- { -- g_autoptr (GFile) root = NULL; -- g_autofree gchar *uri = NULL; -- -- root = g_mount_get_root (mount); -- g_queue_push_tail (self->pending_directories, g_object_ref (root)); -- -- uri = g_file_get_uri (root); -- photos_debug (PHOTOS_DEBUG_IMPORT, "Enumerating device directory %s", uri); -- -- g_file_enumerate_children_async (root, -- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE"," -- G_FILE_ATTRIBUTE_STANDARD_NAME"," -- G_FILE_ATTRIBUTE_STANDARD_TYPE, -- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, -- G_PRIORITY_DEFAULT, -- self->cancellable, -- photos_tracker_import_controller_enumerate_children, -- self); -- } -- - photos_tracker_controller_refresh_for_object (PHOTOS_TRACKER_CONTROLLER (self)); - } - } -@@ -379,7 +362,6 @@ photos_tracker_import_controller_dispose (GObject *object) - - g_clear_object (&self->src_mngr); - g_clear_object (&self->offset_cntrlr); -- g_clear_object (&self->manager); - - G_OBJECT_CLASS (photos_tracker_import_controller_parent_class)->dispose (object); - } -@@ -397,6 +379,37 @@ photos_tracker_import_controller_finalize (GObject *object) - } - - -+static TrackerMinerFilesIndex * -+photos_tracker_import_controller_get_miner_fs_control_proxy (GCancellable *cancellable) -+{ -+ g_autoptr (PhotosTrackerQueue) tracker_queue = NULL; -+ const gchar *miner_fs_control_busname; -+ g_autoptr (GError) error = NULL; -+ TrackerMinerFilesIndex *miner_control_proxy; -+ -+ tracker_queue = photos_tracker_queue_dup_singleton (cancellable, &error); -+ -+ if (!tracker_queue) { -+ g_warning ("Error getting Tracker queue: %s. Import will not work.", error->message); -+ return NULL; -+ } -+ -+ miner_fs_control_busname = photos_tracker_queue_get_miner_fs_control_busname (tracker_queue); -+ miner_control_proxy = tracker_miner_files_index_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, -+ G_DBUS_PROXY_FLAGS_NONE, -+ miner_fs_control_busname, -+ "/org/freedesktop/Tracker3/Miner/Files/Control", -+ NULL, -+ &error); -+ if (!miner_control_proxy) { -+ g_warning ("Error getting Tracker Miner FS control proxy: %s. Import will not work", error->message); -+ return NULL; -+ } -+ -+ return miner_control_proxy; -+} -+ -+ - static void - photos_tracker_import_controller_init (PhotosTrackerImportController *self) - { -@@ -421,13 +434,7 @@ photos_tracker_import_controller_init (PhotosTrackerImportController *self) - - self->offset_cntrlr = photos_offset_import_controller_dup_singleton (); - -- { -- g_autoptr (GError) error = NULL; -- -- self->manager = tracker_miner_manager_new_full (TRUE, &error); -- if (error != NULL) -- g_warning ("Unable to create a TrackerMinerManager, indexing attached devices won't work: %s", error->message); -- } -+ self->miner_control_proxy = photos_tracker_import_controller_get_miner_fs_control_proxy (NULL); - } - - -diff --git a/src/photos-tracker-queue.c b/src/photos-tracker-queue.c -index 76d25d5d..a5f4c91a 100644 ---- a/src/photos-tracker-queue.c -+++ b/src/photos-tracker-queue.c -@@ -37,9 +37,20 @@ struct _PhotosTrackerQueue - GObject parent_instance; - GError *initialization_error; - GQueue *queue; -- TrackerSparqlConnection *connection; -+ TrackerSparqlConnection *local_connection; -+ TrackerSparqlConnection *miner_fs_connection; - gboolean is_initialized; - gboolean running; -+ gboolean miner_fs_ready; -+ const gchar *miner_fs_busname; -+ const gchar *miner_fs_control_busname; -+}; -+ -+enum -+{ -+ PROP_0, -+ PROP_MINER_FS_READY, -+ PROP_MINER_FS_BUSNAME - }; - - static void photos_tracker_queue_initable_iface_init (GInitableIface *iface); -@@ -90,7 +101,6 @@ photos_tracker_queue_data_free (PhotosTrackerQueueData *data) - - G_DEFINE_AUTOPTR_CLEANUP_FUNC (PhotosTrackerQueueData, photos_tracker_queue_data_free); - -- - static PhotosTrackerQueueData * - photos_tracker_queue_data_new (PhotosQuery *query, - PhotosTrackerQueryType query_type, -@@ -179,7 +189,7 @@ photos_tracker_queue_check (PhotosTrackerQueue *self) - switch (data->query_type) - { - case PHOTOS_TRACKER_QUERY_SELECT: -- tracker_sparql_connection_query_async (self->connection, -+ tracker_sparql_connection_query_async (self->local_connection, - sparql, - data->cancellable, - photos_tracker_queue_collector, -@@ -187,18 +197,16 @@ photos_tracker_queue_check (PhotosTrackerQueue *self) - break; - - case PHOTOS_TRACKER_QUERY_UPDATE: -- tracker_sparql_connection_update_async (self->connection, -+ tracker_sparql_connection_update_async (self->local_connection, - sparql, -- G_PRIORITY_DEFAULT, - data->cancellable, - photos_tracker_queue_collector, - g_object_ref (self)); - break; - - case PHOTOS_TRACKER_QUERY_UPDATE_BLANK: -- tracker_sparql_connection_update_blank_async (self->connection, -+ tracker_sparql_connection_update_blank_async (self->local_connection, - sparql, -- G_PRIORITY_DEFAULT, - data->cancellable, - photos_tracker_queue_collector, - g_object_ref (self)); -@@ -211,6 +219,53 @@ photos_tracker_queue_check (PhotosTrackerQueue *self) - } - - -+static gboolean -+photos_tracker_queue_start_session_miner_fs (PhotosTrackerQueue *self, GError **error) -+{ -+ const gchar *busname = "org.freedesktop.Tracker3.Miner.Files"; -+ const gchar *control_busname = "org.freedesktop.Tracker3.Miner.Files.Control"; -+ -+ photos_debug (PHOTOS_DEBUG_TRACKER, "Connecting to %s", busname); -+ self->miner_fs_connection = tracker_sparql_connection_bus_new (busname, NULL, NULL, error); -+ if (*error) -+ { -+ g_warning ("Unable to create connection for session-wide Tracker indexer at %s: %s", busname, (*error)->message); -+ return FALSE; -+ } -+ -+ self->miner_fs_busname = busname; -+ self->miner_fs_control_busname = control_busname; -+ -+ return TRUE; -+} -+ -+ -+static gboolean -+photos_tracker_queue_start_local_miner_fs (PhotosTrackerQueue *self, GError **error) -+{ -+ const gchar *busname = "org.gnome.Photos.Tracker3.Miner.Files"; -+ const gchar *control_busname = "org.gnome.Photos.Tracker3.Miner.Files.Control"; -+ -+ photos_debug (PHOTOS_DEBUG_TRACKER, "Connecting to %s", busname); -+ self->miner_fs_connection = tracker_sparql_connection_bus_new (busname, NULL, NULL, error); -+ if (*error) -+ { -+ g_critical ("Could not start local Tracker indexer at %s: %s", busname, (*error)->message); -+ return FALSE; -+ } -+ -+ self->miner_fs_busname = busname; -+ self->miner_fs_control_busname = control_busname; -+ -+ return TRUE; -+} -+ -+static gboolean -+inside_flatpak (void) -+{ -+ return g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS); -+} -+ - static GObject * - photos_tracker_queue_constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params) - { -@@ -234,7 +289,8 @@ photos_tracker_queue_dispose (GObject *object) - { - PhotosTrackerQueue *self = PHOTOS_TRACKER_QUEUE (object); - -- g_clear_object (&self->connection); -+ g_clear_object (&self->local_connection); -+ g_clear_object (&self->miner_fs_connection); - - G_OBJECT_CLASS (photos_tracker_queue_parent_class)->dispose (object); - } -@@ -258,6 +314,38 @@ photos_tracker_queue_init (PhotosTrackerQueue *self) - self->queue = g_queue_new (); - } - -+static void -+photos_tracker_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -+{ -+ PhotosTrackerQueue *self = PHOTOS_TRACKER_QUEUE (object); -+ -+ switch (prop_id) -+ { -+ case PROP_MINER_FS_READY: -+ g_value_set_boolean (value, self->miner_fs_ready); -+ break; -+ -+ case PROP_MINER_FS_BUSNAME: -+ g_value_set_string (value, self->miner_fs_busname); -+ break; -+ -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; -+ } -+} -+ -+static void -+photos_tracker_queue_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -+{ -+ switch (prop_id) -+ { -+ /* All properties are read only */ -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; -+ } -+} - - static void - photos_tracker_queue_class_init (PhotosTrackerQueueClass *class) -@@ -267,6 +355,24 @@ photos_tracker_queue_class_init (PhotosTrackerQueueClass *class) - object_class->constructor = photos_tracker_queue_constructor; - object_class->dispose = photos_tracker_queue_dispose; - object_class->finalize = photos_tracker_queue_finalize; -+ object_class->get_property = photos_tracker_queue_get_property; -+ object_class->set_property = photos_tracker_queue_set_property; -+ -+ g_object_class_install_property (object_class, -+ PROP_MINER_FS_READY, -+ g_param_spec_boolean ("tracker-miner-fs-ready", -+ "Tracker Miner FS ready", -+ "TRUE if it is possible to query Tracker indexer", -+ FALSE, -+ G_PARAM_READABLE)); -+ -+ g_object_class_install_property (object_class, -+ PROP_MINER_FS_BUSNAME, -+ g_param_spec_string ("tracker-miner-fs-busname", -+ "Tracker Miner FS busname", -+ "D-Bus name of the Tracker indexer daemon", -+ "", -+ G_PARAM_READABLE)); - } - - -@@ -274,13 +380,16 @@ static gboolean - photos_tracker_queue_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) - { - PhotosTrackerQueue *self = PHOTOS_TRACKER_QUEUE (initable); -+ TrackerSparqlConnectionFlags tracker_flags; -+ g_autoptr (GFile) store = NULL; - gboolean ret_val = FALSE; -+ gboolean miner_ok = FALSE; - - G_LOCK (init_lock); - - if (self->is_initialized) - { -- if (self->connection != NULL) -+ if (self->local_connection != NULL && self->miner_fs_connection != NULL) - ret_val = TRUE; - else - g_assert_nonnull (self->initialization_error); -@@ -290,13 +399,49 @@ photos_tracker_queue_initable_init (GInitable *initable, GCancellable *cancellab - - g_assert_no_error (self->initialization_error); - -- tracker_sparql_connection_set_domain ("org.gnome.Photos"); -+ /* Connect to the local database which stores user data. -+ * -+ * Same flags that tracker-miner-fs uses by default. See: -+ * https://gitlab.gnome.org/GNOME/tracker-miners/-/blob/master/src/miners/fs/tracker-main.c#L735 and -+ * https://gitlab.gnome.org/GNOME/tracker-miners/-/blob/master/data/org.freedesktop.Tracker.FTS.gschema.xml */ -+ tracker_flags = TRACKER_SPARQL_CONNECTION_FLAGS_FTS_ENABLE_UNACCENT | -+ TRACKER_SPARQL_CONNECTION_FLAGS_FTS_ENABLE_STOP_WORDS | -+ TRACKER_SPARQL_CONNECTION_FLAGS_FTS_IGNORE_NUMBERS; -+ -+ store = g_file_new_build_filename (g_get_user_data_dir (), "gnome-photos", NULL); -+ -+ photos_debug (PHOTOS_DEBUG_TRACKER, "Opening local database at %s", g_file_peek_path (store)); -+ self->local_connection = tracker_sparql_connection_new (tracker_flags, -+ store, -+ tracker_sparql_get_ontology_nepomuk (), -+ cancellable, -+ &self->initialization_error); - -- self->connection = tracker_sparql_connection_get (cancellable, &self->initialization_error); - if (G_UNLIKELY (self->initialization_error != NULL)) - goto out; - -- ret_val = TRUE; -+ /* Connect to filesystem indexer. */ -+ miner_ok = photos_tracker_queue_start_session_miner_fs (self, &self->initialization_error); -+ -+ if (!miner_ok && inside_flatpak ()) -+ { -+ g_clear_error (&self->initialization_error); -+ miner_ok = photos_tracker_queue_start_local_miner_fs (self, &self->initialization_error); -+ } -+ -+ if (miner_ok) -+ { -+ photos_debug (PHOTOS_DEBUG_TRACKER, "Using %s as tracker-miner-fs", self->miner_fs_busname); -+ ret_val = TRUE; -+ } -+ else -+ { -+ photos_debug (PHOTOS_DEBUG_TRACKER, "Initialization failed due to %s", self->initialization_error->message); -+ g_clear_object (&self->miner_fs_connection); -+ g_clear_object (&self->local_connection); -+ ret_val = FALSE; -+ } -+ - - out: - self->is_initialized = TRUE; -@@ -321,10 +466,44 @@ photos_tracker_queue_initable_iface_init (GInitableIface *iface) - PhotosTrackerQueue * - photos_tracker_queue_dup_singleton (GCancellable *cancellable, GError **error) - { -+ GObject *singleton; -+ - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - -- return g_initable_new (PHOTOS_TYPE_TRACKER_QUEUE, cancellable, error, NULL); -+ singleton = g_object_new (PHOTOS_TYPE_TRACKER_QUEUE, NULL); -+ -+ if (g_initable_init (G_INITABLE (singleton), cancellable, error)) -+ return PHOTOS_TRACKER_QUEUE (singleton); -+ -+ /* On error we deliberately don't unref the object so that we won't try -+ * and re-initialize Tracker when called again. -+ */ -+ return NULL; -+} -+ -+ -+const gchar * -+photos_tracker_queue_get_miner_fs_busname (PhotosTrackerQueue *self) -+{ -+ return self->miner_fs_busname; -+} -+ -+ -+const gchar * -+photos_tracker_queue_get_miner_fs_control_busname (PhotosTrackerQueue *self) -+{ -+ return self->miner_fs_control_busname; -+} -+ -+ -+TrackerNotifier * -+photos_tracker_queue_get_notifier (PhotosTrackerQueue *self) -+{ -+ /* We want notifications on filesystem changes, we don't need them for the -+ * local database which we manage ourselves. -+ */ -+ return tracker_sparql_connection_create_notifier (self->miner_fs_connection); - } - - -@@ -353,6 +532,7 @@ photos_tracker_queue_select (PhotosTrackerQueue *self, - } - - -+ - void - photos_tracker_queue_update (PhotosTrackerQueue *self, - PhotosQuery *query, -diff --git a/src/photos-tracker-queue.h b/src/photos-tracker-queue.h -index 93d97306..6e31ecf6 100644 ---- a/src/photos-tracker-queue.h -+++ b/src/photos-tracker-queue.h -@@ -24,16 +24,23 @@ - #define PHOTOS_TRACKER_QUEUE_H - - #include -+#include - - #include "photos-query.h" - - G_BEGIN_DECLS - -+#define TRACKER_PICTURES_GRAPH "http://tracker.api.gnome.org/ontology/v3/tracker#Pictures" -+ - #define PHOTOS_TYPE_TRACKER_QUEUE (photos_tracker_queue_get_type ()) - G_DECLARE_FINAL_TYPE (PhotosTrackerQueue, photos_tracker_queue, PHOTOS, TRACKER_QUEUE, GObject); - - PhotosTrackerQueue *photos_tracker_queue_dup_singleton (GCancellable *cancellable, GError **error); - -+const gchar * photos_tracker_queue_get_miner_fs_busname (PhotosTrackerQueue *self); -+const gchar * photos_tracker_queue_get_miner_fs_control_busname (PhotosTrackerQueue *self); -+TrackerNotifier * photos_tracker_queue_get_notifier (PhotosTrackerQueue *self); -+ - void photos_tracker_queue_select (PhotosTrackerQueue *self, - PhotosQuery *query, - GCancellable *cancellable, -diff --git a/src/photos-tracker-resources.xml b/src/photos-tracker-resources.xml -deleted file mode 100644 -index 18177aa0..00000000 ---- a/src/photos-tracker-resources.xml -+++ /dev/null -@@ -1,31 +0,0 @@ -- -- -- -- -- -- -- -- -- -- -- -- -- -diff --git a/src/photos-utils.c b/src/photos-utils.c -index d659b47d..72d2e98b 100644 ---- a/src/photos-utils.c -+++ b/src/photos-utils.c -@@ -1324,7 +1324,13 @@ photos_utils_set_edited_name (const gchar *urn, const gchar *title) - g_autoptr (PhotosTrackerQueue) queue = NULL; - g_autofree gchar *sparql = NULL; - -- sparql = g_strdup_printf ("INSERT OR REPLACE { <%s> nie:title \"%s\" }", urn, title); -+ sparql = g_strdup_printf ("WITH tracker:Pictures " -+ "DELETE { <%s> nie:title ?title } " -+ "INSERT { " -+ " <%s> a nmm:Photo ; " -+ " nie:title \"%s\" . " -+ "}" -+ "WHERE { <%s> nie:title ?title }", urn, urn, title, urn); - query = photos_query_new (NULL, sparql); - - { -@@ -1352,9 +1358,19 @@ photos_utils_set_favorite (const gchar *urn, gboolean is_favorite) - g_autoptr (PhotosTrackerQueue) queue = NULL; - g_autofree gchar *sparql = NULL; - -- sparql = g_strdup_printf ("%s { <%s> nao:hasTag nao:predefined-tag-favorite }", -- (is_favorite) ? "INSERT OR REPLACE" : "DELETE", -- urn); -+ if (is_favorite) -+ sparql = g_strdup_printf ("INSERT DATA { " -+ " GRAPH tracker:Pictures {" -+ " <%s> a nmm:Photo ; " -+ " nao:hasTag nao:predefined-tag-favorite " -+ " } " -+ "}", urn); -+ else -+ sparql = g_strdup_printf ("DELETE DATA {" -+ " GRAPH tracker:Pictures {" -+ " <%s> nao:hasTag nao:predefined-tag-favorite " -+ " } " -+ "}", urn); - query = photos_query_new (NULL, sparql); - - { -diff --git a/src/photos-utils.h b/src/photos-utils.h -index a4d69abf..57069892 100644 ---- a/src/photos-utils.h -+++ b/src/photos-utils.h -@@ -46,7 +46,7 @@ G_BEGIN_DECLS - #define PHOTOS_TRACKER_CONTROLLER_EXTENSION_POINT_NAME "photos-tracker-controller" - - #define PHOTOS_COLLECTION_SCREENSHOT \ -- "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#image-category-screenshot" -+ "http://tracker.api.gnome.org/ontology/v3/nfo#image-category-screenshot" - #define PHOTOS_EXPORT_SUBPATH "Exports" - - typedef enum -diff --git a/src/queries/all.sparql.template b/src/queries/all.sparql.template -index 1cef98e8..14e08027 100644 ---- a/src/queries/all.sparql.template -+++ b/src/queries/all.sparql.template -@@ -1,30 +1,42 @@ --SELECT {{projection}} -+SELECT {{final_projection}} -+FROM NAMED tracker:Pictures - { - { -- SELECT {{projection}} -+ SELECT {{main_projection}} - { - { - SELECT ?urn COUNT(?item) AS ?count - { -+ {{values}} -+ VALUES (?file ?filename ?creator ?publisher) { ("" "" "" "") } - ?urn a nfo:DataContainer. -- ?item a nmm:Photo; nie:isPartOf ?urn. -- } GROUP BY ?urn -+ ?item a nmm:Photo ; -+ nie:isPartOf ?urn . -+ {{item_pattern}} -+ } -+ GROUP BY ?urn - } - FILTER (?count > 0 && {{collections_default_filter}} && {{search_filter}}) - } -- GROUP BY ?urn - } - UNION - { -- SELECT {{projection}} -+ SELECT {{second_projection}} - { -- ?urn a nmm:Photo . -- OPTIONAL { ?urn nco:creator ?creator . } -- OPTIONAL { ?urn nco:publisher ?publisher . } - {{item_pattern}} -- FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+ SERVICE -+ { -+ SELECT {{main_projection}} -+ { -+ {{values}} -+ ?urn a nmm:Photo ; -+ nie:isStoredAs ?file . -+ OPTIONAL { ?urn nco:creator ?creator . } -+ OPTIONAL { ?urn nco:publisher ?publisher . } -+ FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+ } -+ } - } -- GROUP BY ?urn - } - } - {{order}} -diff --git a/src/queries/collections.sparql.template b/src/queries/collections.sparql.template -index 20b35cd6..4dfb345a 100644 ---- a/src/queries/collections.sparql.template -+++ b/src/queries/collections.sparql.template -@@ -1,14 +1,20 @@ --SELECT {{projection}} -+SELECT {{final_projection}} - { -+ SELECT {{main_projection}} - { -- SELECT ?urn COUNT(?item) AS ?count - { -- ?urn a nfo:DataContainer. -- ?item a nmm:Photo; nie:isPartOf ?urn. -- } GROUP BY ?urn -+ SELECT ?urn COUNT(?item) AS ?count -+ { -+ {{values}} -+ VALUES (?file ?filename ?creator ?publisher) { ("" "" "" "") } -+ ?urn a nfo:DataContainer . -+ ?item a nmm:Photo ; -+ nie:isPartOf ?urn . -+ } -+ GROUP BY ?urn -+ } -+ FILTER (?count > 0 && {{collections_default_filter}} && {{search_filter}}) - } -- FILTER (?count > 0 && {{collections_default_filter}} && {{search_filter}}) - } --GROUP BY ?urn - {{order}} - {{offset_limit}} -diff --git a/src/queries/favorite-photos.sparql.template b/src/queries/favorite-photos.sparql.template -index 0885a08a..9a0d7806 100644 ---- a/src/queries/favorite-photos.sparql.template -+++ b/src/queries/favorite-photos.sparql.template -@@ -1,12 +1,20 @@ --SELECT {{projection}} -+SELECT {{final_projection}} -+FROM tracker:Pictures - { - ?urn a nmm:Photo . - ?urn a nmm:Photo; nao:hasTag nao:predefined-tag-favorite . -- OPTIONAL { ?urn nco:creator ?creator . } -- OPTIONAL { ?urn nco:publisher ?publisher . } -- {{item_pattern}} -- FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+ SERVICE -+ { -+ SELECT {{main_projection}} -+ { -+ ?urn a nmm:Photo ; -+ nie:isStoredAs ?file . -+ OPTIONAL { ?urn nco:creator ?creator . } -+ OPTIONAL { ?urn nco:publisher ?publisher . } -+ {{item_pattern}} -+ FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+ } -+ } - } --GROUP BY ?urn - {{order}} - {{offset_limit}} -diff --git a/src/queries/photos.sparql.template b/src/queries/photos.sparql.template -index 4eb10b74..6ade35e2 100644 ---- a/src/queries/photos.sparql.template -+++ b/src/queries/photos.sparql.template -@@ -1,11 +1,19 @@ --SELECT {{projection}} -+SELECT {{final_projection}} -+FROM tracker:Pictures - { -- ?urn a nmm:Photo . -- OPTIONAL { ?urn nco:creator ?creator . } -- OPTIONAL { ?urn nco:publisher ?publisher . } -- {{item_pattern}} -- FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+ SERVICE -+ { -+ SELECT {{main_projection}} -+ { -+ {{values}} -+ ?urn a nmm:Photo ; -+ nie:isStoredAs ?file . -+ OPTIONAL { ?urn nco:creator ?creator . } -+ OPTIONAL { ?urn nco:publisher ?publisher . } -+ {{item_pattern}} -+ FILTER ({{photos_default_filter}} && {{source_filter}} && {{search_filter}}) -+ } -+ } - } --GROUP BY ?urn - {{order}} - {{offset_limit}} --- -GitLab - diff --git a/srcpkgs/gnome-photos/template b/srcpkgs/gnome-photos/template index ca3f4be7162e..fee19723ed89 100644 --- a/srcpkgs/gnome-photos/template +++ b/srcpkgs/gnome-photos/template @@ -1,6 +1,6 @@ # Template file for 'gnome-photos' pkgname=gnome-photos -version=3.38.0 +version=40.0 revision=1 build_helper="gir" build_style=meson @@ -9,15 +9,14 @@ hostmakedepends="pkg-config gettext itstool glib-devel gdk-pixbuf librsvg" makedepends="gtk+3-devel babl-devel exempi-devel lcms2-devel gfbgraph-devel tracker3-devel libexif-devel librsvg-devel grilo-devel libgexiv2-devel gnome-online-accounts-devel gnome-desktop-devel libgdata-devel - geocode-glib-devel libdazzle-devel gegl-devel" + geocode-glib-devel libdazzle-devel gegl-devel libhandy1-devel" depends="desktop-file-utils tracker3 tracker3-miners" short_desc="Access, organize, and share your photos on GNOME" maintainer="Enno Boland " license="GPL-2.0-or-later" homepage="https://wiki.gnome.org/Apps/Photos" distfiles="${GNOME_SITE}/gnome-photos/${version%.*}/gnome-photos-${version}.tar.xz" -checksum=667f39477579d577470740e01f37b05c62e461e6f6da6377724d8f3993e1c4c4 -patch_args="-Np1" +checksum=e02d73e138af8b2868b5cad7faa1bdd278aeade3b6c3c92836511a4e6f3af1af build_options="gir" build_options_default="gir"