summaryrefslogtreecommitdiffstats
path: root/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/packagekit/gs-plugin-packagekit-refine-repos.c')
-rw-r--r--plugins/packagekit/gs-plugin-packagekit-refine-repos.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/plugins/packagekit/gs-plugin-packagekit-refine-repos.c b/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
new file mode 100644
index 0000000..4b41c44
--- /dev/null
+++ b/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ * vi:set noexpandtab tabstop=8 shiftwidth=8:
+ *
+ * Copyright (C) 2018 Kalev Lember <klember@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+
+#include <packagekit-glib2/packagekit.h>
+#include <gnome-software.h>
+
+#include "gs-packagekit-helper.h"
+#include "packagekit-common.h"
+
+/*
+ * SECTION:
+ * Uses the system PackageKit instance to return convert repo filenames to
+ * package-ids.
+ *
+ * Requires: | [repos::repo-filename]
+ * Refines: | [source-id]
+ */
+
+struct GsPluginData {
+ PkClient *client;
+ GMutex client_mutex;
+};
+
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+ GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
+
+ g_mutex_init (&priv->client_mutex);
+ priv->client = pk_client_new ();
+ pk_client_set_background (priv->client, FALSE);
+ pk_client_set_cache_age (priv->client, G_MAXUINT);
+
+ /* need repos::repo-filename */
+ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "repos");
+}
+
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_mutex_clear (&priv->client_mutex);
+ g_object_unref (priv->client);
+}
+
+static gboolean
+gs_plugin_packagekit_refine_repo_from_filename (GsPlugin *plugin,
+ GsApp *app,
+ const gchar *filename,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ const gchar *to_array[] = { NULL, NULL };
+ g_autoptr(GsPackagekitHelper) helper = gs_packagekit_helper_new (plugin);
+ g_autoptr(PkResults) results = NULL;
+ g_autoptr(GPtrArray) packages = NULL;
+
+ to_array[0] = filename;
+ gs_packagekit_helper_add_app (helper, app);
+ g_mutex_lock (&priv->client_mutex);
+ results = pk_client_search_files (priv->client,
+ pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED, -1),
+ (gchar **) to_array,
+ cancellable,
+ gs_packagekit_helper_cb, helper,
+ error);
+ g_mutex_unlock (&priv->client_mutex);
+ if (!gs_plugin_packagekit_results_valid (results, error)) {
+ g_prefix_error (error, "failed to search file %s: ", filename);
+ return FALSE;
+ }
+
+ /* get results */
+ packages = pk_results_get_package_array (results);
+ if (packages->len == 1) {
+ PkPackage *package = g_ptr_array_index (packages, 0);
+ gs_app_add_source_id (app, pk_package_get_id (package));
+ } else {
+ g_debug ("failed to find one package for repo %s, %s, [%u]",
+ gs_app_get_id (app), filename, packages->len);
+ }
+ return TRUE;
+}
+
+gboolean
+gs_plugin_refine (GsPlugin *plugin,
+ GsAppList *list,
+ GsPluginRefineFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ GsApp *app = gs_app_list_index (list, i);
+ const gchar *fn;
+ if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD))
+ continue;
+ if (gs_app_get_kind (app) != AS_APP_KIND_SOURCE)
+ continue;
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0)
+ continue;
+ fn = gs_app_get_metadata_item (app, "repos::repo-filename");
+ if (fn == NULL)
+ continue;
+ /* set the source package name for an installed .repo file */
+ if (!gs_plugin_packagekit_refine_repo_from_filename (plugin,
+ app,
+ fn,
+ cancellable,
+ error))
+ return FALSE;
+ }
+
+ /* success */
+ return TRUE;
+}