[gnome-software/wip/rancell/ubuntu-ratings] Add functionality to the plugin loader to get distro upgrades



commit 0d3fdc7ae51bb3e403d7c8c58c202795039f80ad
Author: Richard Hughes <richard hughsie com>
Date:   Thu Oct 29 10:54:37 2015 +0000

    Add functionality to the plugin loader to get distro upgrades

 src/gs-app.c                      |    2 +
 src/gs-app.h                      |   15 ++++---
 src/gs-cmd.c                      |   16 +++++++-
 src/gs-plugin-loader-sync.c       |   47 ++++++++++++++++++++-
 src/gs-plugin-loader-sync.h       |    6 ++-
 src/gs-plugin-loader.c            |   85 ++++++++++++++++++++++++++++++++++++-
 src/gs-plugin-loader.h            |   10 ++++-
 src/gs-plugin.h                   |    4 ++
 src/plugins/gs-plugin-appstream.c |   49 +++++++++++++++++++++
 9 files changed, 222 insertions(+), 12 deletions(-)
---
diff --git a/src/gs-app.c b/src/gs-app.c
index c1afe05..dc6315c 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -154,6 +154,8 @@ gs_app_kind_to_string (GsAppKind kind)
                return "source";
        if (kind == GS_APP_KIND_CORE)
                return "core";
+       if (kind == GS_APP_KIND_DISTRO_UPGRADE)
+               return "distro-upgrade";
        return NULL;
 }
 
diff --git a/src/gs-app.h b/src/gs-app.h
index 233d252..0513e41 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -39,13 +39,14 @@ typedef enum {
 
 typedef enum {
        GS_APP_KIND_UNKNOWN,
-       GS_APP_KIND_NORMAL,     /* app  [ install:1 remove:1 update:1 ] */
-       GS_APP_KIND_SYSTEM,     /* app  [ install:0 remove:0 update:1 ] */
-       GS_APP_KIND_PACKAGE,    /* pkg  [ install:0 remove:0 update:1 ] */
-       GS_APP_KIND_OS_UPDATE,  /* pkg  [ install:0 remove:0 update:1 ] */
-       GS_APP_KIND_MISSING,    /* meta [ install:0 remove:0 update:0 ] */
-       GS_APP_KIND_SOURCE,     /* src  [ install:1 remove:0 update:0 ] */
-       GS_APP_KIND_CORE,       /* pkg  [ install:0 remove:0 update:1 ] */
+       GS_APP_KIND_NORMAL,             /* app  [ install:1 remove:1 update:1 ] */
+       GS_APP_KIND_SYSTEM,             /* app  [ install:0 remove:0 update:1 ] */
+       GS_APP_KIND_PACKAGE,            /* pkg  [ install:0 remove:0 update:1 ] */
+       GS_APP_KIND_OS_UPDATE,          /* pkg  [ install:0 remove:0 update:1 ] */
+       GS_APP_KIND_MISSING,            /* meta [ install:0 remove:0 update:0 ] */
+       GS_APP_KIND_SOURCE,             /* src  [ install:1 remove:0 update:0 ] */
+       GS_APP_KIND_CORE,               /* pkg  [ install:0 remove:0 update:1 ] */
+       GS_APP_KIND_DISTRO_UPGRADE,     /* meta [ install:0 remove:0 update:1 ] */
        GS_APP_KIND_LAST
 } GsAppKind;
 
diff --git a/src/gs-cmd.c b/src/gs-cmd.c
index 459c42f..31ddcc1 100644
--- a/src/gs-cmd.c
+++ b/src/gs-cmd.c
@@ -308,6 +308,19 @@ main (int argc, char **argv)
                                break;
                        }
                }
