/**
 * gs_plugin_xdg_app_reviews_invalidate_cache:
 */
static gboolean
gs_plugin_xdg_app_reviews_invalidate_cache (GsReview *review, GError **error)
{
	g_autofree gchar *cachedir = NULL;
	g_autofree gchar *cachefn = NULL;
	g_autoptr(GFile) cachefn_file = NULL;

	/* look in the cache */
	cachedir = gs_utils_get_cachedir ("reviews", error);
	if (cachedir == NULL)
		return FALSE;
	cachefn = g_strdup_printf ("%s/%s.json",
				   cachedir,
				   gs_review_get_metadata_item (review, "app_id"));
	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);
}
示例#2
0
/**
 * gs_refine_item_pixbuf:
 */
static void
gs_refine_item_pixbuf (GsPlugin *plugin, GsApp *app, AsApp *item)
{
	AsIcon *icon;
	gboolean ret;
	g_autoptr(GError) error = NULL;
	g_autofree gchar *fn = NULL;
	g_autofree gchar *cachedir = NULL;

	icon = as_app_get_icon_default (item);
	switch (as_icon_get_kind (icon)) {
	case AS_ICON_KIND_REMOTE:
		gs_app_set_icon (app, icon);
		if (as_icon_get_filename (icon) == NULL) {
			cachedir = gs_utils_get_cachedir ("icons", NULL);
			fn = g_build_filename (cachedir, as_icon_get_name (icon), NULL);
			as_icon_set_filename (icon, fn);
			as_icon_set_prefix (icon, cachedir);
		}
		if (g_file_test (fn, G_FILE_TEST_EXISTS)) {
			as_icon_set_kind (icon, AS_ICON_KIND_LOCAL);
			ret = gs_app_load_icon (app, plugin->scale, &error);
			if (!ret) {
				g_warning ("failed to load icon %s: %s",
					   as_icon_get_name (icon),
					   error->message);
				return;
			}
		}
		break;
	case AS_ICON_KIND_STOCK:
	case AS_ICON_KIND_LOCAL:
		gs_app_set_icon (app, icon);

		/* does not exist, so try to find using the icon theme */
		if (as_icon_get_kind (icon) == AS_ICON_KIND_LOCAL &&
		    as_icon_get_filename (icon) == NULL)
			as_icon_set_kind (icon, AS_ICON_KIND_STOCK);

		/* load */
		ret = gs_app_load_icon (app, plugin->scale, &error);
		if (!ret) {
			g_warning ("failed to load %s icon %s: %s",
				   as_icon_kind_to_string (as_icon_get_kind (icon)),
				   as_icon_get_name (icon),
				   error->message);
				return;
		}
		break;
	case AS_ICON_KIND_CACHED:
		if (plugin->scale == 2)
			icon = as_app_get_icon_for_size (item, 128, 128);
		if (icon == NULL)
			icon = as_app_get_icon_for_size (item, 64, 64);
		if (icon == NULL) {
			g_warning ("failed to find cached icon %s",
				   as_icon_get_name (icon));
			return;
		}
		if (!as_icon_load (icon, AS_ICON_LOAD_FLAG_SEARCH_SIZE, &error)) {
			g_warning ("failed to load cached icon %s: %s",
				   as_icon_get_name (icon), error->message);
				return;
		}
		gs_app_set_pixbuf (app, as_icon_get_pixbuf (icon));
		break;
	default:
		g_warning ("icon kind unknown for %s", as_app_get_id (item));
		break;
	}
}
/**
 * xdg_app_review_fetch_for_app:
 */
