Ejemplo n.º 1
0
/**
 * as_screenshot_get_image_for_locale:
 * @screenshot: a #AsScreenshot instance.
 * @locale: locale, or %NULL
 * @width: target width
 * @height: target height
 *
 * Gets the AsImage closest to the target size with the specified locale.
 * The #AsImage may not actually be the requested size, and the application may
 * have to pad / rescale the image to make it fit.
 *
 * FIXME: This function assumes the images are ordered in preference order, e.g.
 * "en_GB -> en -> NULL"
 *
 * Returns: (transfer none): an #AsImage, or %NULL
 *
 * Since: 0.5.14
 **/
AsImage *
as_screenshot_get_image_for_locale (AsScreenshot *screenshot,
				    const gchar *locale,
				    guint width, guint height)
{
	AsImage *im;
	AsImage *im_best = NULL;
	AsScreenshotPrivate *priv = GET_PRIVATE (screenshot);
	gint64 best_size = G_MAXINT64;
	guint i;
	gint64 tmp;

	g_return_val_if_fail (AS_IS_SCREENSHOT (screenshot), NULL);

	for (i = 0; i < priv->images->len; i++) {
		im = g_ptr_array_index (priv->images, i);
		if (!as_utils_locale_is_compatible (as_image_get_locale (im), locale))
			continue;
		tmp = ABS ((gint64) (width * height) -
			   (gint64) (as_image_get_width (im) * as_image_get_height (im)));
		if (tmp < best_size) {
			best_size = tmp;
			im_best = im;
		}
	}
	return im_best;
}
Ejemplo n.º 2
0
/**
 * gs_appstream_are_screenshots_perfect:
 */
