[gnome-software] Allow clients to require certain optional properties on an application



commit 6079ef6c4bea1d440506256f4472219444ac29fe
Author: Richard Hughes <richard hughsie com>
Date:   Wed Oct 9 13:16:24 2013 +0100

    Allow clients to require certain optional properties on an application
    
    These properties take a few seconds to collect, and we don't want them in all circumstances.

 src/gs-plugin.h                           |    5 +-
 src/gs-self-test.c                        |   41 ++++++++
 src/plugins/gs-plugin-packagekit-refine.c |  147 ++++++++++++++++++++++++++++-
 3 files changed, 191 insertions(+), 2 deletions(-)
---
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 74b4015..48c3e3d 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -74,7 +74,10 @@ typedef enum {
 
 typedef enum {
        GS_PLUGIN_REFINE_FLAGS_DEFAULT                  = 0,
-       GS_PLUGIN_REFINE_FLAGS_USE_HISTORY              = 1,
+       GS_PLUGIN_REFINE_FLAGS_USE_HISTORY              = 1 << 0,
+       GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENCE          = 1 << 1,
+       GS_PLUGIN_REFINE_FLAGS_REQUIRE_URL              = 1 << 2,
+       GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION      = 1 << 3,
        GS_PLUGIN_REFINE_FLAGS_LAST
 } GsPluginRefineFlags;
 
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index eca3d31..55c45df 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -293,6 +293,45 @@ gs_plugin_loader_func (void)
 }
 
 static void
