[gnome-software/wip/hughsie/xdg-app-reviews] Add a plugin to do application reviews using the xdg-app webservice
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/xdg-app-reviews] Add a plugin to do application reviews using the xdg-app webservice
- Date: Wed, 3 Feb 2016 16:47:02 +0000 (UTC)
commit 63759e81fe7608f01d270c1270f4580b25d87d4f
Author: Richard Hughes <richard hughsie com>
Date: Wed Feb 3 16:42:46 2016 +0000
Add a plugin to do application reviews using the xdg-app webservice
src/plugins/Makefile.am | 14 ++
src/plugins/gs-plugin-xdg-app-reviews.c | 305 +++++++++++++++++++++++++++++++
2 files changed, 319 insertions(+), 0 deletions(-)
---
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 3349a3f..0ab42f1 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -10,6 +10,7 @@ AM_CPPFLAGS = \
$(SOUP_CFLAGS) \
$(SQLITE_CFLAGS) \
$(FWUPD_CFLAGS) \
+ $(JSON_GLIB_CFLAGS) \
$(LIMBA_CFLAGS) \
$(XDG_APP_CFLAGS) \
-DBINDIR=\"$(bindir)\" \
@@ -23,6 +24,14 @@ AM_CPPFLAGS = \
-DTESTDATADIR=\""$(top_srcdir)/data/tests"\" \
-I$(top_srcdir)/src
+noinst_PROGRAMS = xdg-app-reviews
+xdg_app_reviews_SOURCES = gs-plugin-xdg-app-reviews.c
+xdg_app_reviews_LDADD = $(GLIB_LIBS) $(JSON_GLIB_LIBS) $(SOUP_LIBS)
+xdg_app_reviews_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
+gnome_software_cmd_CFLAGS = \
+ $(WARN_CFLAGS)
+
noinst_LTLIBRARIES = \
libgs_plugin_self_test.la
@@ -126,6 +135,11 @@ libgs_plugin_xdg_app_la_LDFLAGS = -module -avoid-version
libgs_plugin_xdg_app_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
endif
+#libgs_plugin_xdg_app_reviews_la_SOURCES = gs-plugin-xdg-app-reviews.c
+#libgs_plugin_xdg_app_reviews_la_LIBADD = $(GS_PLUGIN_LIBS) $(JSON_GLIB_LIBS)
+#libgs_plugin_xdg_app_reviews_la_LDFLAGS = -module -avoid-version
+#libgs_plugin_xdg_app_reviews_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
libgs_plugin_moduleset_la_SOURCES = \
gs-moduleset.c \
gs-moduleset.h \
diff --git a/src/plugins/gs-plugin-xdg-app-reviews.c b/src/plugins/gs-plugin-xdg-app-reviews.c
new file mode 100644
index 0000000..5439852
--- /dev/null
+++ b/src/plugins/gs-plugin-xdg-app-reviews.c
@@ -0,0 +1,305 @@
+/* -*- 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 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 <json-glib/json-glib.h>
+#include <libsoup/soup.h>
+#include <string.h>
+
+#define XDG_APP_SERVER "http://apps-xdgapp.rhcloud.com/1.0/reviews"
+//#define XDG_APP_SERVER "http://localhost:5000/1.0/reviews"
+
+#ifndef JsonParser_autoptr
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(JsonParser, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(JsonBuilder, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(JsonNode, json_node_free)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(JsonGenerator, g_object_unref)
+#endif
+
+#define GS_PLUGIN_ERROR 1
+#define GS_PLUGIN_ERROR_FAILED 0
+
+/**
+ * gs_plugin_xdg_app_reviews_parse_results:
+ */
+static gboolean
+gs_plugin_xdg_app_reviews_parse_results (const gchar *data,
+ gsize data_len,
+ GError **error)
+{
+ JsonArray *json_reviews;
+ JsonNode *json_root;
+ guint i;
+ g_autoptr(JsonParser) json_parser = NULL;
+
+ /* parse the data and find the array or ratings */
+ json_parser = json_parser_new ();
+ if (!json_parser_load_from_data (json_parser, data, data_len, error))
+ return FALSE;
+ 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 root");
+ return FALSE;
+ }
+ if (json_node_get_node_type (json_root) != JSON_NODE_ARRAY) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no array");
+ return FALSE;
+ }
+
+ /* parse each rating */
+ json_reviews = json_node_get_array (json_root);
+ for (i = 0; i < json_array_get_length (json_reviews); i++) {
+ JsonNode *json_review;
+ JsonObject *json_item;
+
+ /* extract the data */
+ json_review = json_array_get_element (json_reviews, i);
+ if (json_node_get_node_type (json_review) != JSON_NODE_OBJECT) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no object type");
+ return FALSE;
+ }
+ json_item = json_node_get_object (json_review);
+ if (json_item == NULL) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no object");
+ return FALSE;
+ }
+
+ g_warning ("appid=%s, karma=%" G_GINT64_FORMAT,
+ json_object_get_string_member (json_item, "appid"),
+ json_object_get_int_member (json_item, "karma"));
+ }
+ return TRUE;
+}
+
+/**
+ * gs_plugin_xdg_app_reviews_parse_success:
+ */
+static gboolean
+gs_plugin_xdg_app_reviews_parse_success (const gchar *data,
+ gsize data_len,
+ GError **error)
+{
+ JsonNode *json_root;
+ JsonObject *json_item;
+ const gchar *msg = NULL;
+ g_autoptr(JsonParser) json_parser = 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 FALSE;
+ 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 FALSE;
+ }
+ 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 FALSE;
+ }
+ 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 FALSE;
+ }
+
+ /* failed? */
+ if (json_object_has_member (json_item, "msg"))
+ msg = json_object_get_string_member (json_item, "msg");
+ if (!json_object_get_boolean_member (json_item, "success")) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ msg != NULL ? msg : "unknown failure");
+ return FALSE;
+ }
+
+ /* just for the console */
+ if (msg != NULL)
+ g_debug ("success: %s", msg);
+ return TRUE;
+}
+
+/**
+ * get_reviews_for_appid:
+ */
+static gboolean
+get_reviews_for_appid (SoupSession *session, const gchar *appid, GError **error)
+{
+ guint status_code;
+ g_autofree gchar *uri = NULL;
+ g_autoptr(SoupMessage) msg = NULL;
+
+ /* create the GET data */
+ uri = g_strdup_printf ("%s/app/%s", XDG_APP_SERVER, appid);
+ msg = soup_message_new (SOUP_METHOD_GET, uri);
+ status_code = soup_session_send_message (session, msg);
+ if (status_code != SOUP_STATUS_OK) {
+ return gs_plugin_xdg_app_reviews_parse_success (msg->response_body->data,
+ msg->response_body->length,
+ error);
+ }
+
+ if (!gs_plugin_xdg_app_reviews_parse_results (msg->response_body->data,
+ msg->response_body->length,
+ error)) {
+ return FALSE;
+ }
+
+ g_warning ("GOT: %s", msg->response_body->data);
+ return TRUE;
+}
+
+/**
+ * gs_plugin_get_machine_hash:
+ */
+static gchar *
+gs_plugin_get_machine_hash (GError **error)
+{
+ g_autofree gchar *data = NULL;
+ g_autofree gchar *salted = NULL;
+
+ if (!g_file_get_contents ("/etc/machine-id", &data, NULL, error))
+ return NULL;
+
+ salted = g_strdup_printf ("gnome-software[%s]", data);
+ return g_compute_checksum_for_string (G_CHECKSUM_SHA1, salted, -1);
+}
+
+/**
+ * gs_plugin_xdg_app_reviews_build_review:
+ */
+static gchar *
+gs_plugin_xdg_app_reviews_build_review (GError **error)
+{
+ g_autofree gchar *machine_hash = NULL;
+ g_autoptr(JsonBuilder) json_builder = NULL;
+ g_autoptr(JsonGenerator) json_generator = NULL;
+ g_autoptr(JsonNode) json_root = NULL;
+
+ json_builder = json_builder_new ();
+
+ /* create object with review data */
+ machine_hash = gs_plugin_get_machine_hash (error);
+ if (machine_hash == NULL)
+ return NULL;
+
+ json_builder_begin_object (json_builder);
+ json_builder_set_member_name (json_builder, "user_id");
+ json_builder_add_string_value (json_builder, machine_hash);
+ json_builder_set_member_name (json_builder, "appid");
+ json_builder_add_string_value (json_builder, "org.gnome.Software.desktop");
+ json_builder_set_member_name (json_builder, "locale");
+ json_builder_add_string_value (json_builder, "en_GB");
+ json_builder_set_member_name (json_builder, "distro");
+ json_builder_add_string_value (json_builder, "fedora");
+ json_builder_set_member_name (json_builder, "version");
+ json_builder_add_string_value (json_builder, "3.19.4");
+ json_builder_set_member_name (json_builder, "summary");
+ json_builder_add_string_value (json_builder, "Simply Awesome!");
+ json_builder_set_member_name (json_builder, "description");
+ json_builder_add_string_value (json_builder, "It is really easy to install and remove applications
with this program");
+ json_builder_end_object (json_builder);
+
+ /* export as a string */
+ json_root = json_builder_get_root (json_builder);
+ json_generator = json_generator_new ();
+ json_generator_set_pretty (json_generator, TRUE);
+ json_generator_set_root (json_generator, json_root);
+ return json_generator_to_data (json_generator, NULL);
+}
+
+/**
+ * add_review:
+ */
+static gboolean
+add_review (SoupSession *session, GError **error)
+{
+ guint status_code;
+ g_autofree gchar *data = NULL;
+ g_autofree gchar *uri = NULL;
+ g_autoptr(SoupMessage) msg = NULL;
+
+ /* create the GET data */
+ uri = g_strdup_printf ("%s/app", XDG_APP_SERVER);
+ msg = soup_message_new (SOUP_METHOD_POST, uri);
+ data = gs_plugin_xdg_app_reviews_build_review (error);
+ if (data == NULL)
+ return FALSE;
+g_warning ("SENDING: %s", data);
+ soup_message_set_request (msg, "application/json",
+ SOUP_MEMORY_COPY, data, strlen (data));
+
+ /* set sync request */
+ status_code = soup_session_send_message (session, msg);
+ if (status_code != SOUP_STATUS_OK) {
+ g_warning ("Failed to set rating on xdg-app-review: %s",
+ soup_status_get_phrase (status_code));
+ }
+
+ /* process returned JSON */
+g_warning ("RECIEVED: %s", msg->response_body->data);
+ return gs_plugin_xdg_app_reviews_parse_success (msg->response_body->data,
+ msg->response_body->length,
+ error);
+}
+
+int
+main (void)
+{
+ SoupSession *session;
+ const gchar *appid = "org.gnome.Software.desktop";
+ g_autoptr(GError) error = NULL;
+
+ session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, "FIXME", NULL);
+
+ /* get existing ratings */
+ if (!get_reviews_for_appid (session, appid, &error))
+ g_error ("failed to get reviews: %s", error->message);
+
+ /* add new review */
+ if (!add_review (session, &error))
+ g_error ("failed to add review: %s", error->message);
+
+ g_object_unref (session);
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]