[gnome-software: 3/8] packagekit: Merge packagekit-local plugin into packagekit




commit 2818a033d0c2fdf0a71694591f9deea0dd975bc3
Author: Philip Withnall <pwithnall endlessos org>
Date:   Thu May 20 15:14:36 2021 +0100

    packagekit: Merge packagekit-local plugin into packagekit
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>

 contrib/gnome-software.spec.in                  |   1 -
 plugins/packagekit/gs-plugin-packagekit-local.c | 273 ------------------------
 plugins/packagekit/gs-plugin-packagekit.c       | 244 +++++++++++++++++++++
 plugins/packagekit/gs-self-test.c               |   4 +-
 plugins/packagekit/meson.build                  |  17 --
 plugins/rpm-ostree/gs-plugin-rpm-ostree.c       |   1 -
 6 files changed, 246 insertions(+), 294 deletions(-)
---
diff --git a/contrib/gnome-software.spec.in b/contrib/gnome-software.spec.in
index a624aae3b..d067ae7c4 100644
--- a/contrib/gnome-software.spec.in
+++ b/contrib/gnome-software.spec.in
@@ -163,7 +163,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
 %{gs_plugin_dir}/libgs_plugin_icons.so
 %{gs_plugin_dir}/libgs_plugin_modalias.so
 %{gs_plugin_dir}/libgs_plugin_os-release.so
-%{gs_plugin_dir}/libgs_plugin_packagekit-local.so
 %{gs_plugin_dir}/libgs_plugin_packagekit-offline.so
 %{gs_plugin_dir}/libgs_plugin_packagekit-proxy.so
 %{gs_plugin_dir}/libgs_plugin_packagekit-refine-repos.so
diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c
index 358670976..326414bd2 100644
--- a/plugins/packagekit/gs-plugin-packagekit.c
+++ b/plugins/packagekit/gs-plugin-packagekit.c
@@ -37,6 +37,9 @@ struct GsPluginData {
        GMutex                   client_mutex_refine;
 
        GDBusConnection         *connection_history;
+
+       PkTask                  *task_local;
+       GMutex                   task_mutex_local;
 };
 
 static void gs_plugin_packagekit_updates_changed_cb (PkControl *control, GsPlugin *plugin);
@@ -70,6 +73,12 @@ gs_plugin_initialize (GsPlugin *plugin)
        pk_client_set_cache_age (priv->client_refine, G_MAXUINT);
        pk_client_set_interactive (priv->client_refine, gs_plugin_has_flags (plugin, 
GS_PLUGIN_FLAGS_INTERACTIVE));
 
+       /* local */
+       g_mutex_init (&priv->task_mutex_local);
+       priv->task_local = pk_task_new ();
+       pk_client_set_background (PK_CLIENT (priv->task_local), FALSE);
+       pk_client_set_interactive (PK_CLIENT (priv->task_local), gs_plugin_has_flags (plugin, 
GS_PLUGIN_FLAGS_INTERACTIVE));
+
        /* need pkgname and ID */
        gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "appstream");
 }
@@ -91,6 +100,10 @@ gs_plugin_destroy (GsPlugin *plugin)
        /* history */
        if (priv->connection_history != NULL)
                g_object_unref (priv->connection_history);
+
+       /* local */
+       g_mutex_clear (&priv->task_mutex_local);
+       g_object_unref (priv->task_local);
 }
 
 static gboolean
@@ -1784,3 +1797,234 @@ gs_plugin_packagekit_refine_history (GsPlugin      *plugin,
        }
        return TRUE;
 }