static gboolean
gs_appstream_are_screenshots_perfect (AsApp *app)
{
	AsImage *image;
	AsScreenshot *screenshot;
	GPtrArray *screenshots;
	guint height;
	guint i;
	guint width;

	screenshots = as_app_get_screenshots (app);
	if (screenshots->len == 0)
		return FALSE;
	for (i = 0; i < screenshots->len; i++) {

		/* get the source image as the thumbs will be resized & padded */
		screenshot = g_ptr_array_index (screenshots, i);
		image = as_screenshot_get_source (screenshot);
		if (image == NULL)
			return FALSE;

		width = as_image_get_width (image);
		height = as_image_get_height (image);

		/* too small */
		if (width < AS_IMAGE_LARGE_WIDTH || height < AS_IMAGE_LARGE_HEIGHT)
			return FALSE;

		/* too large */
		if (width > AS_IMAGE_LARGE_WIDTH * 2 || height > AS_IMAGE_LARGE_HEIGHT * 2)
			return FALSE;

		/* not 16:9 */
		if ((width / 16) * 9 != height)
			return FALSE;
	}
	return TRUE;
}
Ejemplo n.º 3
0
static gboolean
ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper)
{
	AsImageAlphaFlags alpha_flags;
	const gchar *url;
	gboolean require_correct_aspect_ratio = FALSE;
	gdouble desired_aspect = 1.777777778;
	gdouble screenshot_aspect;
	guint status_code;
	guint screenshot_height;
	guint screenshot_width;
	guint ss_size_height_max = 900;
	guint ss_size_height_min = 351;
	guint ss_size_width_max = 1600;
	guint ss_size_width_min = 624;
	g_autoptr(GdkPixbuf) pixbuf = NULL;
	g_autoptr(GInputStream) stream = NULL;
	g_autoptr(SoupMessage) msg = NULL;
	g_autoptr(SoupURI) base_uri = NULL;

	/* make the requirements more strict */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_STRICT) > 0) {
		require_correct_aspect_ratio = TRUE;
	}

	/* relax the requirements a bit */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_RELAX) > 0) {
		ss_size_height_max = 1800;
		ss_size_height_min = 150;
		ss_size_width_max = 3200;
		ss_size_width_min = 300;
	}

	/* have we got network access */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_NO_NETWORK) > 0)
		return TRUE;

	/* GET file */
	url = as_image_get_url (im);
	g_debug ("checking %s", url);
	base_uri = soup_uri_new (url);
	if (!SOUP_URI_VALID_FOR_HTTP (base_uri)) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_URL_NOT_FOUND,
				     "<screenshot> url not valid [%s]", url);
		return FALSE;
	}
	msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri);
	if (msg == NULL) {
		g_warning ("Failed to setup message");
		return FALSE;
	}

	/* send sync */
	status_code = soup_session_send_message (helper->session, msg);
	if (SOUP_STATUS_IS_TRANSPORT_ERROR(status_code)) {
		ai_app_validate_add (helper,
			AS_PROBLEM_KIND_URL_NOT_FOUND,
			"<screenshot> failed to connect: %s [%s]",
			soup_status_get_phrase(status_code), url);
		return FALSE;
	} else if (status_code != SOUP_STATUS_OK) {
		ai_app_validate_add (helper,
			AS_PROBLEM_KIND_URL_NOT_FOUND,
			"<screenshot> failed to download (HTTP %d: %s) [%s]",
			status_code, soup_status_get_phrase(status_code), url);
		return FALSE;
	}

	/* check if it's a zero sized file */
	if (msg->response_body->length == 0) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_FILE_INVALID,
				     "<screenshot> url is a zero length file [%s]",
				     url);
		return FALSE;
	}

	/* create a buffer with the data */
	stream = g_memory_input_stream_new_from_data (msg->response_body->data,
						      (gssize) msg->response_body->length,
						      NULL);
	if (stream == NULL) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_URL_NOT_FOUND,
				     "<screenshot> failed to load data [%s]",
				     url);
		return FALSE;
	}

	/* load the image */
	pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
	if (pixbuf == NULL) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_FILE_INVALID,
				     "<screenshot> failed to load [%s]",
				     url);
		return FALSE;
	}

	/* check width matches */
	screenshot_width = (guint) gdk_pixbuf_get_width (pixbuf);
	screenshot_height = (guint) gdk_pixbuf_get_height (pixbuf);
	if (as_image_get_width (im) != 0 &&
	    as_image_get_width (im) != screenshot_width) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> width did not match specified [%s]",
				     url);
	}

	/* check height matches */
	if (as_image_get_height (im) != 0 &&
	    as_image_get_height (im) != screenshot_height) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> height did not match specified [%s]",
				     url);
	}

	/* check size is reasonable */
	if (screenshot_width < ss_size_width_min) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> width too small [%s] minimum is %upx",
				     url, ss_size_width_min);
	}
	if (screenshot_height < ss_size_height_min) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> height too small [%s] minimum is %upx",
				     url, ss_size_height_min);
	}
	if (screenshot_width > ss_size_width_max) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> width too large [%s] maximum is %upx",
				     url, ss_size_width_max);
	}
	if (screenshot_height > ss_size_height_max) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> height too large [%s] maximum is %upx",
				     url, ss_size_height_max);
	}

	/* check padding */
	as_image_set_pixbuf (im, pixbuf);
	alpha_flags = as_image_get_alpha_flags (im);
	if ((alpha_flags & AS_IMAGE_ALPHA_FLAG_TOP) > 0||
	    (alpha_flags & AS_IMAGE_ALPHA_FLAG_BOTTOM) > 0) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_STYLE_INCORRECT,
				     "<image> has vertical padding [%s]",
				     url);
	}
	if ((alpha_flags & AS_IMAGE_ALPHA_FLAG_LEFT) > 0||
	    (alpha_flags & AS_IMAGE_ALPHA_FLAG_RIGHT) > 0) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_STYLE_INCORRECT,
				     "<image> has horizontal padding [%s]",
				     url);
	}

	/* check aspect ratio */
	if (require_correct_aspect_ratio) {
		screenshot_aspect = (gdouble) screenshot_width / (gdouble) screenshot_height;
		if (ABS (screenshot_aspect - 1.777777777) > 0.1) {
			g_debug ("got aspect %.2f, wanted %.2f",
				 screenshot_aspect, desired_aspect);
			ai_app_validate_add (helper,
					     AS_PROBLEM_KIND_ASPECT_RATIO_INCORRECT,
					     "<screenshot> aspect ratio not 16:9 [%s]",
					     url);
		}
	}
	return TRUE;
}
/**
 * ai_app_validate_image_check:
 */