+gs_plugin_loader_refine_func (void)
+{
+       GError *error = NULL;
+       GsApp *app;
+       GsPluginLoader *loader;
+       gboolean ret;
+
+       /* load the plugins */
+       loader = gs_plugin_loader_new ();
+       gs_plugin_loader_set_location (loader, "./plugins/.libs");
+       ret = gs_plugin_loader_setup (loader, &error);
+       g_assert_no_error (error);
+       g_assert (ret);
+
+       ret = gs_plugin_loader_set_enabled (loader, "packagekit-refine", TRUE);
+       g_assert (ret);
+
+       /* get the extra bits */
+       app = gs_app_new ("gimp");
+       gs_app_set_source (app, "gimp");
+       ret = gs_plugin_loader_app_refine (loader, app,
+                                          GS_PLUGIN_REFINE_FLAGS_DEFAULT |
+                                          GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION |
+                                          GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENCE |
+                                          GS_PLUGIN_REFINE_FLAGS_REQUIRE_URL,
+                                          NULL,
+                                          &error);
+       g_assert_no_error (error);
+       g_assert (ret);
+
+       g_assert_cmpstr (gs_app_get_licence (app), ==, "GPLv3+ and GPLv3");
+       g_assert_cmpstr (gs_app_get_description (app), !=, NULL);
+       g_assert_cmpstr (gs_app_get_url (app), ==, "http://www.gimp.org/";);
+
+       g_object_unref (app);
+       g_object_unref (loader);
+}
+
+static void
 gs_plugin_loader_empty_func (void)
 {
        gboolean ret;
@@ -384,11 +423,13 @@ main (int argc, char **argv)
 {
        gtk_init (&argc, &argv);
        g_test_init (&argc, &argv, NULL);
+       g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
 
        /* only critical and error are fatal */
        g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
 
        /* tests go here */
+       g_test_add_func ("/gnome-software/plugin-loader{refine}", gs_plugin_loader_refine_func);
        g_test_add_func ("/gnome-software/plugin", gs_plugin_func);
        g_test_add_func ("/gnome-software/app", gs_app_func);
        if (g_getenv ("HAS_APPSTREAM") != NULL)
diff --git a/src/plugins/gs-plugin-packagekit-refine.c b/src/plugins/gs-plugin-packagekit-refine.c
index 5b02072..3b83451 100644
--- a/src/plugins/gs-plugin-packagekit-refine.c
+++ b/src/plugins/gs-plugin-packagekit-refine.c
@@ -280,7 +280,7 @@ out:
 }
 
 /**
- * gs_plugin_refine:
+ * gs_plugin_packagekit_refine_updatedetails:
  */
 static gboolean
 gs_plugin_packagekit_refine_updatedetails (GsPlugin *plugin,
@@ -347,6 +347,139 @@ out:
 }
 
 /**
+ * gs_plugin_packagekit_refine_details:
+ */
+static gboolean
+gs_plugin_packagekit_refine_details (GsPlugin *plugin,
+                                    GList *list,
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+       GList *l;
+       GPtrArray *array = NULL;
+       GsApp *app;
+       PkDetails *details;
+       PkResults *results = NULL;
+       const gchar **package_ids;
+       const gchar *package_id;
+       gboolean ret = TRUE;
+       guint i = 0;
+       guint size;
+#if !PK_CHECK_VERSION(0,8,12)
+       gboolean matches;
+       gchar *tmp;
+#endif
+
+       size = g_list_length (list);
+       package_ids = g_new0 (const gchar *, size + 1);
+       for (l = list; l != NULL; l = l->next) {
+               app = GS_APP (l->data);
+               package_id = gs_app_get_metadata_item (app, "PackageKit::package-id");
+               package_ids[i++] = package_id;
+       }
+
+       /* get any details */
+       results = pk_client_get_details (plugin->priv->client,
+                                        (gchar **) package_ids,
+                                        cancellable,
+                                        gs_plugin_packagekit_progress_cb, plugin,
+                                        error);
+       if (results == NULL) {
+               ret = FALSE;
+               goto out;
+       }
+
+       /* set the update details for the update */
+       array = pk_results_get_details_array (results);
+       for (l = list; l != NULL; l = l->next) {
+               app = GS_APP (l->data);
+               package_id = gs_app_get_metadata_item (app, "PackageKit::package-id");
+               for (i = 0; i < array->len; i++) {
+                       /* right package? */
+                       details = g_ptr_array_index (array, i);
+#if PK_CHECK_VERSION(0,8,12)
+                       if (g_strcmp0 (package_id, pk_details_get_package_id (details)) != 0)
+                               continue;
+                       if (gs_app_get_licence (app) == NULL)
+                               gs_app_set_licence (app, pk_details_get_license (details));
+                       if (gs_app_get_url (app) == NULL)
+                               gs_app_set_url (app, pk_details_get_url (details));
+                       if (gs_app_get_description (app) == NULL)
+                               gs_app_set_description (app, pk_details_get_description (details));
+#else
+                       g_object_get (details, "package-id", &tmp, NULL);
+                       matches = g_strcmp0 (package_id, tmp) != 0;
+                       g_free (tmp);
+                       if (matches)
+                               continue;
+                       if (gs_app_get_licence (app) == NULL) {
+                               g_object_get (details, "license", &tmp, NULL);
+                               gs_app_set_licence (app, tmp);
+                               g_free (tmp);
+                       }
+                       if (gs_app_get_url (app) == NULL) {
+                               g_object_get (details, "url", &tmp, NULL);
+                               gs_app_set_licence (app, tmp);
+                               g_free (tmp);
+                       }
+                       if (gs_app_get_description (app) == NULL) {
+                               g_object_get (details, "description", &tmp, NULL);
+                               gs_app_set_description (app, tmp);
+                               g_free (tmp);
+                       }
+#endif
+                       break;
+               }
+       }
+out:
+       if (array != NULL)
+               g_ptr_array_unref (array);
+       if (results != NULL)
+               g_object_unref (results);
+       g_free (package_ids);
+       return ret;
+}
+
+/**
+ * gs_plugin_refine_require_details:
+ */
+static gboolean
+gs_plugin_refine_require_details (GsPlugin *plugin,
+                                 GList *list,
+                                 GCancellable *cancellable,
+                                 GError **error)
+{
+       GList *l;
+       GList *list_tmp = NULL;
+       GsApp *app;
+       gboolean ret = TRUE;
+
+       gs_profile_start_full (plugin->profile, "packagekit-refine[source->licence]");
+       for (l = list; l != NULL; l = l->next) {
+               app = GS_APP (l->data);
+               if (gs_app_get_licence (app) != NULL &&
+                   gs_app_get_url (app) != NULL &&
+                   gs_app_get_description (app) != NULL)
+                       continue;
+               if (gs_app_get_metadata_item (app, "PackageKit::package-id") == NULL)
+                       continue;
+               list_tmp = g_list_prepend (list_tmp, app);
+       }
+       if (list_tmp == NULL)
+               goto out;
+       ret = gs_plugin_packagekit_refine_details (plugin,
+                                                  list_tmp,
+                                                  cancellable,
+                                                  error);
+       if (!ret)
+               goto out;
+out:
+       gs_profile_stop_full (plugin->profile, "packagekit-refine[source->licence]");
+       g_list_free (list_tmp);
+       return ret;
+}
+
+/**
  * gs_plugin_refine:
  */
 gboolean
@@ -419,6 +552,18 @@ gs_plugin_refine (GsPlugin *plugin,
                                                                 error);
        }
        gs_profile_stop_full (plugin->profile, "packagekit-refine[id->update-details]");
+
+       /* any important details missing? */
+       if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENCE) > 0 ||
+           (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_URL) > 0 ||
+           (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION) > 0) {
+               ret = gs_plugin_refine_require_details (plugin,
+                                                       list,
+                                                       cancellable,
+                                                       error);
+               if (!ret)
+                       goto out;
+       }
 out:
        g_list_free (resolve_all);
        g_list_free (updatedetails_all);


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