[gnome-software/wip/temp/ubuntu-xenial-rebased: 210/329] Use dpkg-deb info to create a GsApp when double clicking on a .deb file



commit 40d6342555b2bf23d5675254f7a6a45f16de47fb
Author: William Hua <william hua canonical com>
Date:   Tue Apr 12 14:19:18 2016 +0100

    Use dpkg-deb info to create a GsApp when double clicking on a .deb file

 src/plugins/Makefile.am                    |    6 +
 src/plugins/gs-plugin-appstream.c          |    1 +
 src/plugins/gs-plugin-apt.cc               |  145 ++++------------------------
 src/plugins/gs-plugin-dpkg.c               |  124 ++++++++++++++++++++++++
 src/plugins/gs-plugin-packagekit-refresh.c |   12 +++
 5 files changed, 164 insertions(+), 124 deletions(-)
---
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 2a0e3ae..08ca812 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -31,6 +31,7 @@ plugin_LTLIBRARIES =                                  \
        libgs_plugin_appstream.la                       \
        libgs_plugin_dummy.la                           \
        libgs_plugin_hardcoded-featured.la              \
+       libgs_plugin_dpkg.la                            \
        libgs_plugin_hardcoded-blacklist.la             \
        libgs_plugin_moduleset.la                       \
        libgs_plugin_menu-spec-categories.la            \
@@ -85,6 +86,11 @@ libgs_plugin_dummy_la_LIBADD = $(GS_PLUGIN_LIBS)
 libgs_plugin_dummy_la_LDFLAGS = -module -avoid-version
 libgs_plugin_dummy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
 
+libgs_plugin_dpkg_la_SOURCES = gs-plugin-dpkg.c
+libgs_plugin_dpkg_la_LIBADD = $(GS_PLUGIN_LIBS)
+libgs_plugin_dpkg_la_LDFLAGS = -module -avoid-version
+libgs_plugin_dpkg_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
 libgs_plugin_fedora_distro_upgrades_la_SOURCES = gs-plugin-fedora-distro-upgrades.c
 libgs_plugin_fedora_distro_upgrades_la_LIBADD = $(GS_PLUGIN_LIBS) $(JSON_GLIB_LIBS) $(SOUP_LIBS)
 libgs_plugin_fedora_distro_upgrades_la_LDFLAGS = -module -avoid-version
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 40f0a49..e028e25 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -88,6 +88,7 @@ gs_plugin_order_after (GsPlugin *plugin)
 {
        static const gchar *deps[] = {
                "menu-spec-categories", /* need category list */
+               "dpkg",                 /* need package name */
                NULL };
        return deps;
 }
diff --git a/src/plugins/gs-plugin-apt.cc b/src/plugins/gs-plugin-apt.cc
index 49369eb..cf54343 100644
--- a/src/plugins/gs-plugin-apt.cc
+++ b/src/plugins/gs-plugin-apt.cc
@@ -464,9 +464,6 @@ gs_plugin_add_installed (GsPlugin *plugin,
                        continue;
 
                app = gs_app_new (NULL);
-               // FIXME: Since appstream marks all packages as owned by
-               // PackageKit and we are replacing PackageKit we need to accept
-               // those packages
                gs_app_set_management_plugin (app, "apt");
                gs_app_set_name (app, GS_APP_QUALITY_LOWEST, info->name);
                gs_app_add_source (app, info->name);
@@ -657,8 +654,9 @@ app_is_ours (GsApp *app)
 
        // FIXME: Since appstream marks all packages as owned by PackageKit and
        // we are replacing PackageKit we need to accept those packages
-       return g_strcmp0 (management_plugin, "PackageKit") == 0 ||
-              g_strcmp0 (management_plugin, "dpkg") == 0;
+       const gchar *our_management_plugins[] = { "PackageKit", "apt", NULL };
+
+       return g_strv_contains (our_management_plugins, management_plugin);
 }
 
 gboolean
@@ -675,12 +673,25 @@ gs_plugin_app_install (GsPlugin *plugin,
        if (gs_app_get_source_default (app) == NULL)
                return TRUE;
 
-       gs_app_set_state (app, AS_APP_STATE_INSTALLING);
-
-       if (g_strcmp0 (gs_app_get_management_plugin (app), "PackageKit") == 0)
+       switch (gs_app_get_state (app)) {
+       case AS_APP_STATE_AVAILABLE:
+       case AS_APP_STATE_UPDATABLE:
+               gs_app_set_state (app, AS_APP_STATE_INSTALLING);
                success = aptd_transaction (plugin, "InstallPackages", app, error);
-       else if (g_strcmp0 (gs_app_get_management_plugin (app), "dpkg") == 0)
+               break;
+       case AS_APP_STATE_AVAILABLE_LOCAL:
+               gs_app_set_state (app, AS_APP_STATE_INSTALLING);
                success = aptd_transaction (plugin, "InstallFile", app, error);
+               break;
+       default:
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "do not know how to install app in state %s",
+                            as_app_state_to_string (gs_app_get_state (app)));
+               return FALSE;
+       }
+
 
        if (success)
                gs_app_set_state (app, AS_APP_STATE_INSTALLED);