static gboolean
ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper)
{
	const gchar *url;
	gboolean require_correct_aspect_ratio = FALSE;
	gdouble desired_aspect = 1.777777778;
	gdouble screenshot_aspect;
	gint status_code;
	guint screenshot_height;
	guint screenshot_width;
	guint ss_size_height_max = 900;
	guint ss_size_height_min = 351;
	guint ss_size_width_max = 1600;
	guint ss_size_width_min = 624;
	_cleanup_object_unref_ GdkPixbuf *pixbuf = NULL;
	_cleanup_object_unref_ GInputStream *stream = NULL;
	_cleanup_object_unref_ SoupMessage *msg = NULL;
	_cleanup_uri_unref_ SoupURI *base_uri = NULL;

	/* make the requirements more strict */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_STRICT) > 0) {
		require_correct_aspect_ratio = TRUE;
	}

	/* relax the requirements a bit */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_RELAX) > 0) {
		ss_size_height_max = 1800;
		ss_size_height_min = 150;
		ss_size_width_max = 3200;
		ss_size_width_min = 300;
	}

	/* have we got network access */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_NO_NETWORK) > 0)
		return TRUE;

	/* GET file */
	url = as_image_get_url (im);
	g_debug ("checking %s", url);
	base_uri = soup_uri_new (url);
	if (base_uri == NULL) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_URL_NOT_FOUND,
				     "<screenshot> url not valid");
		return FALSE;
	}
	msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri);
	if (msg == NULL) {
		g_warning ("Failed to setup message");
		return FALSE;
	}

	/* send sync */
	status_code = soup_session_send_message (helper->session, msg);
	if (status_code != SOUP_STATUS_OK) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_URL_NOT_FOUND,
				     "<screenshot> url not found");
		return FALSE;
	}

	/* check if it's a zero sized file */
	if (msg->response_body->length == 0) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_FILE_INVALID,
				     "<screenshot> url is a zero length file");
		return FALSE;
	}

	/* create a buffer with the data */
	stream = g_memory_input_stream_new_from_data (msg->response_body->data,
						      msg->response_body->length,
						      NULL);
	if (stream == NULL) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_URL_NOT_FOUND,
				     "<screenshot> failed to load data");
		return FALSE;
	}

	/* load the image */
	pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
	if (pixbuf == NULL) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_FILE_INVALID,
				     "<screenshot> failed to load image");
		return FALSE;
	}

	/* check width matches */
	screenshot_width = gdk_pixbuf_get_width (pixbuf);
	screenshot_height = gdk_pixbuf_get_height (pixbuf);
	if (as_image_get_width (im) != 0 &&
	    as_image_get_width (im) != screenshot_width) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> width did not match specified");
	}

	/* check height matches */
	if (as_image_get_height (im) != 0 &&
	    as_image_get_height (im) != screenshot_height) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> height did not match specified");
	}

	/* check size is reasonable */
	if (screenshot_width < ss_size_width_min) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> width was too small");
	}
	if (screenshot_height < ss_size_height_min) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> height was too small");
	}
	if (screenshot_width > ss_size_width_max) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> width was too large");
	}
	if (screenshot_height > ss_size_height_max) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<screenshot> height was too large");
	}

	/* check aspect ratio */
	if (require_correct_aspect_ratio) {
		screenshot_aspect = (gdouble) screenshot_width / (gdouble) screenshot_height;
		if (ABS (screenshot_aspect - 1.777777777) > 0.1) {
			g_debug ("got aspect %.2f, wanted %.2f",
				 screenshot_aspect, desired_aspect);
			ai_app_validate_add (helper->probs,
					     AS_PROBLEM_KIND_ASPECT_RATIO_INCORRECT,
					     "<screenshot> aspect ratio was not 16:9");
		}
	}
	return TRUE;
}