[gnome-software/wip/rancell/ubuntu-ratings] Attempt to upload ratings to reviews.ubuntu.com
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/rancell/ubuntu-ratings] Attempt to upload ratings to reviews.ubuntu.com
- Date: Fri, 11 Dec 2015 01:36:28 +0000 (UTC)
commit 5fca825651eacd6a5e423a5bfe799d079628f238
Author: Robert Ancell <robert ancell canonical com>
Date: Fri Dec 11 14:34:55 2015 +1300
Attempt to upload ratings to reviews.ubuntu.com
configure.ac | 1 +
src/plugins/Makefile.am | 3 +-
src/plugins/gs-plugin-ubuntu-reviews.c | 186 ++++++++++++++++++++++++++++----
3 files changed, 168 insertions(+), 22 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index b001017..caf89d1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,7 @@ PKG_CHECK_MODULES(GSETTINGS_DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.11.5
PKG_CHECK_MODULES(GNOME_DESKTOP, gnome-desktop-3.0 >= 3.17.92)
PKG_CHECK_MODULES(POLKIT, polkit-gobject-1)
PKG_CHECK_MODULES(JSON_GLIB, json-glib-1.0 >= 0.12)
+PKG_CHECK_MODULES(OAUTH, oauth)
AC_PATH_PROG(APPSTREAM_UTIL, [appstream-util], [unfound])
AC_ARG_ENABLE(man,
[AS_HELP_STRING([--enable-man],
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index ba38d96..aef1e58 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -9,6 +9,7 @@ AM_CPPFLAGS = \
$(PACKAGEKIT_CFLAGS) \
$(SOUP_CFLAGS) \
$(SQLITE_CFLAGS) \
+ $(OAUTH_CFLAGS) \
$(FWUPD_CFLAGS) \
$(LIMBA_CFLAGS) \
$(JSON_GLIB_CFLAGS) \
@@ -133,7 +134,7 @@ libgs_plugin_local_ratings_la_LDFLAGS = -module -avoid-version
libgs_plugin_local_ratings_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
libgs_plugin_ubuntu_reviews_la_SOURCES = gs-plugin-ubuntu-reviews.c
-libgs_plugin_ubuntu_reviews_la_LIBADD = $(GS_PLUGIN_LIBS) $(SOUP_LIBS) $(SQLITE_LIBS) $(JSON_GLIB_LIBS)
+libgs_plugin_ubuntu_reviews_la_LIBADD = $(GS_PLUGIN_LIBS) $(SOUP_LIBS) $(SQLITE_LIBS) $(JSON_GLIB_LIBS)
$(OAUTH_LIBS)
libgs_plugin_ubuntu_reviews_la_LDFLAGS = -module -avoid-version
libgs_plugin_ubuntu_reviews_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
diff --git a/src/plugins/gs-plugin-ubuntu-reviews.c b/src/plugins/gs-plugin-ubuntu-reviews.c
index 6e5a203..c63d3e8 100644
--- a/src/plugins/gs-plugin-ubuntu-reviews.c
+++ b/src/plugins/gs-plugin-ubuntu-reviews.c
@@ -25,6 +25,7 @@
#include <libsoup/soup.h>
#include <sqlite3.h>
#include <json-glib/json-glib.h>
+#include <oauth.h>
#include <gs-plugin.h>
#include <gs-utils.h>
@@ -44,23 +45,17 @@ typedef struct {
gint64 five_star_count;
} Histogram;
-/**
- * gs_plugin_get_name:
- */
const gchar *
gs_plugin_get_name (void)
{
return "ubuntu-reviews";
}
-#define GS_PLUGIN_UBUNTU_REVIEWS_SERVER "https://reviews.ubuntu.com/reviews"
+#define UBUNTU_REVIEWS_SERVER "https://reviews.ubuntu.com/reviews"
/* 3 months */
#define GS_PLUGIN_UBUNTU_REVIEWS_AGE_MAX (60 * 60 * 24 * 7 * 4 * 3)
-/**
- * gs_plugin_initialize:
- */
void
gs_plugin_initialize (GsPlugin *plugin)
{
@@ -80,9 +75,6 @@ gs_plugin_initialize (GsPlugin *plugin)
}
}
-/**
- * gs_plugin_get_deps:
- */
const gchar **
gs_plugin_get_deps (GsPlugin *plugin)
{
@@ -90,9 +82,6 @@ gs_plugin_get_deps (GsPlugin *plugin)
return deps;
}
-/**
- * gs_plugin_destroy:
- */
void
gs_plugin_destroy (GsPlugin *plugin)
{
@@ -125,16 +114,174 @@ setup_networking (GsPlugin *plugin, GError **error)
return TRUE;
}
-/**
- * gs_plugin_app_set_rating:
- */
+static void
+add_string_member (JsonBuilder *builder, const gchar *name, const gchar *value)
+{
+ json_builder_set_member_name (builder, name);
+ json_builder_add_string_value (builder, value);
+}
+
+static void
+add_int_member (JsonBuilder *builder, const gchar *name, gint64 value)
+{
+ json_builder_set_member_name (builder, name);
+ json_builder_add_int_value (builder, value);
+}
+
+static void
+sign_message (SoupMessage *message, OAuthMethod method,
+ const gchar *oauth_consumer_key, const gchar *oauth_consumer_secret,
+ const gchar *oauth_token, const gchar *oauth_token_secret)
+{
+ g_autofree gchar *url = NULL, *oauth_authorization_parameters = NULL, *authorization_text = NULL;
+ gchar **url_parameters = NULL;
+ int url_parameters_length;
+
+ url = soup_uri_to_string (soup_message_get_uri (message), FALSE);
+
+ url_parameters_length = oauth_split_url_parameters(url, &url_parameters);
+ oauth_sign_array2_process (&url_parameters_length, &url_parameters,
+ NULL,
+ method,
+ message->method,
+ oauth_consumer_key, oauth_consumer_secret,
+ oauth_token, oauth_token_secret);
+ oauth_authorization_parameters = oauth_serialize_url_sep (url_parameters_length, 1, url_parameters,
", ", 6);
+ oauth_free_array (&url_parameters_length, &url_parameters);
+ authorization_text = g_strdup_printf ("OAuth realm=\"Ratings and Reviews\", %s",
oauth_authorization_parameters);
+ soup_message_headers_append (message->request_headers, "Authorization", authorization_text);
+}
+
+static void
+set_request (SoupMessage *message, JsonBuilder *builder)
+{
+ JsonGenerator *generator = json_generator_new ();
+ json_generator_set_root (generator, json_builder_get_root (builder));
+ gsize length;
+ gchar *data = json_generator_to_data (generator, &length);
+ soup_message_set_request (message, "application/json", SOUP_MEMORY_TAKE, data, length);
+ g_object_unref (generator);
+}
+
+static gboolean
+set_package_rating (GsPlugin *plugin,
+ GsApp *app,
+ const gchar *package_name,
+ GError **error)
+{
+ g_autofree gchar *uri = NULL, *path = NULL;
+ g_autofree gchar *oauth_consumer_key = NULL, *oauth_consumer_secret = NULL, *oauth_token = NULL,
*oauth_token_secret = NULL;
+ const gchar *review_text = NULL;
+ g_autoptr(GKeyFile) config = NULL;
+ gint rating, n_stars = 0;
+ g_autoptr(SoupMessage) msg = NULL;
+ JsonBuilder *builder;
+ guint status_code;
+
+ /* Ubuntu reviews require a summary and description - just make one up for now */
+ rating = gs_app_get_rating (app);
+ if (rating > 80) {
+ review_text = "★★★★★";
+ n_stars = 5;
+ }
+ else if (rating > 60) {
+ review_text = "★★★★";
+ n_stars = 4;
+ }
+ else if (rating > 40) {
+ review_text = "★★★";
+ n_stars = 3;
+ }
+ else if (rating > 20) {
+ review_text = "★★";
+ n_stars = 2;
+ }
+ else {
+ review_text = "★";
+ n_stars = 1;
+ }
+
+ /* Load OAuth token - FIXME needs to integrate with GNOME Online Accounts / libaccounts */
+ config = g_key_file_new ();
+ path = g_build_filename (g_get_user_config_dir (), "gnome-software", "ubuntu-one-credentials", NULL);
+ g_key_file_load_from_file (config, path, G_KEY_FILE_NONE, NULL);
+ oauth_consumer_key = g_key_file_get_string (config, "gnome-software", "consumer-key", NULL);
+ oauth_consumer_secret = g_key_file_get_string (config, "gnome-software", "consumer-secret", NULL);
+ oauth_token = g_key_file_get_string (config, "gnome-software", "token", NULL);
+ oauth_token_secret = g_key_file_get_string (config, "gnome-software", "token-secret", NULL);
+ if (!oauth_consumer_key || !oauth_consumer_secret || !oauth_token || !oauth_token_secret) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "%s", "No Ubuntu One OAuth tokens");
+ return FALSE;
+ }
+
+ uri = g_strdup_printf ("%s/api/1.0/reviews/", UBUNTU_REVIEWS_SERVER);
+ msg = soup_message_new (SOUP_METHOD_POST, uri);
+ builder = json_builder_new ();
+ json_builder_begin_object (builder);
+ add_string_member (builder, "package_name", package_name);
+ add_string_member (builder, "summary", review_text);
+ add_string_member (builder, "review_text", review_text);
+ add_string_member (builder, "language", "en"); // FIXME
+ add_string_member (builder, "origin", gs_app_get_origin (app));
+ add_string_member (builder, "distroseries", "xenial"); // FIXME
+ add_string_member (builder, "version", gs_app_get_version (app));
+ add_int_member (builder, "rating", n_stars);
+ add_string_member (builder, "arch_tag", "amd64"); // FIXME
+ json_builder_end_object (builder);
+ set_request (msg, builder);
+ g_object_unref (builder);
+ sign_message (msg, OA_HMAC, oauth_consumer_key, oauth_consumer_secret, oauth_token,
oauth_token_secret);
+
+ status_code = soup_session_send_message (plugin->priv->session, msg);
+ if (status_code != SOUP_STATUS_OK) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "Failed to post review: %s",
+ soup_status_get_phrase (status_code));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
gboolean
gs_plugin_app_set_rating (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
GError **error)
{
- return FALSE;
+ GPtrArray *sources;
+ const gchar *package_name;
+ gboolean ret;
+ guint i;
+ g_autoptr(SoupMessage) msg = NULL;
+
+ /* get the package name */
+ sources = gs_app_get_sources (app);
+ if (sources->len == 0) {
+ g_warning ("no package name for %s", gs_app_get_id (app));
+ return TRUE;
+ }
+
+ if (!setup_networking (plugin, error))
+ return FALSE;
+
+ /* set rating for each package */
+ for (i = 0; i < sources->len; i++) {
+ package_name = g_ptr_array_index (sources, i);
+ ret = set_package_rating (plugin,
+ app,
+ package_name,
+ error);
+ if (!ret)
+ return FALSE;
+ }
+
+ return TRUE;
}
static gint
@@ -296,7 +443,7 @@ download_review_stats (GsPlugin *plugin, GError **error)
/* Get the review stats using HTTP */
uri = g_strdup_printf ("%s/api/1.0/review-stats/any/any/",
- GS_PLUGIN_UBUNTU_REVIEWS_SERVER);
+ UBUNTU_REVIEWS_SERVER);
msg = soup_message_new (SOUP_METHOD_GET, uri);
if (!setup_networking (plugin, error))
return FALSE;
@@ -462,9 +609,6 @@ get_rating (GsPlugin *plugin,
return TRUE;
}
-/**
- * gs_plugin_refine:
- */
gboolean
gs_plugin_refine (GsPlugin *plugin,
GList **list,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]