+
+static gboolean
+gs_plugin_packagekit_refresh_guess_app_id (GsPlugin *plugin,
+                                          GsApp *app,
+                                          const gchar *filename,
+                                          GCancellable *cancellable,
+                                          GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       g_autoptr(GsPackagekitHelper) helper = gs_packagekit_helper_new (plugin);
+       g_auto(GStrv) files = NULL;
+       g_autoptr(PkResults) results = NULL;
+       g_autoptr(GPtrArray) array = NULL;
+       g_autoptr(GString) basename_best = g_string_new (NULL);
+
+       /* get file list so we can work out ID */
+       files = g_strsplit (filename, "\t", -1);
+       gs_packagekit_helper_add_app (helper, app);
+       g_mutex_lock (&priv->task_mutex_local);
+       results = pk_client_get_files_local (PK_CLIENT (priv->task_local),
+                                            files,
+                                            cancellable,
+                                            gs_packagekit_helper_cb, helper,
+                                            error);
+       g_mutex_unlock (&priv->task_mutex_local);
+       if (!gs_plugin_packagekit_results_valid (results, error)) {
+               gs_utils_error_add_origin_id (error, app);
+               return FALSE;
+       }
+       array = pk_results_get_files_array (results);
+       if (array->len == 0) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_INVALID_FORMAT,
+                            "no files for %s", filename);
+               return FALSE;
+       }
+
+       /* find the smallest length desktop file, on the logic that
+        * ${app}.desktop is going to be better than ${app}-${action}.desktop */
+       for (guint i = 0; i < array->len; i++) {
+               PkFiles *item = g_ptr_array_index (array, i);
+               gchar **fns = pk_files_get_files (item);
+               for (guint j = 0; fns[j] != NULL; j++) {
+                       if (g_str_has_prefix (fns[j], "/etc/yum.repos.d/") &&
+                           g_str_has_suffix (fns[j], ".repo")) {
+                               gs_app_add_quirk (app, GS_APP_QUIRK_HAS_SOURCE);
+                       }
+                       if (g_str_has_prefix (fns[j], "/usr/share/applications/") &&
+                           g_str_has_suffix (fns[j], ".desktop")) {
+                               g_autofree gchar *basename = g_path_get_basename (fns[j]);
+                               if (basename_best->len == 0 ||
+                                   strlen (basename) < basename_best->len)
+                                       g_string_assign (basename_best, basename);
+                       }
+               }
+       }
+       if (basename_best->len > 0) {
+               gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
+               gs_app_set_id (app, basename_best->str);
+       }
+
+       return TRUE;
+}
+
+static void
+add_quirks_from_package_name (GsApp *app, const gchar *package_name)
+{
+       /* these packages don't have a .repo file in their file lists, but
+        * instead install one through rpm scripts / cron job */
+       const gchar *packages_with_repos[] = {
+               "google-chrome-stable",
+               "google-earth-pro-stable",
+               "google-talkplugin",
+               NULL };
+
+       if (g_strv_contains (packages_with_repos, package_name))
+               gs_app_add_quirk (app, GS_APP_QUIRK_HAS_SOURCE);
+}
+
+static gboolean
+gs_plugin_packagekit_local_check_installed (GsPlugin *plugin,
+                                           GsApp *app,
+                                           GCancellable *cancellable,
+                                           GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       PkBitfield filter;
+       const gchar *names[] = { gs_app_get_source_default (app), NULL };
+       g_autoptr(GPtrArray) packages = NULL;
+       g_autoptr(PkResults) results = NULL;
+
+       filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST,
+                                        PK_FILTER_ENUM_ARCH,
+                                        PK_FILTER_ENUM_INSTALLED,
+                                        -1);
+       results = pk_client_resolve (PK_CLIENT (priv->task_local), filter, (gchar **) names,
+                                    cancellable, NULL, NULL, error);
+       if (results == NULL)
+               return FALSE;
+       packages = pk_results_get_package_array (results);
+       if (packages->len > 0) {
+               gs_app_set_state (app, GS_APP_STATE_UNKNOWN);
+               gs_app_set_state (app, GS_APP_STATE_INSTALLED);
+               for (guint i = 0; i < packages->len; i++){
+                       PkPackage *pkg = g_ptr_array_index (packages, i);
+                       gs_app_add_source_id (app, pk_package_get_id (pkg));
+               }
+       }
+       return TRUE;
+}
+
+gboolean
+gs_plugin_file_to_app (GsPlugin *plugin,
+                      GsAppList *list,
+                      GFile *file,
+                      GCancellable *cancellable,
+                      GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       const gchar *package_id;
+       PkDetails *item;
+       g_autoptr(GsPackagekitHelper) helper = gs_packagekit_helper_new (plugin);
+       g_autoptr(PkResults) results = NULL;
+       g_autofree gchar *content_type = NULL;
+       g_autofree gchar *filename = NULL;
+       g_autofree gchar *license_spdx = NULL;
+       g_auto(GStrv) files = NULL;
+       g_auto(GStrv) split = NULL;
+       g_autoptr(GPtrArray) array = NULL;
+       g_autoptr(GsApp) app = NULL;
+       const gchar *mimetypes[] = {
+               "application/x-app-package",
+               "application/x-deb",
+               "application/vnd.debian.binary-package",
+               "application/x-redhat-package-manager",
+               "application/x-rpm",
+               NULL };
+
+       /* does this match any of the mimetypes we support */
+       content_type = gs_utils_get_content_type (file, cancellable, error);
+       if (content_type == NULL)
+               return FALSE;
+       if (!g_strv_contains (mimetypes, content_type))
+               return TRUE;
+
+       /* get details */
+       filename = g_file_get_path (file);
+       files = g_strsplit (filename, "\t", -1);
+       g_mutex_lock (&priv->task_mutex_local);
+       pk_client_set_cache_age (PK_CLIENT (priv->task_local), G_MAXUINT);
+       pk_client_set_interactive (PK_CLIENT (priv->task_local), gs_plugin_has_flags (plugin, 
GS_PLUGIN_FLAGS_INTERACTIVE));
+       results = pk_client_get_details_local (PK_CLIENT (priv->task_local),
+                                              files,
+                                              cancellable,
+                                              gs_packagekit_helper_cb, helper,
+                                              error);
+       g_mutex_unlock (&priv->task_mutex_local);
+       if (!gs_plugin_packagekit_results_valid (results, error))
+               return FALSE;
+
+       /* get results */
+       array = pk_results_get_details_array (results);
+       if (array->len == 0) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_INVALID_FORMAT,
+                            "no details for %s", filename);
+               return FALSE;
+       }
+       if (array->len > 1) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_INVALID_FORMAT,
+                            "too many details [%u] for %s",
+                            array->len, filename);
+               return FALSE;
+       }
+
+       /* create application */
+       item = g_ptr_array_index (array, 0);
+       app = gs_app_new (NULL);
+       gs_plugin_packagekit_set_packaging_format (plugin, app);
+       gs_app_set_metadata (app, "GnomeSoftware::Creator",
+                            gs_plugin_get_name (plugin));
+       package_id = pk_details_get_package_id (item);
+       split = pk_package_id_split (package_id);
+       if (split == NULL) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_INVALID_FORMAT,
+                            "invalid package-id: %s", package_id);
+               return FALSE;
+       }
+       gs_app_set_management_plugin (app, "packagekit");
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
+       gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
+       gs_app_set_state (app, GS_APP_STATE_AVAILABLE_LOCAL);
+       gs_app_set_name (app, GS_APP_QUALITY_LOWEST, split[PK_PACKAGE_ID_NAME]);
+       gs_app_set_summary (app, GS_APP_QUALITY_LOWEST,
+                           pk_details_get_summary (item));
+       gs_app_set_version (app, split[PK_PACKAGE_ID_VERSION]);
+       gs_app_add_source (app, split[PK_PACKAGE_ID_NAME]);
+       gs_app_add_source_id (app, package_id);
+       gs_app_set_description (app, GS_APP_QUALITY_LOWEST,
+                               pk_details_get_description (item));
+       gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, pk_details_get_url (item));
+       gs_app_set_size_installed (app, pk_details_get_size (item));
+       gs_app_set_size_download (app, 0);
+       license_spdx = as_license_to_spdx_id (pk_details_get_license (item));
+       gs_app_set_license (app, GS_APP_QUALITY_LOWEST, license_spdx);
+       add_quirks_from_package_name (app, split[PK_PACKAGE_ID_NAME]);
+
+       /* is already installed? */
+       if (!gs_plugin_packagekit_local_check_installed (plugin,
+                                                        app,
+                                                        cancellable,
+                                                        error))
+               return FALSE;
+
+       /* look for a desktop file so we can use a valid application id */
+       if (!gs_plugin_packagekit_refresh_guess_app_id (plugin,
+                                                       app,
+                                                       filename,
+                                                       cancellable,
+                                                       error))
+               return FALSE;
+
+       gs_app_list_add (list, app);
+       return TRUE;
+}
diff --git a/plugins/packagekit/gs-self-test.c b/plugins/packagekit/gs-self-test.c
index 5dbaf0a7b..e0d50ea5e 100644
--- a/plugins/packagekit/gs-self-test.c
+++ b/plugins/packagekit/gs-self-test.c
@@ -203,7 +203,7 @@ gs_plugins_packagekit_local_func (GsPluginLoader *plugin_loader)
        g_autoptr(GsPluginJob) plugin_job = NULL;
 
        /* no packagekit, abort */
