static gboolean gs_plugin_odrs_vote (GsPlugin *plugin, AsReview *review, const gchar *uri, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); const gchar *tmp; g_autofree gchar *data = NULL; g_autoptr(JsonBuilder) builder = NULL; g_autoptr(JsonGenerator) json_generator = NULL; g_autoptr(JsonNode) json_root = NULL; /* create object with vote data */ builder = json_builder_new (); json_builder_begin_object (builder); json_builder_set_member_name (builder, "user_hash"); json_builder_add_string_value (builder, priv->user_hash); json_builder_set_member_name (builder, "user_skey"); json_builder_add_string_value (builder, as_review_get_metadata_item (review, "user_skey")); json_builder_set_member_name (builder, "app_id"); json_builder_add_string_value (builder, as_review_get_metadata_item (review, "app_id")); tmp = as_review_get_id (review); if (tmp != NULL) { gint64 review_id; json_builder_set_member_name (builder, "review_id"); review_id = g_ascii_strtoll (tmp, NULL, 10); json_builder_add_int_value (builder, review_id); } json_builder_end_object (builder); /* export as a string */ json_root = json_builder_get_root (builder); json_generator = json_generator_new (); json_generator_set_pretty (json_generator, TRUE); json_generator_set_root (json_generator, json_root); data = json_generator_to_data (json_generator, NULL); if (data == NULL) return FALSE; /* clear cache */ if (!gs_plugin_odrs_invalidate_cache (review, error)) return FALSE; /* send to server */ if (!gs_plugin_odrs_json_post (gs_plugin_get_soup_session (plugin), uri, data, error)) return FALSE; /* mark as voted */ as_review_add_flags (review, AS_REVIEW_FLAG_VOTED); /* success */ return TRUE; }
gboolean gs_plugin_review_remove (GsPlugin *plugin, GsApp *app, AsReview *review, GCancellable *cancellable, GError **error) { const gchar *review_id; g_autofree gchar *path = NULL; guint status_code; /* Can only modify Ubuntu reviews */ review_id = as_review_get_metadata_item (review, "ubuntu-id"); if (review_id == NULL) return TRUE; /* Create message for reviews.ubuntu.com */ path = g_strdup_printf ("/api/1.0/reviews/delete/%s/", review_id); if (!send_review_request (plugin, SOUP_METHOD_POST, path, NULL, TRUE, &status_code, NULL, cancellable, error)) return FALSE; if (status_code != SOUP_STATUS_OK) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to remove review, server returned status code %u", status_code); return FALSE; } return TRUE; }
static gboolean gs_plugin_odrs_refine_reviews (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); AsReview *review; guint i; g_autoptr(AsProfileTask) ptask = NULL; g_autoptr(GPtrArray) reviews = NULL; /* profile */ ptask = as_profile_start_literal (gs_plugin_get_profile (plugin), "odrs::refine-reviews"); g_assert (ptask != NULL); /* get from server */ reviews = gs_plugin_odrs_fetch_for_app (plugin, app, error); if (reviews == NULL) return FALSE; for (i = 0; i < reviews->len; i++) { review = g_ptr_array_index (reviews, i); /* save this on the application object so we can use it for * submitting a new review */ if (i == 0) { gs_app_set_metadata (app, "ODRS::user_skey", as_review_get_metadata_item (review, "user_skey")); } /* ignore invalid reviews */ if (as_review_get_rating (review) == 0) continue; /* the user_hash matches, so mark this as our own review */ if (g_strcmp0 (as_review_get_reviewer_id (review), priv->user_hash) == 0) { as_review_set_flags (review, AS_REVIEW_FLAG_SELF); } gs_app_add_review (app, review); } return TRUE; }
gboolean gs_plugin_review_downvote (GsPlugin *plugin, GsApp *app, AsReview *review, GCancellable *cancellable, GError **error) { const gchar *review_id; /* Can only modify Ubuntu reviews */ review_id = as_review_get_metadata_item (review, "ubuntu-id"); if (review_id == NULL) return TRUE; if (!set_review_usefulness (plugin, review_id, FALSE, cancellable, error)) return FALSE; as_review_add_flags (review, AS_REVIEW_FLAG_VOTED); return TRUE; }
static gboolean gs_plugin_odrs_invalidate_cache (AsReview *review, GError **error) { g_autofree gchar *cachefn_basename = NULL; g_autofree gchar *cachefn = NULL; g_autoptr(GFile) cachefn_file = NULL; /* look in the cache */ cachefn_basename = g_strdup_printf ("%s.json", as_review_get_metadata_item (review, "app_id")); cachefn = gs_utils_get_cache_filename ("reviews", cachefn_basename, GS_UTILS_CACHE_FLAG_WRITEABLE, error); if (cachefn == NULL) return FALSE; cachefn_file = g_file_new_for_path (cachefn); if (!g_file_query_exists (cachefn_file, NULL)) return TRUE; return g_file_delete (cachefn_file, NULL, error); }
gboolean gs_plugin_review_report (GsPlugin *plugin, GsApp *app, AsReview *review, GCancellable *cancellable, GError **error) { const gchar *review_id; g_autofree gchar *reason = NULL; g_autofree gchar *text = NULL; g_autofree gchar *path = NULL; guint status_code; /* Can only modify Ubuntu reviews */ review_id = as_review_get_metadata_item (review, "ubuntu-id"); if (review_id == NULL) return TRUE; /* Create message for reviews.ubuntu.com */ reason = soup_uri_encode ("FIXME: gnome-software", NULL); text = soup_uri_encode ("FIXME: gnome-software", NULL); path = g_strdup_printf ("/api/1.0/reviews/%s/recommendations/?reason=%s&text=%s", review_id, reason, text); if (!send_review_request (plugin, SOUP_METHOD_POST, path, NULL, TRUE, &status_code, NULL, cancellable, error)) return FALSE; if (status_code != SOUP_STATUS_CREATED) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to report review, server returned status code %u", status_code); return FALSE; } as_review_add_flags (review, AS_REVIEW_FLAG_VOTED); return TRUE; }
gboolean gs_plugin_add_unvoted_reviews (GsPlugin *plugin, GsAppList *list, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); guint status_code; guint i; g_autofree gchar *uri = NULL; g_autoptr(GHashTable) hash = NULL; g_autoptr(GPtrArray) reviews = NULL; g_autoptr(SoupMessage) msg = NULL; /* create the GET data *with* the machine hash so we can later * review the application ourselves */ uri = g_strdup_printf ("%s/moderate/%s/%s", priv->review_server, priv->user_hash, gs_plugin_get_locale (plugin)); msg = soup_message_new (SOUP_METHOD_GET, uri); status_code = soup_session_send_message (gs_plugin_get_soup_session (plugin), msg); if (status_code != SOUP_STATUS_OK) { if (!gs_plugin_odrs_parse_success (msg->response_body->data, msg->response_body->length, error)) return FALSE; /* not sure what to do here */ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_DOWNLOAD_FAILED, "status code invalid"); gs_utils_error_add_unique_id (error, priv->cached_origin); return FALSE; } g_debug ("odrs returned: %s", msg->response_body->data); reviews = gs_plugin_odrs_parse_reviews (plugin, msg->response_body->data, msg->response_body->length, error); if (reviews == NULL) return FALSE; /* look at all the reviews; faking application objects */ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); for (i = 0; i < reviews->len; i++) { GsApp *app; AsReview *review; const gchar *app_id; /* same app? */ review = g_ptr_array_index (reviews, i); app_id = as_review_get_metadata_item (review, "app_id"); app = g_hash_table_lookup (hash, app_id); if (app == NULL) { app = gs_plugin_create_app_dummy (app_id); gs_app_list_add (list, app); g_hash_table_insert (hash, g_strdup (app_id), app); } gs_app_add_review (app, review); } return TRUE; }
gboolean gs_plugin_review_submit (GsPlugin *plugin, GsApp *app, AsReview *review, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autofree gchar *data = NULL; g_autofree gchar *uri = NULL; g_autofree gchar *version = NULL; g_autoptr(JsonBuilder) builder = NULL; g_autoptr(JsonGenerator) json_generator = NULL; g_autoptr(JsonNode) json_root = NULL; /* save as we don't re-request the review from the server */ as_review_set_reviewer_name (review, g_get_real_name ()); as_review_add_metadata (review, "app_id", gs_app_get_id (app)); as_review_add_metadata (review, "user_skey", gs_app_get_metadata_item (app, "ODRS::user_skey")); /* create object with review data */ builder = json_builder_new (); json_builder_begin_object (builder); json_builder_set_member_name (builder, "user_hash"); json_builder_add_string_value (builder, priv->user_hash); json_builder_set_member_name (builder, "user_skey"); json_builder_add_string_value (builder, as_review_get_metadata_item (review, "user_skey")); json_builder_set_member_name (builder, "app_id"); json_builder_add_string_value (builder, as_review_get_metadata_item (review, "app_id")); json_builder_set_member_name (builder, "locale"); json_builder_add_string_value (builder, gs_plugin_get_locale (plugin)); json_builder_set_member_name (builder, "distro"); json_builder_add_string_value (builder, priv->distro); json_builder_set_member_name (builder, "version"); version = gs_plugin_odrs_sanitize_version (as_review_get_version (review)); json_builder_add_string_value (builder, version); json_builder_set_member_name (builder, "user_display"); json_builder_add_string_value (builder, as_review_get_reviewer_name (review)); json_builder_set_member_name (builder, "summary"); json_builder_add_string_value (builder, as_review_get_summary (review)); json_builder_set_member_name (builder, "description"); json_builder_add_string_value (builder, as_review_get_description (review)); json_builder_set_member_name (builder, "rating"); json_builder_add_int_value (builder, as_review_get_rating (review)); json_builder_end_object (builder); /* export as a string */ json_root = json_builder_get_root (builder); json_generator = json_generator_new (); json_generator_set_pretty (json_generator, TRUE); json_generator_set_root (json_generator, json_root); data = json_generator_to_data (json_generator, NULL); /* clear cache */ if (!gs_plugin_odrs_invalidate_cache (review, error)) return FALSE; /* POST */ uri = g_strdup_printf ("%s/submit", priv->review_server); return gs_plugin_odrs_json_post (gs_plugin_get_soup_session (plugin), uri, data, error); }