[gnome-software/wip/hughsie/vnd.flatpak.ref: 2/3] Add support for vnd.flatpak.ref



commit 3cec7c472fdb39fcf36e5efdc2c4fc48d1b28bf4
Author: Richard Hughes <richard hughsie com>
Date:   Tue Sep 13 15:24:26 2016 +0100

    Add support for vnd.flatpak.ref

 src/gnome-software-local-file.desktop.in |    2 +-
 src/plugins/gs-flatpak-symlinks.c        |    4 +-
 src/plugins/gs-flatpak.c                 |  150 ++++++++++++++++++++++++++++++
 3 files changed, 154 insertions(+), 2 deletions(-)
---
diff --git a/src/gnome-software-local-file.desktop.in b/src/gnome-software-local-file.desktop.in
index 5ca6c72..d5d6d6f 100644
--- a/src/gnome-software-local-file.desktop.in
+++ b/src/gnome-software-local-file.desktop.in
@@ -8,4 +8,4 @@ Type=Application
 Icon=system-software-install
 StartupNotify=true
 NoDisplay=true
-MimeType=application/x-rpm;application/x-redhat-package-manager;application/x-deb;application/x-app-package;application/vnd.ms-cab-compressed;application/vnd.flatpak;application/vnd.flatpak.repo;x-scheme-handler/apt;application/vnd.snap;
+MimeType=application/x-rpm;application/x-redhat-package-manager;application/x-deb;application/x-app-package;application/vnd.ms-cab-compressed;application/vnd.flatpak;application/vnd.flatpak.repo;application/vnd.flatpak.ref;x-scheme-handler/apt;application/vnd.snap;
diff --git a/src/plugins/gs-flatpak-symlinks.c b/src/plugins/gs-flatpak-symlinks.c
index cf15ac8..1212482 100644
--- a/src/plugins/gs-flatpak-symlinks.c
+++ b/src/plugins/gs-flatpak-symlinks.c
@@ -41,8 +41,10 @@ gs_flatpak_symlinks_cleanup_kind (const gchar *cache_dir,
        if (!g_file_test (subdir, G_FILE_TEST_EXISTS))
                return TRUE;
        dir = g_dir_open (subdir, 0, error);
-       if (dir == NULL)
+       if (dir == NULL) {
+               gs_utils_error_convert_gio (error);
                return FALSE;
+       }
        while ((tmp = g_dir_read_name (dir)) != NULL) {
                gchar *str;
                g_autofree gchar *fn = NULL;
diff --git a/src/plugins/gs-flatpak.c b/src/plugins/gs-flatpak.c
index 7e32097..f1290da 100644
--- a/src/plugins/gs-flatpak.c
+++ b/src/plugins/gs-flatpak.c
@@ -47,6 +47,13 @@ struct _GsFlatpak {
 
 G_DEFINE_TYPE (GsFlatpak, gs_flatpak, G_TYPE_OBJECT)
 
+/* we have to do this until we hard dep on 0.6.11 */
+#define _FLATPAK_CHECK_VERSION(major,minor,micro)    \
+    (FLATPAK_MAJOR_VERSION > (major) || \
+     (FLATPAK_MAJOR_VERSION == (major) && FLATPAK_MINOR_VERSION > (minor)) || \
+     (FLATPAK_MAJOR_VERSION == (major) && FLATPAK_MINOR_VERSION == (minor) && \
+      FLATPAK_MICRO_VERSION >= (micro)))
+
 static gboolean
 gs_flatpak_refresh_appstream (GsFlatpak *self, guint cache_age,
                              GCancellable *cancellable, GError **error);
@@ -2134,6 +2141,139 @@ gs_flatpak_file_to_app_repo (GsFlatpak *self,
        return TRUE;
 }
 
+static gboolean
+gs_flatpak_update_appstream_for_remote (GsFlatpak *self,
+                                       const gchar *remote_name,
+                                       GCancellable *cancellable,
+                                       GError **error)
+{
+       g_autoptr(AsProfileTask) ptask = NULL;
+
+       /* search categories for the search term */
+       ptask = as_profile_start (gs_plugin_get_profile (self->plugin),
+                                 "flatpak::update-appstream{%s}",
+                                 remote_name);
+       g_assert (ptask != NULL);
+
+       /* get the new appstream data */
+       if (!flatpak_installation_update_appstream_sync (self->installation,
+                                                        remote_name,
+                                                        NULL,
+                                                        NULL,
+                                                        cancellable,
+                                                        error)) {
+               gs_plugin_flatpak_error_convert (error);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+static gboolean
+gs_flatpak_file_to_app_ref (GsFlatpak *self,
+                           GsAppList *list,
+                           GFile *file,
+                           GCancellable *cancellable,
+                           GError **error)
+{
+       const gchar *remote_name;
+       gsize len = 0;
+       g_autofree gchar *contents = NULL;
+       g_autofree gchar *unique_id = NULL;
+       g_autoptr(FlatpakRemoteRef) xref = NULL;
+       g_autoptr(GBytes) ref_file_data = NULL;
+       g_autoptr(GsApp) app = NULL;
+       g_autoptr(FlatpakRemote) xremote = NULL;
+       g_autofree gchar *origin_url = NULL;
+       g_autofree gchar *origin_title = NULL;
+
+       /* get file data */
+       if (!g_file_load_contents (file,
+                                  cancellable,
+                                  &contents,
+                                  &len,
+                                  NULL,
+                                  error)) {
+               gs_utils_error_convert_gio (error);
+               return FALSE;
+       }
+
+#if _FLATPAK_CHECK_VERSION(0,6,10)
+       /* install the remote, but not the app */
+       ref_file_data = g_bytes_new (contents, len);
+       xref = flatpak_installation_install_ref_file (self->installation,
+                                                     ref_file_data,
+                                                     cancellable,
+                                                     error);
+       if (xref == NULL) {
+               gs_plugin_flatpak_error_convert (error);
+               return FALSE;
+       }
+#else
+       g_set_error_literal (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                            "not new enough libflatpak to support flatpakref");
+       return FALSE;
+#endif
+
+       /* create a virtual ID */
+       unique_id = gs_flatpak_build_unique_id (self->installation,
+                                               FLATPAK_REF (xref));
+       app = gs_plugin_cache_lookup (self->plugin, unique_id);
+       if (app == NULL) {
+               g_autofree gchar *id = gs_flatpak_build_id (FLATPAK_REF (xref));
+               app = gs_app_new (id);
+               gs_plugin_cache_add (self->plugin, unique_id, app);
+       }
+
+       /* load metadata */
+       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
+       gs_flatpak_set_metadata (self, app, FLATPAK_REF (xref));
+
+       /* FIXME: perhaps use the data from the flatpakref file as a fallback? */
+
+       /* set the origin data */
+       remote_name = flatpak_remote_ref_get_remote_name (xref);
+       g_debug ("auto-created remote name: %s", remote_name);
+       xremote = flatpak_installation_get_remote_by_name (self->installation,
+                                                          remote_name,
+                                                          cancellable,
+                                                          error);
+       if (xremote == NULL) {
+               gs_plugin_flatpak_error_convert (error);
+               return FALSE;
+       }
+       origin_title = flatpak_remote_get_title (xremote);
+       origin_url = flatpak_remote_get_url (xremote);
+       if (origin_url == NULL) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_INVALID_FORMAT,
+                            "no URL for remote %s",
+                            flatpak_remote_get_name (xremote));
+               return FALSE;
+       }
+       gs_app_set_origin (app, remote_name);
+       gs_app_set_origin_hostname (app, origin_url);
+       gs_app_set_origin_ui (app, origin_title);
+
+       /* get the new appstream data */
+       if (!gs_flatpak_update_appstream_for_remote (self, remote_name,
+                                                    cancellable, error)) {
+               gs_plugin_flatpak_error_convert (error);
+               return FALSE;
+       }
+
+       /* parse it */
+       if (!gs_flatpak_add_apps_from_xremote (self, xremote, cancellable, error))
+               return FALSE;
+
+       /* success */
+       gs_app_list_add (list, app);
+       return TRUE;
+}
+
 gboolean
 gs_flatpak_file_to_app (GsFlatpak *self,
                        GsAppList *list,
@@ -2148,6 +2288,9 @@ gs_flatpak_file_to_app (GsFlatpak *self,
        const gchar *mimetypes_repo[] = {
                "application/vnd.flatpak.repo",
                NULL };
+       const gchar *mimetypes_ref[] = {
+               "application/vnd.flatpak.ref",
+               NULL };
 
        /* does this match any of the mimetypes_bundle we support */
        content_type = gs_utils_get_content_type (file, cancellable, error);
@@ -2167,6 +2310,13 @@ gs_flatpak_file_to_app (GsFlatpak *self,
                                                    cancellable,
                                                    error);
        }
+       if (g_strv_contains (mimetypes_ref, content_type)) {
+               return gs_flatpak_file_to_app_ref (self,
+                                                  list,
+                                                  file,
+                                                  cancellable,
+                                                  error);
+       }
        return TRUE;
 }
 


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