diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | contrib/libappstream-glib.spec.in | 1 | ||||
-rw-r--r-- | libappstream-builder/plugins/Makefile.am | 7 | ||||
-rw-r--r-- | libappstream-builder/plugins/asb-plugin-shell-extension.c | 234 |
4 files changed, 243 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac index 60dbcdd..3352bbc 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,7 @@ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.45.8 gio-2.0 gobject-2.0 gthread-2.0 gio-u PKG_CHECK_MODULES(UUID, uuid) PKG_CHECK_MODULES(LIBARCHIVE, libarchive) PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.51.92) +PKG_CHECK_MODULES(JSON_GLIB, json-glib-1.0 >= 1.1.1) PKG_CHECK_MODULES(GDKPIXBUF, gdk-pixbuf-2.0 >= 2.31.5) # firmware support (default enabled) diff --git a/contrib/libappstream-glib.spec.in b/contrib/libappstream-glib.spec.in index cf47ac8..eb2ff9f 100644 --- a/contrib/libappstream-glib.spec.in +++ b/contrib/libappstream-glib.spec.in @@ -22,6 +22,7 @@ BuildRequires: gettext BuildRequires: intltool BuildRequires: libgcab1-devel BuildRequires: libuuid-devel +BuildRequires: json-glib-devel >= 1.1.1 # for the builder component BuildRequires: fontconfig-devel diff --git a/libappstream-builder/plugins/Makefile.am b/libappstream-builder/plugins/Makefile.am index b933ed2..861fa37 100644 --- a/libappstream-builder/plugins/Makefile.am +++ b/libappstream-builder/plugins/Makefile.am @@ -5,6 +5,7 @@ AM_CPPFLAGS = \ $(LIBARCHIVE_CFLAGS) \ $(SOUP_CFLAGS) \ $(RPM_CFLAGS) \ + $(JSON_GLIB_CFLAGS) \ $(FREETYPE_CFLAGS) \ -I$(top_srcdir)/libappstream-glib \ -I$(top_builddir)/libappstream-glib \ @@ -16,6 +17,7 @@ plugindir = $(libdir)/asb-plugins-$(AS_PLUGIN_VERSION) plugin_LTLIBRARIES = \ libasb_plugin_absorb.la \ libasb_plugin_appdata.la \ + libasb_plugin_shell_extension.la \ libasb_plugin_desktop.la \ libasb_plugin_gettext.la \ libasb_plugin_hardcoded.la @@ -50,6 +52,11 @@ libasb_plugin_appdata_la_LIBADD = $(GLIB_LIBS) $(GDKPIXBUF_LIBS) libasb_plugin_appdata_la_LDFLAGS = -module -avoid-version libasb_plugin_appdata_la_CFLAGS = $(GLIB_CFLAGS) $(WARNINGFLAGS_C) +libasb_plugin_shell_extension_la_SOURCES = asb-plugin-shell-extension.c +libasb_plugin_shell_extension_la_LIBADD = $(GLIB_LIBS) $(JSON_GLIB_LIBS) +libasb_plugin_shell_extension_la_LDFLAGS = -module -avoid-version +libasb_plugin_shell_extension_la_CFLAGS = $(GLIB_CFLAGS) $(WARNINGFLAGS_C) + if HAVE_FONTS libasb_plugin_font_la_SOURCES = asb-plugin-font.c libasb_plugin_font_la_LIBADD = $(GLIB_LIBS) $(FREETYPE_LIBS) $(GDKPIXBUF_LIBS) $(GTK_LIBS) diff --git a/libappstream-builder/plugins/asb-plugin-shell-extension.c b/libappstream-builder/plugins/asb-plugin-shell-extension.c new file mode 100644 index 0000000..8842b1f --- /dev/null +++ b/libappstream-builder/plugins/asb-plugin-shell-extension.c @@ -0,0 +1,234 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2016 Richard Hughes <richard@hughsie.com> + * + * 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 <fnmatch.h> +#include <json-glib/json-glib.h> + +#include <asb-plugin.h> + +/** + * asb_plugin_get_name: + */ +const gchar * +asb_plugin_get_name (void) +{ + return "shell-extension"; +} + +/** + * asb_plugin_add_globs: + */ +void +asb_plugin_add_globs (AsbPlugin *plugin, GPtrArray *globs) +{ + asb_plugin_add_glob (globs, "/usr/share/gnome-shell/extensions/*/metadata.json"); +} + +/** + * _asb_plugin_check_filename: + */ +static gboolean +_asb_plugin_check_filename (const gchar *filename) +{ + if (asb_plugin_match_glob ("/usr/share/gnome-shell/extensions/*/metadata.json", filename)) + return TRUE; + return FALSE; +} + +/** + * asb_plugin_check_filename: + */ +gboolean +asb_plugin_check_filename (AsbPlugin *plugin, const gchar *filename) +{ + return _asb_plugin_check_filename (filename); +} + +/** + * as_app_parse_shell_extension_data: + */ +static gboolean +as_app_parse_shell_extension_data (AsApp *app, + const gchar *data, + gsize len, + GError **error) +{ + JsonArray *json_array; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *tmp; + g_autoptr(AsIcon) ic = NULL; + g_autoptr(JsonParser) json_parser = NULL; + + /* parse the data */ + json_parser = json_parser_new (); + if (!json_parser_load_from_data (json_parser, data, len, error)) + return FALSE; + json_root = json_parser_get_root (json_parser); + if (json_root == NULL) { + g_set_error_literal (error, + ASB_PLUGIN_ERROR, + ASB_PLUGIN_ERROR_FAILED, + "no root"); + return FALSE; + } + json_obj = json_node_get_object (json_root); + if (json_obj == NULL) { + g_set_error_literal (error, + ASB_PLUGIN_ERROR, + ASB_PLUGIN_ERROR_FAILED, + "no obect"); + return FALSE; + } + + as_app_set_kind (app, AS_APP_KIND_SHELL_EXTENSION); + as_app_set_comment (app, NULL, "GNOME Shell Extension"); + as_app_add_category (AS_APP (app), "Addons"); + as_app_add_category (AS_APP (app), "ShellExtensions"); + tmp = json_object_get_string_member (json_obj, "uuid"); + if (tmp != NULL) { + g_autofree gchar *id = NULL; + id = g_strdup_printf ("%s.shell-extension", tmp); + as_app_set_id (app, id); + } + if (json_object_has_member (json_obj, "gettext-domain")) { + tmp = json_object_get_string_member (json_obj, "gettext-domain"); + if (tmp != NULL) { + g_autoptr(AsTranslation) transaction = NULL; + transaction = as_translation_new (); + as_translation_set_kind (transaction, AS_TRANSLATION_KIND_GETTEXT); + as_translation_set_id (transaction, tmp); + as_app_add_translation (app, transaction); + } + } + if (json_object_has_member (json_obj, "name")) { + tmp = json_object_get_string_member (json_obj, "name"); + if (tmp != NULL) + as_app_set_name (app, NULL, tmp); + } + if (json_object_has_member (json_obj, "description")) { + tmp = json_object_get_string_member (json_obj, "description"); + if (tmp != NULL) { + g_autofree gchar *desc = NULL; + desc = as_markup_import (tmp); + if (desc != NULL) + as_app_set_description (app, NULL, desc); + } + } + if (json_object_has_member (json_obj, "url")) { + tmp = json_object_get_string_member (json_obj, "url"); + if (tmp != NULL) + as_app_add_url (app, AS_URL_KIND_HOMEPAGE, tmp); + } + if (json_object_has_member (json_obj, "original-authors")) { + json_array = json_object_get_array_member (json_obj, "original-authors"); + if (json_array != NULL) { + tmp = json_array_get_string_element (json_array, 0); + as_app_set_developer_name (app, NULL, tmp); + } + } + if (as_app_get_release_default (app) == NULL && + json_object_has_member (json_obj, "shell-version")) { + json_array = json_object_get_array_member (json_obj, "shell-version"); + if (json_array != NULL) { + g_autoptr(AsRelease) release = NULL; + tmp = json_array_get_string_element (json_array, 0); + release = as_release_new (); + as_release_set_state (release, AS_RELEASE_STATE_INSTALLED); + as_release_set_version (release, tmp); + as_app_add_release (app, release); + } + } + + /* use a stock icon */ + ic = as_icon_new (); + as_icon_set_kind (ic, AS_ICON_KIND_STOCK); + as_icon_set_name (ic, "application-x-addon-symbolic"); + as_app_add_icon (app, ic); + return TRUE; +} + +/** + * asb_plugin_process_filename: + */ +static gboolean +asb_plugin_process_filename (AsbPlugin *plugin, + AsbPackage *pkg, + const gchar *filename, + GList **apps, + GError **error) +{ + gsize len; + g_autoptr(AsbApp) app = NULL; + g_autofree gchar *data = NULL; + + app = asb_app_new (pkg, NULL); + if (!g_file_get_contents (filename, &data, &len, error)) + return FALSE; + if (!as_app_parse_shell_extension_data (AS_APP (app), data, len, error)) + return FALSE; + asb_plugin_add_app (apps, AS_APP (app)); + return TRUE; +} + +/** + * asb_plugin_process: + */ +GList * +asb_plugin_process (AsbPlugin *plugin, + AsbPackage *pkg, + const gchar *tmpdir, + GError **error) +{ + gboolean ret; + GList *apps = NULL; + guint i; + gchar **filelist; + + filelist = asb_package_get_filelist (pkg); + for (i = 0; filelist[i] != NULL; i++) { + g_autofree gchar *filename_tmp = NULL; + if (!_asb_plugin_check_filename (filelist[i])) + continue; + filename_tmp = g_build_filename (tmpdir, filelist[i], NULL); + ret = asb_plugin_process_filename (plugin, + pkg, + filename_tmp, + &apps, + error); + if (!ret) { + g_list_free_full (apps, (GDestroyNotify) g_object_unref); + return NULL; + } + } + + /* no desktop files we care about */ + if (apps == NULL) { + g_set_error (error, + ASB_PLUGIN_ERROR, + ASB_PLUGIN_ERROR_FAILED, + "nothing interesting in %s", + asb_package_get_basename (pkg)); + return NULL; + } + return apps; +} |