static GPtrArray *
xdg_app_review_fetch_for_app (GsPlugin *plugin, GsApp *app, GError **error)
{
	const gchar *version;
	guint karma_min;
	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(GPtrArray) reviews = NULL;
	g_autoptr(JsonBuilder) builder = NULL;
	g_autoptr(JsonGenerator) json_generator = NULL;
	g_autoptr(JsonNode) json_root = NULL;
	g_autoptr(SoupMessage) msg = NULL;

	/* look in the cache */
	cachedir = gs_utils_get_cachedir ("reviews", error);
	if (cachedir == NULL)
		return NULL;
	cachefn = g_strdup_printf ("%s/%s.json", cachedir, gs_app_get_id_no_prefix (app));
	cachefn_file = g_file_new_for_path (cachefn);
	if (gs_utils_get_file_age (cachefn_file) < XDG_APP_REVIEW_CACHE_AGE_MAX) {
		g_autofree gchar *json_data = NULL;
		if (!g_file_get_contents (cachefn, &json_data, NULL, error))
			return NULL;
		g_debug ("got review data for %s from %s",
			 gs_app_get_id_no_prefix (app), cachefn);
		return xdg_app_review_parse_reviews (json_data, -1, error);
	}

	/* not always available */
	version = gs_app_get_version (app);
	if (version == NULL)
		version = "unknown";

	/* 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, plugin->priv->user_hash);
	json_builder_set_member_name (builder, "app_id");
	json_builder_add_string_value (builder, gs_app_get_id_no_prefix (app));
	json_builder_set_member_name (builder, "locale");
	json_builder_add_string_value (builder, plugin->locale);
	json_builder_set_member_name (builder, "distro");
	json_builder_add_string_value (builder, plugin->priv->distro);
	json_builder_set_member_name (builder, "version");
	json_builder_add_string_value (builder, version);
	json_builder_set_member_name (builder, "limit");
	json_builder_add_int_value (builder, XDG_APP_REVIEW_NUMBER_RESULTS_MAX);
	json_builder_set_member_name (builder, "karma");
	karma_min = g_settings_get_int (plugin->priv->settings,
					"review-karma-required");
	json_builder_add_int_value (builder, karma_min);
	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 NULL;
	uri = g_strdup_printf ("%s/fetch", plugin->priv->review_server);
	msg = soup_message_new (SOUP_METHOD_POST, uri);
	soup_message_set_request (msg, "application/json",
				  SOUP_MEMORY_COPY, data, strlen (data));
	status_code = soup_session_send_message (plugin->soup_session, msg);
	if (status_code != SOUP_STATUS_OK) {
		if (!xdg_app_review_parse_success (msg->response_body->data,
						   msg->response_body->length,
						   error))
			return NULL;
		/* not sure what to do here */
		g_set_error_literal (error,
				     GS_PLUGIN_ERROR,
				     GS_PLUGIN_ERROR_FAILED,
				     "status code invalid");
		return NULL;
	}
	reviews = xdg_app_review_parse_reviews (msg->response_body->data,
						msg->response_body->length,
						error);
	if (reviews == NULL)
		return NULL;
	g_debug ("xdg-app-review returned: %s", msg->response_body->data);

	/* save to the cache */
	if (!g_file_set_contents (cachefn,
				  msg->response_body->data,
				  msg->response_body->length,
				  error))
		return NULL;

	/* success */
	return g_steal_pointer (&reviews);
}
/**
 * xdg_app_review_get_ratings:
 */
static GArray *
xdg_app_review_get_ratings (GsPlugin *plugin, GsApp *app, GError **error)
{
	GArray *ratings;
	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 ("ratings", error);
	if (cachedir == NULL)
		return NULL;
	cachefn = g_strdup_printf ("%s/%s.json", cachedir, gs_app_get_id_no_prefix (app));
	cachefn_file = g_file_new_for_path (cachefn);
	if (gs_utils_get_file_age (cachefn_file) < XDG_APP_REVIEW_CACHE_AGE_MAX) {
		g_autofree gchar *json_data = NULL;
		if (!g_file_get_contents (cachefn, &json_data, NULL, error))
			return NULL;
		g_debug ("got ratings data for %s from %s",
			 gs_app_get_id_no_prefix (app), cachefn);
		return xdg_app_review_parse_ratings (json_data, -1, error);
	}

	/* create the GET data *with* the machine hash so we can later
	 * review the application ourselves */
	uri = g_strdup_printf ("%s/ratings/%s",
			       plugin->priv->review_server,
			       gs_app_get_id_no_prefix (app));
	msg = soup_message_new (SOUP_METHOD_GET, uri);
	status_code = soup_session_send_message (plugin->soup_session, msg);
	if (status_code != SOUP_STATUS_OK) {
		if (!xdg_app_review_parse_success (msg->response_body->data,
						   msg->response_body->length,
						   error))
			return NULL;
		/* not sure what to do here */
		g_set_error_literal (error,
				     GS_PLUGIN_ERROR,
				     GS_PLUGIN_ERROR_FAILED,
				     "status code invalid");
		return NULL;
	}
	g_debug ("xdg-app-review returned: %s", msg->response_body->data);
	ratings = xdg_app_review_parse_ratings (msg->response_body->data,
						msg->response_body->length,
						error);
	if (ratings == 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 ratings;
}