From 57fc51353f939fa23538066edb4b0ad495e7cbee Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Tue, 22 Jan 2019 09:28:26 +0000 Subject: Add support for per-release URLs --- libappstream-glib/as-enums.c | 4 +++ libappstream-glib/as-enums.h | 2 ++ libappstream-glib/as-release.c | 74 +++++++++++++++++++++++++++++++++++++++- libappstream-glib/as-release.h | 5 +++ libappstream-glib/as-self-test.c | 8 +++++ 5 files changed, 92 insertions(+), 1 deletion(-) diff --git a/libappstream-glib/as-enums.c b/libappstream-glib/as-enums.c index 4b7c47b..a9ec19e 100644 --- a/libappstream-glib/as-enums.c +++ b/libappstream-glib/as-enums.c @@ -95,6 +95,8 @@ as_url_kind_to_string (AsUrlKind url_kind) return as_ref_string_new_static ("missing"); if (url_kind == AS_URL_KIND_TRANSLATE) return as_ref_string_new_static ("translate"); + if (url_kind == AS_URL_KIND_DETAILS) + return as_ref_string_new_static ("details"); return as_ref_string_new_static ("unknown"); } @@ -125,6 +127,8 @@ as_url_kind_from_string (const gchar *url_kind) return AS_URL_KIND_MISSING; if (g_strcmp0 (url_kind, "translate") == 0) return AS_URL_KIND_TRANSLATE; + if (g_strcmp0 (url_kind, "details") == 0) + return AS_URL_KIND_DETAILS; return AS_URL_KIND_UNKNOWN; } diff --git a/libappstream-glib/as-enums.h b/libappstream-glib/as-enums.h index 951fe51..a760b67 100644 --- a/libappstream-glib/as-enums.h +++ b/libappstream-glib/as-enums.h @@ -72,6 +72,7 @@ typedef enum { * @AS_URL_KIND_HELP: Application help manual * @AS_URL_KIND_MISSING: The package is available, but missing * @AS_URL_KIND_TRANSLATE: Application translation page + * @AS_URL_KIND_DETAILS: Release details * * The URL type. **/ @@ -84,6 +85,7 @@ typedef enum { AS_URL_KIND_HELP, /* Since: 0.1.5 */ AS_URL_KIND_MISSING, /* Since: 0.2.2 */ AS_URL_KIND_TRANSLATE, /* Since: 0.6.1 */ + AS_URL_KIND_DETAILS, /* Since: 0.7.15 */ /*< private >*/ AS_URL_KIND_LAST } AsUrlKind; diff --git a/libappstream-glib/as-release.c b/libappstream-glib/as-release.c index e4d58c6..bb1537f 100644 --- a/libappstream-glib/as-release.c +++ b/libappstream-glib/as-release.c @@ -33,7 +33,7 @@ * Releases can be automatically generated by parsing upstream ChangeLogs or * .spec files, or can be populated using AppData files. * - * See also: #AsApp + * See also: #AsRelease */ #include "config.h" @@ -57,6 +57,7 @@ typedef struct AsRefString *version; GHashTable *blobs; /* of AsRefString:GBytes */ GHashTable *descriptions; + GHashTable *urls; /* of AsRefString:AsRefString */ guint64 timestamp; guint64 install_duration; GPtrArray *locations; /* of AsRefString, lazy */ @@ -74,6 +75,7 @@ as_release_finalize (GObject *object) AsReleasePrivate *priv = GET_PRIVATE (release); g_free (priv->sizes); + g_hash_table_unref (priv->urls); if (priv->version != NULL) as_ref_string_unref (priv->version); if (priv->blobs != NULL) @@ -95,6 +97,9 @@ as_release_init (AsRelease *release) priv->urgency = AS_URGENCY_KIND_UNKNOWN; priv->kind = AS_RELEASE_KIND_UNKNOWN; priv->state = AS_RELEASE_STATE_UNKNOWN; + priv->urls = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); } static void @@ -769,6 +774,50 @@ as_release_set_description (AsRelease *release, as_ref_string_new (description)); } +/** + * as_release_get_url: + * @release: a #AsRelease instance. + * @url_kind: the URL kind, e.g. %AS_URL_KIND_HOMEPAGE. + * + * Gets a URL. + * + * Returns: string, or %NULL if unset + * + * Since: 0.7.15 + **/ +const gchar * +as_release_get_url (AsRelease *release, AsUrlKind url_kind) +{ + AsReleasePrivate *priv = GET_PRIVATE (release); + return g_hash_table_lookup (priv->urls, + as_url_kind_to_string (url_kind)); +} + +/** + * as_release_set_url: + * @release: a #AsRelease instance. + * @url_kind: the URL kind, e.g. %AS_URL_KIND_DETAILS + * @url: the full URL. + * + * Adds some URL data to the application. + * + * Since: 0.7.15 + **/ +void +as_release_set_url (AsRelease *release, + AsUrlKind url_kind, + const gchar *url) +{ + AsReleasePrivate *priv = GET_PRIVATE (release); + if (url == NULL) { + g_hash_table_remove (priv->urls, as_url_kind_to_string (url_kind)); + } else { + g_hash_table_insert (priv->urls, + (AsRefString *) as_url_kind_to_string (url_kind), + as_ref_string_new (url)); + } +} + /** * as_release_node_insert: (skip) * @release: a #AsRelease instance. @@ -829,6 +878,8 @@ as_release_node_insert (AsRelease *release, GNode *parent, AsNodeContext *ctx) checksum = g_ptr_array_index (priv->checksums, i); as_checksum_node_insert (checksum, n, ctx); } + if (priv->urls != NULL) + as_node_insert_hash (n, "url", "type", priv->urls, 0); if (priv->descriptions != NULL) { as_node_insert_localized (n, "description", priv->descriptions, AS_NODE_INSERT_FLAG_PRE_ESCAPED | @@ -897,6 +948,16 @@ as_release_node_parse (AsRelease *release, GNode *node, if (tmp != NULL) priv->install_duration = g_ascii_strtoull (tmp, NULL, 10); + /* */ + for (n = node->children; n != NULL; n = n->next) { + if (as_node_get_tag (n) != AS_TAG_URL) + continue; + tmp = as_node_get_attribute (n, "type"); + as_release_set_url (release, + as_url_kind_from_string (tmp), + as_node_get_data (n)); + } + /* get optional locations */ if (priv->locations != NULL) g_ptr_array_set_size (priv->locations, 0); @@ -1019,6 +1080,17 @@ as_release_node_parse_dep11 (AsRelease *release, GNode *node, } continue; } + if (g_strcmp0 (tmp, "url") == 0) { + for (c = n->children; c != NULL; c = c->next) { + if (g_strcmp0 (as_yaml_node_get_key (c), "details") == 0) { + as_release_set_url (release, + AS_URL_KIND_DETAILS, + as_yaml_node_get_value (c)); + continue; + } + } + continue; + } } return TRUE; } diff --git a/libappstream-glib/as-release.h b/libappstream-glib/as-release.h index 06725de..5455ea6 100644 --- a/libappstream-glib/as-release.h +++ b/libappstream-glib/as-release.h @@ -113,6 +113,8 @@ AsReleaseKind as_release_get_kind (AsRelease *release); AsReleaseState as_release_get_state (AsRelease *release); guint64 as_release_get_size (AsRelease *release, AsSizeKind kind); +const gchar *as_release_get_url (AsRelease *release, + AsUrlKind url_kind); /* setters */ void as_release_set_version (AsRelease *release, @@ -140,6 +142,9 @@ void as_release_set_state (AsRelease *release, void as_release_set_size (AsRelease *release, AsSizeKind kind, guint64 size); +void as_release_set_url (AsRelease *release, + AsUrlKind url_kind, + const gchar *url); G_END_DECLS diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c index 0e77088..f151d97 100644 --- a/libappstream-glib/as-self-test.c +++ b/libappstream-glib/as-self-test.c @@ -615,6 +615,7 @@ as_test_launchable_func (void) static void as_test_release_appstream_func (void) { + const gchar *url; AsChecksum *csum; GError *error = NULL; AsNode *n; @@ -628,6 +629,7 @@ as_test_release_appstream_func (void) "http://baz.com/bar.cab\n" "12345\n" "deadbeef\n" + "http://foo.bar/\n" "

This is a new release

  • Point
\n" "

Oprogramowanie

\n" "123456\n" @@ -683,6 +685,12 @@ as_test_release_appstream_func (void) sz = as_release_get_size (release, AS_SIZE_KIND_DOWNLOAD); g_assert_cmpuint (sz, ==, 654321); + /* URL */ + url = as_release_get_url (release, AS_URL_KIND_DETAILS); + g_assert_cmpstr (url, ==, "http://foo.bar/"); + url = as_release_get_url (release, AS_URL_KIND_HOMEPAGE); + g_assert_null (url); + /* back to node */ root = as_node_new (); as_node_context_set_version (ctx, 1.0); -- cgit v1.2.1