gnome-photos/0001-wip-item-manager-Handle-collection-COLUMNS_URNs-with.patch
2023-01-31 19:28:04 +08:00

310 lines
11 KiB
Diff

From 62c75d289f21223902bcdb61b8fb51fce9830bf6 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 3 May 2022 12:50:21 -0400
Subject: [PATCH] wip! item-manager: Handle collection COLUMNS_URNs with
stripped prefix
For reasons I don't understand, tracker sometimes returns
blank node urns without their qualifiers (so "82" instead of "urn:bnode:82")
That causes duplicate entries to get added to the collection model, and
makes the album view get confused.
This commit tries to accomodate the oddity by manually adding the
prefix back.
https://gitlab.gnome.org/GNOME/gnome-photos/-/issues/197
---
src/photos-base-item.c | 16 ++++++++++++----
src/photos-item-manager.c | 15 +++++++++++++++
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index 3b20bc2e..eef0bf66 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -2780,98 +2780,106 @@ photos_base_item_update_info_from_type (PhotosBaseItem *self)
if (strstr (priv->rdf_type, "nfo#DataContainer") != NULL)
priv->collection = TRUE;
PHOTOS_BASE_ITEM_GET_CLASS (self)->update_type_description (self);
}
static void
photos_base_item_populate_from_cursor (PhotosBaseItem *self, TrackerSparqlCursor *cursor)
{
PhotosBaseItemPrivate *priv;
gboolean favorite;
const gchar *author;
const gchar *ctime;
const gchar *equipment;
const gchar *flash;
const gchar *id;
const gchar *identifier;
const gchar *location;
const gchar *mime_type;
const gchar *orientation;
const gchar *rdf_type;
const gchar *resource_urn;
const gchar *title;
const gchar *uri;
gchar *filename;
gchar *name_fallback;
gint64 height;
gint64 width;
+ g_autofree char *bnode_id = NULL;
priv = photos_base_item_get_instance_private (self);
uri = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URI, NULL);
if (uri == NULL)
uri = "";
photos_utils_set_string (&priv->uri, uri);
g_object_notify (G_OBJECT (self), "uri");
+ rdf_type = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_RDF_TYPE, NULL);
+ photos_utils_set_string (&priv->rdf_type, rdf_type);
+
+ photos_base_item_update_info_from_type (self);
+
id = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URN, NULL);
+
+ if (priv->collection && !g_str_has_prefix (id, "urn:bnode:"))
+ {
+ bnode_id = g_strdup_printf ("urn:bnode:%s", id);
+ id = bnode_id;
+ }
photos_utils_set_string (&priv->id, id);
g_object_notify (G_OBJECT (self), "id");
identifier = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_IDENTIFIER, NULL);
photos_utils_set_string (&priv->identifier, identifier);
author = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_AUTHOR, NULL);
photos_utils_set_string (&priv->author, author);
g_object_notify (G_OBJECT (self), "secondary-text");
location = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_LOCATION, NULL);
photos_utils_set_string (&priv->location, location);
resource_urn = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_RESOURCE_URN, NULL);
photos_utils_set_string (&priv->resource_urn, resource_urn);
favorite = tracker_sparql_cursor_get_boolean (cursor, PHOTOS_QUERY_COLUMNS_RESOURCE_FAVORITE);
priv->mtime = photos_utils_get_mtime_from_sparql_cursor (cursor);
g_object_notify (G_OBJECT (self), "mtime");
mime_type = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_MIME_TYPE, NULL);
photos_utils_set_string (&priv->mime_type, mime_type);
- rdf_type = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_RDF_TYPE, NULL);
- photos_utils_set_string (&priv->rdf_type, rdf_type);
-
- photos_base_item_update_info_from_type (self);
priv->favorite = favorite && !priv->collection;
priv->ctime = -1;
ctime = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_DATE_CREATED, NULL);
if (ctime != NULL)
{
g_autoptr (GDateTime) date_created = NULL;
date_created = g_date_time_new_from_iso8601 (ctime, NULL);
if (date_created != NULL)
priv->ctime = g_date_time_to_unix (date_created);
}
if (g_strcmp0 (priv->id, PHOTOS_COLLECTION_SCREENSHOT) == 0)
title = _("Screenshots");
else
title = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_TITLE, NULL);
if (title == NULL)
title = "";
photos_utils_set_string (&priv->name, title);
g_object_notify (G_OBJECT (self), "primary-text");
filename = g_strdup (tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_FILENAME, NULL));
if ((filename == NULL || filename[0] == '\0') && !priv->collection)
filename = PHOTOS_BASE_ITEM_GET_CLASS (self)->create_filename_fallback (self);
photos_utils_take_string (&priv->filename, filename);
equipment = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_EQUIPMENT, NULL);
priv->equipment = g_quark_from_string (equipment);
diff --git a/src/photos-item-manager.c b/src/photos-item-manager.c
index 73ccaaa6..30a31769 100644
--- a/src/photos-item-manager.c
+++ b/src/photos-item-manager.c
@@ -278,81 +278,88 @@ photos_item_manager_info_updated (PhotosBaseItem *item, gpointer user_data)
{
photos_base_manager_remove_object (self->item_mngr_chldrn[PHOTOS_WINDOW_MODE_COLLECTION_VIEW],
G_OBJECT (item));
photos_base_manager_remove_object (self->item_mngr_chldrn[PHOTOS_WINDOW_MODE_FAVORITES], G_OBJECT (item));
photos_base_manager_remove_object (self->item_mngr_chldrn[PHOTOS_WINDOW_MODE_OVERVIEW], G_OBJECT (item));
}
else
{
photos_base_manager_remove_object (self->item_mngr_chldrn[PHOTOS_WINDOW_MODE_COLLECTIONS], G_OBJECT (item));
if (!is_favorite)
photos_base_manager_remove_object (self->item_mngr_chldrn[PHOTOS_WINDOW_MODE_FAVORITES], G_OBJECT (item));
}
out:
return;
}
static void
photos_item_manager_add_cursor_for_mode (PhotosItemManager *self,
GType base_item_type,
TrackerSparqlCursor *cursor,
PhotosWindowMode mode,
gboolean force)
{
g_autoptr (PhotosBaseItem) item = NULL;
PhotosBaseManager *item_mngr_chld;
gboolean is_collection;
const gchar *id;
+ g_autofree char *bnode_id = NULL;
g_return_if_fail (PHOTOS_IS_ITEM_MANAGER (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_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);
is_collection = photos_item_manager_cursor_is_collection (cursor);
g_return_if_fail ((is_collection
&& (mode == PHOTOS_WINDOW_MODE_COLLECTIONS || mode == PHOTOS_WINDOW_MODE_SEARCH))
|| (!is_collection && mode != PHOTOS_WINDOW_MODE_COLLECTIONS));
if (!force && !photos_item_manager_can_add_cursor_for_mode (self, cursor, mode))
goto out;
item_mngr_chld = self->item_mngr_chldrn[mode];
id = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URN, NULL);
+ if (mode == PHOTOS_WINDOW_MODE_COLLECTIONS && !g_str_has_prefix (id, "urn:bnode:"))
+ {
+ bnode_id = g_strdup_printf ("urn:bnode:%s", id);
+ id = bnode_id;
+ }
+
item = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (item_mngr_chld, id));
if (item != NULL)
{
g_object_ref (item);
}
else
{
gboolean already_present = FALSE;
item = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (PHOTOS_BASE_MANAGER (self), id));
if (item != NULL)
{
g_object_ref (item);
already_present = TRUE;
}
else
{
item = photos_item_manager_create_item (self, base_item_type, cursor, TRUE);
if (photos_base_item_is_collection (item))
g_hash_table_insert (self->collections, g_strdup (id), g_object_ref (item));
g_signal_connect_object (item, "info-updated", G_CALLBACK (photos_item_manager_info_updated), self, 0);
}
photos_base_manager_add_object (item_mngr_chld, G_OBJECT (item));
photos_base_manager_add_object (self->item_mngr_chldrn[0], G_OBJECT (item));
if (!already_present)
g_signal_emit_by_name (self, "object-added", G_OBJECT (item));
}
@@ -1351,68 +1358,76 @@ photos_item_manager_clear (PhotosItemManager *self, PhotosWindowMode mode)
continue;
item1 = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (self->item_mngr_chldrn[j], id));
if (item1 != NULL)
break;
}
if (item1 == NULL)
{
item1 = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (self->item_mngr_chldrn[0], id));
g_assert_true (item == item1);
g_signal_handlers_disconnect_by_func (item, photos_item_manager_info_updated, self);
photos_base_manager_remove_object_by_id (self->item_mngr_chldrn[0], id);
}
}
photos_base_manager_clear (item_mngr_chld);
}
PhotosBaseItem *
photos_item_manager_create_item (PhotosItemManager *self,
GType base_item_type,
TrackerSparqlCursor *cursor,
gboolean create_thumbnails)
{
PhotosBaseItem *item;
PhotosBaseItem *ret_val = NULL;
const gchar *id;
+ g_autofree char *bnode_id = NULL;
g_return_val_if_fail (PHOTOS_IS_ITEM_MANAGER (self), NULL);
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_IS_SPARQL_CURSOR (cursor), NULL);
id = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URN, NULL);
+
+ if (photos_item_manager_cursor_is_collection (cursor) && !g_str_has_prefix (id, "urn:bnode:"))
+ {
+ bnode_id = g_strdup_printf ("urn:bnode:%s", id);
+ id = bnode_id;
+ }
+
item = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (PHOTOS_BASE_MANAGER (self), id));
if (item != NULL)
{
ret_val = g_object_ref (item);
}
else
{
GType type;
if (base_item_type == G_TYPE_NONE)
{
GIOExtension *extension;
g_auto (GStrv) split_identifier = NULL;
const gchar *extension_name = "local";
g_autofree gchar *identifier = NULL;
identifier = g_strdup (tracker_sparql_cursor_get_string (cursor,
PHOTOS_QUERY_COLUMNS_IDENTIFIER,
NULL));
if (identifier != NULL)
{
split_identifier = g_strsplit (identifier, ":", 4);
if (photos_item_manager_cursor_is_collection (cursor))
{
/* Its a collection. */
extension_name = split_identifier[2];
}
else
{
--
2.35.1