@@ -752,10 +763,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
                        continue;
 
                app = gs_app_new (NULL);
-               // FIXME: Since appstream marks all packages as owned by
-               // PackageKit and we are replacing PackageKit we need to accept
-               // those packages
-               gs_app_set_management_plugin (app, "PackageKit");
+               gs_app_set_management_plugin (app, "apt");
                gs_app_set_name (app, GS_APP_QUALITY_LOWEST, info->name);
                gs_app_set_kind (app, AS_APP_KIND_GENERIC);
                gs_app_add_source (app, info->name);
@@ -797,115 +805,4 @@ gs_plugin_launch (GsPlugin *plugin,
        return gs_plugin_app_launch (plugin, app, error);
 }
 
-static gboolean
-content_type_matches (const gchar *filename,
-                     gboolean *matches,
-                     GCancellable *cancellable,
-                     GError **error)
-{
-       const gchar *content_type;
-       g_autoptr(GFile) file = NULL;
-       g_autoptr(GFileInfo) info = NULL;
-       const gchar *supported_types[] = {
-               "application/vnd.debian.binary-package",
-               NULL };
-
-       /* get content type */
-       file = g_file_new_for_path (filename);
-       info = g_file_query_info (file,
-                                 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
-                                 G_FILE_QUERY_INFO_NONE,
-                                 cancellable,
-                                 error);
-       if (info == NULL)
-               return FALSE;
-
-       content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
-       *matches = g_strv_contains (supported_types, content_type);
-
-       return TRUE;
-}
-
-gboolean
-gs_plugin_filename_to_app (GsPlugin      *plugin,
-                          GList        **list,
-                          const gchar   *filename,
-                          GCancellable  *cancellable,
-                          GError       **error)
-{
-       gboolean supported;
-       GsApp *app;
-       g_autoptr(GFile) file = NULL;
-       gchar *argv[5] = { NULL };
-       g_autofree gchar *argv0 = NULL;
-       g_autofree gchar *argv1 = NULL;
-       g_autofree gchar *argv2 = NULL;
-       g_autofree gchar *argv3 = NULL;
-       g_autofree gchar *output = NULL;
-       g_autofree gchar *description = NULL;
-       g_autofree gchar *path = NULL;
-       g_auto(GStrv) tokens = NULL;
-
-       if (!content_type_matches (filename,
-                                  &supported,
-                                  cancellable,
-                                  error))
-               return FALSE;
-       if (!supported)
-               return TRUE;
-
-       argv[0] = argv0 = g_strdup ("dpkg-deb");
-       argv[1] = argv1 = g_strdup ("--showformat=${Package}\\n"
-                                   "${Version}\\n"
-                                   "${Installed-Size}\\n"
-                                   "${Homepage}\\n"
-                                   "${Description}");
-       argv[2] = argv2 = g_strdup ("-W");
-       argv[3] = argv3 = g_strdup (filename);
-
-       if (!g_spawn_sync (NULL, /* working_directory */
-                          argv,
-                          NULL, /* envp */
-                          (GSpawnFlags) (G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL),
-                          NULL, /* child_setup */
-                          NULL, /* user_data */
-                          &output,
-                          NULL, /* standard_error */
-                          NULL, /* exit_status */
-                          error))
-               return FALSE;
-
-       tokens = g_strsplit (output, "\n", 0);
-
-       if (g_strv_length (tokens) < 5) {
-               g_set_error (error,
-                            GS_PLUGIN_ERROR,
-                            GS_PLUGIN_ERROR_FAILED,
-                            "dpkg-deb output format incorrect:\n\"%s\"\n", output);
-               return FALSE;
-       }
-
-       description = g_strjoinv (NULL, tokens + 5);
-
-       app = gs_app_new (NULL);
-       file = g_file_new_for_commandline_arg (filename);
-       path = g_file_get_path (file);
-
-       gs_app_set_name (app, GS_APP_QUALITY_LOWEST, tokens[0]);
-       gs_app_set_version (app, tokens[1]);
-       gs_app_set_size (app, 1024 * atoi (tokens[2]));
-       gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, tokens[3]);
-       gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, tokens[4]);
-       gs_app_set_description (app, GS_APP_QUALITY_LOWEST, description + 1);
-       gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
-       gs_app_set_management_plugin (app, "dpkg");
-       gs_app_add_source (app, tokens[0]);
-       gs_app_set_origin (app, path);
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
-
-       gs_plugin_add_app (list, app);
-
-       return TRUE;
-}
-
 /* vim: set noexpandtab ts=8 sw=8: */
