[gnome-software] trivial: Merge back appstream-common back into the AppStream plugin



commit 871e5203663b0b43c013b2b24461c8cb957bb7b7
Author: Richard Hughes <richard hughsie com>
Date:   Wed Jan 20 13:27:42 2016 +0000

    trivial: Merge back appstream-common back into the AppStream plugin
    
    We only had one user...

 src/plugins/Makefile.am           |    5 +-
 src/plugins/appstream-common.c    |  479 -------------------------------------
 src/plugins/appstream-common.h    |   38 ---
 src/plugins/gs-plugin-appstream.c |  453 ++++++++++++++++++++++++++++++++++-
 4 files changed, 447 insertions(+), 528 deletions(-)
---
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 66e926b..507c496 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -91,10 +91,7 @@ libgs_plugin_self_test_la_LIBADD = $(GS_PLUGIN_LIBS)
 libgs_plugin_self_test_la_LDFLAGS = -module -avoid-version
 libgs_plugin_self_test_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
 
-libgs_plugin_appstream_la_SOURCES =                    \
-       appstream-common.c                              \
-       appstream-common.h                              \
-       gs-plugin-appstream.c
+libgs_plugin_appstream_la_SOURCES = gs-plugin-appstream.c
 libgs_plugin_appstream_la_LIBADD = $(GS_PLUGIN_LIBS) $(APPSTREAM_LIBS)
 libgs_plugin_appstream_la_LDFLAGS = -module -avoid-version
 libgs_plugin_appstream_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index c8a2710..d34e432 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -26,8 +26,6 @@
 #include <gs-plugin.h>
 #include <gs-plugin-loader.h>
 
