[gnome-software] Add gs_app_get_unique_id() and use it for de-duplication
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Add gs_app_get_unique_id() and use it for de-duplication
- Date: Mon, 8 Aug 2016 15:59:56 +0000 (UTC)
commit d987d35438b45125b333dc8248de17d763619283
Author: Richard Hughes <richard hughsie com>
Date: Wed Aug 3 15:13:52 2016 +0100
Add gs_app_get_unique_id() and use it for de-duplication
This allows us to finally support more than one version of application,
and also more than one distribution system without hacks like an ID prefix.
This requires a new appstream-glib as well.
configure.ac | 2 +-
src/gs-app-list.c | 29 ++++++--
src/gs-app.c | 97 ++++++++++++++++++++-------
src/gs-app.h | 4 +-
src/gs-plugin-loader.c | 36 ++++++++---
src/gs-plugin.c | 2 +-
src/gs-self-test.c | 31 +++++++--
src/gs-shell-search.c | 4 +-
src/plugins/gs-appstream.c | 16 +++--
src/plugins/gs-flatpak.c | 73 ++++++++++++++-------
src/plugins/gs-flatpak.h | 3 -
src/plugins/gs-plugin-appstream.c | 70 +++++++++++++++-----
src/plugins/gs-plugin-dummy.c | 9 ++-
src/plugins/gs-plugin-epiphany.c | 6 +-
src/plugins/gs-plugin-flatpak-system.c | 4 +-
src/plugins/gs-plugin-flatpak-user.c | 4 +-
src/plugins/gs-plugin-hardcoded-featured.c | 2 +-
src/plugins/gs-plugin-limba.c | 12 ++++
src/plugins/gs-plugin-odrs.c | 12 ++--
src/plugins/gs-plugin-packagekit-refine.c | 10 +--
src/plugins/gs-plugin-shell-extensions.c | 14 +++-
src/plugins/gs-plugin-snap.c | 11 +++
22 files changed, 318 insertions(+), 133 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index ecb6513..8a13731 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,7 +63,7 @@ dnl ---------------------------------------------------------------------------
dnl - Check library dependencies
dnl ---------------------------------------------------------------------------
PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.18.2 gio-unix-2.0)
-PKG_CHECK_MODULES(APPSTREAM, appstream-glib >= 0.5.18)
+PKG_CHECK_MODULES(APPSTREAM, appstream-glib >= 0.6.1)
PKG_CHECK_MODULES(GDK_PIXBUF, gdk-pixbuf-2.0 >= 2.31.5)
PKG_CHECK_MODULES(JSON_GLIB, json-glib-1.0 >= 1.1.1)
PKG_CHECK_MODULES(SQLITE, sqlite3)
diff --git a/src/gs-app-list.c b/src/gs-app-list.c
index da3d851..ee19b29 100644
--- a/src/gs-app-list.c
+++ b/src/gs-app-list.c
@@ -62,23 +62,36 @@ void
gs_app_list_add (GsAppList *list, GsApp *app)
{
const gchar *id;
+ guint i;
g_return_if_fail (GS_IS_APP_LIST (list));
g_return_if_fail (GS_IS_APP (app));
/* if we're lazy-loading the ID then we can't filter for duplicates */
- id = gs_app_get_id (app);
+ id = gs_app_get_unique_id (app);
if (id == NULL) {
g_ptr_array_add (list->array, g_object_ref (app));
return;
}
- /* check for hash_by_id */
+ /* check for duplicate */
if (g_hash_table_lookup (list->hash_by_id, id) != NULL) {
g_debug ("not adding duplicate %s", id);
return;
}
+ /* check for duplicate using globs (slower) */
+ for (i = 0; i < list->array->len; i++) {
+ GsApp *app_tmp = g_ptr_array_index (list->array, i);
+ if (as_utils_unique_id_equal (gs_app_get_unique_id (app),
+ gs_app_get_unique_id (app_tmp))) {
+ g_debug ("not adding duplicate %s as %s exists",
+ gs_app_get_unique_id (app),
+ gs_app_get_unique_id (app_tmp));
+ return;
+ }
+ }
+
/* just use the ref */
g_ptr_array_add (list->array, g_object_ref (app));
g_hash_table_insert (list->hash_by_id, (gpointer) id, (gpointer) app);
@@ -266,9 +279,9 @@ gs_app_list_filter_duplicates (GsAppList *list, GsAppListFilterFlags flags)
g_free, (GDestroyNotify) g_object_unref);
for (i = 0; i < list->array->len; i++) {
app = gs_app_list_index (list, i);
- id = gs_app_get_id (app);
+ id = gs_app_get_unique_id (app);
if (flags & GS_APP_LIST_FILTER_FLAG_PRIORITY)
- id = gs_app_get_id_no_prefix (app);
+ id = gs_app_get_id (app);
if (id == NULL) {
g_autofree gchar *str = gs_app_to_string (app);
g_debug ("ignoring as no application id for: %s", str);
@@ -276,7 +289,7 @@ gs_app_list_filter_duplicates (GsAppList *list, GsAppListFilterFlags flags)
}
found = g_hash_table_lookup (hash, id);
if (found == NULL) {
- g_debug ("found new %s", gs_app_get_id (app));
+ g_debug ("found new %s", id);
g_hash_table_insert (hash,
g_strdup (id),
g_object_ref (app));
@@ -288,7 +301,7 @@ gs_app_list_filter_duplicates (GsAppList *list, GsAppListFilterFlags flags)
if (gs_app_get_priority (app) >
gs_app_get_priority (found)) {
g_debug ("using better %s (priority %u > %u)",
- gs_app_get_id (app),
+ id,
gs_app_get_priority (app),
gs_app_get_priority (found));
g_hash_table_insert (hash,
@@ -297,12 +310,12 @@ gs_app_list_filter_duplicates (GsAppList *list, GsAppListFilterFlags flags)
continue;
}
g_debug ("ignoring worse duplicate %s (priority %u > %u)",
- gs_app_get_id (app),
+ id,
gs_app_get_priority (app),
gs_app_get_priority (found));
continue;
}
- g_debug ("ignoring duplicate %s", gs_app_get_id (app));
+ g_debug ("ignoring duplicate %s", id);
continue;
}
diff --git a/src/gs-app.c b/src/gs-app.c
index 7721009..068fad6 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -59,6 +59,7 @@ struct _GsApp
GObject parent_instance;
gchar *id;
+ gchar *unique_id;
gchar *name;
GsAppQuality name_quality;
GPtrArray *icons;
@@ -254,6 +255,8 @@ gs_app_to_string (GsApp *app)
gs_app_kv_printf (str, "progress", "%u%%", app->progress);
if (app->id != NULL)
gs_app_kv_lpad (str, "id", app->id);
+ if (app->unique_id != NULL)
+ gs_app_kv_lpad (str, "unique-id", app->unique_id);
if ((app->kudos & GS_APP_KUDO_MY_LANGUAGE) > 0)
gs_app_kv_lpad (str, "kudo", "my-language");
if ((app->kudos & GS_APP_KUDO_RECENT_RELEASE) > 0)
@@ -486,7 +489,7 @@ gs_app_queue_notify (GsApp *app, const gchar *property_name)
*
* Gets the application ID.
*
- * Returns: The whole ID, e.g. "gimp.desktop" or "flatpak:org.gnome.Gimp.desktop"
+ * Returns: The whole ID, e.g. "gimp.desktop"
**/
const gchar *
gs_app_get_id (GsApp *app)
@@ -496,27 +499,6 @@ gs_app_get_id (GsApp *app)
}
/**
- * gs_app_get_id_no_prefix:
- * @app: a #GsApp
- *
- * Gets the application ID without any prefix set.
- *
- * Returns: The whole ID, e.g. gimp.desktop" or "org.gnome.Gimp.desktop"
- **/
-const gchar *
-gs_app_get_id_no_prefix (GsApp *app)
-{
- gchar *tmp;
- g_return_val_if_fail (GS_IS_APP (app), NULL);
- if (app->id == NULL)
- return NULL;
- tmp = g_strrstr (app->id, ":");
- if (tmp != NULL)
- return tmp + 1;
- return app->id;
-}
-
-/**
* gs_app_set_id:
* @app: a #GsApp
* @id: a application ID, e.g. "gimp.desktop"
@@ -527,6 +509,15 @@ void
gs_app_set_id (GsApp *app, const gchar *id)
{
g_return_if_fail (GS_IS_APP (app));
+
+ /* check for old-style prefix */
+ if (id != NULL && g_strstr_len (id, -1, ":") != NULL) {
+ g_warning ("Invalid ID of %s -- use "
+ "gs_app_set_unique_id() and use the actual "
+ "desktop-style ID here instead!", id);
+ return;
+ }
+
g_free (app->id);
app->id = g_strdup (id);
}
@@ -829,6 +820,61 @@ gs_app_set_kind (GsApp *app, AsAppKind kind)
}
/**
+ * gs_app_get_unique_id:
+ * @app: a #GsApp
+ *
+ * Gets the unique application ID used for de-duplication.
+ * If nothing has been set the value from gs_app_get_id() will be used.
+ *
+ * Returns: The unique ID, e.g. `system/package/fedora/desktop/gimp.desktop/i386/master/1.2.3`, or %NULL
+ **/
+const gchar *
+gs_app_get_unique_id (GsApp *app)
+{
+ g_return_val_if_fail (GS_IS_APP (app), NULL);
+
+ /* invalid */
+ if (app->id == NULL)
+ return NULL;
+
+ /* hmm, do what we can */
+ if (app->unique_id == NULL) {
+ g_debug ("autogenerating unique-id for %s", app->id);
+ app->unique_id = as_utils_unique_id_build (AS_APP_SCOPE_UNKNOWN,
+ AS_BUNDLE_KIND_UNKNOWN,
+ app->origin,
+ app->kind,
+ app->id,
+ NULL, /* arch */
+ NULL, /* branch */
+ app->version);
+ }
+ return app->unique_id;
+}
+
+/**
+ * gs_app_set_unique_id:
+ * @app: a #GsApp
+ * @unique_id: a unique application ID, e.g. `system/package/fedora/desktop/gimp.desktop/i386/master/1.2.3`
+ *
+ * Sets the unique application ID. Any #GsApp using the same ID will be
+ * deduplicated. This means that applications that can exist from more than
+ * one plugin should use this method.
+ */
+void
+gs_app_set_unique_id (GsApp *app, const gchar *unique_id)
+{
+ g_return_if_fail (GS_IS_APP (app));
+
+ /* check for sanity */
+ if (!as_utils_unique_id_valid (unique_id))
+ g_warning ("unique_id %s not valid", unique_id);
+
+ g_free (app->unique_id);
+ app->unique_id = g_strdup (unique_id);
+}
+
+/**
* gs_app_get_name:
* @app: a #GsApp
*
@@ -1629,7 +1675,7 @@ gs_app_set_origin (GsApp *app, const gchar *origin)
if (app->origin != NULL && origin != NULL) {
g_warning ("automatically prevented from changing "
"origin on %s from %s to %s!",
- gs_app_get_id (app),
+ gs_app_get_unique_id (app),
app->origin, origin);
return;
}
@@ -1921,7 +1967,7 @@ gs_app_set_management_plugin (GsApp *app, const gchar *management_plugin)
if (app->management_plugin != NULL && management_plugin != NULL) {
g_warning ("automatically prevented from changing "
"management plugin on %s from %s to %s!",
- gs_app_get_id (app),
+ gs_app_get_unique_id (app),
app->management_plugin,
management_plugin);
return;
@@ -2868,6 +2914,7 @@ gs_app_finalize (GObject *object)
GsApp *app = GS_APP (object);
g_free (app->id);
+ g_free (app->unique_id);
g_free (app->name);
g_hash_table_unref (app->urls);
g_free (app->license);
@@ -3037,7 +3084,7 @@ gs_app_init (GsApp *app)
/**
* gs_app_new:
- * @id: an application ID, or %NULL, e.g. "flatpak:org.gnome.Software.desktop"
+ * @id: an application ID, or %NULL, e.g. "org.gnome.Software.desktop"
*
* Creates a new application object.
*
diff --git a/src/gs-app.h b/src/gs-app.h
index d7dacc6..f6e1672 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -103,7 +103,6 @@ gchar *gs_app_to_string (GsApp *app);
const gchar *gs_app_get_id (GsApp *app);
void gs_app_set_id (GsApp *app,
const gchar *id);
-const gchar *gs_app_get_id_no_prefix (GsApp *app);
AsAppKind gs_app_get_kind (GsApp *app);
void gs_app_set_kind (GsApp *app,
AsAppKind kind);
@@ -114,6 +113,9 @@ void gs_app_set_state_recover (GsApp *app);
guint gs_app_get_progress (GsApp *app);
void gs_app_set_progress (GsApp *app,
guint percentage);
+const gchar *gs_app_get_unique_id (GsApp *app);
+void gs_app_set_unique_id (GsApp *app,
+ const gchar *unique_id);
const gchar *gs_app_get_name (GsApp *app);
void gs_app_set_name (GsApp *app,
GsAppQuality quality,
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index d808bce..33c7e09 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -172,12 +172,19 @@ gs_plugin_loader_free_async_state (GsPluginLoaderAsyncState *state)
}
static gint
-gs_plugin_loader_app_sort_cb (GsApp *app1, GsApp *app2, gpointer user_data)
+gs_plugin_loader_app_sort_name_cb (GsApp *app1, GsApp *app2, gpointer user_data)
{
return g_strcmp0 (gs_app_get_name (app1),
gs_app_get_name (app2));
}
+static gint
+gs_plugin_loader_app_sort_id_cb (GsApp *app1, GsApp *app2, gpointer user_data)
+{
+ return g_strcmp0 (gs_app_get_unique_id (app1),
+ gs_app_get_unique_id (app2));
+}
+
static GsPlugin *
gs_plugin_loader_find_plugin (GsPluginLoader *plugin_loader,
const gchar *plugin_name)
@@ -260,10 +267,18 @@ gs_plugin_loader_run_adopt (GsPluginLoader *plugin_loader, GsAppList *list)
if (gs_app_get_management_plugin (app) != NULL) {
g_debug ("%s adopted %s",
gs_plugin_get_name (plugin),
- gs_app_get_id (app));
+ gs_app_get_unique_id (app));
}
}
}
+ for (j = 0; j < gs_app_list_length (list); j++) {
+ GsApp *app = gs_app_list_index (list, j);
+ if (gs_app_get_management_plugin (app) != NULL)
+ continue;
+ if (gs_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX))
+ continue;
+ g_debug ("nothing adopted %s", gs_app_get_unique_id (app));
+ }
}
static gint
@@ -665,7 +680,7 @@ gs_plugin_loader_get_app_str (GsApp *app)
const gchar *id;
/* first try the actual id */
- id = gs_app_get_id (app);
+ id = gs_app_get_unique_id (app);
if (id != NULL)
return id;
@@ -883,12 +898,12 @@ gs_plugin_loader_set_app_error (GsApp *app, GError *error)
/* random, non-plugin error domains are never shown to the user */
if (error->domain == GS_PLUGIN_ERROR) {
g_debug ("saving error for %s: %s",
- gs_app_get_id (app),
+ gs_app_get_unique_id (app),
error->message);
gs_app_set_last_error (app, error);
} else {
g_warning ("not saving error for %s: %s",
- gs_app_get_id (app),
+ gs_app_get_unique_id (app),
error->message);
}
}
@@ -1078,6 +1093,9 @@ gs_plugin_loader_get_updates_thread_cb (GTask *task,
gs_app_list_filter (state->list, gs_plugin_loader_app_set_prio, plugin_loader);
gs_app_list_filter_duplicates (state->list, GS_APP_LIST_FILTER_FLAG_NONE);
+ /* predictable return order */
+ gs_app_list_sort (state->list, gs_plugin_loader_app_sort_id_cb, NULL);
+
/* success */
g_task_return_pointer (task, g_object_ref (state->list), (GDestroyNotify) g_object_unref);
}
@@ -2498,7 +2516,7 @@ gs_plugin_loader_get_category_apps_thread_cb (GTask *task,
gs_app_list_filter_duplicates (state->list, GS_APP_LIST_FILTER_FLAG_PRIORITY);
/* sort, just in case the UI doesn't do this */
- gs_app_list_sort (state->list, gs_plugin_loader_app_sort_cb, NULL);
+ gs_app_list_sort (state->list, gs_plugin_loader_app_sort_name_cb, NULL);
/* success */
g_task_return_pointer (task, g_object_ref (state->list), (GDestroyNotify) g_object_unref);
@@ -2727,7 +2745,7 @@ gs_plugin_loader_app_action_thread_cb (GTask *task,
case AS_APP_STATE_INSTALLING:
case AS_APP_STATE_REMOVING:
g_warning ("application %s left in %s state",
- gs_app_get_id (state->app),
+ gs_app_get_unique_id (state->app),
as_app_state_to_string (gs_app_get_state (state->app)));
gs_app_set_state (state->app, AS_APP_STATE_UNKNOWN);
break;
@@ -2867,7 +2885,7 @@ load_install_queue (GsPluginLoader *plugin_loader, GError **error)
g_object_ref (app));
g_mutex_unlock (&priv->pending_apps_mutex);
- g_debug ("adding pending app %s", gs_app_get_id (app));
+ g_debug ("adding pending app %s", gs_app_get_unique_id (app));
gs_app_list_add (list, app);
}
@@ -3970,7 +3988,7 @@ gs_plugin_loader_app_installed_cb (GObject *source,
if (!ret) {
remove_app_from_install_queue (plugin_loader, app);
g_warning ("failed to install %s: %s",
- gs_app_get_id (app), error->message);
+ gs_app_get_unique_id (app), error->message);
}
}
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index a596089..d6f9b52 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -801,7 +801,7 @@ gs_plugin_app_launch (GsPlugin *plugin, GsApp *app, GError **error)
const gchar *desktop_id;
g_autoptr(GAppInfo) appinfo = NULL;
- desktop_id = gs_app_get_id_no_prefix (app);
+ desktop_id = gs_app_get_id (app);
if (desktop_id == NULL) {
g_set_error (error,
GS_PLUGIN_ERROR,
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 7def349..decd21e 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -154,22 +154,39 @@ gs_plugin_func (void)
/* respect priority when deduplicating */
list = gs_app_list_new ();
- app = gs_app_new ("foo:e");
+ app = gs_app_new ("e");
+ gs_app_set_unique_id (app, "user/foo/*/*/e/*/*/*");
gs_app_list_add (list, app);
gs_app_set_priority (app, 0);
g_object_unref (app);
- app = gs_app_new ("bar:e");
+ app = gs_app_new ("e");
+ gs_app_set_unique_id (app, "user/bar/*/*/e/*/*/*");
gs_app_list_add (list, app);
gs_app_set_priority (app, 99);
g_object_unref (app);
- app = gs_app_new ("baz:e");
+ app = gs_app_new ("e");
+ gs_app_set_unique_id (app, "user/baz/*/*/e/*/*/*");
gs_app_list_add (list, app);
gs_app_set_priority (app, 50);
g_object_unref (app);
g_assert_cmpint (gs_app_list_length (list), ==, 3);
gs_app_list_filter_duplicates (list, GS_APP_LIST_FILTER_FLAG_PRIORITY);
g_assert_cmpint (gs_app_list_length (list), ==, 1);
- g_assert_cmpstr (gs_app_get_id (gs_app_list_index (list, 0)), ==, "bar:e");
+ g_assert_cmpstr (gs_app_get_unique_id (gs_app_list_index (list, 0)), ==, "user/bar/*/*/e/*/*/*");
+ g_object_unref (list);
+
+ /* use globs when adding */
+ list = gs_app_list_new ();
+ app = gs_app_new ("b");
+ gs_app_set_unique_id (app, "a/b/c/d/e/f/g/h");
+ gs_app_list_add (list, app);
+ g_object_unref (app);
+ app = gs_app_new ("b");
+ gs_app_set_unique_id (app, "a/b/c/*/e/f/g/h");
+ gs_app_list_add (list, app);
+ g_object_unref (app);
+ g_assert_cmpint (gs_app_list_length (list), ==, 1);
+ g_assert_cmpstr (gs_app_get_id (gs_app_list_index (list, 0)), ==, "b");
g_object_unref (list);
}
@@ -178,11 +195,9 @@ gs_app_func (void)
{
g_autoptr(GsApp) app = NULL;
- app = gs_app_new ("flatpak:gnome-software");
+ app = gs_app_new ("gnome-software.desktop");
g_assert (GS_IS_APP (app));
-
- g_assert_cmpstr (gs_app_get_id (app), ==, "flatpak:gnome-software");
- g_assert_cmpstr (gs_app_get_id_no_prefix (app), ==, "gnome-software");
+ g_assert_cmpstr (gs_app_get_id (app), ==, "gnome-software.desktop");
/* check we clean up the version, but not at the expense of having
* the same string as the update version */
diff --git a/src/gs-shell-search.c b/src/gs-shell-search.c
index 995782f..6fb9bfb 100644
--- a/src/gs-shell-search.c
+++ b/src/gs-shell-search.c
@@ -111,8 +111,8 @@ _gs_app_list_is_duplicate (GsAppList *list, GsApp *app)
}
/* same D-Bus ID */
- if (g_strcmp0 (gs_app_get_id_no_prefix (tmp),
- gs_app_get_id_no_prefix (app)) == 0) {
+ if (g_strcmp0 (gs_app_get_id (tmp),
+ gs_app_get_id (app)) == 0) {
return TRUE;
}
diff --git a/src/plugins/gs-appstream.c b/src/plugins/gs-appstream.c
index 937decf..a9f0f82 100644
--- a/src/plugins/gs-appstream.c
+++ b/src/plugins/gs-appstream.c
@@ -331,7 +331,8 @@ gs_refine_item_management_plugin (GsPlugin *plugin, GsApp *app, AsApp *item)
app2 = gs_appstream_create_runtime (plugin, app, runtime);
if (app2 != NULL) {
g_debug ("runtime for %s is %s",
- gs_app_get_id (app), runtime);
+ gs_app_get_unique_id (app),
+ runtime);
gs_app_set_runtime (app, app2);
}
}
@@ -511,6 +512,10 @@ gs_appstream_refine_app (GsPlugin *plugin,
if (as_app_get_id (item) != NULL && gs_app_get_id (app) == NULL)
gs_app_set_id (app, as_app_get_id (item));
+ /* set unique-id */
+ if (as_app_get_unique_id (item) != NULL && gs_app_get_unique_id (app) == NULL)
+ gs_app_set_unique_id (app, as_app_get_unique_id (item));
+
/* set source */
gs_app_set_metadata (app, "appstream::source-file", as_app_get_source_file (item));
@@ -555,11 +560,10 @@ gs_appstream_refine_app (GsPlugin *plugin,
/* set origin */
if (as_app_get_origin (item) != NULL &&
gs_app_get_origin (app) == NULL ) {
- tmp = as_app_get_origin (item);
- if (g_str_has_prefix (tmp, "flatpak:"))
- gs_app_set_origin (app, tmp + 8);
- if (g_str_has_prefix (tmp, "user-flatpak:"))
- gs_app_set_origin (app, tmp + 13);
+ tmp = as_app_get_unique_id (item);
+ if (g_str_has_prefix (tmp, "user/flatpak/") ||
+ g_str_has_prefix (tmp, "system/flatpak/"))
+ gs_app_set_origin (app, as_app_get_origin (item));
}
/* set description */
diff --git a/src/plugins/gs-flatpak.c b/src/plugins/gs-flatpak.c
index 6b9c2fd..4eef283 100644
--- a/src/plugins/gs-flatpak.c
+++ b/src/plugins/gs-flatpak.c
@@ -284,31 +284,45 @@ gs_flatpak_set_metadata_installed (GsFlatpak *self, GsApp *app,
}
static gchar *
-gs_flatpak_build_id (FlatpakInstallation *installation, FlatpakRef *xref)
+gs_flatpak_build_id (FlatpakRef *xref)
{
- const gchar *prefix = GS_FLATPAK_SYSTEM_PREFIX;
-
- /* use a different prefix if we're somehow running this as per-user */
- if (flatpak_installation_get_is_user (installation))
- prefix = GS_FLATPAK_USER_PREFIX;
-
- /* flatpak doesn't use a suffix; AppStream does */
if (flatpak_ref_get_kind (xref) == FLATPAK_REF_KIND_APP) {
- return g_strdup_printf ("%s:%s.desktop",
- prefix,
+ return g_strdup_printf ("%s.desktop",
flatpak_ref_get_name (xref));
}
- return g_strdup_printf ("%s:%s.runtime",
- prefix,
+ return g_strdup_printf ("%s.runtime",
flatpak_ref_get_name (xref));
}
+static gchar *
+gs_flatpak_build_unique_id (FlatpakInstallation *installation, FlatpakRef *xref)
+{
+ AsAppKind kind = AS_APP_KIND_DESKTOP;
+ AsAppScope scope = AS_APP_SCOPE_SYSTEM;
+ g_autofree gchar *id = NULL;
+
+ /* use a different prefix if we're somehow running this as per-user */
+ if (flatpak_installation_get_is_user (installation))
+ scope = AS_APP_SCOPE_USER;
+ if (flatpak_ref_get_kind (xref) == FLATPAK_REF_KIND_RUNTIME)
+ kind = AS_APP_KIND_RUNTIME;
+ id = gs_flatpak_build_id (xref);
+ return as_utils_unique_id_build (scope,
+ AS_BUNDLE_KIND_FLATPAK,
+ NULL, /* origin */
+ kind,
+ id,
+ flatpak_ref_get_arch (xref),
+ flatpak_ref_get_branch (xref),
+ NULL); /* version */
+}
+
static GsApp *
gs_flatpak_create_installed (GsFlatpak *self,
FlatpakInstalledRef *xref,
GError **error)
{
- g_autofree gchar *id = NULL;
+ g_autofree gchar *unique_id = NULL;
g_autoptr(AsIcon) icon = NULL;
g_autoptr(GsApp) app = NULL;
@@ -333,11 +347,14 @@ gs_flatpak_create_installed (GsFlatpak *self,
}
/* create new object */
- id = gs_flatpak_build_id (self->installation, FLATPAK_REF (xref));
- app = gs_plugin_cache_lookup (self->plugin, id);
+ unique_id = gs_flatpak_build_unique_id (self->installation,
+ FLATPAK_REF (xref));
+ app = gs_plugin_cache_lookup (self->plugin, unique_id);
if (app == NULL) {
+ g_autofree gchar *id = gs_flatpak_build_id (FLATPAK_REF (xref));
app = gs_app_new (id);
- gs_plugin_cache_add (self->plugin, id, app);
+ gs_app_set_unique_id (app, unique_id);
+ gs_plugin_cache_add (self->plugin, unique_id, app);
}
gs_flatpak_set_metadata_installed (self, app, xref);
@@ -932,8 +949,8 @@ gs_flatpak_app_matches_xref (GsFlatpak *self, GsApp *app, FlatpakRef *xref)
g_autofree gchar *id = NULL;
/* check ID */
- id = gs_flatpak_build_id (self->installation, xref);
- if (g_strcmp0 (id, gs_app_get_id (app)) == 0)
+ id = gs_flatpak_build_unique_id (self->installation, xref);
+ if (g_strcmp0 (id, gs_app_get_unique_id (app)) == 0)
return TRUE;
/* do all the metadata items match? */
@@ -1048,9 +1065,11 @@ gs_plugin_refine_item_state (GsFlatpak *self,
gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
}
} else {
- g_warning ("failed to find flatpak user remote %s for %s",
+ g_warning ("failed to find flatpak %s remote %s for %s",
+ flatpak_installation_get_is_user (self->installation) ? "user" : "system",
gs_app_get_origin (app),
- gs_app_get_id (app));
+ gs_app_get_unique_id (app));
+ g_warning ("%s", gs_app_to_string (app));
}
}
@@ -1589,7 +1608,7 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
{
gint size;
g_autofree gchar *content_type = NULL;
- g_autofree gchar *id_prefixed = NULL;
+ g_autofree gchar *unique_id = NULL;
g_autoptr(GBytes) appstream_gz = NULL;
g_autoptr(GBytes) icon_data = NULL;
g_autoptr(GBytes) metadata = NULL;
@@ -1604,11 +1623,17 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
}
/* create a virtual ID */
- id_prefixed = gs_flatpak_build_id (self->installation,
- FLATPAK_REF (xref_bundle));
+ unique_id = gs_flatpak_build_unique_id (self->installation,
+ FLATPAK_REF (xref_bundle));
+ app = gs_plugin_cache_lookup (self->plugin, unique_id);
+ if (app == NULL) {
+ g_autofree gchar *id = gs_flatpak_build_id (FLATPAK_REF (xref_bundle));
+ app = gs_app_new (id);
+ gs_app_set_unique_id (app, unique_id);
+ gs_plugin_cache_add (self->plugin, unique_id, app);
+ }
/* load metadata */
- app = gs_app_new (id_prefixed);
gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
gs_app_set_size_installed (app, flatpak_bundle_ref_get_installed_size (xref_bundle));
diff --git a/src/plugins/gs-flatpak.h b/src/plugins/gs-flatpak.h
index c84e4ef..b58f292 100644
--- a/src/plugins/gs-flatpak.h
+++ b/src/plugins/gs-flatpak.h
@@ -47,9 +47,6 @@ typedef enum {
GS_FLATPAK_SCOPE_USER
} GsFlatpakScope;
-#define GS_FLATPAK_SYSTEM_PREFIX "flatpak"
-#define GS_FLATPAK_USER_PREFIX "user-flatpak"
-
GsFlatpak *gs_flatpak_new (GsPlugin *plugin,
GsFlatpakScope scope);
gboolean gs_flatpak_setup (GsFlatpak *self,
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index ac91f96..3b0afb4 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -137,6 +137,9 @@ gs_plugin_initialize (GsPlugin *plugin)
{
GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
priv->store = as_store_new ();
+ as_store_set_add_flags (priv->store,
+ AS_STORE_ADD_FLAG_USE_UNIQUE_ID |
+ AS_STORE_ADD_FLAG_USE_MERGE_HEURISTIC);
as_store_set_watch_flags (priv->store,
AS_STORE_WATCH_FLAG_ADDED |
AS_STORE_WATCH_FLAG_REMOVED);
@@ -274,6 +277,23 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
}
}
+ /* add keyword for non-package sources */
+ for (i = 0; i < items->len; i++) {
+ g_auto(GStrv) split = NULL;
+ app = g_ptr_array_index (items, i);
+ split = g_strsplit (as_app_get_unique_id (app), "/", -1);
+ if (g_strv_length (split) != 8)
+ continue;
+ if (g_strcmp0 (split[1], "package") == 0)
+ continue;
+ if (g_strcmp0 (split[1], "*") == 0)
+ continue;
+ g_debug ("Adding keyword '%s' to %s",
+ split[1],
+ as_app_get_unique_id (app));
+ as_app_add_keyword (app, NULL, split[1]);
+ }
+
/* fix up these */
for (i = 0; i < items->len; i++) {
app = g_ptr_array_index (items, i);
@@ -305,21 +325,35 @@ gs_plugin_refine_from_id (GsPlugin *plugin,
GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
- const gchar *id;
+ const gchar *unique_id;
AsApp *item;
/* unfound */
*found = FALSE;
/* find anything that matches the ID */
- id = gs_app_get_id (app);
- if (id == NULL)
+ unique_id = gs_app_get_unique_id (app);
+ if (unique_id == NULL)
return TRUE;
/* nothing found */
- item = as_store_get_app_by_id (priv->store, id);
- if (item == NULL)
+ g_debug ("searching appstream for %s", unique_id);
+ item = as_store_get_app_by_unique_id (priv->store, unique_id,
+ AS_STORE_SEARCH_FLAG_USE_WILDCARDS);
+ if (item == NULL) {
+ guint i;
+ GPtrArray *apps;
+ g_debug ("no app with ID %s found in appstream", unique_id);
+ apps = as_store_get_apps (priv->store);
+ for (i = 0; i < apps->len; i++) {
+ item = g_ptr_array_index (apps, i);
+ if (g_strcmp0 (as_app_get_id (item), gs_app_get_id (app)) != 0)
+ continue;
+ g_debug ("possible match: %s",
+ as_app_get_unique_id (item));
+ }
return TRUE;
+ }
/* set new properties */
if (!gs_appstream_refine_app (plugin, app, item, error))
@@ -359,14 +393,16 @@ gs_plugin_refine_from_pkgname (GsPlugin *plugin,
}
static GsApp *
-gs_plugin_appstream_create_app (GsPlugin *plugin, const gchar *id)
+gs_plugin_appstream_create_app (GsPlugin *plugin, AsApp *item)
{
- GsApp *app = gs_plugin_cache_lookup (plugin, id);
+ const gchar *unique_id = as_app_get_unique_id (item);
+ GsApp *app = gs_plugin_cache_lookup (plugin, unique_id);
if (app == NULL) {
- app = gs_app_new (id);
+ app = gs_app_new (as_app_get_id (item));
+ gs_app_set_unique_id (app, unique_id);
gs_app_set_metadata (app, "GnomeSoftware::Creator",
gs_plugin_get_name (plugin));
- gs_plugin_cache_add (plugin, id, app);
+ gs_plugin_cache_add (plugin, unique_id, app);
}
return app;
}
@@ -391,7 +427,7 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
continue;
/* create */
- app = gs_plugin_appstream_create_app (plugin, as_app_get_id (item));
+ app = gs_plugin_appstream_create_app (plugin, item);
gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE);
gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
if (!gs_appstream_refine_app (plugin, app, item, error))
@@ -460,8 +496,7 @@ gs_plugin_appstream_add_wildcards (GsPlugin *plugin,
/* new app */
g_debug ("found %s for wildcard %s",
as_app_get_id (item), id);
- new = gs_plugin_appstream_create_app (plugin,
- as_app_get_id (item));
+ new = gs_plugin_appstream_create_app (plugin, item);
if (!gs_appstream_refine_app (plugin, new, item, error))
return FALSE;
gs_app_list_add (list, new);
@@ -554,8 +589,7 @@ gs_plugin_add_category_apps (GsPlugin *plugin,
continue;
/* add all the data we can */
- app = gs_plugin_appstream_create_app (plugin,
- as_app_get_id (item));
+ app = gs_plugin_appstream_create_app (plugin, item);
if (!gs_appstream_refine_app (plugin, app, item, error))
return FALSE;
gs_app_list_add (list, app);
@@ -591,7 +625,7 @@ gs_plugin_add_search_item (GsPlugin *plugin,
return TRUE;
/* create app */
- app = gs_plugin_appstream_create_app (plugin, as_app_get_id (item));
+ app = gs_plugin_appstream_create_app (plugin, item);
if (!gs_appstream_refine_app (plugin, app, item, error))
return FALSE;
gs_app_set_match_value (app, match_value);
@@ -651,7 +685,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
item = g_ptr_array_index (array, i);
if (as_app_get_state (item) == AS_APP_STATE_INSTALLED) {
g_autoptr(GsApp) app = NULL;
- app = gs_plugin_appstream_create_app (plugin, as_app_get_id (item));
+ app = gs_plugin_appstream_create_app (plugin, item);
if (!gs_appstream_refine_app (plugin, app, item, error))
return FALSE;
gs_app_list_add (list, app);
@@ -746,7 +780,7 @@ gs_plugin_add_popular (GsPlugin *plugin,
continue;
if (!as_app_has_kudo (item, "GnomeSoftware::popular"))
continue;
- app = gs_plugin_appstream_create_app (plugin, as_app_get_id_no_prefix (item));
+ app = gs_plugin_appstream_create_app (plugin, item);
gs_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX);
gs_app_list_add (list, app);
}
@@ -777,7 +811,7 @@ gs_plugin_add_featured (GsPlugin *plugin,
continue;
if (as_app_get_metadata_item (item, "GnomeSoftware::FeatureTile-css") == NULL)
continue;
- app = gs_plugin_appstream_create_app (plugin, as_app_get_id_no_prefix (item));
+ app = gs_plugin_appstream_create_app (plugin, item);
if (!gs_appstream_refine_app (plugin, app, item, error))
return FALSE;
gs_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX);
diff --git a/src/plugins/gs-plugin-dummy.c b/src/plugins/gs-plugin-dummy.c
index 84b49e1..24d61fc 100644
--- a/src/plugins/gs-plugin-dummy.c
+++ b/src/plugins/gs-plugin-dummy.c
@@ -304,7 +304,8 @@ gs_plugin_add_popular (GsPlugin *plugin,
gs_app_list_add (list, app1);
/* add again, this time with a prefix so it gets deduplicated */
- app2 = gs_app_new ("dummy:zeus.desktop");
+ app2 = gs_app_new ("zeus.desktop");
+ gs_app_set_unique_id (app2, "user/dummy/*/*/zeus.desktop/*/*/*");
gs_app_set_metadata (app2, "GnomeSoftware::Creator",
gs_plugin_get_name (plugin));
gs_app_list_add (list, app2);
@@ -384,9 +385,9 @@ gs_plugin_refine_app (GsPlugin *plugin,
GError **error)
{
/* default */
- if (g_strcmp0 (gs_app_get_id_no_prefix (app), "chiron.desktop") == 0 ||
- g_strcmp0 (gs_app_get_id_no_prefix (app), "mate-spell.desktop") == 0 ||
- g_strcmp0 (gs_app_get_id_no_prefix (app), "zeus.desktop") == 0) {
+ if (g_strcmp0 (gs_app_get_id (app), "chiron.desktop") == 0 ||
+ g_strcmp0 (gs_app_get_id (app), "mate-spell.desktop") == 0 ||
+ g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0) {
if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
gs_app_set_state (app, AS_APP_STATE_INSTALLED);
if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN)
diff --git a/src/plugins/gs-plugin-epiphany.c b/src/plugins/gs-plugin-epiphany.c
index 0c8ffaf..a64bb18 100644
--- a/src/plugins/gs-plugin-epiphany.c
+++ b/src/plugins/gs-plugin-epiphany.c
@@ -63,7 +63,7 @@ _gs_app_get_id_nonfull (GsApp *app)
gchar *id;
gchar *tmp;
- id = g_strdup (gs_app_get_id_no_prefix (app));
+ id = g_strdup (gs_app_get_id (app));
tmp = g_strrstr (id, ".desktop");
if (tmp != NULL)
*tmp = '\0';
@@ -191,7 +191,7 @@ gs_plugin_app_install (GsPlugin *plugin, GsApp *app,
/* symlink it to somewhere the shell will notice */
app_desktop = g_build_filename (g_get_user_data_dir (),
"applications",
- gs_app_get_id_no_prefix (app),
+ gs_app_get_id (app),
NULL);
symlink_desktop = g_file_new_for_path (app_desktop);
ret = g_file_make_symbolic_link (symlink_desktop,
@@ -231,7 +231,7 @@ gs_plugin_app_remove (GsPlugin *plugin, GsApp *app,
/* remove the shared desktop file */
app_desktop = g_build_filename (g_get_user_data_dir (),
"applications",
- gs_app_get_id_no_prefix (app),
+ gs_app_get_id (app),
NULL);
file_app = g_file_new_for_path (app_desktop);
if (!g_file_delete (file_app, NULL, error))
diff --git a/src/plugins/gs-plugin-flatpak-system.c b/src/plugins/gs-plugin-flatpak-system.c
index a1b629a..4e27561 100644
--- a/src/plugins/gs-plugin-flatpak-system.c
+++ b/src/plugins/gs-plugin-flatpak-system.c
@@ -64,8 +64,8 @@ gs_plugin_destroy (GsPlugin *plugin)
void
gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
{
- const gchar *id = gs_app_get_id (app);
- if (id != NULL && g_str_has_prefix (id, GS_FLATPAK_SYSTEM_PREFIX ":")) {
+ const gchar *id = gs_app_get_unique_id (app);
+ if (id != NULL && g_str_has_prefix (id, "system/flatpak/")) {
gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
}
}
diff --git a/src/plugins/gs-plugin-flatpak-user.c b/src/plugins/gs-plugin-flatpak-user.c
index 02d3b30..5b63cd1 100644
--- a/src/plugins/gs-plugin-flatpak-user.c
+++ b/src/plugins/gs-plugin-flatpak-user.c
@@ -64,8 +64,8 @@ gs_plugin_destroy (GsPlugin *plugin)
void
gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
{
- const gchar *id = gs_app_get_id (app);
- if (id != NULL && g_str_has_prefix (id, GS_FLATPAK_USER_PREFIX ":")) {
+ const gchar *id = gs_app_get_unique_id (app);
+ if (id != NULL && g_str_has_prefix (id, "user/flatpak/")) {
gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
}
}
diff --git a/src/plugins/gs-plugin-hardcoded-featured.c b/src/plugins/gs-plugin-hardcoded-featured.c
index 66c8721..009617e 100644
--- a/src/plugins/gs-plugin-hardcoded-featured.c
+++ b/src/plugins/gs-plugin-hardcoded-featured.c
@@ -235,7 +235,7 @@ gs_plugin_refine_app (GsPlugin *plugin,
const gchar *key = "GnomeSoftware::FeatureTile-css";
guint i;
for (i = 0; myapps[i].id != NULL; i++) {
- if (g_strcmp0 (gs_app_get_id_no_prefix (app),
+ if (g_strcmp0 (gs_app_get_id (app),
myapps[i].id) != 0)
continue;
if (gs_app_get_metadata_item (app, key) != NULL)
diff --git a/src/plugins/gs-plugin-limba.c b/src/plugins/gs-plugin-limba.c
index 246d9cc..7d187b3 100644
--- a/src/plugins/gs-plugin-limba.c
+++ b/src/plugins/gs-plugin-limba.c
@@ -282,6 +282,7 @@ gs_plugin_app_from_pki (LiPkgInfo *pki)
{
const gchar *cptkind_str;
GsApp *app;
+ g_autofree gchar *unique_id = NULL;
cptkind_str = li_pkg_info_get_component_kind (pki);
if ((cptkind_str != NULL) && (g_strcmp0 (cptkind_str, "desktop") == 0)) {
@@ -297,6 +298,17 @@ gs_plugin_app_from_pki (LiPkgInfo *pki)
gs_app_set_kind (app, AS_APP_KIND_GENERIC);
}
+ /* create a unique ID for deduplication, TODO: scope?, branch?, arch? */
+ unique_id = as_utils_unique_id_build (AS_APP_SCOPE_UNKNOWN,
+ AS_BUNDLE_KIND_LIMBA,
+ NULL, /* origin */
+ AS_APP_KIND_UNKNOWN,
+ id,
+ NULL, /* arch */
+ NULL, /* branch */
+ NULL); /* version */
+
+ gs_app_set_unique_id (app, unique_id);
gs_app_set_management_plugin (app, "limba");
gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE);
gs_app_set_name (app,
diff --git a/src/plugins/gs-plugin-odrs.c b/src/plugins/gs-plugin-odrs.c
index ddd066b..db1c10a 100644
--- a/src/plugins/gs-plugin-odrs.c
+++ b/src/plugins/gs-plugin-odrs.c
@@ -469,7 +469,7 @@ gs_plugin_refine_ratings (GsPlugin *plugin,
/* get ratings */
review_ratings = g_hash_table_lookup (priv->ratings,
- gs_app_get_id_no_prefix (app));
+ gs_app_get_id (app));
if (review_ratings == NULL)
return TRUE;
gs_app_set_review_ratings (app, review_ratings);
@@ -503,7 +503,7 @@ gs_plugin_odrs_fetch_for_app (GsPlugin *plugin, GsApp *app, GError **error)
g_autoptr(SoupMessage) msg = NULL;
/* look in the cache */
- cachefn_basename = g_strdup_printf ("%s.json", gs_app_get_id_no_prefix (app));
+ cachefn_basename = g_strdup_printf ("%s.json", gs_app_get_id (app));
cachefn = gs_utils_get_cache_filename ("reviews",
cachefn_basename,
GS_UTILS_CACHE_FLAG_WRITEABLE,
@@ -516,7 +516,7 @@ gs_plugin_odrs_fetch_for_app (GsPlugin *plugin, GsApp *app, GError **error)
if (!g_file_get_contents (cachefn, &json_data, NULL, error))
return NULL;
g_debug ("got review data for %s from %s",
- gs_app_get_id_no_prefix (app), cachefn);
+ gs_app_get_id (app), cachefn);
return gs_plugin_odrs_parse_reviews (plugin,
json_data, -1,
error);
@@ -533,7 +533,7 @@ gs_plugin_odrs_fetch_for_app (GsPlugin *plugin, GsApp *app, GError **error)
json_builder_set_member_name (builder, "user_hash");
json_builder_add_string_value (builder, priv->user_hash);
json_builder_set_member_name (builder, "app_id");
- json_builder_add_string_value (builder, gs_app_get_id_no_prefix (app));
+ json_builder_add_string_value (builder, gs_app_get_id (app));
json_builder_set_member_name (builder, "locale");
json_builder_add_string_value (builder, gs_plugin_get_locale (plugin));
json_builder_set_member_name (builder, "distro");
@@ -639,7 +639,7 @@ gs_plugin_refine_app (GsPlugin *plugin,
/* not valid */
if (gs_app_get_kind (app) == AS_APP_KIND_ADDON)
return TRUE;
- if (gs_app_get_id_no_prefix (app) == NULL)
+ if (gs_app_get_id (app) == NULL)
return TRUE;
/* add reviews if possible */
@@ -730,7 +730,7 @@ gs_plugin_review_submit (GsPlugin *plugin,
/* save as we don't re-request the review from the server */
as_review_set_reviewer_name (review, g_get_real_name ());
- as_review_add_metadata (review, "app_id", gs_app_get_id_no_prefix (app));
+ as_review_add_metadata (review, "app_id", gs_app_get_id (app));
as_review_add_metadata (review, "user_skey",
gs_app_get_metadata_item (app, "ODRS::user_skey"));
diff --git a/src/plugins/gs-plugin-packagekit-refine.c b/src/plugins/gs-plugin-packagekit-refine.c
index e983e46..ca98f05 100644
--- a/src/plugins/gs-plugin-packagekit-refine.c
+++ b/src/plugins/gs-plugin-packagekit-refine.c
@@ -83,12 +83,8 @@ gs_plugin_destroy (GsPlugin *plugin)
void
gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
{
- const gchar *tmp;
-
- /* this was installed system-wide and picked up by AppStream */
- tmp = gs_app_get_metadata_item (app, "appstream::source-file");
- if (tmp != NULL && g_str_has_prefix (tmp, "/usr/share/") &&
- gs_app_get_source_default (app) != NULL) {
+ const gchar *id = gs_app_get_unique_id (app);
+ if (id != NULL && g_str_has_prefix (id, "system/package/")) {
gs_app_set_management_plugin (app, "packagekit");
return;
}
@@ -860,6 +856,8 @@ gs_plugin_refine (GsPlugin *plugin,
tmp = gs_app_get_id (app);
if (tmp == NULL)
continue;
+ if (gs_app_get_management_plugin (app) != NULL)
+ continue;
switch (gs_app_get_kind (app)) {
case AS_APP_KIND_DESKTOP:
fn = g_strdup_printf ("/usr/share/applications/%s", tmp);
diff --git a/src/plugins/gs-plugin-shell-extensions.c b/src/plugins/gs-plugin-shell-extensions.c
index e0c6557..76a7206 100644
--- a/src/plugins/gs-plugin-shell-extensions.c
+++ b/src/plugins/gs-plugin-shell-extensions.c
@@ -120,12 +120,20 @@ gs_plugin_shell_extensions_add_app (GsPlugin *plugin,
gchar *str;
GVariant *val;
g_autofree gchar *id = NULL;
- g_autofree gchar *id_prefix = NULL;
+ g_autofree gchar *unique_id = NULL;
g_autoptr(AsIcon) ic = NULL;
id = gs_plugin_shell_extensions_id_from_uuid (uuid);
- id_prefix = g_strdup_printf ("user:%s", id);
- gs_app_set_id (app, id_prefix);
+ unique_id = as_utils_unique_id_build (AS_APP_SCOPE_USER,
+ AS_BUNDLE_KIND_UNKNOWN,
+ NULL, /* origin */
+ AS_APP_KIND_SHELL_EXTENSION,
+ id,
+ NULL, /* arch */
+ NULL, /* branch */
+ NULL); /* version */
+ gs_app_set_id (app, id);
+ gs_app_set_unique_id (app, unique_id);
gs_app_set_metadata (app, "GnomeSoftware::Creator",
gs_plugin_get_name (plugin));
gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
diff --git a/src/plugins/gs-plugin-snap.c b/src/plugins/gs-plugin-snap.c
index 0d6cb7a..0745e97 100644
--- a/src/plugins/gs-plugin-snap.c
+++ b/src/plugins/gs-plugin-snap.c
@@ -327,6 +327,7 @@ get_apps (GsPlugin *plugin,
for (l = snaps; l != NULL; l = l->next) {
JsonObject *package = json_node_get_object (l->data);
g_autoptr(GsApp) app = NULL;
+ g_autofree gchar *unique_id = NULL;
const gchar *id;
id = json_object_get_string_member (package, "name");
@@ -334,7 +335,17 @@ get_apps (GsPlugin *plugin,
if (filter_func != NULL && !filter_func (id, package, user_data))
continue;
+ /* create a unique ID for deduplication, TODO: branch?, arch? */
+ unique_id = as_utils_unique_id_build (AS_APP_SCOPE_SYSTEM,
+ AS_BUNDLE_KIND_SNAP,
+ NULL, /* origin */
+ AS_APP_KIND_UNKNOWN,
+ id,
+ NULL, /* arch */
+ NULL, /* branch */
+ NULL); /* version */
app = gs_app_new (id);
+ gs_app_set_unique_id (app, unique_id);
gs_app_set_management_plugin (app, "snap");
gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
gs_app_add_quirk (app, AS_APP_QUIRK_NOT_REVIEWABLE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]