[gnome-software] packagekit: Support apt:// URLs



commit 39e1c3d975108be230392bb7641658b7310145b8
Author: Iain Lane <iain orangesquash org uk>
Date:   Mon Oct 23 16:57:26 2017 +0100

    packagekit: Support apt:// URLs
    
    When we receive an apt:// URL and we're runing a Debian-based distro,
    try to resolve it to a package using PK.

 lib/gs-os-release.c                              |   22 ++++++
 lib/gs-os-release.h                              |    1 +
 plugins/packagekit/gs-plugin-packagekit-refine.c |   82 ++++++++++++++++++++++
 3 files changed, 105 insertions(+), 0 deletions(-)
---
diff --git a/lib/gs-os-release.c b/lib/gs-os-release.c
index 2c3b1cb..231b91c 100644
--- a/lib/gs-os-release.c
+++ b/lib/gs-os-release.c
@@ -43,6 +43,7 @@ struct _GsOsRelease
        gchar                   *name;
        gchar                   *version;
        gchar                   *id;
+       gchar                   *id_like;
        gchar                   *version_id;
        gchar                   *pretty_name;
        gchar                   *cpe_name;
@@ -111,6 +112,10 @@ gs_os_release_initable_init (GInitable *initable,
                        os_release->id = g_strdup (tmp);
                        continue;
                }
+               if (g_strcmp0 (lines[i], "ID_LIKE") == 0) {
+                       os_release->id_like = g_strdup (tmp);
+                       continue;
+               }
                if (g_strcmp0 (lines[i], "VERSION_ID") == 0) {
                        os_release->version_id = g_strdup (tmp);
                        continue;
@@ -187,6 +192,23 @@ gs_os_release_get_id (GsOsRelease *os_release)
 }
 
 /**
+ * gs_os_release_get_id_like:
+ * @os_release: A #GsOsRelease
+ *
+ * Gets the ID_LIKE from the os-release parser.
+ *
+ * Returns: a string, or %NULL
+ *
+ * Since: 3.26.2
+ **/
+const gchar *
+gs_os_release_get_id_like (GsOsRelease *os_release)
+{
+       g_return_val_if_fail (GS_IS_OS_RELEASE (os_release), NULL);
+       return os_release->id_like;
+}
+
+/**
  * gs_os_release_get_version_id:
  * @os_release: A #GsOsRelease
  *
diff --git a/lib/gs-os-release.h b/lib/gs-os-release.h
index 8da104a..d789b12 100644
--- a/lib/gs-os-release.h
+++ b/lib/gs-os-release.h
@@ -37,6 +37,7 @@ GsOsRelease   *gs_os_release_new                      (GError         **error);
 const gchar    *gs_os_release_get_name                 (GsOsRelease    *os_release);
 const gchar    *gs_os_release_get_version              (GsOsRelease    *os_release);
 const gchar    *gs_os_release_get_id                   (GsOsRelease    *os_release);
+const gchar    *gs_os_release_get_id_like              (GsOsRelease    *os_release);
 const gchar    *gs_os_release_get_version_id           (GsOsRelease    *os_release);
 const gchar    *gs_os_release_get_pretty_name          (GsOsRelease    *os_release);
 const gchar    *gs_os_release_get_cpe_name             (GsOsRelease    *os_release);
diff --git a/plugins/packagekit/gs-plugin-packagekit-refine.c 
b/plugins/packagekit/gs-plugin-packagekit-refine.c
index 486f4b0..07f9701 100644
--- a/plugins/packagekit/gs-plugin-packagekit-refine.c
+++ b/plugins/packagekit/gs-plugin-packagekit-refine.c
@@ -1034,3 +1034,85 @@ gs_plugin_refine_app (GsPlugin *plugin,
 
        return TRUE;
 }
+
+gboolean
+gs_plugin_url_to_app (GsPlugin *plugin,
+                     GsAppList *list,
+                     const gchar *url,
+                     GCancellable *cancellable,
+                     GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+
+       g_autofree gchar *scheme = NULL;
+       g_autofree gchar *path = NULL;
+       const gchar *id = NULL;
+       const gchar *id_like = NULL;
+       g_auto(GStrv) package_ids = NULL;
+       g_autoptr(PkResults) results = NULL;
+       g_autoptr(GsApp) app = NULL;
+       g_autoptr(GsOsRelease) os_release = NULL;
+       g_autoptr(GPtrArray) packages = NULL;
+       g_autoptr(GPtrArray) details = NULL;
+       ProgressData data;
+
+       path = gs_utils_get_url_path (url);
+
+       data.app = app;
+       data.plugin = plugin;
+       data.ptask = NULL;
+       data.profile_id = path;
+
+       /* only do this for apt:// on debian or debian-like distros */
+       os_release = gs_os_release_new (error);
+       if (os_release == NULL) {
+               g_prefix_error (error, "failed to determine OS information:");
+                return FALSE;
+       } else  {
+               id = gs_os_release_get_id (os_release);
+               id_like = gs_os_release_get_id_like (os_release);
+               scheme = gs_utils_get_url_scheme (url);
+               if (!(g_strcmp0 (scheme, "apt") == 0 &&
+                    (g_strcmp0 (id, "debian") == 0 ||
+                     g_strcmp0 (id_like, "debian") == 0))) {
+                       return TRUE;
+               }
+       }
+
+       app = gs_app_new (NULL);
+       gs_app_add_source (app, path);
+       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+
+       package_ids = g_new0 (gchar *, 2);
+       package_ids[0] = g_strdup (path);
+
+       results = pk_client_resolve (priv->client,
+                                    pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST, PK_FILTER_ENUM_ARCH, -1),
+                                    package_ids,
+                                    cancellable,
+                                    gs_plugin_packagekit_progress_cb, &data,
+                                    error);
+
+       if (!gs_plugin_packagekit_results_valid (results, error)) {
+               g_prefix_error (error, "failed to resolve package_ids: ");
+               return FALSE;
+       }
+
+       /* get results */
+       packages = pk_results_get_package_array (results);
+       details = pk_results_get_details_array (results);
+
+       if (packages->len >= 1) {
+               if (gs_app_get_local_file (app) != NULL)
+                       return TRUE;
+
+               gs_plugin_packagekit_resolve_packages_app (plugin, packages, app);
+               gs_plugin_packagekit_refine_details_app (plugin, details, app);
+
+               gs_app_list_add (list, app);
+       } else {
+               g_warning ("no results returned");
+       }
+
+       return TRUE;
+}


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