-#include "appstream-common.h"
-
 /*
  * SECTION:
  * Uses offline AppStream data to populate and refine package results.
@@ -230,16 +228,457 @@ out:
        return ret;
 }
 
+#define        GS_PLUGIN_APPSTREAM_MAX_SCREENSHOTS     5
+
+/**
+ * _as_app_has_compulsory_for_desktop:
+ */
+static gboolean
+_as_app_has_compulsory_for_desktop (AsApp *app, const gchar *compulsory_for_desktop)
+{
+       GPtrArray *compulsory_for_desktops;
+       const gchar *tmp;
+       guint i;
+
+       compulsory_for_desktops = as_app_get_compulsory_for_desktops (app);
+       for (i = 0; i < compulsory_for_desktops->len; i++) {
+               tmp = g_ptr_array_index (compulsory_for_desktops, i);
+               if (g_strcmp0 (tmp, compulsory_for_desktop) == 0)
+                       return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * gs_plugin_refine_item_pixbuf:
+ */
+static void
+gs_plugin_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 *path = 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) {
+                       path = g_build_filename (g_get_user_data_dir (),
+                                                "gnome-software",
+                                                "icons",
+                                                NULL);
+                       fn = g_build_filename (path, as_icon_get_name (icon), NULL);
+                       as_icon_set_filename (icon, fn);
+                       as_icon_set_prefix (icon, path);
+               }
+               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;
+       }
+}
+
+/**
+ * gs_plugin_appstream_refine_add_addons:
+ */
+static void
+gs_plugin_appstream_refine_add_addons (GsPlugin *plugin, GsApp *app, AsApp *item)
+{
+       GPtrArray *addons;
+       guint i;
+
+       addons = as_app_get_addons (item);
+       if (addons == NULL)
+               return;
+
+       for (i = 0; i < addons->len; i++) {
+               AsApp *as_addon = g_ptr_array_index (addons, i);
+               g_autoptr(GError) error = NULL;
+               g_autoptr(GsApp) addon = NULL;
+
+               addon = gs_app_new (as_app_get_id (as_addon));
+
+               /* add all the data we can */
+               if (!gs_plugin_refine_item (plugin, addon, as_addon, &error)) {
+                       g_warning ("failed to refine addon: %s", error->message);
+                       continue;
+               }
+               gs_app_add_addon (app, addon);
+       }
+}
+/**
+ * gs_plugin_appstream_refine_add_screenshots:
+ */
+static void
+gs_plugin_appstream_refine_add_screenshots (GsApp *app, AsApp *item)
+{
+       AsScreenshot *ss;
+       GPtrArray *images_as;
+       GPtrArray *screenshots_as;
+       guint i;
+
+       /* do we have any to add */
+       screenshots_as = as_app_get_screenshots (item);
+       if (screenshots_as->len == 0)
+               return;
+
+       /* does the app already have some */
+       gs_app_add_kudo (app, GS_APP_KUDO_HAS_SCREENSHOTS);
+       if (gs_app_get_screenshots(app)->len > 0)
+               return;
+
+       /* add any we know */
+       for (i = 0; i < screenshots_as->len &&
+                   i < GS_PLUGIN_APPSTREAM_MAX_SCREENSHOTS; i++) {
+               ss = g_ptr_array_index (screenshots_as, i);
+               images_as = as_screenshot_get_images (ss);
+               if (images_as->len == 0)
+                       continue;
+               if (as_screenshot_get_kind (ss) == AS_SCREENSHOT_KIND_UNKNOWN)
+                       continue;
+               gs_app_add_screenshot (app, ss);
+       }
+}
+
+/**
+ * gs_plugin_appstream_is_recent_release:
+ */
+static gboolean
+gs_plugin_appstream_is_recent_release (AsApp *app)
+{
+       AsRelease *release;
+       GPtrArray *releases;
+       guint secs;
+
+       /* get newest release */
+       releases = as_app_get_releases (app);
+       if (releases->len == 0)
+               return FALSE;
+       release = g_ptr_array_index (releases, 0);
+
+       /* is last build less than one year ago? */
+       secs = (g_get_real_time () / G_USEC_PER_SEC) -
+               as_release_get_timestamp (release);
+       return secs / (60 * 60 * 24) < 365;
+}
+
+/**
+ * gs_plugin_appstream_are_screenshots_perfect:
+ */
+static gboolean
+gs_plugin_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;
+}
+
+/**
+ * gs_plugin_appstream_copy_metadata:
+ */
+static void
+gs_plugin_appstream_copy_metadata (GsApp *app, AsApp *item)
+{
+       GHashTable *hash;
+       GList *l;
+       g_autoptr(GList) keys = NULL;
+
+       hash = as_app_get_metadata (item);
+       keys = g_hash_table_get_keys (hash);
+       for (l = keys; l != NULL; l = l->next) {
+               const gchar *key = l->data;
+               const gchar *value = g_hash_table_lookup (hash, key);
+               gs_app_set_metadata (app, key, value);
+       }
+}
+
 /**
  * gs_plugin_refine_item:
  */
 static gboolean