-       if (!gs_plugin_loader_get_enabled (plugin_loader, "packagekit-local")) {
+       if (!gs_plugin_loader_get_enabled (plugin_loader, "packagekit")) {
                g_test_skip ("not enabled");
                return;
        }
@@ -240,7 +240,7 @@ main (int argc, char **argv)
        g_autoptr(GError) error = NULL;
        g_autoptr(GsPluginLoader) plugin_loader = NULL;
        const gchar *allowlist[] = {
-               "packagekit-local",
+               "packagekit",
                NULL
        };
 
diff --git a/plugins/packagekit/meson.build b/plugins/packagekit/meson.build
index c1dcabfbd..22b410fb5 100644
--- a/plugins/packagekit/meson.build
+++ b/plugins/packagekit/meson.build
@@ -78,23 +78,6 @@ shared_module(
   dependencies : [ plugin_libs, packagekit ],
 )
 
-shared_module(
-  'gs_plugin_packagekit-local',
-  sources : [
-    'gs-plugin-packagekit-local.c',
-    'gs-packagekit-helper.c',
-    'packagekit-common.c',
-  ],
-  include_directories : [
-    include_directories('../..'),
-    include_directories('../../lib'),
-  ],
-  install : true,
-  install_dir: plugin_dir,
-  c_args : cargs,
-  dependencies : [ plugin_libs, packagekit ],
-)
-
 shared_module(
   'gs_plugin_packagekit-upgrade',
   sources : [
diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index b26c4e517..eda1d134f 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -68,7 +68,6 @@ gs_plugin_initialize (GsPlugin *plugin)
         * more sense to use a custom plugin instead of using PackageKit.
         */
        gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_CONFLICTS, "packagekit");
-       gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_CONFLICTS, "packagekit-local");
        gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_CONFLICTS, "packagekit-offline");
        gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_CONFLICTS, "packagekit-proxy");
        gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_CONFLICTS, "packagekit-refine-repos");


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]