[gnome-software/1649-support-appstream-merging: 91/103] gs-appstream: Add gs_appstream_load_desktop_files()




commit f5d3f4d12afa7f82861a755b35b7d659dee96062
Author: Milan Crha <mcrha redhat com>
Date:   Thu Mar 31 11:57:31 2022 +0200

    gs-appstream: Add gs_appstream_load_desktop_files()
    
    It can be used by the plugins, to avoid code duplication.

 lib/gs-appstream.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/gs-appstream.h |   5 +++
 2 files changed, 115 insertions(+)
---
diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c
index 1908e5eef..ed73ebad5 100644
--- a/lib/gs-appstream.c
+++ b/lib/gs-appstream.c
@@ -1844,6 +1844,116 @@ gs_appstream_url_to_app (GsPlugin *plugin,
        return TRUE;
 }
 
+static GInputStream *
+gs_appstream_load_desktop_cb (XbBuilderSource *self,
+                             XbBuilderSourceCtx *ctx,
+                             gpointer user_data,
+                             GCancellable *cancellable,
+                             GError **error)
+{
+       g_autofree gchar *xml = NULL;
+       g_autoptr(AsComponent) cpt = as_component_new ();
+       g_autoptr(AsContext) actx = as_context_new ();
+       g_autoptr(GBytes) bytes = NULL;
+       gboolean ret;
+
+       bytes = xb_builder_source_ctx_get_bytes (ctx, cancellable, error);
+       if (bytes == NULL)
+               return NULL;
+
+       as_component_set_id (cpt, xb_builder_source_ctx_get_filename (ctx));
+       ret = as_component_load_from_bytes (cpt,
+                                          actx,
+                                          AS_FORMAT_KIND_DESKTOP_ENTRY,
+                                          bytes,
+                                          error);
+       if (!ret)
+               return NULL;
+       xml = as_component_to_xml_data (cpt, actx, error);
+       if (xml == NULL)
+               return NULL;
+       return g_memory_input_stream_new_from_data (g_steal_pointer (&xml), (gssize) -1, g_free);
+}
+
+static gboolean
+gs_appstream_load_desktop_fn (XbBuilder     *builder,
+                             const gchar   *filename,
+                             GCancellable  *cancellable,
+                             GError        **error)
+{
+       g_autoptr(GFile) file = g_file_new_for_path (filename);
+       g_autoptr(XbBuilderNode) info = NULL;
+       g_autoptr(XbBuilderSource) source = xb_builder_source_new ();
+
+       /* add support for desktop files */
+       xb_builder_source_add_adapter (source, "application/x-desktop",
+                                      gs_appstream_load_desktop_cb, NULL, NULL);
+
+       /* add source */
+       if (!xb_builder_source_load_file (source, file,
+#if LIBXMLB_CHECK_VERSION(0, 2, 0)
+                                         XB_BUILDER_SOURCE_FLAG_WATCH_DIRECTORY,
+#else
+                                         XB_BUILDER_SOURCE_FLAG_WATCH_FILE,
+#endif
+                                         cancellable,
+                                         error)) {
+               return FALSE;
+       }
+
+       /* add metadata */
+       info = xb_builder_node_insert (NULL, "info", NULL);
+       xb_builder_node_insert_text (info, "filename", filename, NULL);
+       xb_builder_source_set_info (source, info);
+
+       /* success */
+       xb_builder_import_source (builder, source);
+       return TRUE;
+}
+
+gboolean
+gs_appstream_load_desktop_files (XbBuilder      *builder,
+                                const gchar    *path,
+                                gboolean       *out_any_loaded,
+                                GCancellable   *cancellable,
+                                GError         **error)
+{
+       const gchar *fn;
+       g_autoptr(GDir) dir = NULL;
+       g_autoptr(GFile) parent = g_file_new_for_path (path);
+       if (out_any_loaded)
+               *out_any_loaded = FALSE;
+       if (!g_file_query_exists (parent, cancellable)) {
+               g_debug ("appstream: Skipping desktop path '%s' as %s", path, g_cancellable_is_cancelled 
(cancellable) ? "cancelled" : "does not exist");
+               return TRUE;
+       }
+
+       g_debug ("appstream: Loading desktop path '%s'", path);
+
+       dir = g_dir_open (path, 0, error);
+       if (dir == NULL)
+               return FALSE;
+
+       while ((fn = g_dir_read_name (dir)) != NULL) {
+               if (g_str_has_suffix (fn, ".desktop")) {
+                       g_autofree gchar *filename = g_build_filename (path, fn, NULL);
+                       g_autoptr(GError) error_local = NULL;
+                       if (!gs_appstream_load_desktop_fn (builder,
+                                                          filename,
+                                                          cancellable,
+                                                          &error_local)) {
+                               g_debug ("ignoring %s: %s", filename, error_local->message);
+                               continue;
+                       }
+                       if (out_any_loaded)
+                               *out_any_loaded = TRUE;
+               }
+       }
+
+       /* success */
+       return TRUE;
+}
+
 void
 gs_appstream_component_add_keyword (XbBuilderNode *component, const gchar *str)
 {
diff --git a/lib/gs-appstream.h b/lib/gs-appstream.h
index 2900a0c64..59da0151a 100644
--- a/lib/gs-appstream.h
+++ b/lib/gs-appstream.h
@@ -64,6 +64,11 @@ gboolean     gs_appstream_url_to_app                 (GsPlugin       *plugin,
                                                         const gchar    *url,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
+gboolean        gs_appstream_load_desktop_files        (XbBuilder      *builder,
+                                                        const gchar    *path,
+                                                        gboolean       *out_any_loaded,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
 void            gs_appstream_component_add_extra_info  (XbBuilderNode  *component);
 void            gs_appstream_component_add_keyword     (XbBuilderNode  *component,
                                                         const gchar    *str);


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