[gnome-software/wip/hughsie/desktop] Do not show non-applications in the installed panel



commit 308fee36343fd45aeef8884a3c13534b6acbaa5e
Author: Richard Hughes <richard hughsie com>
Date:   Tue Oct 8 17:07:09 2019 +0100

    Do not show non-applications in the installed panel
    
    Using appstream-glib to parse the desktop files into fake AppStream components
    had a drawback: it worked too well. What we wanted to do was only show
    applications with AppData files in the installed list, only using the desktop
    metadata if the icon could not be found in the AppStream metadata.
    
    Instead we showed all apps, even ones that would be disasterous if removed...
    
    Lets make this simpler; we can parse the desktop file directly. We only need
    the icon and the component ID, so create a fake component without using
    as_app_parse_data() at all. This should speed up initial startup, as we're
    doing a lot less IO than before if there are a lot of desktop files installed.
    
    We'll also be storing less data (e.g. translations we're never going to use) in
    the xmlb mmap store -- although it makes no difference to query speed it'll
    make a difference for storage space.
    
    To ensure we only query AppData files for the installed list, we can now just
    query for the existance of the <name> tag -- which the fake components now will
    not have.
    
    So that the xmlb store is regenerated with the fix, also add the package
    version to the libxmlb cache guid.
    
    Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1759193

 plugins/core/gs-plugin-appstream.c | 72 +++++++++++++++++++++++++++++++++-----
 1 file changed, 63 insertions(+), 9 deletions(-)
---
diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c
index 1f18693b..4f5873cf 100644
--- a/plugins/core/gs-plugin-appstream.c
+++ b/plugins/core/gs-plugin-appstream.c
@@ -206,20 +206,71 @@ gs_plugin_appstream_load_desktop_cb (XbBuilderSource *self,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       GString *xml;
-       g_autoptr(AsApp) app = as_app_new ();
+       g_autofree gchar *icon = NULL;
+       g_autofree gchar *type = NULL;
+       g_autofree gchar *xml = NULL;
+       g_autofree gchar *name = NULL;
        g_autoptr(GBytes) bytes = NULL;
+       g_autoptr(GKeyFile) kf = g_key_file_new ();
+
+       /* get icon from desktop file */
        bytes = xb_builder_source_ctx_get_bytes (ctx, cancellable, error);
        if (bytes == NULL)
                return NULL;
-       as_app_set_id (app, xb_builder_source_ctx_get_filename (ctx));
-       if (!as_app_parse_data (app, bytes, AS_APP_PARSE_FLAG_USE_FALLBACKS, error))
+       if (!g_key_file_load_from_data (kf,
+                                       g_bytes_get_data (bytes, NULL),
+                                       g_bytes_get_size (bytes),
+                                       G_KEY_FILE_NONE,
+                                       error))
                return NULL;
-       xml = as_app_to_xml (app, error);
-       if (xml == NULL)
+       if (g_key_file_get_boolean (kf,
+                                   G_KEY_FILE_DESKTOP_GROUP,
+                                   G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY,
+                                   NULL)) {
+               g_set_error_literal (error,
+                                    GS_PLUGIN_ERROR,
+                                    GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                                    "NoDisplay=true");
                return NULL;
-       g_string_prepend (xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-       return g_memory_input_stream_new_from_data (g_string_free (xml, FALSE), -1, g_free);
+       }
+       type = g_key_file_get_string (kf,
+                                     G_KEY_FILE_DESKTOP_GROUP,
+                                     G_KEY_FILE_DESKTOP_KEY_TYPE,
+                                     error);
+       if (type == NULL)
+               return NULL;
+       if (g_strcmp0 (type, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                            "Type=%s", type);
+               return NULL;
+       }
+       icon = g_key_file_get_string (kf,
+                                     G_KEY_FILE_DESKTOP_GROUP,
+                                     G_KEY_FILE_DESKTOP_KEY_ICON,
+                                     error);
+       if (icon == NULL)
+               return NULL;
+
+       name = g_key_file_get_string (kf,
+                                     G_KEY_FILE_DESKTOP_GROUP,
+                                     G_KEY_FILE_DESKTOP_KEY_NAME,
+                                     error);
+       if (name == NULL)
+               return NULL;
+
+       /* build a super-simple fake AppData file */
+       xml = g_strdup_printf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+                              "<component type=\"desktop\">\n"
+                              "<id>%s</id>\n"
+                              "<name>%s</name>"
+                              "<icon type=\"stock\">%s</icon>\n"
+                              "</component>\n",
+                              xb_builder_source_ctx_get_filename (ctx),
+                              name,
+                              icon);
+       return g_memory_input_stream_new_from_data (g_steal_pointer (&xml), -1, g_free);
 }
 
 static gboolean
@@ -517,6 +568,9 @@ gs_plugin_appstream_check_silo (GsPlugin *plugin,
                }
        }
 
+       /* regenerate with each minor release */
+       xb_builder_append_guid (builder, PACKAGE_VERSION);
+
        /* create per-user cache */
        blobfn = gs_utils_get_cache_filename ("appstream", "components.xmlb",
                                              GS_UTILS_CACHE_FLAG_WRITEABLE,
@@ -925,7 +979,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
        locker = g_rw_lock_reader_locker_new (&priv->silo_lock);
 
        /* get all installed appdata files (notice no 'components/' prefix...) */
-       components = xb_silo_query (priv->silo, "component", 0, NULL);
+       components = xb_silo_query (priv->silo, "component/description/..", 0, NULL);
        if (components == NULL)
                return TRUE;
        for (guint i = 0; i < components->len; i++) {


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