[gnome-software/wip/hughsie/shell-extensions] Add support for GNOME Shell extensions
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/shell-extensions] Add support for GNOME Shell extensions
- Date: Thu, 25 Feb 2016 10:00:56 +0000 (UTC)
commit ebc97e05b1b1f140af628c71d91ec17e0ae9b444
Author: Richard Hughes <richard hughsie com>
Date: Thu Feb 25 09:56:21 2016 +0000
Add support for GNOME Shell extensions
src/plugins/Makefile.am | 6 +
src/plugins/gs-plugin-shell-extensions.c | 310 ++++++++++++++++++++++++++++++
2 files changed, 316 insertions(+), 0 deletions(-)
---
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 5156bb7..9f859be 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -40,6 +40,7 @@ plugin_LTLIBRARIES = \
libgs_plugin_fedora_provenance.la \
libgs_plugin_ubuntu-reviews.la \
libgs_plugin_fedora_tagger_usage.la \
+ libgs_plugin_shell-extensions.la \
libgs_plugin_epiphany.la \
libgs_plugin_icons.la
@@ -73,6 +74,11 @@ libgs_plugin_dummy_la_LIBADD = $(GS_PLUGIN_LIBS)
libgs_plugin_dummy_la_LDFLAGS = -module -avoid-version
libgs_plugin_dummy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+libgs_plugin_shell_extensions_la_SOURCES = gs-plugin-shell-extensions.c
+libgs_plugin_shell_extensions_la_LIBADD = $(GS_PLUGIN_LIBS) $(JSON_GLIB_LIBS)
+libgs_plugin_shell_extensions_la_LDFLAGS = -module -avoid-version
+libgs_plugin_shell_extensions_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
libgs_plugin_fedora_distro_upgrades_la_SOURCES = gs-plugin-fedora-distro-upgrades.c
libgs_plugin_fedora_distro_upgrades_la_LIBADD = $(GS_PLUGIN_LIBS) $(JSON_GLIB_LIBS) $(SOUP_LIBS)
libgs_plugin_fedora_distro_upgrades_la_LDFLAGS = -module -avoid-version
diff --git a/src/plugins/gs-plugin-shell-extensions.c b/src/plugins/gs-plugin-shell-extensions.c
new file mode 100644
index 0000000..dcecc6c
--- /dev/null
+++ b/src/plugins/gs-plugin-shell-extensions.c
@@ -0,0 +1,310 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2016 Kalev Lember <klember redhat com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <json-glib/json-glib.h>
+
+#include <gs-plugin.h>
+#include <gs-os-release.h>
+#include <gs-utils.h>
+
+#define SHELL_EXTENSIONS_CACHE_AGE_MAX 237000 /* 1 week */
+#define SHELL_EXTENSIONS_API_URI "https://extensions.gnome.org/extension-query/"
+
+// See https://git.gnome.org/browse/extensions-web/tree/sweettooth/extensions/views.py for src
+
+#if 0
+{
+ "numpages": 1,
+ "total": 1,
+ "extensions": [
+ {
+ "shell_version_map": {
+ "3.18": {
+ "pk": 5353,
+ "version": 23
+ },
+ "3.4.0": {
+ "pk": 2119,
+ "version": 9
+ },
+ "3.20": {
+ "pk": 2999,
+ "version": 110
+ },
+ "3.3.4": {
+ "pk": 848,
+ "version": 6
+ }
+ },
+ "description": "Now updated for shell 3.18\nissue:\nsudo apt-get install gir1.2-gconf\nor similar
prior to installing",
+ "creator": "jablona123",
+ "name": "Gmail Notify",
+ "link": "\/extension\/154\/gmail-notify\/",
+ "pk": 154,
+ "creator_url": "\/accounts\/profile\/jablona123",
+ "icon": "\/static\/extension-data\/icons\/icon_154_1.png",
+ "uuid": "gmail_notify jablona123 pl"
+ }
+ ]
+}
+#endif
+
+#ifndef JsonParser_autoptr
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(JsonParser, g_object_unref)
+#endif
+
+struct GsPluginPrivate {
+ GPtrArray *distros;
+};
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+ return "shell-extensions";
+}
+
+/**
+ * gs_plugin_shell_extensions_parse_apps:
+ */
+static GPtrArray *
+gs_plugin_shell_extensions_parse_apps (const gchar *data,
+ gsize data_len,
+ GError **error)
+{
+ GPtrArray *apps;
+ JsonNode *json_root;
+ JsonObject *json_item;
+// guint i;
+ g_autoptr(JsonParser) json_parser = NULL;
+
+ /* nothing */
+ if (data == NULL) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "server returned no data");
+ return NULL;
+ }
+
+ /* parse the data and find the success */
+ json_parser = json_parser_new ();
+ if (!json_parser_load_from_data (json_parser, data, data_len, error))
+ return NULL;
+ json_root = json_parser_get_root (json_parser);
+ if (json_root == NULL) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no error root");
+ return NULL;
+ }
+ if (json_node_get_node_type (json_root) != JSON_NODE_OBJECT) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no error object");
+ return NULL;
+ }
+ json_item = json_node_get_object (json_root);
+ if (json_item == NULL) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no error object");
+ return NULL;
+ }
+ apps = g_ptr_array_new ();
+ return apps;
+}
+
+/**
+ * gs_plugin_shell_extensions_get_apps:
+ */
+static GPtrArray *
+gs_plugin_shell_extensions_get_apps (GsPlugin *plugin, GError **error)
+{
+ GPtrArray *apps;
+ guint status_code;
+ g_autofree gchar *cachedir = NULL;
+ g_autofree gchar *cachefn = NULL;
+ g_autofree gchar *data = NULL;
+ g_autofree gchar *uri = NULL;
+ g_autoptr(GFile) cachefn_file = NULL;
+ g_autoptr(SoupMessage) msg = NULL;
+
+ /* look in the cache */
+ cachedir = gs_utils_get_cachedir ("extensions", error);
+ if (cachedir == NULL)
+ return NULL;
+ cachefn = g_strdup_printf ("%s/gnome.json", cachedir);
+ cachefn_file = g_file_new_for_path (cachefn);
+ if (gs_utils_get_file_age (cachefn_file) < SHELL_EXTENSIONS_CACHE_AGE_MAX) {
+ g_autofree gchar *json_data = NULL;
+ if (!g_file_get_contents (cachefn, &json_data, NULL, error))
+ return NULL;
+ g_debug ("got cached extension data from %s", cachefn);
+ return gs_plugin_shell_extensions_parse_apps (json_data, -1, error);
+ }
+
+ /* create the GET data */
+ uri = g_strdup_printf ("%s/?shell_version=%s&page=1&n_per_page=1000",
+ SHELL_EXTENSIONS_API_URI,
+ "3.20");
+ msg = soup_message_new (SOUP_METHOD_GET, uri);
+ status_code = soup_session_send_message (plugin->soup_session, msg);
+ if (status_code != SOUP_STATUS_OK) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "failed to get shell extensions: %s",
+ msg->response_body->data);
+ return NULL;
+ }
+ g_debug ("%s returned: %s",
+ SHELL_EXTENSIONS_API_URI,
+ msg->response_body->data);
+ apps = gs_plugin_shell_extensions_parse_apps (msg->response_body->data,
+ msg->response_body->length,
+ error);
+ if (apps == NULL)
+ return NULL;
+
+ /* save to the cache */
+ if (!g_file_set_contents (cachefn,
+ msg->response_body->data,
+ msg->response_body->length,
+ error))
+ return NULL;
+
+ return apps;
+}
+
+/**
+ * _gs_plugin_startup:
+ */
+static gboolean
+_gs_plugin_startup (GsPlugin *plugin, GError **error)
+{
+ AsApp *app;
+ guint i;
+ g_autoptr(GPtrArray) apps = NULL;
+
+ /* get data */
+ apps = gs_plugin_shell_extensions_get_apps (plugin, error);
+ if (apps == NULL)
+ return FALSE;
+
+ /* add to global store */
+ for (i = 0; i < apps->len; i++) {
+ app = g_ptr_array_index (apps, i);
+ g_debug ("Adding to global store %s", as_app_get_id (app));
+ }
+
+ return TRUE;
+}
+
+/**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+ plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
+
+ /* this really belongs in _startup() or something that runs as a 2nd phase */
+ _gs_plugin_startup (plugin, NULL);
+}
+
+/**
+ * gs_plugin_destroy:
+ */
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+ if (plugin->priv->distros != NULL)
+ g_ptr_array_unref (plugin->priv->distros);
+}
+
+/**
+ * gs_plugin_add_category_apps:
+ */
+gboolean
+gs_plugin_add_category_apps (GsPlugin *plugin,
+ GsCategory *category,
+ GList **list,
+ GCancellable *cancellable,
+ GError **error)
+{
+ if (g_strcmp0 (gs_category_get_id (category), "shell-extensions") != 0)
+ return TRUE;
+
+ //FIXME: add apps with the ShellExtensions management plugin?
+ //FIXME or leave to the appstream plugin?
+ return TRUE;
+}
+
+/**
+ * gs_plugin_app_remove:
+ */
+gboolean
+gs_plugin_app_remove (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "ShellExtensions") != 0)
+ return TRUE;
+
+ /* FIXME */
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "Not yet supported");
+ return FALSE;
+}
+
+/**
+ * gs_plugin_app_install:
+ */
+gboolean
+gs_plugin_app_install (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "ShellExtensions") != 0)
+ return TRUE;
+
+ /* FIXME */
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "No yet supported");
+ return FALSE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]