-gs_plugin_refine_item (GsPlugin *plugin,
-                      GsApp *app,
-                      AsApp *item,
-                      GError **error)
+gs_plugin_refine_item (GsPlugin *plugin, GsApp *app, AsApp *item, GError **error)
 {
-       return gs_appstream_refine_app (plugin, app, item, error);
+       AsRelease *rel;
+       GHashTable *urls;
+       GPtrArray *pkgnames;
+       GPtrArray *kudos;
+       const gchar *tmp;
+       guint i;
+
+       /* is an app */
+       if (gs_app_get_kind (app) == GS_APP_KIND_UNKNOWN ||
+           gs_app_get_kind (app) == GS_APP_KIND_PACKAGE) {
+               if (as_app_get_id_kind (item) == AS_ID_KIND_SOURCE) {
+                       gs_app_set_kind (app, GS_APP_KIND_SOURCE);
+               } else {
+                       gs_app_set_kind (app, GS_APP_KIND_NORMAL);
+               }
+       }
+
+       /* is installed already */
+       if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN) {
+               switch (as_app_get_source_kind (item)) {
+               case AS_APP_SOURCE_KIND_APPDATA:
+               case AS_APP_SOURCE_KIND_DESKTOP:
+                       gs_app_set_kind (app, GS_APP_KIND_NORMAL);
+                       gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+                       break;
+               case AS_APP_SOURCE_KIND_METAINFO:
+                       gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+                       break;
+               case AS_APP_SOURCE_KIND_APPSTREAM:
+                       gs_app_set_state (app, as_app_get_state (item));
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       /* set id */
+       if (as_app_get_id (item) != NULL && gs_app_get_id (app) == NULL)
+               gs_app_set_id (app, as_app_get_id (item));
+
+       /* set name */
+       tmp = as_app_get_name (item, NULL);
+       if (tmp != NULL) {
+               gs_app_set_name (app,
+                                GS_APP_QUALITY_HIGHEST,
+                                as_app_get_name (item, NULL));
+       }
+
+       /* set summary */
+       tmp = as_app_get_comment (item, NULL);
+       if (tmp != NULL) {
+               gs_app_set_summary (app,
+                                   GS_APP_QUALITY_HIGHEST,
+                                   as_app_get_comment (item, NULL));
+       }
+
+       /* add urls */
+       urls = as_app_get_urls (item);
+       if (g_hash_table_size (urls) > 0 &&
+           gs_app_get_url (app, AS_URL_KIND_HOMEPAGE) == NULL) {
+               GList *l;
+               g_autoptr(GList) keys = NULL;
+               keys = g_hash_table_get_keys (urls);
+               for (l = keys; l != NULL; l = l->next) {
+                       gs_app_set_url (app,
+                                       as_url_kind_from_string (l->data),
+                                       g_hash_table_lookup (urls, l->data));
+               }
+       }
+
+       /* set licence */
+       if (as_app_get_project_license (item) != NULL && gs_app_get_licence (app) == NULL)
+               gs_app_set_licence (app,
+                                   as_app_get_project_license (item),
+                                   GS_APP_QUALITY_HIGHEST);
+
+       /* set keywords */
+       if (as_app_get_keywords (item, NULL) != NULL &&
+           gs_app_get_keywords (app) == NULL) {
+               gs_app_set_keywords (app, as_app_get_keywords (item, NULL));
+               gs_app_add_kudo (app, GS_APP_KUDO_HAS_KEYWORDS);
+       }
+
+       /* set description */
+       tmp = as_app_get_description (item, NULL);
+       if (tmp != NULL) {
+               g_autofree gchar *from_xml = NULL;
+               from_xml = as_markup_convert_simple (tmp, error);
+               if (from_xml == NULL) {
+                       g_prefix_error (error, "trying to parse '%s': ", tmp);
+                       return FALSE;
+               }
+               gs_app_set_description (app,
+                                       GS_APP_QUALITY_HIGHEST,
+                                       from_xml);
+       }
+
+       /* set icon */
+       if (as_app_get_icon_default (item) != NULL && gs_app_get_pixbuf (app) == NULL)
+               gs_plugin_refine_item_pixbuf (plugin, app, item);
+
+       /* set categories */
+       if (as_app_get_categories (item) != NULL &&
+           gs_app_get_categories (app)->len == 0)
+               gs_app_set_categories (app, as_app_get_categories (item));
+
+       /* set project group */
+       if (as_app_get_project_group (item) != NULL &&
+           gs_app_get_project_group (app) == NULL)
+               gs_app_set_project_group (app, as_app_get_project_group (item));
+
+       /* set default bundle (if any) */
+       if (as_app_get_bundle_default (item) != NULL &&
+           gs_app_get_bundle (app) == NULL)
+               gs_app_set_bundle (app, as_app_get_bundle_default (item));
+
+       /* this is a core application for the desktop and cannot be removed */
+       if (_as_app_has_compulsory_for_desktop (item, "GNOME") &&
+           gs_app_get_kind (app) == GS_APP_KIND_NORMAL)
+               gs_app_set_kind (app, GS_APP_KIND_SYSTEM);
+
+       /* set id kind */
+       if (gs_app_get_id_kind (app) == AS_ID_KIND_UNKNOWN)
+               gs_app_set_id_kind (app, as_app_get_id_kind (item));
+
+       /* copy all the metadata */
+       gs_plugin_appstream_copy_metadata (app, item);
+
+       /* set package names */
+       pkgnames = as_app_get_pkgnames (item);
+       if (pkgnames->len > 0 && gs_app_get_sources(app)->len == 0)
+               gs_app_set_sources (app, pkgnames);
+
+       /* set addons */
+       gs_plugin_appstream_refine_add_addons (plugin, app, item);
+
+       /* set screenshots */
+       gs_plugin_appstream_refine_add_screenshots (app, item);
+
+       /* are the screenshots perfect */
+       if (gs_plugin_appstream_are_screenshots_perfect (item))
+               gs_app_add_kudo (app, GS_APP_KUDO_PERFECT_SCREENSHOTS);
+
+       /* was this application released recently */
+       if (gs_plugin_appstream_is_recent_release (item))
+               gs_app_add_kudo (app, GS_APP_KUDO_RECENT_RELEASE);
+
+       /* add kudos */
+       if (as_app_get_language (item, plugin->locale) > 50)
+               gs_app_add_kudo (app, GS_APP_KUDO_MY_LANGUAGE);
+
+       /* add new-style kudos */
+       kudos = as_app_get_kudos (item);
+       for (i = 0; i < kudos->len; i++) {
+               tmp = g_ptr_array_index (kudos, i);
+               switch (as_kudo_kind_from_string (tmp)) {
+               case AS_KUDO_KIND_SEARCH_PROVIDER:
+                       gs_app_add_kudo (app, GS_APP_KUDO_SEARCH_PROVIDER);
+                       break;
+               case AS_KUDO_KIND_USER_DOCS:
+                       gs_app_add_kudo (app, GS_APP_KUDO_INSTALLS_USER_DOCS);
+                       break;
+               case AS_KUDO_KIND_APP_MENU:
+                       gs_app_add_kudo (app, GS_APP_KUDO_USES_APP_MENU);
+                       break;
+               case AS_KUDO_KIND_MODERN_TOOLKIT:
+                       gs_app_add_kudo (app, GS_APP_KUDO_MODERN_TOOLKIT);
+                       break;
+               case AS_KUDO_KIND_NOTIFICATIONS:
+                       gs_app_add_kudo (app, GS_APP_KUDO_USES_NOTIFICATIONS);
+                       break;
+               case AS_KUDO_KIND_HIGH_CONTRAST:
+                       gs_app_add_kudo (app, GS_APP_KUDO_HIGH_CONTRAST);
+                       break;
+               case AS_KUDO_KIND_HI_DPI_ICON:
+                       gs_app_add_kudo (app, GS_APP_KUDO_HI_DPI_ICON);
+                       break;
+               default:
+                       g_debug ("no idea how to handle kudo '%s'", tmp);
+                       break;
+               }
+       }
+
+       /* is there any update information */
+       rel = as_app_get_release_default (item);
+       if (rel != NULL) {
+               tmp = as_release_get_description (rel, NULL);
+               if (tmp != NULL) {
+                       g_autofree gchar *desc = NULL;
+                       desc = as_markup_convert (tmp,
+                                                 AS_MARKUP_CONVERT_FORMAT_MARKDOWN,
+                                                 error);
+                       if (desc == NULL)
+                               return FALSE;
+                       gs_app_set_update_details (app, desc);
+               }
+               gs_app_set_update_urgency (app, as_release_get_urgency (rel));
+               gs_app_set_update_version (app, as_release_get_version (rel));
+       }
+
+       return TRUE;
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]