[gnome-software/gnome-40: 1/2] flatpak: Download appstream data on demand when missing




commit 5d4743046948116ece5165eda3f955ba21e96d03
Author: Milan Crha <mcrha redhat com>
Date:   Fri Apr 23 10:52:44 2021 +0200

    flatpak: Download appstream data on demand when missing
    
    The flatpak can have missing appstream data for example when a remote
    is added and Software has disabled automatic update. In such case,
    download the appstream data on demand.
    
    Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1217

 plugins/flatpak/gs-flatpak.c | 75 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 66 insertions(+), 9 deletions(-)
---
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index 3dd1160b6..1d2b9bedc 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -657,6 +657,12 @@ fixup_flatpak_appstream_xml (XbBuilderSource *source,
        }
 }
 
+static gboolean
+gs_flatpak_refresh_appstream_remote (GsFlatpak *self,
+                                    const gchar *remote_name,
+                                    GCancellable *cancellable,
+                                    GError **error);
+
 static gboolean
 gs_flatpak_add_apps_from_xremote (GsFlatpak *self,
                                  XbBuilder *builder,
@@ -673,23 +679,74 @@ gs_flatpak_add_apps_from_xremote (GsFlatpak *self,
        g_autoptr(GSettings) settings = NULL;
        g_autoptr(XbBuilderNode) info = NULL;
        g_autoptr(XbBuilderSource) source = xb_builder_source_new ();
+       const gchar *remote_name = flatpak_remote_get_name (xremote);
+       gboolean did_refresh = FALSE;
 
        /* get the AppStream data location */
        appstream_dir = flatpak_remote_get_appstream_dir (xremote, NULL);
        if (appstream_dir == NULL) {
-               g_debug ("no appstream dir for %s, skipping",
-                        flatpak_remote_get_name (xremote));
-               return TRUE;
+               g_autoptr(GError) error_local = NULL;
+               g_debug ("no appstream dir for %s, trying refresh...",
+                        remote_name);
+
+               if (!gs_flatpak_refresh_appstream_remote (self, remote_name, cancellable, &error_local)) {
+                       g_debug ("Failed to refresh appstream data for '%s': %s", remote_name, 
error_local->message);
+                       if (g_error_matches (error_local, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED)) {
+                               g_autoptr(GMutexLocker) locker = NULL;
+
+                               locker = g_mutex_locker_new (&self->broken_remotes_mutex);
+
+                               /* don't try to fetch this again until refresh() */
+                               g_hash_table_insert (self->broken_remotes,
+                                                    g_strdup (remote_name),
+                                                    GUINT_TO_POINTER (1));
+                       }
+                       return TRUE;
+               }
+
+               appstream_dir = flatpak_remote_get_appstream_dir (xremote, NULL);
+               if (appstream_dir == NULL) {
+                       g_debug ("no appstream dir for %s even after refresh, skipping",
+                                remote_name);
+                       return TRUE;
+               }
+
+               did_refresh = TRUE;
        }
 
        /* load the file into a temp silo */
        appstream_dir_fn = g_file_get_path (appstream_dir);
        appstream_fn = g_build_filename (appstream_dir_fn, "appstream.xml.gz", NULL);
        if (!g_file_test (appstream_fn, G_FILE_TEST_EXISTS)) {
-               g_debug ("no %s appstream metadata found: %s",
-                        flatpak_remote_get_name (xremote),
-                        appstream_fn);
-               return TRUE;
+               g_autoptr(GError) error_local = NULL;
+               g_debug ("no appstream metadata found for '%s' (file: %s), %s",
+                        remote_name,
+                        appstream_fn,
+                        did_refresh ? "skipping" : "trying refresh...");
+               if (did_refresh)
+                       return TRUE;
+
+               if (!gs_flatpak_refresh_appstream_remote (self, remote_name, cancellable, &error_local)) {
+                       g_debug ("Failed to refresh appstream data for '%s': %s", remote_name, 
error_local->message);
+                       if (g_error_matches (error_local, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED)) {
+                               g_autoptr(GMutexLocker) locker = NULL;
+
+                               locker = g_mutex_locker_new (&self->broken_remotes_mutex);
+
+                               /* don't try to fetch this again until refresh() */
+                               g_hash_table_insert (self->broken_remotes,
+                                                    g_strdup (remote_name),
+                                                    GUINT_TO_POINTER (1));
+                       }
+                       return TRUE;
+               }
+
+               if (!g_file_test (appstream_fn, G_FILE_TEST_EXISTS)) {
+                       g_debug ("no appstream metadata found for '%s', even after refresh (file: %s), 
skipping",
+                                remote_name,
+                                appstream_fn);
+                       return TRUE;
+               }
        }
 
        /* add source */
@@ -701,7 +758,7 @@ gs_flatpak_add_apps_from_xremote (GsFlatpak *self,
                                          error))
                return FALSE;
 
-       fixup_flatpak_appstream_xml (source, flatpak_remote_get_name (xremote));
+       fixup_flatpak_appstream_xml (source, remote_name);
 
        /* add metadata */
        icon_prefix = g_build_filename (appstream_dir_fn, "icons", NULL);
@@ -1064,7 +1121,7 @@ gs_flatpak_refresh_appstream_remote (GsFlatpak *self,
                                                      remote_name,
                                                      cancellable,
                                                      &error_local)) {
-               g_debug ("Failed to update metadata for remote %s: %s\n",
+               g_debug ("Failed to update metadata for remote %s: %s",
                         remote_name, error_local->message);
                gs_flatpak_error_convert (&error_local);
                g_propagate_error (error, g_steal_pointer (&error_local));


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