+       } else if (argc == 2 && g_strcmp0 (argv[1], "upgrades") == 0) {
+               for (i = 0; i < repeat; i++) {
+                       if (list != NULL)
+                               gs_plugin_list_free (list);
+                       list = gs_plugin_loader_get_distro_upgrades (plugin_loader,
+                                                                    refine_flags,
+                                                                    NULL,
+                                                                    &error);
+                       if (list == NULL) {
+                               ret = FALSE;
+                               break;
+                       }
+               }
        } else if (argc == 2 && g_strcmp0 (argv[1], "sources") == 0) {
                list = gs_plugin_loader_get_sources (plugin_loader,
                                                     refine_flags,
@@ -402,7 +415,8 @@ main (int argc, char **argv)
                gs_cmd_show_results_categories (categories);
        }
 out:
-       as_profile_dump (profile);
+       if (profile != NULL)
+               as_profile_dump (profile);
        g_option_context_free (context);
        gs_plugin_list_free (list);
        gs_plugin_list_free (categories);
diff --git a/src/gs-plugin-loader-sync.c b/src/gs-plugin-loader-sync.c
index 462a2ba..254b8b9 100644
--- a/src/gs-plugin-loader-sync.c
+++ b/src/gs-plugin-loader-sync.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2012-2014 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2012-2015 Richard Hughes <richard hughsie com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -193,6 +193,51 @@ gs_plugin_loader_get_updates (GsPluginLoader *plugin_loader,
 }
 
 static void
+gs_plugin_loader_get_distro_upgrades_finish_sync (GsPluginLoader *plugin_loader,
+                                         GAsyncResult *res,
+                                         GsPluginLoaderHelper *helper)
+{
+       helper->list = gs_plugin_loader_get_distro_upgrades_finish (plugin_loader,
+                                                                   res,
+                                                                   helper->error);
+       g_main_loop_quit (helper->loop);
+}
+
+/**
+ * gs_plugin_loader_get_distro_upgrades:
+ **/
+GList *
+gs_plugin_loader_get_distro_upgrades (GsPluginLoader *plugin_loader,
+                             GsPluginRefineFlags flags,
+                             GCancellable *cancellable,
+                             GError **error)
+{
+       GsPluginLoaderHelper helper;
+
+       /* create temp object */
+       helper.context = g_main_context_new ();
+       helper.loop = g_main_loop_new (helper.context, FALSE);
+       helper.error = error;
+
+       g_main_context_push_thread_default (helper.context);
+
+       /* run async method */
+       gs_plugin_loader_get_distro_upgrades_async (plugin_loader,
+                                                   flags,
+                                                   cancellable,
+                                                   (GAsyncReadyCallback) 
gs_plugin_loader_get_distro_upgrades_finish_sync,
+                                                   &helper);
+       g_main_loop_run (helper.loop);
+
+       g_main_context_pop_thread_default (helper.context);
+
+       g_main_loop_unref (helper.loop);
+       g_main_context_unref (helper.context);
+
+       return helper.list;
+}
+
+static void
 gs_plugin_loader_get_sources_finish_sync (GsPluginLoader *plugin_loader,
                                          GAsyncResult *res,
                                          GsPluginLoaderHelper *helper)
diff --git a/src/gs-plugin-loader-sync.h b/src/gs-plugin-loader-sync.h
index c600545..b1b88ec 100644
--- a/src/gs-plugin-loader-sync.h
+++ b/src/gs-plugin-loader-sync.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007-2014 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2015 Richard Hughes <richard hughsie com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -41,6 +41,10 @@ GList                *gs_plugin_loader_get_updates           (GsPluginLoader 
*plugin_loader,
                                                         GsPluginRefineFlags flags,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
+GList          *gs_plugin_loader_get_distro_upgrades   (GsPluginLoader *plugin_loader,
+                                                        GsPluginRefineFlags flags,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
 GList          *gs_plugin_loader_get_sources           (GsPluginLoader *plugin_loader,
                                                         GsPluginRefineFlags flags,
                                                         GCancellable   *cancellable,
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 27d9f5d..d6d0424 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007-2014 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2015 Richard Hughes <richard hughsie com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -914,6 +914,89 @@ gs_plugin_loader_get_updates_finish (GsPluginLoader *plugin_loader,
 /******************************************************************************/
 
 /**
+ * gs_plugin_loader_get_distro_upgrades_thread_cb:
+ **/
+static void
+gs_plugin_loader_get_distro_upgrades_thread_cb (GTask *task,
+                                               gpointer object,
+                                               gpointer task_data,
+                                               GCancellable *cancellable)
+{
+       GsPluginLoaderAsyncState *state = (GsPluginLoaderAsyncState *) task_data;
+       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
+       GError *error = NULL;
+
+       state->list = gs_plugin_loader_run_results (plugin_loader,
+                                                   "gs_plugin_add_distro_upgrades",
+                                                   state->flags,
+                                                   cancellable,
+                                                   &error);
+       if (error != NULL) {
+               g_task_return_error (task, error);
+               return;
+       }
+
+       /* filter package list */
+       gs_plugin_list_filter_duplicates (&state->list);
+
+       /* dedupe applications we already know about */
+       gs_plugin_loader_list_dedupe (plugin_loader, state->list);
+
+       /* success */
+       g_task_return_pointer (task, gs_plugin_list_copy (state->list), (GDestroyNotify) gs_plugin_list_free);
+}
+
+/**
+ * gs_plugin_loader_get_distro_upgrades_async:
+ *
+ * This method calls all plugins that implement the gs_plugin_add_distro_upgrades()
+ * function. The plugins can returns #GsApp objects of kind %GS_APP_KIND_DISTRO_UPGRADE.
+ **/
+void
+gs_plugin_loader_get_distro_upgrades_async (GsPluginLoader *plugin_loader,
+                                           GsPluginRefineFlags flags,
+                                           GCancellable *cancellable,
+                                           GAsyncReadyCallback callback,
+                                           gpointer user_data)
+{
+       GsPluginLoaderAsyncState *state;
+       g_autoptr(GTask) task = NULL;
+
+       g_return_if_fail (GS_IS_PLUGIN_LOADER (plugin_loader));
+       g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+       /* save state */
+       state = g_slice_new0 (GsPluginLoaderAsyncState);
+       state->flags = flags;
+
+       /* run in a thread */
+       task = g_task_new (plugin_loader, cancellable, callback, user_data);
+       g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+       g_task_set_return_on_cancel (task, TRUE);
+       g_task_run_in_thread (task, gs_plugin_loader_get_distro_upgrades_thread_cb);
+}
+
+/**
+ * gs_plugin_loader_get_distro_upgrades_finish:
+ *
+ * Return value: (element-type GsApp) (transfer full): A list of applications
+ **/
+GList *
+gs_plugin_loader_get_distro_upgrades_finish (GsPluginLoader *plugin_loader,
+                                            GAsyncResult *res,
+                                            GError **error)
+{
+       g_return_val_if_fail (GS_IS_PLUGIN_LOADER (plugin_loader), NULL);
+       g_return_val_if_fail (G_IS_TASK (res), NULL);
+       g_return_val_if_fail (g_task_is_valid (res, plugin_loader), NULL);
+       g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+       return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+/******************************************************************************/
+
+/**
  * gs_plugin_loader_get_sources_thread_cb:
  **/
 static void
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index b823efd..1181f19 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007-2014 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2015 Richard Hughes <richard hughsie com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -82,6 +82,14 @@ void          gs_plugin_loader_get_updates_async     (GsPluginLoader *plugin_loader,
 GList          *gs_plugin_loader_get_updates_finish    (GsPluginLoader *plugin_loader,
                                                         GAsyncResult   *res,
                                                         GError         **error);
+void            gs_plugin_loader_get_distro_upgrades_async (GsPluginLoader     *plugin_loader,
+                                                        GsPluginRefineFlags flags,
+                                                        GCancellable   *cancellable,
+                                                        GAsyncReadyCallback callback,
+                                                        gpointer        user_data);
+GList          *gs_plugin_loader_get_distro_upgrades_finish (GsPluginLoader    *plugin_loader,
+                                                        GAsyncResult   *res,
+                                                        GError         **error);
 void            gs_plugin_loader_get_sources_async     (GsPluginLoader *plugin_loader,
                                                         GsPluginRefineFlags flags,
                                                         GCancellable   *cancellable,
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index b5b7005..f05732d 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -204,6 +204,10 @@ gboolean    gs_plugin_add_updates                  (GsPlugin       *plugin,
                                                         GList          **list,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
+gboolean        gs_plugin_add_distro_upgrades          (GsPlugin       *plugin,
+                                                        GList          **list,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
 gboolean        gs_plugin_add_sources                  (GsPlugin       *plugin,
                                                         GList          **list,
                                                         GCancellable   *cancellable,
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 7bf49b9..1b9cd3b 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -750,6 +750,55 @@ out:
 }
 
 /**
+ * gs_plugin_add_distro_upgrades:
+ */
+gboolean
+gs_plugin_add_distro_upgrades (GsPlugin *plugin,
+                              GList **list,
+                              GCancellable *cancellable,
+                              GError **error)
+{
+       AsApp *item;
+       GPtrArray *array;
+       gboolean ret = TRUE;
+       guint i;
+
+       /* load XML files */
+       if (g_once_init_enter (&plugin->priv->done_init)) {
+               ret = gs_plugin_startup (plugin, error);
+               g_once_init_leave (&plugin->priv->done_init, TRUE);
+               if (!ret)
+                       return FALSE;
+       }
+
+       /* find any upgrades */
+       g_mutex_lock (&plugin->priv->store_mutex);
+       array = as_store_get_apps (plugin->priv->store);
+       for (i = 0; i < array->len; i++) {
+               g_autoptr(GsApp) app = NULL;
+               item = g_ptr_array_index (array, i);
+
+               // FIXME: AS_ID_KIND_DISTRO_UPGRADE
+               if (as_app_get_id_kind (item) != AS_ID_KIND_UNKNOWN)
+                       continue;
+               if (as_app_get_metadata_item (item, "X-IsUpgrade") == NULL)
+                       continue;
+
+               /* create */
+               app = gs_app_new (as_app_get_id (item));
+               gs_app_set_kind (app, GS_APP_KIND_DISTRO_UPGRADE);
+               gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+               ret = gs_plugin_refine_item (plugin, app, item, error);
+               if (!ret)
+                       goto out;
+               gs_plugin_add_app (list, app);
+       }
+out:
+       g_mutex_unlock (&plugin->priv->store_mutex);
+       return ret;
+}
+
+/**
  * gs_plugin_refine:
  */
 gboolean


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