diff --git a/src/plugins/gs-plugin-dpkg.c b/src/plugins/gs-plugin-dpkg.c
new file mode 100644
index 0000000..125539b
--- /dev/null
+++ b/src/plugins/gs-plugin-dpkg.c
@@ -0,0 +1,124 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2011-2013 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gs-plugin.h>
+#include <gs-utils.h>
+
+#define DPKG_DEB_BINARY                "/usr/bin/dpkg-deb"
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+       return "dpkg";
+}
+
+/**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+       if (!g_file_test (DPKG_DEB_BINARY, G_FILE_TEST_EXISTS)) {
+               g_debug ("disabling '%s' as no %s available",
+                        plugin->name, DPKG_DEB_BINARY);
+               gs_plugin_set_enabled (plugin, FALSE);
+       }
+}
+
+/**
+ * gs_plugin_filename_to_app:
+ */
+gboolean
+gs_plugin_filename_to_app (GsPlugin *plugin,
+                          GList **list,
+                          const gchar *filename,
+                          GCancellable *cancellable,
+                          GError **error)
+{
+       GsApp *app;
+       g_autofree gchar *content_type = NULL;
+       g_autofree gchar *description = NULL;
+       g_autofree gchar *output = NULL;
+       g_auto(GStrv) argv = NULL;
+       g_auto(GStrv) tokens = NULL;
+       const gchar *mimetypes[] = {
+               "application/vnd.debian.binary-package",
+               NULL };
+
+       /* does this match any of the mimetypes we support */
+       content_type = gs_utils_get_content_type (filename, cancellable, error);
+       if (content_type == NULL)
+               return FALSE;
+       if (!g_strv_contains (mimetypes, content_type))
+               return TRUE;
+
+       /* exec sync */
+       argv = g_new0 (gchar *, 4);
+       argv[0] = g_strdup (DPKG_DEB_BINARY);
+       argv[1] = g_strdup ("--showformat=${Package}\\n"
+                           "${Version}\\n"
+                           "${Installed-Size}\\n"
+                           "${Homepage}\\n"
+                           "${Description}");
+       argv[2] = g_strdup ("-W");
+       argv[3] = g_strdup (filename);
+       if (!g_spawn_sync (NULL, argv, NULL,
+                          G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
+                          NULL, NULL, &output, NULL, NULL, error))
+               return FALSE;
+
+       /* parse output */
+       tokens = g_strsplit (output, "\n", 0);
+       if (g_strv_length (tokens) < 5) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "dpkg-deb output format incorrect:\n\"%s\"\n", output);
+               return FALSE;
+       }
+
+       /* create app */
+       app = gs_app_new (NULL);
+       gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
+       gs_app_add_source (app, tokens[0]);
+       gs_app_set_name (app, GS_APP_QUALITY_LOWEST, tokens[0]);
+       gs_app_set_version (app, tokens[1]);
+       gs_app_set_size (app, 1024 * atoi (tokens[2]));
+       gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, tokens[3]);
+       gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, tokens[4]);
+       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_management_plugin (app, "apt");
+
+       /* multiline text */
+       description = g_strjoinv (NULL, tokens + 5);
+       gs_app_set_description (app, GS_APP_QUALITY_LOWEST, description + 1);
+
+       /* success */
+       gs_plugin_add_app (list, app);
+       return TRUE;
+}
diff --git a/src/plugins/gs-plugin-packagekit-refresh.c b/src/plugins/gs-plugin-packagekit-refresh.c
index 9b1e99e..083e2d1 100644
--- a/src/plugins/gs-plugin-packagekit-refresh.c
+++ b/src/plugins/gs-plugin-packagekit-refresh.c
@@ -50,6 +50,18 @@ gs_plugin_get_name (void)
 }
 
 /**
+ * gs_plugin_get_conflicts:
+ */
+const gchar **
+gs_plugin_get_conflicts (GsPlugin *plugin)
+{
+       static const gchar *deps[] = {
+               "dpkg",
+               NULL };
+       return deps;
+}
+
+/**
  * gs_plugin_initialize:
  */
 void


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