[gnome-software/1111-version-history-box: 3/4] Add version history info into GsApp




commit e88ee143284f320101e5d8cc59563675f11c28e8
Author: Phaedrus Leeds <mwleeds endlessos org>
Date:   Mon Feb 8 12:21:10 2021 -0800

    Add version history info into GsApp
    
    This will be used by follow-up commits.

 lib/gs-app.c                | 42 +++++++++++++++++++++++++++++++++
 lib/gs-app.h                |  3 +++
 plugins/core/gs-appstream.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 9dc4465f5..6cfeafb81 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -122,6 +122,7 @@ typedef struct
        GsPluginAction           pending_action;
        GsAppPermissions         permissions;
        gboolean                 is_update_downloaded;
+       GPtrArray               *version_history; /* (element-type AsRelease) */
 } GsAppPrivate;
 
 enum {
@@ -4392,6 +4393,7 @@ gs_app_dispose (GObject *object)
        g_clear_pointer (&priv->reviews, g_ptr_array_unref);
        g_clear_pointer (&priv->provides, g_ptr_array_unref);
        g_clear_pointer (&priv->icons, g_ptr_array_unref);
+       g_clear_pointer (&priv->version_history, g_ptr_array_unref);
 
        G_OBJECT_CLASS (gs_app_parent_class)->dispose (object);
 }
@@ -4895,3 +4897,43 @@ gs_app_set_update_permissions (GsApp *app, GsAppPermissions update_permissions)
        g_return_if_fail (GS_IS_APP (app));
        priv->update_permissions = update_permissions;
 }
+
+/**
+ * gs_app_get_version_history:
+ * @app: a #GsApp
+ *
+ * Gets the list of past releases for an application (including the latest
+ * one).
+ *
+ * Returns: (element-type AsRelease) (transfer none): a list
+ *
+ * Since: 40
+ **/
+GPtrArray *
+gs_app_get_version_history (GsApp *app)
+{
+       GsAppPrivate *priv = gs_app_get_instance_private (app);
+       g_return_val_if_fail (GS_IS_APP (app), NULL);
+       return priv->version_history;
+}
+
+/**
+ * gs_app_set_version_history:
+ * @app: a #GsApp
+ * @version_history: (element-type AsRelease): a set of entries representing
+ *   the version history
+ *
+ * Set the list of past releases for an application (including the latest one).
+ *
+ * Since: 40
+ **/
+void
+gs_app_set_version_history (GsApp *app, GPtrArray *version_history)
+{
+       GsAppPrivate *priv = gs_app_get_instance_private (app);
+       g_autoptr(GMutexLocker) locker = NULL;
+       g_return_if_fail (GS_IS_APP (app));
+       g_return_if_fail (version_history != NULL);
+       locker = g_mutex_locker_new (&priv->mutex);
+       _g_set_ptr_array (&priv->version_history, version_history);
+}
diff --git a/lib/gs-app.h b/lib/gs-app.h
index 6018dfd0a..3ef89ec50 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -440,5 +440,8 @@ void                 gs_app_set_permissions         (GsApp          *app,
 GsAppPermissions gs_app_get_update_permissions (GsApp          *app);
 void            gs_app_set_update_permissions  (GsApp          *app,
                                                 GsAppPermissions update_permissions);
+GPtrArray      *gs_app_get_version_history     (GsApp          *app);
+void            gs_app_set_version_history     (GsApp          *app,
+                                                GPtrArray      *version_history);
 
 G_END_DECLS
diff --git a/plugins/core/gs-appstream.c b/plugins/core/gs-appstream.c
index 866013d6a..94b0666f8 100644
--- a/plugins/core/gs-appstream.c
+++ b/plugins/core/gs-appstream.c
@@ -553,6 +553,59 @@ gs_appstream_refine_app_updates (GsPlugin *plugin,
        return TRUE;
 }
 
+static gboolean
+gs_appstream_refine_add_version_history (GsApp *app, XbNode *component, GError **error)
+{
+       g_autoptr(GError) error_local = NULL;
+       g_autoptr(GPtrArray) version_history = NULL; /* (element-type AsRelease) */
+       g_autoptr(GPtrArray) releases = NULL; /* (element-type XbNode) */
+
+       /* get all components */
+       releases = xb_node_query (component, "releases/*", 0, &error_local);
+       if (releases == NULL) {
+               if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+                       return TRUE;
+               if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT))
+                       return TRUE;
+               g_propagate_error (error, g_steal_pointer (&error_local));
+               return FALSE;
+       }
+
+       version_history = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+       for (guint i = 0; i < releases->len; i++) {
+               XbNode *release_node = g_ptr_array_index (releases, i);
+               const gchar *version = xb_node_get_attr (release, "version");
+               g_autoptr(XbNode) description_node = NULL;
+               g_autofree gchar *description = NULL;
+               guint64 timestamp;
+
+               /* ignore releases with no version */
+               if (version == NULL)
+                       continue;
+
+               timestamp = xb_node_query_attr_as_uint (release_node, "timestamp", NULL);
+
+               /* include updates with or without a description */
+               description_node = xb_node_query_first (release_node, "description", NULL);
+               if (description_node != NULL)
+                       description = gs_appstream_format_description (description_node, NULL);
+
+               release = as_release_new ();
+               as_release_set_version (release, version);
+               as_release_set_timestamp (release, timestamp);
+               if (description != NULL)
+                       as_release_set_description (release, description, NULL);
+
+               g_ptr_array_add (version_history, g_steal_pointer (&release));
+       }
+
+       if (version_history->len > 0)
+               gs_app_set_version_history (app, version_history);
+
+       /* success */
+       return TRUE;
+}
+
 /**
  * _gs_utils_locale_has_translations:
  * @locale: A locale, e.g. `en_GB` or `uz_UZ.utf8@cyrillic`
@@ -896,6 +949,10 @@ gs_appstream_refine_app (GsPlugin *plugin,
        if (timestamp != G_MAXUINT64)
                gs_app_set_release_date (app, timestamp);
 
+       /* set the version history */
+       if (!gs_appstream_refine_add_version_history (app, component, error))
+               return FALSE;
+
        /* copy all the metadata */
        if (!gs_appstream_copy_metadata (app, component, error))
                return FALSE;


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