[gnome-software] Add screenshots to each application if specified in the AppStream metadata
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Add screenshots to each application if specified in the AppStream metadata
- Date: Fri, 4 Oct 2013 12:23:56 +0000 (UTC)
commit ae7544bf74b38141e65d32a8242d279b799a0224
Author: Richard Hughes <richard hughsie com>
Date: Fri Oct 4 13:22:00 2013 +0100
Add screenshots to each application if specified in the AppStream metadata
src/Makefile.am | 2 +
src/gs-app.c | 54 ++++------
src/gs-app.h | 8 +-
src/gs-screenshot.c | 195 +++++++++++++++++++++++++++++++++++++
src/gs-screenshot.h | 68 +++++++++++++
src/plugins/gs-plugin-appstream.c | 53 ++++++++++
6 files changed, 345 insertions(+), 35 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 81e4a2e..a45dd21 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,8 @@ gnome_software_SOURCES = \
gs-plugin.h \
gs-profile.c \
gs-profile.h \
+ gs-screenshot.c \
+ gs-screenshot.h \
gs-shell.c \
gs-shell.h \
gs-shell-details.c \
diff --git a/src/gs-app.c b/src/gs-app.c
index c1f68f5..e23b04d 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -60,7 +60,7 @@ struct GsAppPrivate
gchar *version;
gchar *summary;
gchar *description;
- gchar *screenshot;
+ GPtrArray *screenshots;
gchar *url;
gchar *update_version;
gchar *update_details;
@@ -84,7 +84,6 @@ enum {
PROP_SUMMARY,
PROP_DESCRIPTION,
PROP_URL,
- PROP_SCREENSHOT,
PROP_RATING,
PROP_KIND,
PROP_STATE,
@@ -160,11 +159,13 @@ gs_app_state_to_string (GsAppState state)
gchar *
gs_app_to_string (GsApp *app)
{
- const gchar *tmp;
GList *keys;
GList *l;
- GsAppPrivate *priv = app->priv;
GString *str;
+ GsAppPrivate *priv = app->priv;
+ GsScreenshot *ss;
+ const gchar *tmp;
+ guint i;
str = g_string_new ("GsApp:\n");
g_string_append_printf (str, "\tkind:\t%s\n",
@@ -181,8 +182,11 @@ gs_app_to_string (GsApp *app)
g_string_append_printf (str, "\tsummary:\t%s\n", priv->summary);
if (priv->description != NULL)
g_string_append_printf (str, "\tdescription:\t%lu\n", strlen (priv->description));
- if (priv->screenshot != NULL)
- g_string_append_printf (str, "\tscreenshot:\t%s\n", priv->screenshot);
+ for (i = 0; i < priv->screenshots->len; i++) {
+ ss = g_ptr_array_index (priv->screenshots, i);
+ g_string_append_printf (str, "\tscreenshot-%02i:\t%s\n",
+ i, gs_screenshot_get_url (ss, G_MAXUINT, G_MAXUINT));
+ }
if (priv->url != NULL)
g_string_append_printf (str, "\turl:\t%s\n", priv->url);
if (priv->rating != -1)
@@ -655,24 +659,23 @@ gs_app_set_url (GsApp *app, const gchar *url)
}
/**
- * gs_app_get_screenshot:
+ * gs_app_add_screenshot:
*/
-const gchar *
-gs_app_get_screenshot (GsApp *app)
+void
+gs_app_add_screenshot (GsApp *app, GsScreenshot *screenshot)
{
- g_return_val_if_fail (GS_IS_APP (app), NULL);
- return app->priv->screenshot;
+ g_return_if_fail (GS_IS_APP (app));
+ g_ptr_array_add (app->priv->screenshots, g_object_ref (screenshot));
}
/**
- * gs_app_set_screenshot:
+ * gs_app_get_screenshots:
*/
-void
-gs_app_set_screenshot (GsApp *app, const gchar *screenshot)
+GPtrArray *
+gs_app_get_screenshots (GsApp *app)
{
- g_return_if_fail (GS_IS_APP (app));
- g_free (app->priv->screenshot);
- app->priv->screenshot = g_strdup (screenshot);
+ g_return_val_if_fail (GS_IS_APP (app), NULL);
+ return app->priv->screenshots;
}
/**
@@ -865,9 +868,6 @@ gs_app_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *
case PROP_URL:
g_value_set_string (value, priv->url);
break;
- case PROP_SCREENSHOT:
- g_value_set_string (value, priv->screenshot);
- break;
case PROP_RATING:
g_value_set_uint (value, priv->rating);
break;
@@ -913,9 +913,6 @@ gs_app_set_property (GObject *object, guint prop_id, const GValue *value, GParam
case PROP_URL:
gs_app_set_url (app, g_value_get_string (value));
break;
- case PROP_SCREENSHOT:
- gs_app_set_screenshot (app, g_value_get_string (value));
- break;
case PROP_RATING:
gs_app_set_rating (app, g_value_get_int (value));
break;
@@ -990,14 +987,6 @@ gs_app_class_init (GsAppClass *klass)
g_object_class_install_property (object_class, PROP_URL, pspec);
/**
- * GsApp:screenshot:
- */
- pspec = g_param_spec_string ("screenshot", NULL, NULL,
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
- g_object_class_install_property (object_class, PROP_SCREENSHOT, pspec);
-
- /**
* GsApp:rating:
*/
pspec = g_param_spec_int ("rating", NULL, NULL,
@@ -1050,6 +1039,7 @@ gs_app_init (GsApp *app)
app->priv->rating = -1;
app->priv->related = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
app->priv->history = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ app->priv->screenshots = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
app->priv->metadata = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
@@ -1074,7 +1064,7 @@ gs_app_finalize (GObject *object)
g_free (priv->version);
g_free (priv->summary);
g_free (priv->description);
- g_free (priv->screenshot);
+ g_ptr_array_unref (priv->screenshots);
g_free (priv->update_version);
g_free (priv->update_details);
g_free (priv->management_plugin);
diff --git a/src/gs-app.h b/src/gs-app.h
index 04f5bd8..24a5587 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -25,6 +25,8 @@
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "gs-screenshot.h"
+
G_BEGIN_DECLS
#define GS_TYPE_APP (gs_app_get_type ())
@@ -113,9 +115,9 @@ void gs_app_set_description (GsApp *app,
const gchar *gs_app_get_url (GsApp *app);
void gs_app_set_url (GsApp *app,
const gchar *url);
-const gchar *gs_app_get_screenshot (GsApp *app);
-void gs_app_set_screenshot (GsApp *app,
- const gchar *screenshot);
+GPtrArray *gs_app_get_screenshots (GsApp *app);
+void gs_app_add_screenshot (GsApp *app,
+ GsScreenshot *screenshot);
const gchar *gs_app_get_update_version (GsApp *app);
void gs_app_set_update_version (GsApp *app,
const gchar *update_version);
diff --git a/src/gs-screenshot.c b/src/gs-screenshot.c
new file mode 100644
index 0000000..989a99f
--- /dev/null
+++ b/src/gs-screenshot.c
@@ -0,0 +1,195 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2013 Matthias Clasen <mclasen redhat 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 "config.h"
+
+#include <glib/gi18n.h>
+
+#include "gs-screenshot.h"
+
+static void gs_screenshot_finalize (GObject *object);
+
+#define GS_SCREENSHOT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_SCREENSHOT,
GsScreenshotPrivate))
+
+struct GsScreenshotPrivate
+{
+ GPtrArray *array;
+ gboolean is_default;
+};
+
+typedef struct {
+ gchar *url;
+ guint width;
+ guint height;
+} GsScreenshotItem;
+
+G_DEFINE_TYPE (GsScreenshot, gs_screenshot, G_TYPE_OBJECT)
+
+/**
+ * gs_screenshot_item_free:
+ **/
+static void
+gs_screenshot_item_free (GsScreenshotItem *item)
+{
+ g_free (item->url);
+ g_slice_free (GsScreenshotItem, item);
+}
+
+/**
+ * gs_screenshot_get_is_default:
+ **/
+gboolean
+gs_screenshot_get_is_default (GsScreenshot *screenshot)
+{
+ g_return_val_if_fail (GS_IS_SCREENSHOT (screenshot), FALSE);
+ return screenshot->priv->is_default;
+}
+
+/**
+ * gs_screenshot_set_is_default:
+ **/
+void
+gs_screenshot_set_is_default (GsScreenshot *screenshot, gboolean is_default)
+{
+ g_return_if_fail (GS_IS_SCREENSHOT (screenshot));
+ screenshot->priv->is_default = is_default;
+}
+
+/**
+ * gs_screenshot_get_item:
+ **/
+static GsScreenshotItem *
+gs_screenshot_get_item (GsScreenshot *screenshot, guint width, guint height)
+{
+ GsScreenshotItem *item;
+ guint i;
+
+ g_return_val_if_fail (GS_IS_SCREENSHOT (screenshot), NULL);
+
+ for (i = 0; i < screenshot->priv->array->len; i++) {
+ item = g_ptr_array_index (screenshot->priv->array, i);
+ if ((item->width == width || width == G_MAXUINT) &&
+ (item->height == height || height == G_MAXUINT))
+ return item;
+ }
+
+ return NULL;
+}
+
+/**
+ * gs_screenshot_add_image:
+ **/
+void
+gs_screenshot_add_image (GsScreenshot *screenshot,
+ const gchar *url,
+ guint width,
+ guint height)
+{
+ GsScreenshotItem *item;
+
+ g_return_if_fail (GS_IS_SCREENSHOT (screenshot));
+ g_return_if_fail (url != NULL);
+ g_return_if_fail (width > 0);
+ g_return_if_fail (height > 0);
+
+ /* check if already exists */
+ item = gs_screenshot_get_item (screenshot, width, height);
+ if (item != NULL) {
+ g_warning ("replaced URL %s with %s for %ux%u",
+ item->url, url, width, height);
+ g_free (item->url);
+ item->url = g_strdup (url);
+ } else {
+ item = g_slice_new0 (GsScreenshotItem);
+ item->url = g_strdup (url);
+ item->width = width;
+ item->height = height;
+ g_ptr_array_add (screenshot->priv->array, item);
+ }
+}
+
+/**
+ * gs_screenshot_get_url:
+ **/
+const gchar *
+gs_screenshot_get_url (GsScreenshot *screenshot, guint width, guint height)
+{
+ GsScreenshotItem *item;
+
+ g_return_val_if_fail (GS_IS_SCREENSHOT (screenshot), NULL);
+ g_return_val_if_fail (width > 0, NULL);
+ g_return_val_if_fail (height > 0, NULL);
+
+ item = gs_screenshot_get_item (screenshot, width, height);
+ if (item == NULL)
+ return NULL;
+
+ return item->url;
+}
+
+/**
+ * gs_screenshot_class_init:
+ **/
+static void
+gs_screenshot_class_init (GsScreenshotClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gs_screenshot_finalize;
+ g_type_class_add_private (klass, sizeof (GsScreenshotPrivate));
+}
+
+/**
+ * gs_screenshot_init:
+ **/
+static void
+gs_screenshot_init (GsScreenshot *screenshot)
+{
+ screenshot->priv = GS_SCREENSHOT_GET_PRIVATE (screenshot);
+ screenshot->priv->array = g_ptr_array_new_with_free_func ((GDestroyNotify) gs_screenshot_item_free);
+}
+
+/**
+ * gs_screenshot_finalize:
+ **/
+static void
+gs_screenshot_finalize (GObject *object)
+{
+ GsScreenshot *screenshot = GS_SCREENSHOT (object);
+ GsScreenshotPrivate *priv = screenshot->priv;
+
+ g_ptr_array_unref (priv->array);
+
+ G_OBJECT_CLASS (gs_screenshot_parent_class)->finalize (object);
+}
+
+/**
+ * gs_screenshot_new:
+ **/
+GsScreenshot *
+gs_screenshot_new (void)
+{
+ GsScreenshot *screenshot;
+ screenshot = g_object_new (GS_TYPE_SCREENSHOT, NULL);
+ return GS_SCREENSHOT (screenshot);
+}
+
+/* vim: set noexpandtab: */
diff --git a/src/gs-screenshot.h b/src/gs-screenshot.h
new file mode 100644
index 0000000..f253f62
--- /dev/null
+++ b/src/gs-screenshot.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef __GS_SCREENSHOT_H
+#define __GS_SCREENSHOT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GS_TYPE_SCREENSHOT (gs_screenshot_get_type ())
+#define GS_SCREENSHOT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_SCREENSHOT, GsScreenshot))
+#define GS_SCREENSHOT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_SCREENSHOT, GsScreenshotClass))
+#define GS_IS_SCREENSHOT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_SCREENSHOT))
+#define GS_IS_SCREENSHOT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_SCREENSHOT))
+#define GS_SCREENSHOT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_SCREENSHOT,
GsScreenshotClass))
+
+typedef struct GsScreenshotPrivate GsScreenshotPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GsScreenshotPrivate *priv;
+} GsScreenshot;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GsScreenshotClass;
+
+GType gs_screenshot_get_type (void);
+
+GsScreenshot *gs_screenshot_new (void);
+
+gboolean gs_screenshot_get_is_default (GsScreenshot *screenshot);
+void gs_screenshot_set_is_default (GsScreenshot *screenshot,
+ gboolean is_default);
+void gs_screenshot_add_image (GsScreenshot *screenshot,
+ const gchar *url,
+ guint width,
+ guint height);
+const gchar *gs_screenshot_get_url (GsScreenshot *screenshot,
+ guint width,
+ guint height);
+
+G_END_DECLS
+
+#endif /* __GS_SCREENSHOT_H */
+
+/* vim: set noexpandtab: */
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index b51c5c8..a1e5b6e 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -364,6 +364,56 @@ gs_plugin_refine_item_pixbuf (GsPlugin *plugin, GsApp *app, AppstreamApp *item)
}
/**
+ * gs_plugin_refine_add_screenshots:
+ */
+static void
+gs_plugin_refine_add_screenshots (GsApp *app, AppstreamApp *item)
+{
+ AppstreamImage *im;
+ AppstreamScreenshot *ss;
+ AppstreamScreenshotKind ss_kind;
+ GPtrArray *images_as;
+ GPtrArray *screenshots_as;
+ GsScreenshot *screenshot;
+ guint i;
+ guint j;
+
+ /* do we have any to add */
+ screenshots_as = appstream_app_get_screenshots (item);
+ if (screenshots_as->len == 0)
+ return;
+
+ /* does the app already have some */
+ if (gs_app_get_screenshots(app)->len > 0)
+ return;
+
+ /* add any we know */
+ for (i = 0; i < screenshots_as->len; i++) {
+ ss = g_ptr_array_index (screenshots_as, i);
+ images_as = appstream_screenshot_get_images (ss);
+ if (images_as->len == 0)
+ continue;
+ ss_kind = appstream_screenshot_get_kind (ss);
+ if (ss_kind == APPSTREAM_SCREENSHOT_KIND_UNKNOWN)
+ continue;
+
+ /* create a new application screenshot and add each image */
+ screenshot = gs_screenshot_new ();
+ gs_screenshot_set_is_default (screenshot,
+ ss_kind == APPSTREAM_SCREENSHOT_KIND_DEFAULT);
+ for (j = 0; j < images_as->len; j++) {
+ im = g_ptr_array_index (images_as, j);
+ gs_screenshot_add_image (screenshot,
+ appstream_image_get_url (im),
+ appstream_image_get_width (im),
+ appstream_image_get_height (im));
+ }
+ gs_app_add_screenshot (app, screenshot);
+ g_object_unref (screenshot);
+ }
+}
+
+/**
* gs_plugin_refine_item:
*/
static gboolean
@@ -412,6 +462,9 @@ gs_plugin_refine_item (GsPlugin *plugin,
if (appstream_app_get_pkgname (item) != NULL && gs_app_get_source (app) == NULL)
gs_app_set_source (app, appstream_app_get_pkgname (item));
+ /* set screenshots */
+ gs_plugin_refine_add_screenshots (app, item);
+
return ret;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]