Hello community, here is the log from the commit of package appstream-glib for openSUSE:Factory checked in at 2015-03-03 11:10:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/appstream-glib (Old) and /work/SRC/openSUSE:Factory/.appstream-glib.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "appstream-glib" Changes: -------- --- /work/SRC/openSUSE:Factory/appstream-glib/appstream-glib.changes 2015-01-08 23:05:46.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.appstream-glib.new/appstream-glib.changes 2015-03-03 11:10:21.000000000 +0100 @@ -1,0 +2,18 @@ +Wed Jan 28 10:32:30 UTC 2015 - [email protected] + +- Update to version 0.3.4: + + Allow specifying --packages-dir multiple times + + Show the offending text when validation fails + + Do not blacklist applications with broken AppData files + + Remove the composite plugin + + Add as_app_get_search_tokens() + + Add show-search-tokens subcommand to appstream-util + + Do not store short search tokens like 'a' and 'or' + + trivial: Do not store search tokens with markup + + Blacklist the 40 most common search tokens + + Check if the search entries are valid before searching + + Accept <metadata_licence> as a fallback for <metadata_license> + + trivial: Fix 'make distcheck' now the composite plugin has gone + + Release version 0.3.4 + +------------------------------------------------------------------- Old: ---- appstream-glib-0.3.1.git.20150103.a7941d7.tar.xz New: ---- appstream-glib-0.3.4.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ appstream-glib.spec ++++++ --- /var/tmp/diff_new_pack.aGN3Iv/_old 2015-03-03 11:10:21.000000000 +0100 +++ /var/tmp/diff_new_pack.aGN3Iv/_new 2015-03-03 11:10:21.000000000 +0100 @@ -20,7 +20,7 @@ %define _build_from_vcs 1 Name: appstream-glib -Version: 0.3.1.git.20150103.a7941d7 +Version: 0.3.4 Release: 0 Summary: AppStream Abstraction Library License: LGPL-2.1+ ++++++ _service ++++++ --- /var/tmp/diff_new_pack.aGN3Iv/_old 2015-03-03 11:10:21.000000000 +0100 +++ /var/tmp/diff_new_pack.aGN3Iv/_new 2015-03-03 11:10:21.000000000 +0100 @@ -2,8 +2,9 @@ <service name="tar_scm" mode="disabled"> <param name="url">https://github.com/hughsie/appstream-glib.git</param> <param name="scm">git</param> - <param name="versionformat">0.3.1.git.%cd.%h</param> + <param name="versionformat">0.3.4</param> <param name="changesgenerate">enable</param> + <param name="revision">refs/tags/appstream_glib_0_3_4</param> </service> <service name="recompress" mode="disabled"> <param name="file">*.tar</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.aGN3Iv/_old 2015-03-03 11:10:21.000000000 +0100 +++ /var/tmp/diff_new_pack.aGN3Iv/_new 2015-03-03 11:10:21.000000000 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/hughsie/appstream-glib.git</param> - <param name="changesrevision">a7941d71cc5835853ed952d2f12360e11928afb9</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">b0009f1670ce73796f5847018b4e2215a403b673</param></service></servicedata> \ No newline at end of file ++++++ appstream-glib-0.3.1.git.20150103.a7941d7.tar.xz -> appstream-glib-0.3.4.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/NEWS new/appstream-glib-0.3.4/NEWS --- old/appstream-glib-0.3.1.git.20150103.a7941d7/NEWS 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/NEWS 2015-01-28 11:32:30.000000000 +0100 @@ -1,3 +1,36 @@ +Version 0.3.4 +~~~~~~~~~~~~~ +Released: 2015-01-17 + +New Features: + - Add an --origin option to appstream-builder (Richard Hughes) + - Add as_app_get_search_tokens() (Richard Hughes) + - Add show-search-tokens subcommand to appstream-util (Richard Hughes) + - Add the matrix-html subcommand to appstream-util (Richard Hughes) + - Add the VCS information to the AppStream metadata (Richard Hughes) + +Bugfixes: + - Add more applications to the blacklist (Richard Hughes, Igor Gnatenko) + - Allow specifying --packages-dir multiple times (Richard Hughes) + - Alow setting the cachedir different from the outputdir (Richard Hughes) + - Always return errors from the correct domain when parsing broken AppData files (Richard Hughes) + - Assume <image>foo</image> is a source image kind for AppData files (Richard Hughes) + - Assume that stock icons are available in HiDPI sizes (Richard Hughes) + - Blacklist the 40 most common search tokens (Richard Hughes) + - Check if the search entries are valid before searching (Richard Hughes) + - Check screenshots are a reasonable size (Richard Hughes) + - Do not absorb metainfo files for package deps (Richard Hughes) + - Do not blacklist applications with broken AppData files (Richard Hughes) + - Do not veto applications with NoDisplay=false (Richard Hughes) + - Fall back to the dumb tokenizer for keywords with special chars (Richard Hughes) + - Handle other-endian MO files (Andreas Schwab) + - Move as_utils_install_filename() into libappstream-glib (Richard Hughes) + - Output the full filename for local icons (Richard Hughes) + - Preserve the URL for remote icon types and filename for local icons (Richard Hughes) + - Require AppData for Xvfb-using applications (Richard Hughes) + - Set an error if an XML file contains font markup (Richard Hughes) + - Show the offending text when validation fails (Richard Hughes) + Version 0.3.3 ~~~~~~~~~~~~~ Released: 2014-11-24 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/RELEASE new/appstream-glib-0.3.4/RELEASE --- old/appstream-glib-0.3.1.git.20150103.a7941d7/RELEASE 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/RELEASE 2015-01-28 11:32:30.000000000 +0100 @@ -7,7 +7,7 @@ -------------------------------------------------------------------------------- Version 0.3.4 ~~~~~~~~~~~~~ -Released: 2014-xx-xx +Released: 2015-xx-xx Notes: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/client/as-builder.c new/appstream-glib-0.3.4/client/as-builder.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/client/as-builder.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/client/as-builder.c 2015-01-28 11:32:30.000000000 +0100 @@ -86,12 +86,12 @@ _cleanup_free_ gchar *old_metadata = NULL; _cleanup_free_ gchar *origin = NULL; _cleanup_free_ gchar *output_dir = NULL; - _cleanup_free_ gchar *packages_dir = NULL; _cleanup_free_ gchar *screenshot_dir = NULL; _cleanup_free_ gchar *screenshot_uri = NULL; _cleanup_free_ gchar *temp_dir = NULL; _cleanup_free_ gchar **veto_ignore = NULL; _cleanup_ptrarray_unref_ GPtrArray *packages = NULL; + _cleanup_strv_free_ gchar **packages_dirs = NULL; _cleanup_timer_destroy_ GTimer *timer = NULL; const GOptionEntry options[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, @@ -115,7 +115,7 @@ { "screenshot-dir", '\0', 0, G_OPTION_ARG_FILENAME, &screenshot_dir, /* TRANSLATORS: command line option */ _("Set the screenshots directory"), "DIR" }, - { "packages-dir", '\0', 0, G_OPTION_ARG_FILENAME, &packages_dir, + { "packages-dir", '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &packages_dirs, /* TRANSLATORS: command line option */ _("Set the packages directory"), "DIR" }, { "temp-dir", '\0', 0, G_OPTION_ARG_FILENAME, &temp_dir, @@ -190,8 +190,8 @@ /* set defaults */ if (api_version < 0.01) api_version = 0.41; - if (packages_dir == NULL) - packages_dir = g_strdup ("./packages"); + if (packages_dirs == NULL) + packages_dirs = g_strsplit ("./packages", "@", 1); if (temp_dir == NULL) temp_dir = g_strdup ("./tmp"); if (log_dir == NULL) @@ -246,10 +246,12 @@ /* scan each package */ packages = g_ptr_array_new_with_free_func (g_free); if (argc == 1) { - if (!as_builder_search_path (packages, packages_dir, &error)) { - /* TRANSLATORS: error message */ - g_warning ("%s: %s", _("Failed to open packages"), error->message); - goto out; + for (i = 0; packages_dirs[i] != NULL; i++) { + if (!as_builder_search_path (packages, packages_dirs[i], &error)) { + /* TRANSLATORS: error message */ + g_warning ("%s: %s", _("Failed to open packages"), error->message); + goto out; + } } } else { for (i = 1; i < (guint) argc; i++) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/client/as-util.c new/appstream-glib-0.3.4/client/as-util.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/client/as-util.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/client/as-util.c 2015-01-28 11:32:30.000000000 +0100 @@ -827,6 +827,76 @@ } /** + * as_util_search_token_sort_cb: + **/ +static gint +as_util_search_token_sort_cb (gconstpointer a, gconstpointer b, gpointer user_data) +{ + guint *cnt_a; + guint *cnt_b; + GHashTable *dict = (GHashTable *) user_data; + cnt_a = g_hash_table_lookup (dict, (const gchar *) a); + cnt_b = g_hash_table_lookup (dict, (const gchar *) b); + if (*cnt_a < *cnt_b) + return 1; + if (*cnt_a > *cnt_b) + return -1; + return 0; +} + +/** + * as_util_show_search_tokens: + **/ +static gboolean +as_util_show_search_tokens (AsUtilPrivate *priv, gchar **values, GError **error) +{ + GPtrArray *apps; + GList *l; + guint i; + guint j; + const gchar *tmp; + guint *cnt; + _cleanup_hashtable_unref_ GHashTable *dict = NULL; + _cleanup_object_unref_ AsStore *store = NULL; + _cleanup_list_free_ GList *keys = NULL; + + /* load system database */ + store = as_store_new (); + if (!as_store_load (store, AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM, NULL, error)) + return FALSE; + dict = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + apps = as_store_get_apps (store); + for (i = 0; i < apps->len; i++) { + AsApp *app; + _cleanup_ptrarray_unref_ GPtrArray *tokens = NULL; + app = g_ptr_array_index (apps, i); + tokens = as_app_get_search_tokens (app); + for (j = 0; j < tokens->len; j++) { + tmp = g_ptr_array_index (tokens, j); + cnt = g_hash_table_lookup (dict, tmp); + if (cnt == NULL) { + cnt = g_new0 (guint, 1); + g_hash_table_insert (dict, + g_strdup (tmp), + cnt); + } + (*cnt)++; + } + } + + /* display the keywords sorted */ + keys = g_hash_table_get_keys (dict); + keys = g_list_sort_with_data (keys, as_util_search_token_sort_cb, dict); + for (l = keys; l != NULL; l = l->next) { + tmp = l->data; + cnt = g_hash_table_lookup (dict, tmp); + g_print ("%s [%i]\n", tmp, *cnt); + } + + return TRUE; +} + +/** * as_util_install: **/ static gboolean @@ -2476,6 +2546,12 @@ _("Search for AppStream applications"), as_util_search); as_util_add (priv->cmd_array, + "show-search-tokens", + NULL, + /* TRANSLATORS: command description */ + _("Display application search tokens"), + as_util_show_search_tokens); + as_util_add (priv->cmd_array, "install", NULL, /* TRANSLATORS: command description */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/asb-plugin-loader.c new/appstream-glib-0.3.4/libappstream-builder/asb-plugin-loader.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/asb-plugin-loader.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-builder/asb-plugin-loader.c 2015-01-28 11:32:30.000000000 +0100 @@ -169,6 +169,7 @@ AsbPluginLoaderPrivate *priv = GET_PRIVATE (plugin_loader); AsbPlugin *plugin; AsbPluginProcessAppFunc plugin_func = NULL; + GError *error_local = NULL; gboolean ret; guint i; @@ -184,8 +185,20 @@ ASB_PACKAGE_LOG_LEVEL_DEBUG, "Running asb_plugin_process_app() from %s", plugin->name); - if (!plugin_func (plugin, pkg, app, tmpdir, error)) - return FALSE; + if (!plugin_func (plugin, pkg, app, tmpdir, &error_local)) { + if (g_error_matches (error_local, + ASB_PLUGIN_ERROR, + ASB_PLUGIN_ERROR_IGNORE)) { + asb_package_log (pkg, + ASB_PACKAGE_LOG_LEVEL_WARNING, + "Ignoring: %s", + error_local->message); + g_clear_error (&error_local); + } else { + g_propagate_error (error, error_local); + return FALSE; + } + } } return TRUE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/asb-plugin.h new/appstream-glib-0.3.4/libappstream-builder/asb-plugin.h --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/asb-plugin.h 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-builder/asb-plugin.h 2015-01-28 11:32:30.000000000 +0100 @@ -50,6 +50,7 @@ typedef enum { ASB_PLUGIN_ERROR_FAILED, ASB_PLUGIN_ERROR_NOT_SUPPORTED, + ASB_PLUGIN_ERROR_IGNORE, ASB_PLUGIN_ERROR_LAST } AsbPluginError; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/asb-self-test.c new/appstream-glib-0.3.4/libappstream-builder/asb-self-test.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/asb-self-test.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-builder/asb-self-test.c 2015-01-28 11:32:30.000000000 +0100 @@ -222,14 +222,14 @@ g_assert (ret); /* get the list of globs */ - globs = asb_plugin_loader_get_globs (loader); + globs = asb_plugin_loader_get_globs (loader);\ g_assert_cmpint (globs->len, ==, 22); g_assert_cmpstr (asb_glob_value_search (globs, "/usr/share/applications/gimp.desktop"), ==, ""); g_assert_cmpstr (asb_glob_value_search (globs, "/srv/dave.txt"), ==, NULL); /* get the list of plugins */ plugins = asb_plugin_loader_get_plugins (loader); - g_assert_cmpint (plugins->len, ==, 18); + g_assert_cmpint (plugins->len, ==, 17); plugin = g_ptr_array_index (plugins, 0); g_assert (plugin != NULL); g_assert (plugin->module != NULL); @@ -355,7 +355,7 @@ ret = as_store_from_file (store, file, NULL, NULL, &error); g_assert_no_error (error); g_assert (ret); - g_assert_cmpint (as_store_get_size (store), ==, 4); + g_assert_cmpint (as_store_get_size (store), ==, 5); app = as_store_get_app_by_pkgname (store, "app"); g_assert (app != NULL); app = as_store_get_app_by_id (store, "app.desktop"); @@ -455,7 +455,7 @@ "</metadata>\n" "</component>\n" "<component type=\"desktop\">\n" - "<id>valid.desktop</id>\n" + "<id>valid1.desktop</id>\n" "<pkgname>composite</pkgname>\n" "<name>Frobnicator</name>\n" "<summary>Frobnicator</summary>\n" @@ -475,6 +475,27 @@ "<value key=\"X-CacheID\">composite-1-1.fc21.x86_64.rpm</value>\n" "</metadata>\n" "</component>\n" + "<component type=\"desktop\">\n" + "<id>valid2.desktop</id>\n" + "<pkgname>composite</pkgname>\n" + "<name>Frobnicator Example</name>\n" + "<summary>Frobnicator Example Program</summary>\n" + "<icon type=\"stock\">computer</icon>\n" + "<categories>\n" + "<category>Profiling</category>\n" + "</categories>\n" + "<kudos>\n" + "<kudo>HiDpiIcon</kudo>\n" + "</kudos>\n" + "<project_license>GPL-2.0+</project_license>\n" + "<url type=\"homepage\">http://people.freedesktop.org/</url>\n" + "<releases>\n" + "<release version=\"1\" timestamp=\"1407844800\"/>\n" + "</releases>\n" + "<metadata>\n" + "<value key=\"X-CacheID\">composite-1-1.fc21.x86_64.rpm</value>\n" + "</metadata>\n" + "</component>\n" "</components>\n"; ret = asb_test_compare_lines (xml->str, expected_xml, &error); g_assert_no_error (error); @@ -486,13 +507,11 @@ ret = as_store_from_file (store_failed, file_failed, NULL, NULL, &error); g_assert_no_error (error); g_assert (ret); - g_assert_cmpint (as_store_get_size (store_failed), ==, 5); + g_assert_cmpint (as_store_get_size (store_failed), ==, 4); app = as_store_get_app_by_id (store_failed, "console1.desktop"); g_assert (app != NULL); app = as_store_get_app_by_id (store_failed, "console2.desktop"); g_assert (app != NULL); - app = as_store_get_app_by_id (store_failed, "valid2.desktop"); - g_assert (app != NULL); /* check output */ xml_failed = as_store_to_xml (store_failed, AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE); @@ -622,30 +641,6 @@ "<value key=\"X-CacheID\">app-console-1-1.fc21.noarch.rpm</value>\n" "</metadata>\n" "</component>\n" - "<component type=\"desktop\">\n" - "<id>valid2.desktop</id>\n" - "<pkgname>composite</pkgname>\n" - "<name>Frobnicator Example</name>\n" - "<summary>Frobnicator Example Program</summary>\n" - "<icon type=\"stock\">computer</icon>\n" - "<categories>\n" - "<category>Profiling</category>\n" - "</categories>\n" - "<kudos>\n" - "<kudo>HiDpiIcon</kudo>\n" - "</kudos>\n" - "<vetos>\n" - "<veto>absorbed into valid.desktop</veto>\n" - "</vetos>\n" - "<project_license>GPL-2.0+</project_license>\n" - "<url type=\"homepage\">http://people.freedesktop.org/</url>\n" - "<releases>\n" - "<release version=\"1\" timestamp=\"1407844800\"/>\n" - "</releases>\n" - "<metadata>\n" - "<value key=\"X-CacheID\">composite-1-1.fc21.x86_64.rpm</value>\n" - "</metadata>\n" - "</component>\n" "</components>\n"; ret = asb_test_compare_lines (xml_failed->str, expected_xml, &error); g_assert_no_error (error); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/plugins/Makefile.am new/appstream-glib-0.3.4/libappstream-builder/plugins/Makefile.am --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/plugins/Makefile.am 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-builder/plugins/Makefile.am 2015-01-28 11:32:30.000000000 +0100 @@ -17,7 +17,6 @@ libasb_plugin_absorb.la \ libasb_plugin_appdata.la \ libasb_plugin_blacklist.la \ - libasb_plugin_composite.la \ libasb_plugin_dbus.la \ libasb_plugin_desktop.la \ libasb_plugin_gir.la \ @@ -118,9 +117,4 @@ libasb_plugin_font_la_LDFLAGS = -module -avoid-version libasb_plugin_font_la_CFLAGS = $(GLIB_CFLAGS) $(WARNINGFLAGS_C) -libasb_plugin_composite_la_SOURCES = asb-plugin-composite.c -libasb_plugin_composite_la_LIBADD = $(GLIB_LIBS) $(FREETYPE_LIBS) $(GDKPIXBUF_LIBS) -libasb_plugin_composite_la_LDFLAGS = -module -avoid-version -libasb_plugin_composite_la_CFLAGS = $(GLIB_CFLAGS) $(WARNINGFLAGS_C) - -include $(top_srcdir)/git.mk diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/plugins/asb-plugin-appdata.c new/appstream-glib-0.3.4/libappstream-builder/plugins/asb-plugin-appdata.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/plugins/asb-plugin-appdata.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-builder/plugins/asb-plugin-appdata.c 2015-01-28 11:32:30.000000000 +0100 @@ -502,6 +502,7 @@ const gchar *tmpdir, GError **error) { + GError *error_local = NULL; const gchar *kind_str; const gchar *tmp; _cleanup_free_ gchar *appdata_basename = NULL; @@ -545,10 +546,20 @@ /* any installed appdata file */ if (g_file_test (appdata_filename, G_FILE_TEST_EXISTS)) { - return asb_plugin_process_filename (plugin, - app, - appdata_filename, - error); + /* be understanding if upstream gets the AppData file + * wrong -- just fall back to the desktop file data */ + if (!asb_plugin_process_filename (plugin, + app, + appdata_filename, + &error_local)) { + error_local->code = ASB_PLUGIN_ERROR_IGNORE; + g_propagate_error (error, error_local); + g_prefix_error (error, + "AppData file '%s' invalid: ", + appdata_filename); + return FALSE; + } + return TRUE; } /* we're going to require this soon */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/plugins/asb-plugin-composite.c new/appstream-glib-0.3.4/libappstream-builder/plugins/asb-plugin-composite.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-builder/plugins/asb-plugin-composite.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-builder/plugins/asb-plugin-composite.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,179 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Copyright (C) 2014 Richard Hughes <[email protected]> - * - * Licensed under the GNU Lesser General Public License Version 2.1 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <config.h> -#include <string.h> - -#include <asb-plugin.h> - -/** - * asb_plugin_get_name: - */ -const gchar * -asb_plugin_get_name (void) -{ - return "composite"; -} - -/** - * _as_app_is_id_valid: - */ -static gboolean -_as_app_is_id_valid (const gchar *id) -{ - gchar *tmp; - tmp = g_strrstr (id, "."); - if (tmp == NULL) - return FALSE; - if (tmp - id < 4) - return FALSE; - return TRUE; -} - -/** - * _as_app_composite: - */ -static gboolean -_as_app_composite (AsApp *app, AsApp *donor, GError **error) -{ - AsApp *tmp; - gint rc; - _cleanup_free_ gchar *id = NULL; - - /* check this makes sense */ - if (as_app_get_id_kind (app) != as_app_get_id_kind (donor)) { - g_set_error (error, - AS_APP_ERROR, - AS_APP_ERROR_INVALID_TYPE, - "Cannot composite %s:%s of different id kind", - as_app_get_id (app), - as_app_get_id (donor)); - return FALSE; - } - - /* the ID, name with the shortest length wins */ - rc = strlen (as_app_get_id (app)) - strlen (as_app_get_id (donor)); - if (rc == 0) { - rc = strlen (as_app_get_name (app, "C")) - - strlen (as_app_get_name (donor, "C")); - } - if (rc > 0) { - tmp = app; - app = donor; - donor = tmp; - } - - /* set the new composite string */ - id = as_utils_get_string_overlap (as_app_get_id (app), as_app_get_id (donor)); - if (id == NULL || !_as_app_is_id_valid (id)) { - g_set_error (error, - AS_APP_ERROR, - AS_APP_ERROR_INVALID_TYPE, - "Cannot composite %s:%s as no ID overlap", - as_app_get_id (app), - as_app_get_id (donor)); - return FALSE; - } - - - /* log */ - if (ASB_IS_APP (app) && g_strcmp0 (as_app_get_id (app), id) != 0) { - asb_package_log (asb_app_get_package (ASB_APP (app)), - ASB_PACKAGE_LOG_LEVEL_INFO, - "Renamed %s into %s so it could be " - "composited with %s", - as_app_get_id (app), id, - as_app_get_id (donor)); - } - if (ASB_IS_APP (donor)) { - asb_package_log (asb_app_get_package (ASB_APP (donor)), - ASB_PACKAGE_LOG_LEVEL_INFO, - "Composited %s into %s", - as_app_get_id (donor), id); - } - - /* set the new ID (on both apps?) */ - as_app_set_id (app, id, -1); - - /* add some easily merged properties */ - as_app_subsume_full (app, donor, AS_APP_SUBSUME_FLAG_PARTIAL); - as_app_add_veto (donor, "absorbed into %s", as_app_get_id (app)); - return TRUE; -} - -/** - * asb_plugin_composite_app: - */ -static void -asb_plugin_composite_app (AsApp *app, AsApp *donor) -{ - _cleanup_error_free_ GError *error = NULL; - - /* composite the app */ - if (!_as_app_composite (app, donor, &error)) { - if (ASB_IS_APP (app)) { - asb_package_log (asb_app_get_package (ASB_APP (app)), - ASB_PACKAGE_LOG_LEVEL_INFO, - "%s", error->message); - } else { - g_warning ("%s", error->message); - } - return; - } -} - -/** - * asb_plugin_merge: - */ -void -asb_plugin_merge (AsbPlugin *plugin, GList *list) -{ - AsApp *app; - AsApp *found; - GList *l; - const gchar *tmp; - _cleanup_hashtable_unref_ GHashTable *hash = NULL; - - /* add all packages to the hash */ - hash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_object_unref); - for (l = list; l != NULL; l = l->next) { - app = AS_APP (l->data); - if (as_app_get_vetos (app)->len > 0) - continue; - tmp = as_app_get_pkgname_default (app); - if (tmp == NULL) - continue; - found = g_hash_table_lookup (hash, tmp); - if (found != NULL) { - /* ignore duplicates */ - if (g_strcmp0 (as_app_get_id (app), - as_app_get_id (found)) == 0) { - continue; - } - asb_plugin_composite_app (app, found); - continue; - } - g_hash_table_insert (hash, - g_strdup (as_app_get_pkgname_default (app)), - g_object_ref (app)); - } -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-app-private.h new/appstream-glib-0.3.4/libappstream-glib/as-app-private.h --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-app-private.h 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-glib/as-app-private.h 2015-01-28 11:32:30.000000000 +0100 @@ -76,6 +76,7 @@ guint as_app_get_name_size (AsApp *app); guint as_app_get_comment_size (AsApp *app); guint as_app_get_description_size (AsApp *app); +GPtrArray *as_app_get_search_tokens (AsApp *app); GNode *as_app_node_insert (AsApp *app, GNode *parent, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-app-validate.c new/appstream-glib-0.3.4/libappstream-glib/as-app-validate.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-app-validate.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-glib/as-app-validate.c 2015-01-28 11:32:30.000000000 +0100 @@ -186,28 +186,29 @@ if (str_len < length_li_min) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<li> is too short"); + "<li> is too short [%s]", text); } if (str_len > length_li_max) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<li> is too long"); + "<li> is too long [%s]", text); } if (ai_app_validate_fullstop_ending (text)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<li> cannot end in '.'"); + "<li> cannot end in '.' [%s]", text); } if (as_app_validate_has_hyperlink (text)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<li> cannot contain a hyperlink"); + "<li> cannot contain a hyperlink [%s]", + text); } if (require_sentence_case && !as_app_validate_has_first_word_capital (helper, text)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<li> requires sentence case"); + "<li> requires sentence case [%s]", text); } } @@ -241,7 +242,7 @@ if (helper->previous_para_was_short) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<p> is too short [p]"); + "<p> is too short [%s]", text); } helper->previous_para_was_short = FALSE; @@ -254,7 +255,7 @@ if (str_len > length_para_max) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<p> is too long"); + "<p> is too long [%s]", text); } if (g_str_has_prefix (text, "This application")) { ai_app_validate_add (helper->probs, @@ -264,20 +265,21 @@ if (as_app_validate_has_hyperlink (text)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<p> cannot contain a hyperlink"); + "<p> cannot contain a hyperlink [%s]", + text); } if (require_sentence_case && !as_app_validate_has_first_word_capital (helper, text)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<p> requires sentence case"); + "<p> requires sentence case [%s]", text); } if (text[str_len - 1] != '.' && text[str_len - 1] != '!' && text[str_len - 1] != ':') { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<p> does not end in '.|:|!'"); + "<p> does not end in '.|:|!' [%s]", text); } helper->number_paragraphs++; helper->para_chars_before_list += str_len; @@ -300,7 +302,8 @@ if (helper->number_paragraphs < 1) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<ul> cannot start a description"); + "<ul> cannot start a description [%s]", + text); } if (helper->para_chars_before_list != 0 && helper->para_chars_before_list < (guint) length_para_before_list) { @@ -459,7 +462,7 @@ if (base_uri == NULL) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, - "<screenshot> url '%s' not valid", url); + "<screenshot> url not valid [%s]", url); return FALSE; } msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); @@ -473,7 +476,7 @@ if (status_code != SOUP_STATUS_OK) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, - "<screenshot> url '%s' not found", url); + "<screenshot> url not found [%s]", url); return FALSE; } @@ -481,7 +484,8 @@ if (msg->response_body->length == 0) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_FILE_INVALID, - "<screenshot> url '%s' is a zero length file", url); + "<screenshot> url is a zero length file [%s]", + url); return FALSE; } @@ -492,7 +496,8 @@ if (stream == NULL) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, - "<screenshot> failed to load data from '%s'", url); + "<screenshot> failed to load data [%s]", + url); return FALSE; } @@ -501,7 +506,7 @@ if (pixbuf == NULL) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_FILE_INVALID, - "<screenshot> failed to load '%s'", + "<screenshot> failed to load [%s]", url); return FALSE; } @@ -513,7 +518,8 @@ as_image_get_width (im) != screenshot_width) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, - "<screenshot> width did not match specified"); + "<screenshot> width did not match specified [%s]", + url); } /* check height matches */ @@ -521,29 +527,34 @@ as_image_get_height (im) != screenshot_height) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, - "<screenshot> height did not match specified"); + "<screenshot> height did not match specified [%s]", + url); } /* check size is reasonable */ if (screenshot_width < ss_size_width_min) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, - "<screenshot> width was too small"); + "<screenshot> width too small [%s]", + url); } if (screenshot_height < ss_size_height_min) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, - "<screenshot> height was too small"); + "<screenshot> height too small [%s]", + url); } if (screenshot_width > ss_size_width_max) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, - "<screenshot> width was too large"); + "<screenshot> width too large [%s]", + url); } if (screenshot_height > ss_size_height_max) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, - "<screenshot> height was too large"); + "<screenshot> height too large [%s]", + url); } /* check padding */ @@ -553,13 +564,15 @@ (alpha_flags & AS_IMAGE_ALPHA_FLAG_BOTTOM) > 0) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<image> has vertical alpha padding"); + "<image> has vertical padding [%s]", + url); } if ((alpha_flags & AS_IMAGE_ALPHA_FLAG_LEFT) > 0|| (alpha_flags & AS_IMAGE_ALPHA_FLAG_RIGHT) > 0) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<image> has horizontal alpha padding"); + "<image> has horizontal padding [%s]", + url); } /* check aspect ratio */ @@ -570,7 +583,8 @@ screenshot_aspect, desired_aspect); ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ASPECT_RATIO_INCORRECT, - "<screenshot> aspect ratio was not 16:9"); + "<screenshot> aspect ratio not 16:9 [%s]", + url); } } return TRUE; @@ -647,28 +661,31 @@ if (str_len < length_caption_min) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<caption> is too short"); + "<caption> is too short [%s]", tmp); } if (str_len > length_caption_max) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<caption> is too long"); + "<caption> is too long [%s]", tmp); } if (ai_app_validate_fullstop_ending (tmp)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<caption> cannot end in '.'"); + "<caption> cannot end in '.' [%s]", + tmp); } if (as_app_validate_has_hyperlink (tmp)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<caption> cannot contain a hyperlink"); + "<caption> cannot contain a hyperlink [%s]", + tmp); } if (require_sentence_case && !as_app_validate_has_first_word_capital (helper, tmp)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<caption> requires sentence case"); + "<caption> requires sentence case [%s]", + tmp); } } } @@ -696,7 +713,7 @@ if (!as_utils_is_stock_icon_name (icon_name)) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_TAG_INVALID, - "stock icon '%s' is not valid", + "stock icon is not valid [%s]", icon_name); } break; @@ -704,7 +721,7 @@ if (!g_str_has_prefix (icon_name, "/")) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_TAG_INVALID, - "local icon '%s' is not a filename", + "local icon is not a filename [%s]", icon_name); } break; @@ -712,7 +729,7 @@ if (g_str_has_prefix (icon_name, "/")) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_TAG_INVALID, - "cached icon '%s' is a filename", + "cached icon is a filename [%s]", icon_name); } break; @@ -721,7 +738,7 @@ !g_str_has_prefix (icon_name, "https://")) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_TAG_INVALID, - "remote icon '%s' is not a url", + "remote icon is not a url [%s]", icon_name); } break; @@ -819,7 +836,7 @@ AS_PROBLEM_KIND_ATTRIBUTE_MISSING, "<release> has no timestamp"); } - if (timestamp > 20120101 && timestamp < 20151231) { + if (timestamp > 20120101 && timestamp < 20251231) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<release> timestamp should be a UNIX time"); @@ -836,7 +853,8 @@ ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_STYLE_INCORRECT, "<release> description should be " - "prose and not contain hyperlinks"); + "prose and not contain hyperlinks [%s]", + tmp); } if (!as_app_validate_description (tmp, helper, @@ -1101,12 +1119,14 @@ !as_app_validate_is_content_license (license)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_TAG_INVALID, - "<metadata_license> is not valid"); + "<metadata_license> is not valid [%s]", + license); } else if (validate_license) { ret = as_app_validate_license (license, &error_local); if (!ret) { g_prefix_error (&error_local, - "<metadata_license> is not valid: "); + "<metadata_license> is not valid [%s]", + license); ai_app_validate_add (probs, AS_PROBLEM_KIND_TAG_INVALID, "%s", error_local->message); @@ -1133,7 +1153,8 @@ ret = as_app_validate_license (license, &error_local); if (!ret) { g_prefix_error (&error_local, - "<project_license> is not valid: "); + "<project_license> is not valid [%s]", + license); ai_app_validate_add (probs, AS_PROBLEM_KIND_TAG_INVALID, "%s", error_local->message); @@ -1181,7 +1202,8 @@ if (update_contact != NULL && strlen (update_contact) < 6) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<update_contact> is too short"); + "<update_contact> is too short [%s]", + update_contact); } if (require_contactdetails && update_contact == NULL) { switch (as_app_get_source_kind (app)) { @@ -1228,7 +1250,7 @@ if (g_strcmp0 (key, "unknown") == 0) { ai_app_validate_add (probs, AS_PROBLEM_KIND_TAG_INVALID, - "<url> type invalid"); + "<url> type invalid [%s]", key); } tmp = g_hash_table_lookup (urls, key); if (tmp == NULL || tmp[0] == '\0') @@ -1237,7 +1259,8 @@ !g_str_has_prefix (tmp, "https://")) { ai_app_validate_add (probs, AS_PROBLEM_KIND_TAG_INVALID, - "<url> does not start with 'http://'"); + "<url> does not start with 'http://' [%s]", + tmp); } } @@ -1259,28 +1282,31 @@ if (str_len < length_name_min) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<name> is too short"); + "<name> is too short [%s]", name); } if (str_len > length_name_max) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<name> is too long"); + "<name> is too long [%s]", name); } if (ai_app_validate_fullstop_ending (name)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<name> cannot end in '.'"); + "<name> cannot end in '.' [%s]", + name); } if (as_app_validate_has_hyperlink (name)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<name> cannot contain a hyperlink"); + "<name> cannot contain a hyperlink [%s]", + name); } if (require_sentence_case && !as_app_validate_has_first_word_capital (&helper, name)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<name> requires sentence case"); + "<name> requires sentence case [%s]", + name); } } else if (require_name) { ai_app_validate_add (probs, @@ -1295,28 +1321,33 @@ if (str_len < length_summary_min) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<summary> is too short"); + "<summary> is too short [%s]", + summary); } if (str_len > length_summary_max) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<summary> is too long"); + "<summary> is too long [%s]", + summary); } if (ai_app_validate_fullstop_ending (summary)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<summary> cannot end in '.'"); + "<summary> cannot end in '.' [%s]", + summary); } if (as_app_validate_has_hyperlink (summary)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<summary> cannot contain a hyperlink"); + "<summary> cannot contain a hyperlink [%s]", + summary); } if (require_sentence_case && !as_app_validate_has_first_word_capital (&helper, summary)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<summary> requires sentence case"); + "<summary> requires sentence case [%s]", + summary); } } else if (require_name) { ai_app_validate_add (probs, @@ -1374,22 +1405,26 @@ if (str_len < length_name_min) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<developer_name> is too short"); + "<developer_name> is too short [%s]", + name); } if (str_len > length_name_max) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<developer_name> is too long"); + "<developer_name> is too long [%s]", + name); } if (as_app_validate_has_hyperlink (name)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<developer_name> cannot contain a hyperlink"); + "<developer_name> cannot contain a hyperlink [%s]", + name); } if (as_app_validate_has_email (name)) { ai_app_validate_add (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, - "<developer_name> cannot contain an email address"); + "<developer_name> cannot contain an email address [%s]", + name); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-app.c new/appstream-glib-0.3.4/libappstream-glib/as-app.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-app.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-glib/as-app.c 2015-01-28 11:32:30.000000000 +0100 @@ -3696,6 +3696,35 @@ } /** + * as_app_remove_invalid_tokens: + **/ +static void +as_app_remove_invalid_tokens (gchar **tokens) +{ + guint i; + guint idx = 0; + guint len; + + if (tokens == NULL) + return; + + /* remove any tokens that are invalid and maintain the order */ + len = g_strv_length (tokens); + for (i = 0; i < len; i++) { + if (!as_utils_search_token_valid (tokens[i])) { + g_free (tokens[i]); + tokens[i] = NULL; + continue; + } + tokens[idx++] = tokens[i]; + } + + /* unused token space */ + for (i = idx; i < len; i++) + tokens[i] = NULL; +} + +/** * as_app_add_tokens: **/ static void @@ -3726,6 +3755,10 @@ if (token_item->values_utf8 == NULL) token_item->values_utf8 = as_app_value_tokenize (value); + /* remove any tokens that are invalid */ + as_app_remove_invalid_tokens (token_item->values_utf8); + as_app_remove_invalid_tokens (token_item->values_ascii); + token_item->score = score; g_ptr_array_add (priv->token_cache, token_item); } @@ -3842,6 +3875,46 @@ } /** + * as_app_get_search_tokens: + * @app: a #AsApp instance. + * + * Returns all the search tokens for the application. These are unsorted. + * + * Returns: (transfer full): The string search tokens + * + * Since: 0.3.4 + */ +GPtrArray * +as_app_get_search_tokens (AsApp *app) +{ + AsAppPrivate *priv = GET_PRIVATE (app); + AsAppTokenItem *item; + GPtrArray *array; + guint i, j; + + /* ensure the token cache is created */ + if (g_once_init_enter (&priv->token_cache_valid)) { + as_app_create_token_cache (app); + g_once_init_leave (&priv->token_cache_valid, TRUE); + } + + /* return all the toek cache */ + array = g_ptr_array_new_with_free_func (g_free); + for (i = 0; i < priv->token_cache->len; i++) { + item = g_ptr_array_index (priv->token_cache, i); + if (item->values_utf8 != NULL) { + for (j = 0; item->values_utf8[j] != NULL; j++) + g_ptr_array_add (array, g_strdup (item->values_utf8[j])); + } + if (item->values_ascii != NULL) { + for (j = 0; item->values_ascii[j] != NULL; j++) + g_ptr_array_add (array, g_strdup (item->values_ascii[j])); + } + } + return array; +} + +/** * as_app_search_matches_all: * @app: a #AsApp instance. * @search: the search terms. @@ -3851,6 +3924,9 @@ * Returns: a match scrore, where 0 is no match and larger numbers are better * matches. * + * It's probably a good idea to use as_utils_search_tokenize() to populate + * search as very short or common keywords will return a lot of matches. + * * Since: 0.1.3 */ guint diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-self-test.c new/appstream-glib-0.3.4/libappstream-glib/as-self-test.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-self-test.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-glib/as-self-test.c 2015-01-28 11:32:30.000000000 +0100 @@ -815,14 +815,22 @@ const gchar *message) { AsProblem *problem; + gchar *tmp; guint i; for (i = 0; i < array->len; i++) { + _cleanup_free_ gchar *message_no_data = NULL; problem = g_ptr_array_index (array, i); - if (as_problem_get_kind (problem) == kind && - g_strcmp0 (as_problem_get_message (problem), message) == 0) + if (as_problem_get_kind (problem) != kind) + continue; + message_no_data = g_strdup (as_problem_get_message (problem)); + tmp = g_strrstr (message_no_data, " ["); + if (tmp != NULL) + *tmp = '\0'; + if (g_strcmp0 (message_no_data, message) == 0) return; } + g_print ("\n"); for (i = 0; i < array->len; i++) { problem = g_ptr_array_index (array, i); g_print ("%i\t%s\n", @@ -1015,7 +1023,6 @@ problem = g_ptr_array_index (probs, i); g_debug ("%s", as_problem_get_message (problem)); } - g_assert_cmpint (probs->len, ==, 26); as_test_app_validate_check (probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<id> has invalid type attribute"); @@ -1024,7 +1031,7 @@ as_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_INVALID, "<metadata_license> is not valid"); as_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_INVALID, - "<project_license> is not valid: SPDX ID 'CC1' unknown"); + "<project_license> is not valid"); as_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_MISSING, "<update_contact> is not present"); as_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_INVALID, @@ -1066,6 +1073,7 @@ "<p> requires sentence case"); as_test_app_validate_check (probs, AS_PROBLEM_KIND_STYLE_INCORRECT, "<li> requires sentence case"); + g_assert_cmpint (probs->len, ==, 28); } static void @@ -1842,7 +1850,7 @@ { const gchar *all[] = { "gnome", "install", "software", NULL }; const gchar *none[] = { "gnome", "xxx", "software", NULL }; - const gchar *mime[] = { "application", "vnd", "oasis", "opendocument","text", NULL }; + const gchar *mime[] = { "vnd", "oasis", "opendocument","text", NULL }; _cleanup_object_unref_ AsApp *app = NULL; app = as_app_new (); @@ -1861,7 +1869,10 @@ g_assert_cmpint (as_app_search_matches (app, "d-feet"), ==, 90); g_assert_cmpint (as_app_search_matches_all (app, (gchar**) all), ==, 220); g_assert_cmpint (as_app_search_matches_all (app, (gchar**) none), ==, 0); - g_assert_cmpint (as_app_search_matches_all (app, (gchar**) mime), ==, 5); + g_assert_cmpint (as_app_search_matches_all (app, (gchar**) mime), ==, 4); + + /* do not add short or common keywords */ + g_assert_cmpint (as_app_search_matches (app, "and"), ==, 0); } /* load and save embedded icons */ @@ -2697,6 +2708,7 @@ { gboolean ret; gchar *tmp; + gchar **tokens; GError *error = NULL; /* as_strndup */ @@ -2770,6 +2782,21 @@ //ret = as_utils_check_url_exists ("http://www.bbc.co.uk/", &error); //g_assert (ret); //g_assert_no_error (error); + + /* valid tokens */ + g_assert (as_utils_search_token_valid ("battery")); + g_assert (!as_utils_search_token_valid ("and")); + g_assert (!as_utils_search_token_valid ("is")); + g_assert (!as_utils_search_token_valid ("<b>")); + + /* check tokenisation */ + tokens = as_utils_search_tokenize ("a c b"); + g_assert (tokens == NULL); + tokens = as_utils_search_tokenize ("batteries are (really) stupid"); + g_assert_cmpstr (tokens[0], ==, "batteries"); + g_assert_cmpstr (tokens[1], ==, "stupid"); + g_assert_cmpstr (tokens[2], ==, NULL); + g_strfreev (tokens); } static void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-tag.c new/appstream-glib-0.3.4/libappstream-glib/as-tag.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-tag.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-glib/as-tag.c 2015-01-28 11:32:30.000000000 +0100 @@ -111,6 +111,9 @@ return AS_TAG_APPLICATION; if (g_strcmp0 (tag, "updatecontact") == 0) return AS_TAG_UPDATE_CONTACT; + /* fix spelling error */ + if (g_strcmp0 (tag, "metadata_licence") == 0) + return AS_TAG_METADATA_LICENSE; } /* translated versions */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-utils.c new/appstream-glib-0.3.4/libappstream-glib/as-utils.c --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-utils.c 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-glib/as-utils.c 2015-01-28 11:32:30.000000000 +0100 @@ -1304,3 +1304,77 @@ } return ret; } + +/** + * as_utils_search_token_valid: + * @token: the search token + * + * Checks the search token if it is valid. Valid tokens are at least 3 chars in + * length, not common words like "and", and do not contain markup. + * + * Returns: %TRUE is the search token was valid + * + * Since: 0.3.4 + **/ +gboolean +as_utils_search_token_valid (const gchar *token) +{ + guint i; + const gchar *blacklist[] = { + "and", "the", "desktop", "application", "for", "you", "your", + "with", "can", "are", "from", "that", "use", "allows", "also", + "this", "other", "all", "using", "has", "some", "like", "them", + "well", "not", "using", "not", "but", "set", "its", "into", + "such", "was", "they", "where", "want", "only", "about", + NULL }; + if (strlen (token) < 3) + return FALSE; + if (g_strstr_len (token, -1, "<") != NULL) + return FALSE; + if (g_strstr_len (token, -1, ">") != NULL) + return FALSE; + if (g_strstr_len (token, -1, "(") != NULL) + return FALSE; + if (g_strstr_len (token, -1, ")") != NULL) + return FALSE; + for (i = 0; blacklist[i] != NULL; i++) { + if (g_strcmp0 (token, blacklist[i]) == 0) + return FALSE; + } + return TRUE; +} + +/** + * as_utils_search_tokenize: + * @search: the search string + * + * Splits up a string into tokens and returns tokens that are suitable for + * searching. This includes taking out common words and casefolding the + * returned search tokens. + * + * Returns: (transfer full): Valid tokens to search for, or %NULL for error + * + * Since: 0.3.4 + **/ +gchar ** +as_utils_search_tokenize (const gchar *search) +{ + gchar **values = NULL; + guint i; + guint idx = 0; + _cleanup_strv_free_ gchar **tmp = NULL; + + /* only add keywords that are long enough */ + tmp = g_strsplit (search, " ", -1); + values = g_new0 (gchar *, g_strv_length (tmp) + 1); + for (i = 0; tmp[i] != NULL; i++) { + if (!as_utils_search_token_valid (tmp[i])) + continue; + values[idx++] = g_utf8_casefold (tmp[i], -1); + } + if (idx == 0) { + g_free (values); + return NULL; + } + return values; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-utils.h new/appstream-glib-0.3.4/libappstream-glib/as-utils.h --- old/appstream-glib-0.3.1.git.20150103.a7941d7/libappstream-glib/as-utils.h 2015-01-05 10:48:51.000000000 +0100 +++ new/appstream-glib-0.3.4/libappstream-glib/as-utils.h 2015-01-28 11:32:30.000000000 +0100 @@ -105,6 +105,8 @@ const gchar *origin, const gchar *destdir, GError **error); +gboolean as_utils_search_token_valid (const gchar *token); +gchar **as_utils_search_tokenize (const gchar *search); G_END_DECLS -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
