diff -Nru appstream-glib-0.7.10/debian/changelog appstream-glib-0.7.12/debian/changelog --- appstream-glib-0.7.10/debian/changelog 2018-07-30 04:15:34.000000000 +0000 +++ appstream-glib-0.7.12/debian/changelog 2018-08-22 20:52:06.000000000 +0000 @@ -1,3 +1,11 @@ +appstream-glib (0.7.12-1) unstable; urgency=medium + + * New upstream version: 0.7.12 + * Update .symbols file + * Bump standards version: No changes needed + + -- Matthias Klumpp Wed, 22 Aug 2018 22:52:06 +0200 + appstream-glib (0.7.10-1) unstable; urgency=medium * New upstream version: 0.7.10 diff -Nru appstream-glib-0.7.10/debian/control appstream-glib-0.7.12/debian/control --- appstream-glib-0.7.10/debian/control 2018-07-30 04:14:19.000000000 +0000 +++ appstream-glib-0.7.12/debian/control 2018-08-22 20:52:06.000000000 +0000 @@ -21,7 +21,7 @@ meson (>= 0.40), uuid-dev, xmlto -Standards-Version: 4.1.5 +Standards-Version: 4.2.0 Homepage: https://github.com/hughsie/appstream-glib Vcs-Git: https://salsa.debian.org/pkgutopia-team/appstream-glib.git Vcs-Browser: https://salsa.debian.org/pkgutopia-team/appstream-glib diff -Nru appstream-glib-0.7.10/debian/libappstream-glib8.symbols appstream-glib-0.7.12/debian/libappstream-glib8.symbols --- appstream-glib-0.7.10/debian/libappstream-glib8.symbols 2018-07-30 04:10:16.000000000 +0000 +++ appstream-glib-0.7.12/debian/libappstream-glib8.symbols 2018-08-22 20:52:06.000000000 +0000 @@ -581,7 +581,11 @@ as_store_get_type@Base 0.5.1 as_store_get_watch_flags@Base 0.5.1 as_store_load@Base 0.5.1 + as_store_load_async@Base 0.7.12 + as_store_load_finish@Base 0.7.12 as_store_load_path@Base 0.5.1 + as_store_load_path_async@Base 0.7.12 + as_store_load_path_finish@Base 0.7.12 as_store_load_search_cache@Base 0.6.5 as_store_new@Base 0.5.1 as_store_remove_all@Base 0.5.1 diff -Nru appstream-glib-0.7.10/libappstream-glib/as-agreement-section.c appstream-glib-0.7.12/libappstream-glib/as-agreement-section.c --- appstream-glib-0.7.10/libappstream-glib/as-agreement-section.c 2018-07-11 18:21:42.000000000 +0000 +++ appstream-glib-0.7.12/libappstream-glib/as-agreement-section.c 2018-08-13 10:48:23.000000000 +0000 @@ -36,11 +36,12 @@ #include "as-agreement-section-private.h" #include "as-ref-string.h" #include "as-tag.h" +#include "as-utils-private.h" typedef struct { AsRefString *kind; - AsRefString *name; - AsRefString *desc; + GHashTable *names; /* of AsRefString:AsRefString */ + GHashTable *descriptions; /* of AsRefString:AsRefString */ } AsAgreementSectionPrivate; G_DEFINE_TYPE_WITH_PRIVATE (AsAgreementSection, as_agreement_section, G_TYPE_OBJECT) @@ -55,10 +56,8 @@ if (priv->kind != NULL) as_ref_string_unref (priv->kind); - if (priv->name != NULL) - as_ref_string_unref (priv->name); - if (priv->desc != NULL) - as_ref_string_unref (priv->desc); + g_hash_table_unref (priv->names); + g_hash_table_unref (priv->descriptions); G_OBJECT_CLASS (as_agreement_section_parent_class)->finalize (object); } @@ -66,7 +65,13 @@ static void as_agreement_section_init (AsAgreementSection *agreement_section) { -// AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section); + AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section); + priv->names = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); + priv->descriptions = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) as_ref_string_unref, + (GDestroyNotify) as_ref_string_unref); } static void @@ -127,7 +132,7 @@ { AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section); g_return_val_if_fail (AS_IS_AGREEMENT_SECTION (agreement_section), NULL); - return priv->name; + return as_hash_lookup_by_locale (priv->names, locale); } /** @@ -145,8 +150,18 @@ const gchar *locale, const gchar *name) { AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section); + g_autoptr(AsRefString) locale_fixed = NULL; + g_return_if_fail (AS_IS_AGREEMENT_SECTION (agreement_section)); - as_ref_string_assign_safe (&priv->name, name); + g_return_if_fail (name != NULL); + + /* get fixed locale */ + locale_fixed = as_node_fix_locale (locale); + if (locale_fixed == NULL) + return; + g_hash_table_insert (priv->names, + as_ref_string_ref (locale_fixed), + as_ref_string_new (name)); } /** @@ -166,7 +181,7 @@ { AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section); g_return_val_if_fail (AS_IS_AGREEMENT_SECTION (agreement_section), NULL); - return priv->desc; + return as_hash_lookup_by_locale (priv->descriptions, locale); } /** @@ -175,7 +190,7 @@ * @locale: (nullable): the locale. e.g. "en_GB" * @desc: the rating desc, e.g. "GDPR" * - * Sets the agreement section desc. + * Sets the agreement section description. * * Since: 0.7.8 **/ @@ -184,8 +199,18 @@ const gchar *locale, const gchar *desc) { AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section); + g_autoptr(AsRefString) locale_fixed = NULL; + g_return_if_fail (AS_IS_AGREEMENT_SECTION (agreement_section)); - as_ref_string_assign_safe (&priv->desc, desc); + g_return_if_fail (desc != NULL); + + /* get fixed locale */ + locale_fixed = as_node_fix_locale (locale); + if (locale_fixed == NULL) + return; + g_hash_table_insert (priv->descriptions, + as_ref_string_ref (locale_fixed), + as_ref_string_new (desc)); } /** @@ -212,14 +237,28 @@ NULL); if (priv->kind != NULL) as_node_add_attribute (n, "type", priv->kind); - if (priv->desc != NULL) { - as_node_insert (n, "description", priv->desc, - AS_NODE_INSERT_FLAG_PRE_ESCAPED, NULL); - } + as_node_insert_localized (n, "name", + priv->names, + AS_NODE_INSERT_FLAG_DEDUPE_LANG); + as_node_insert_localized (n, "description", + priv->descriptions, + AS_NODE_INSERT_FLAG_PRE_ESCAPED | + AS_NODE_INSERT_FLAG_DEDUPE_LANG); return n; } +static void +as_agreement_section_copy_dict (GHashTable *dest, GHashTable *src) +{ + g_autoptr(GList) keys = g_hash_table_get_keys (src); + for (GList *l = keys; l != NULL; l = l->next) { + AsRefString *key = l->data; + AsRefString *value = g_hash_table_lookup (src, key); + g_hash_table_insert (dest, as_ref_string_ref (key), as_ref_string_ref (value)); + } +} + /** * as_agreement_section_node_parse: * @agreement_section: a #AsAgreementSection instance. @@ -234,31 +273,39 @@ * Since: 0.7.8 **/ gboolean -as_agreement_section_node_parse (AsAgreementSection *agreement_section, GNode *node, +as_agreement_section_node_parse (AsAgreementSection *agreement_section, GNode *n, AsNodeContext *ctx, GError **error) { + AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section); const gchar *tmp; + AsRefString *str; /* get ID */ - tmp = as_node_get_attribute (node, "type"); + tmp = as_node_get_attribute (n, "type"); if (tmp != NULL) as_agreement_section_set_kind (agreement_section, tmp); /* get sections and details */ - for (GNode *c = node->children; c != NULL; c = c->next) { + for (GNode *c = n->children; c != NULL; c = c->next) { if (as_node_get_tag (c) == AS_TAG_NAME) { - as_agreement_section_set_name (agreement_section, - as_node_get_attribute (c, "xml:lang"), - as_node_get_data (c)); + g_autoptr(AsRefString) xml_lang = NULL; + xml_lang = as_node_fix_locale_full (n, as_node_get_attribute (n, "xml:lang")); + if (xml_lang == NULL) + break; + str = as_node_get_data_as_refstr (n); + if (str != NULL) { + g_hash_table_insert (priv->names, + as_ref_string_ref (xml_lang), + as_ref_string_ref (str)); + } continue; } if (as_node_get_tag (c) == AS_TAG_DESCRIPTION) { - g_autoptr(GString) xml = NULL; - xml = as_node_to_xml (c->children, - AS_NODE_TO_XML_FLAG_INCLUDE_SIBLINGS); - as_agreement_section_set_description (agreement_section, - as_node_get_attribute (c, "xml:lang"), - xml->str); + g_autoptr(GHashTable) desc = NULL; + desc = as_node_get_localized_unwrap (c, error); + if (desc == NULL) + return FALSE; + as_agreement_section_copy_dict (priv->descriptions, desc); continue; } } diff -Nru appstream-glib-0.7.10/libappstream-glib/as-app.h appstream-glib-0.7.12/libappstream-glib/as-app.h --- appstream-glib-0.7.10/libappstream-glib/as-app.h 2018-07-11 18:21:42.000000000 +0000 +++ appstream-glib-0.7.12/libappstream-glib/as-app.h 2018-08-13 10:48:23.000000000 +0000 @@ -352,6 +352,7 @@ * @AS_APP_QUIRK_NEEDS_USER_ACTION: The component requires some kind of user action * @AS_APP_QUIRK_IS_PROXY: Is a proxy app that operates on other applications * @AS_APP_QUIRK_REMOVABLE_HARDWARE: The device is unusable whilst the action is performed + * @AS_APP_QUIRK_DEVELOPER_VERIFIED: The app developer has been verified * * The component attributes. **/ @@ -368,6 +369,7 @@ AS_APP_QUIRK_NEEDS_USER_ACTION = 1 << 8, /* Since: 0.6.2 */ AS_APP_QUIRK_IS_PROXY = 1 << 9, /* Since: 0.6.6 */ AS_APP_QUIRK_REMOVABLE_HARDWARE = 1 << 10, /* Since: 0.6.6 */ + AS_APP_QUIRK_DEVELOPER_VERIFIED = 1 << 11, /* Since: 0.7.11 */ /*< private >*/ AS_APP_QUIRK_LAST } AsAppQuirk; diff -Nru appstream-glib-0.7.10/libappstream-glib/as-node.c appstream-glib-0.7.12/libappstream-glib/as-node.c --- appstream-glib-0.7.10/libappstream-glib/as-node.c 2018-07-11 18:21:42.000000000 +0000 +++ appstream-glib-0.7.12/libappstream-glib/as-node.c 2018-08-13 10:48:23.000000000 +0000 @@ -343,6 +343,8 @@ as_utils_string_replace (value_safe, "&", "&"); as_utils_string_replace (value_safe, "<", "<"); as_utils_string_replace (value_safe, ">", ">"); + as_utils_string_replace (value_safe, "\"", """); + as_utils_string_replace (value_safe, "'", "'"); g_string_append_printf (str, " %s=\"%s\"", attr->key, value_safe->str); } diff -Nru appstream-glib-0.7.10/libappstream-glib/as-store.c appstream-glib-0.7.12/libappstream-glib/as-store.c --- appstream-glib-0.7.10/libappstream-glib/as-store.c 2018-07-11 18:21:42.000000000 +0000 +++ appstream-glib-0.7.12/libappstream-glib/as-store.c 2018-08-13 10:48:23.000000000 +0000 @@ -2973,6 +2973,70 @@ path, cancellable, error); } +static void +store_load_path_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + AsStore *store = source_object; + const char *path = task_data; + GError *error = NULL; + gboolean success; + + success = as_store_load_path (store, path, cancellable, &error); + if (error) + g_task_return_error (task, error); + else + g_task_return_boolean (task, success); +} + + +/** + * as_store_load_path_async: + * @store: a #AsStore instance. + * @path: A path to load + * @cancellable: a #GCancellable. + * @callback: A #GAsyncReadyCallback + * @user_data: Data to pass to @callback + * + * Asynchronously loads the store from a specific path. + * + * Since: 0.7.11 + **/ +void +as_store_load_path_async (AsStore *store, const gchar *path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task = g_task_new (store, cancellable, callback, user_data); + g_task_set_task_data (task, g_strdup (path), g_free); + g_task_run_in_thread (task, store_load_path_thread); + g_object_unref (task); +} + +/** + * as_store_load_path_finish: + * @store: a #AsStore instance. + * @result: A #GAsyncResult + * @error: A #GError or %NULL. + * + * Retrieve the result of as_store_load_path_async(). + * + * Returns: %TRUE for success + * + * Since: 0.7.11 + **/ +gboolean +as_store_load_path_finish (AsStore *store, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, store), FALSE); + return g_task_propagate_boolean (G_TASK (result), error); +} + static gboolean as_store_search_installed (AsStore *store, guint32 flags, @@ -3252,6 +3316,70 @@ return TRUE; } +static void +store_load_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + AsStore *store = AS_STORE (source_object); + AsStoreLoadFlags flags = GPOINTER_TO_INT (task_data); + GError *error = NULL; + gboolean success; + + success = as_store_load (store, flags, cancellable, &error); + if (error != NULL) + g_task_return_error (task, error); + else + g_task_return_boolean (task, success); +} + +/** + * as_store_load_async: + * @store: a #AsStore instance. + * @flags: #AsStoreLoadFlags, e.g. %AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM + * @cancellable: a #GCancellable. + * @callback: A #GAsyncReadyCallback + * @user_data: Data to pass to @callback + * + * Asynchronously loads the store from the default locations. + * + * Since: 0.7.11 + **/ +void +as_store_load_async (AsStore *store, + AsStoreLoadFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task = g_task_new (store, cancellable, callback, user_data); + g_task_set_task_data (task, GINT_TO_POINTER (flags), NULL); + g_task_run_in_thread (task, store_load_thread); + g_object_unref (task); +} + +/** + * as_store_load_finish: + * @store: a #AsStore instance. + * @result: A #GAsyncResult + * @error: A #GError or %NULL. + * + * Retrieve the result of as_store_load_async(). + * + * Returns: %TRUE for success + * + * Since: 0.7.11 + **/ +gboolean +as_store_load_finish (AsStore *store, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, store), FALSE); + return g_task_propagate_boolean (G_TASK (result), error); +} + G_GNUC_PRINTF (3, 4) static void as_store_validate_add (GPtrArray *problems, AsProblemKind kind, const gchar *fmt, ...) { diff -Nru appstream-glib-0.7.10/libappstream-glib/as-store.h appstream-glib-0.7.12/libappstream-glib/as-store.h --- appstream-glib-0.7.10/libappstream-glib/as-store.h 2018-07-11 18:21:42.000000000 +0000 +++ appstream-glib-0.7.12/libappstream-glib/as-store.h 2018-08-13 10:48:23.000000000 +0000 @@ -176,14 +176,33 @@ const gchar *data, const gchar *icon_root, GError **error); + gboolean as_store_load (AsStore *store, guint32 flags, GCancellable *cancellable, GError **error); +void as_store_load_async (AsStore *store, + AsStoreLoadFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean as_store_load_finish (AsStore *store, + GAsyncResult *result, + GError **error); + gboolean as_store_load_path (AsStore *store, const gchar *path, GCancellable *cancellable, GError **error); +void as_store_load_path_async (AsStore *store, + const gchar *path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean as_store_load_path_finish (AsStore *store, + GAsyncResult *result, + GError **error); + void as_store_load_search_cache (AsStore *store); void as_store_set_search_match (AsStore *store, guint16 search_match); diff -Nru appstream-glib-0.7.10/meson.build appstream-glib-0.7.12/meson.build --- appstream-glib-0.7.10/meson.build 2018-07-11 18:21:42.000000000 +0000 +++ appstream-glib-0.7.12/meson.build 2018-08-13 10:48:23.000000000 +0000 @@ -1,5 +1,5 @@ project('appstream-glib', 'c', - version : '0.7.10', + version : '0.7.12', license : 'LGPL-2.1+', default_options : ['warning_level=1', 'c_std=c99'], meson_version : '>=0.37.0' diff -Nru appstream-glib-0.7.10/NEWS appstream-glib-0.7.12/NEWS --- appstream-glib-0.7.10/NEWS 2018-07-11 18:21:42.000000000 +0000 +++ appstream-glib-0.7.12/NEWS 2018-08-13 10:48:23.000000000 +0000 @@ -1,3 +1,21 @@ +Version 0.7.12 +~~~~~~~~~~~~~~ +Released: 2018-08-13 + +Bugfixes: + - Support localised text in agreement sections (Richard Hughes) + +Version 0.7.11 +~~~~~~~~~~~~~~ +Released: 2018-08-09 + +New Features: + - Add AS_APP_QUIRK_DEVELOPER_VERIFIED (Robert Ancell) + - Provide async variants of store load functions (Florian Müllner) + +Bugfixes: + - Escape quotes in attributes (Robin Richtsfeld) + Version 0.7.10 ~~~~~~~~~~~~~~ Released: 2018-07-11 diff -Nru appstream-glib-0.7.10/RELEASE appstream-glib-0.7.12/RELEASE --- appstream-glib-0.7.10/RELEASE 2018-07-11 18:21:42.000000000 +0000 +++ appstream-glib-0.7.12/RELEASE 2018-08-13 10:48:23.000000000 +0000 @@ -2,10 +2,10 @@ 1. Write NEWS entries for appstream_glib in the same format as usual. -git shortlog appstream_glib_0_7_9.. | grep -i -v trivial | grep -v Merge > NEWS.new +git shortlog appstream_glib_0_7_11.. | grep -i -v trivial | grep -v Merge > NEWS.new -------------------------------------------------------------------------------- -Version 0.7.10 +Version 0.7.12 ~~~~~~~~~~~~~~ Released: 2018-xx-xx @@ -30,8 +30,8 @@ 4. Commit changes in git: -git commit -a -m "Release version 0.7.10" -git tag -s -f -m "Release 0.7.10" appstream_glib_0_7_10 +git commit -a -m "Release version 0.7.12" +git tag -s -f -m "Release 0.7.12" appstream_glib_0_7_12 git push --tags git push