[gnome-software: 5/11] snap: Port gs_plugin_add_alternates() vfunc to GsPluginJobListApps
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software: 5/11] snap: Port gs_plugin_add_alternates() vfunc to GsPluginJobListApps
- Date: Mon, 11 Jul 2022 11:57:03 +0000 (UTC)
commit cdaa11b6fe08567ade638992289b45cc9efda681
Author: Philip Withnall <pwithnall endlessos org>
Date: Wed Jul 6 15:22:12 2022 +0100
snap: Port gs_plugin_add_alternates() vfunc to GsPluginJobListApps
This is a bit complex and has not been tested at runtime (only
compile-tested), as I don’t have a snap setup.
Signed-off-by: Philip Withnall <pwithnall endlessos org>
plugins/snap/gs-plugin-snap.c | 235 +++++++++++++++++++++++++++++++++---------
1 file changed, 184 insertions(+), 51 deletions(-)
---
diff --git a/plugins/snap/gs-plugin-snap.c b/plugins/snap/gs-plugin-snap.c
index a36dbb4b0..e6b1e3c6a 100644
--- a/plugins/snap/gs-plugin-snap.c
+++ b/plugins/snap/gs-plugin-snap.c
@@ -238,6 +238,20 @@ static void get_system_information_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data);
+static void get_store_snap_async (GsPluginSnap *self,
+ SnapdClient *client,
+ const gchar *name,
+ gboolean need_details,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+static SnapdSnap *get_store_snap_finish (GsPluginSnap *self,
+ GAsyncResult *result,
+ GError **error);
+static void add_channels (GsPluginSnap *self,
+ SnapdSnap *snap,
+ GsAppList *list);
+
static void
gs_plugin_snap_setup_async (GsPlugin *plugin,
GCancellable *cancellable,
@@ -555,6 +569,15 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ListAppsData, list_apps_data_free)
static void list_installed_apps_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data);
+static void list_alternate_apps_snap_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data);
+static void list_alternate_apps_nonsnap_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data);
+static void list_alternative_apps_nonsnap_get_store_snap_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data);
static void list_apps_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data);
@@ -579,6 +602,7 @@ gs_plugin_snap_list_apps_async (GsPlugin *plugin,
GsCategory *category = NULL;
GsAppQueryTristate is_installed = GS_APP_QUERY_TRISTATE_UNSET;
const gchar * const *keywords = NULL;
+ GsApp *alternate_of = NULL;
const gchar * const *sections = NULL;
const gchar * const curated_sections[] = { "featured", NULL };
g_autoptr(GError) local_error = NULL;
@@ -599,6 +623,7 @@ gs_plugin_snap_list_apps_async (GsPlugin *plugin,
category = gs_app_query_get_category (query);
is_installed = gs_app_query_get_is_installed (query);
keywords = gs_app_query_get_keywords (query);
+ alternate_of = gs_app_query_get_alternate_of (query);
}
/* Currently only support a subset of query properties, and only one set at once.
@@ -606,7 +631,8 @@ gs_plugin_snap_list_apps_async (GsPlugin *plugin,
if ((is_curated == GS_APP_QUERY_TRISTATE_UNSET &&
category == NULL &&
is_installed == GS_APP_QUERY_TRISTATE_UNSET &&
- keywords == NULL) ||
+ keywords == NULL &&
+ alternate_of == NULL) ||
is_curated == GS_APP_QUERY_TRISTATE_FALSE ||
is_installed == GS_APP_QUERY_TRISTATE_FALSE ||
gs_app_query_get_n_properties_set (query) != 1) {
@@ -626,6 +652,28 @@ gs_plugin_snap_list_apps_async (GsPlugin *plugin,
return;
}
+ /* Listing alternates also requires special handling. */
+ if (alternate_of != NULL) {
+ /* If it is a snap, find the channels that snap provides, otherwise find snaps that match on
common id */
+ if (gs_app_has_management_plugin (alternate_of, plugin)) {
+ const gchar *snap_name;
+
+ snap_name = gs_app_get_metadata_item (alternate_of, "snap::name");
+
+ data->n_pending_ops++;
+ get_store_snap_async (self, client, snap_name, TRUE, cancellable,
list_alternate_apps_snap_cb, g_steal_pointer (&task));
+ } else {
+ data->n_pending_ops++;
+ snapd_client_find_section_async (client,
+ SNAPD_FIND_FLAGS_SCOPE_WIDE |
SNAPD_FIND_FLAGS_MATCH_COMMON_ID,
+ NULL, gs_app_get_id (alternate_of),
+ cancellable,
+ list_alternate_apps_nonsnap_cb, g_steal_pointer
(&task));
+ }
+
+ return;
+ }
+
/* Querying with keywords also requires calling the method differently.
* snapd will tokenise and stem @query internally. */
if (keywords != NULL) {
@@ -719,6 +767,78 @@ list_installed_apps_cb (GObject *source_object,
finish_list_apps_op (task, g_steal_pointer (&local_error));
}
+static void
+list_alternate_apps_snap_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GsPluginSnap *self = GS_PLUGIN_SNAP (source_object);
+ g_autoptr(GTask) task = G_TASK (user_data);
+ ListAppsData *data = g_task_get_task_data (task);
+ g_autoptr(SnapdSnap) snap = NULL;
+ g_autoptr(GError) local_error = NULL;
+
+ snap = get_store_snap_finish (self, result, &local_error);
+
+ if (snap != NULL)
+ add_channels (self, snap, data->results_list);
+
+ finish_list_apps_op (task, g_steal_pointer (&local_error));
+}
+
+static void
+list_alternate_apps_nonsnap_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ SnapdClient *client = SNAPD_CLIENT (source_object);
+ g_autoptr(GTask) task = G_TASK (user_data);
+ GsPluginSnap *self = g_task_get_source_object (task);
+ GCancellable *cancellable = g_task_get_cancellable (task);
+ ListAppsData *data = g_task_get_task_data (task);
+ g_autoptr(GPtrArray) snaps = NULL;
+ g_autoptr(GError) local_error = NULL;
+
+ snaps = snapd_client_find_section_finish (client, result, NULL, &local_error);
+
+ if (snaps == NULL) {
+ snapd_error_convert (&local_error);
+ finish_list_apps_op (task, g_steal_pointer (&local_error));
+ return;
+ }
+
+ store_snap_cache_update (self, snaps, FALSE);
+
+ for (guint i = 0; snaps != NULL && i < snaps->len; i++) {
+ SnapdSnap *snap = g_ptr_array_index (snaps, i);
+
+ data->n_pending_ops++;
+ get_store_snap_async (self, client, snapd_snap_get_name (snap),
+ TRUE, cancellable, list_alternative_apps_nonsnap_get_store_snap_cb,
g_object_ref (task));
+ }
+
+ finish_list_apps_op (task, NULL);
+}
+
+static void
+list_alternative_apps_nonsnap_get_store_snap_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GsPluginSnap *self = GS_PLUGIN_SNAP (source_object);
+ g_autoptr(GTask) task = G_TASK (user_data);
+ ListAppsData *data = g_task_get_task_data (task);
+ g_autoptr(SnapdSnap) store_snap = NULL;
+ g_autoptr(GError) local_error = NULL;
+
+ store_snap = get_store_snap_finish (self, result, &local_error);
+
+ if (store_snap != NULL)
+ add_channels (self, store_snap, data->results_list);
+
+ finish_list_apps_op (task, g_steal_pointer (&local_error));
+}
+
static void
list_apps_cb (GObject *source_object,
GAsyncResult *result,
@@ -812,6 +932,69 @@ get_store_snap (GsPluginSnap *self,
return g_object_ref (g_ptr_array_index (snaps, 0));
}
+static void get_store_snap_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data);
+
+static void
+get_store_snap_async (GsPluginSnap *self,
+ SnapdClient *client,
+ const gchar *name,
+ gboolean need_details,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+ SnapdSnap *snap = NULL;
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, get_store_snap_async);
+
+ /* use cached version if available */
+ snap = store_snap_cache_lookup (self, name, need_details);
+ if (snap != NULL) {
+ g_task_return_pointer (task, g_object_ref (snap), (GDestroyNotify) g_object_unref);
+ return;
+ }
+
+ snapd_client_find_section_async (client,
+ SNAPD_FIND_FLAGS_SCOPE_WIDE | SNAPD_FIND_FLAGS_MATCH_NAME,
+ NULL, name,
+ cancellable,
+ get_store_snap_cb, g_steal_pointer (&task));
+}
+
+static void
+get_store_snap_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ SnapdClient *client = SNAPD_CLIENT (source_object);
+ g_autoptr(GTask) task = g_steal_pointer (&user_data);
+ GsPluginSnap *self = g_task_get_source_object (task);
+ g_autoptr(GPtrArray) snaps = NULL;
+ g_autoptr(GError) local_error = NULL;
+
+ snaps = snapd_client_find_section_finish (client, result, NULL, &local_error);
+
+ if (snaps == NULL || snaps->len < 1) {
+ snapd_error_convert (&local_error);
+ g_task_return_error (task, g_steal_pointer (&local_error));
+ } else {
+ store_snap_cache_update (self, snaps, TRUE);
+ g_task_return_pointer (task, g_object_ref (g_ptr_array_index (snaps, 0)), (GDestroyNotify)
g_object_unref);
+ }
+}
+
+static SnapdSnap *
+get_store_snap_finish (GsPluginSnap *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
static int
track_value (const gchar *track, GStrv tracks)
{
@@ -907,56 +1090,6 @@ add_channels (GsPluginSnap *self, SnapdSnap *snap, GsAppList *list)
}
}
-gboolean
-gs_plugin_add_alternates (GsPlugin *plugin,
- GsApp *app,
- GsAppList *list,
- GCancellable *cancellable,
- GError **error)
-{
- GsPluginSnap *self = GS_PLUGIN_SNAP (plugin);
- g_autoptr(SnapdClient) client = NULL;
- gboolean interactive = gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_INTERACTIVE);
-
- client = get_client (self, interactive, error);
- if (client == NULL)
- return FALSE;
-
- /* If it is a snap, find the channels that snap provides, otherwise find snaps that match on common
id */
- if (gs_app_has_management_plugin (app, plugin)) {
- const gchar *snap_name;
- g_autoptr(SnapdSnap) snap = NULL;
-
- snap_name = gs_app_get_metadata_item (app, "snap::name");
-
- snap = get_store_snap (self, client, snap_name, TRUE, cancellable, NULL);
- if (snap == NULL) {
- g_warning ("Failed to get store snap %s", snap_name);
- return TRUE;
- }
-
- add_channels (self, snap, list);
- } else {
- g_autoptr(GPtrArray) snaps = NULL;
- guint i;
-
- snaps = find_snaps (self, client,
- SNAPD_FIND_FLAGS_SCOPE_WIDE | SNAPD_FIND_FLAGS_MATCH_COMMON_ID,
- NULL, gs_app_get_id (app), cancellable, NULL);
- for (i = 0; snaps != NULL && i < snaps->len; i++) {
- SnapdSnap *snap = g_ptr_array_index (snaps, i);
- SnapdSnap *store_snap;
-
- store_snap = get_store_snap (self, client, snapd_snap_get_name (snap),
- TRUE, cancellable, NULL);
- add_channels (self, store_snap, list);
- }
- return TRUE;
- }
-
- return TRUE;
-}
-
static gboolean
app_name_matches_snap_name (SnapdSnap *snap, SnapdApp *app)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]