[gnome-software] Allow an application to have multiple sources



commit 5ba7f973ddd1a2624b419a4603a55b4420cfc911
Author: Richard Hughes <richard hughsie com>
Date:   Wed Oct 23 10:22:21 2013 +0100

    Allow an application to have multiple sources
    
    This allows us to have an AppStream application that has more than one
    <pkgname/> tags. This allows us to define meta-applications that consist of more
    than one package, for instance a 'font' where each face is in a different package.
    
    This needs a bit more work before things like install and remove work for
    applications with multiple sources, but is certainly a small step in the right
    direction.

 src/gs-app.c                               |   47 +++++++++++----
 src/gs-app.h                               |    7 ++-
 src/gs-plugin-loader.c                     |   11 +++-
 src/gs-self-test.c                         |    4 +-
 src/gs-shell-updates.c                     |    4 +-
 src/plugins/appstream-app.c                |   19 +++---
 src/plugins/appstream-app.h                |    4 +-
 src/plugins/appstream-cache.c              |   15 ++---
 src/plugins/gs-plugin-appstream.c          |   30 ++++++----
 src/plugins/gs-plugin-datadir-apps.c       |    2 +-
 src/plugins/gs-plugin-desktopdb.c          |   15 +++--
 src/plugins/gs-plugin-fedora-tagger.c      |   91 ++++++++++++++++++----------
 src/plugins/gs-plugin-packagekit-history.c |    8 ++-
 src/plugins/gs-plugin-packagekit-offline.c |    2 +-
 src/plugins/gs-plugin-packagekit-refine.c  |   45 ++++++++------
 src/plugins/gs-plugin-packagekit-updates.c |    2 +-
 src/plugins/gs-plugin-systemd-updates.c    |    2 +-
 src/plugins/packagekit-common.c            |    2 +-
 18 files changed, 195 insertions(+), 115 deletions(-)
---
diff --git a/src/gs-app.c b/src/gs-app.c
index 8ba94db..a09ea84 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -58,7 +58,7 @@ struct GsAppPrivate
        gchar                   *id;
        gchar                   *name;
        gchar                   *icon;
-       gchar                   *source;
+       GPtrArray               *sources;
        gchar                   *project_group;
        gchar                   *version;
        gchar                   *version_ui;
@@ -238,6 +238,10 @@ gs_app_to_string (GsApp *app)
                                                                  G_MAXUINT,
                                                                  NULL));
        }
+       for (i = 0; i < priv->sources->len; i++) {
+               tmp = g_ptr_array_index (priv->sources, i);
+               g_string_append_printf (str, "\tsource-%02i:\t%s\n", i, tmp);
+       }
        tmp = g_hash_table_lookup (priv->urls, GS_APP_URL_KIND_HOMEPAGE);
        if (tmp != NULL)
                g_string_append_printf (str, "\turl{homepage}:\t%s\n", tmp);
@@ -520,30 +524,50 @@ gs_app_set_name (GsApp *app, const gchar *name)
 }
 
 /**
- * gs_app_get_source:
+ * gs_app_get_source_default:
  */
 const gchar *
-gs_app_get_source (GsApp *app)
+gs_app_get_source_default (GsApp *app)
+{
+       g_return_val_if_fail (GS_IS_APP (app), NULL);
+       return g_ptr_array_index (app->priv->sources, 0);
+}
+
+/**
+ * gs_app_set_source_default:
+ */
+void
+gs_app_set_source_default (GsApp *app, const gchar *source)
+{
+       g_ptr_array_add (app->priv->sources, g_strdup (source));
+}
+
+/**
+ * gs_app_get_sources:
+ */
+GPtrArray *
+gs_app_get_sources (GsApp *app)
 {
        g_return_val_if_fail (GS_IS_APP (app), NULL);
-       return app->priv->source;
+       return app->priv->sources;
 }
 
 /**
- * gs_app_set_source:
+ * gs_app_set_sources:
  * @app:       A #GsApp instance
- * @source:    The non-localized short name, e.g. "gnome-calculator"
+ * @source:    The non-localized short names, e.g. ["gnome-calculator"]
  *
  * This name is used for the update page if the application is collected into
- * the 'OS Updates' group. It is typically the package name, although this
+ * the 'OS Updates' group. It is typically the package names, although this
  * should not be relied upon.
  */
 void
-gs_app_set_source (GsApp *app, const gchar *source)
+gs_app_set_sources (GsApp *app, GPtrArray *sources)
 {
        g_return_if_fail (GS_IS_APP (app));
-       g_free (app->priv->source);
-       app->priv->source = g_strdup (source);
+       if (app->priv->sources != NULL)
+               g_ptr_array_unref (app->priv->sources);
+       app->priv->sources = g_ptr_array_ref (sources);
 }
 
 /**
@@ -1426,6 +1450,7 @@ gs_app_init (GsApp *app)
 {
        app->priv = GS_APP_GET_PRIVATE (app);
        app->priv->rating = -1;
+       app->priv->sources = g_ptr_array_new_with_free_func (g_free);
        app->priv->related = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
        app->priv->history = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
        app->priv->screenshots = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
@@ -1455,7 +1480,7 @@ gs_app_finalize (GObject *object)
        g_free (priv->icon);
        g_free (priv->licence);
        g_free (priv->menu_path);
-       g_free (priv->source);
+       g_ptr_array_unref (priv->sources);
        g_free (priv->project_group);
        g_free (priv->version);
        g_free (priv->version_ui);
diff --git a/src/gs-app.h b/src/gs-app.h
index 99d72e2..9fedd7d 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -119,9 +119,12 @@ void                gs_app_set_state               (GsApp          *app,
 const gchar    *gs_app_get_name                (GsApp          *app);
 void            gs_app_set_name                (GsApp          *app,
                                                 const gchar    *name);
-const gchar    *gs_app_get_source              (GsApp          *app);
-void            gs_app_set_source              (GsApp          *app,
+const gchar    *gs_app_get_source_default      (GsApp          *app);
+void            gs_app_set_source_default      (GsApp          *app,
                                                 const gchar    *source);
+GPtrArray      *gs_app_get_sources             (GsApp          *app);
+void            gs_app_set_sources             (GsApp          *app,
+                                                GPtrArray      *sources);
 const gchar    *gs_app_get_project_group       (GsApp          *app);
 void            gs_app_set_project_group       (GsApp          *app,
                                                 const gchar    *source);
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 9b384d1..964b1db 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -130,8 +130,8 @@ gs_plugin_loader_dedupe (GsPluginLoader *plugin_loader, GsApp *app)
        }
 
        /* save any properties we already know */
-       if (gs_app_get_source (app) != NULL)
-               gs_app_set_source (new_app, gs_app_get_source (app));
+       if (gs_app_get_sources(app)->len > 0)
+               gs_app_set_sources (new_app, gs_app_get_sources (app));
        if (gs_app_get_project_group (app) != NULL)
                gs_app_set_project_group (new_app, gs_app_get_project_group (app));
        if (gs_app_get_name (app) != NULL)
@@ -406,7 +406,12 @@ gs_plugin_loader_get_app_str (GsApp *app)
        if (id != NULL)
                return id;
 
-       /* first try the actual id */
+       /* then try the source */
+       id = gs_app_get_source_default (app);
+       if (id != NULL)
+               return id;
+
+       /* lastly try the package id */
        id = gs_app_get_metadata_item (app, "PackageKit::package-id");
        if (id != NULL)
                return id;
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index dc565b3..9ce27f9 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -316,7 +316,7 @@ gs_plugin_loader_refine_func (void)
        /* get the extra bits */
        g_setenv ("GNOME_SOFTWARE_USE_PKG_DESCRIPTIONS", "1", TRUE);
        app = gs_app_new ("gimp");
-       gs_app_set_source (app, "gimp");
+       gs_app_set_source_default (app, "gimp");
        ret = gs_plugin_loader_app_refine (loader, app,
                                           GS_PLUGIN_REFINE_FLAGS_DEFAULT |
                                           GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION |
@@ -404,7 +404,7 @@ gs_plugin_loader_empty_func (void)
                                                g_print ("Cat: %s\tSubCat: %s\tPkgName: %s\tAppId: %s\n",
                                                         gs_category_get_id (category),
                                                         gs_category_get_id (sub),
-                                                        gs_app_get_source (GS_APP (g->data)),
+                                                        gs_app_get_source_default (GS_APP (g->data)),
                                                         gs_app_get_id (GS_APP (g->data)));
                                        }
                                }
diff --git a/src/gs-shell-updates.c b/src/gs-shell-updates.c
index 25296a2..089c6b0 100644
--- a/src/gs-shell-updates.c
+++ b/src/gs-shell-updates.c
@@ -230,7 +230,7 @@ gs_shell_updates_set_updates_description_ui (GsShellUpdates *shell_updates, GsAp
                gtk_window_set_title (GTK_WINDOW (widget), gs_app_get_name (app));
        } else {
                tmp = g_strdup_printf ("%s %s",
-                                      gs_app_get_source (app),
+                                      gs_app_get_source_default (app),
                                       gs_app_get_update_version_ui (app));
                gtk_window_set_title (GTK_WINDOW (widget), tmp);
                g_free (tmp);
@@ -302,7 +302,7 @@ show_update_details (GsApp *app, GsShellUpdates *shell_updates)
                        app_related = g_ptr_array_index (related, i);
                        row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
                        g_object_set_data_full (G_OBJECT (row), "app", g_object_ref (app_related), 
g_object_unref);
-                       label = gtk_label_new (gs_app_get_source (app_related));
+                       label = gtk_label_new (gs_app_get_source_default (app_related));
                        g_object_set (label,
                                      "margin-left", 20,
                                      "margin-right", 20,
diff --git a/src/plugins/appstream-app.c b/src/plugins/appstream-app.c
index 1806f07..d6f6c96 100644
--- a/src/plugins/appstream-app.c
+++ b/src/plugins/appstream-app.c
@@ -30,7 +30,7 @@
 struct AppstreamApp
 {
        gchar                   *id;
-       gchar                   *pkgname;
+       GPtrArray               *pkgnames;
        gint                     priority;
        gchar                   *name;
        guint                    name_value;
@@ -59,7 +59,7 @@ void
 appstream_app_free (AppstreamApp *app)
 {
        g_free (app->id);
-       g_free (app->pkgname);
+       g_ptr_array_unref (app->pkgnames);
        g_hash_table_unref (app->urls);
        g_free (app->licence);
        g_free (app->project_group);
@@ -109,6 +109,7 @@ appstream_app_new (void)
        app->appcategories = g_ptr_array_new_with_free_func (g_free);
        app->keywords = g_ptr_array_new_with_free_func (g_free);
        app->mimetypes = g_ptr_array_new_with_free_func (g_free);
+       app->pkgnames = g_ptr_array_new_with_free_func (g_free);
        app->desktop_core = g_ptr_array_new_with_free_func (g_free);
        app->screenshots = g_ptr_array_new_with_free_func ((GDestroyNotify) appstream_screenshot_free);
        app->urls = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
@@ -130,12 +131,12 @@ appstream_app_get_id (AppstreamApp *app)
 }
 
 /**
- * appstream_app_get_pkgname:
+ * appstream_app_get_pkgnames:
  */
-const gchar *
-appstream_app_get_pkgname (AppstreamApp *app)
+GPtrArray *
+appstream_app_get_pkgnames (AppstreamApp *app)
 {
-       return app->pkgname;
+       return app->pkgnames;
 }
 
 /**
@@ -300,14 +301,14 @@ appstream_app_set_id (AppstreamApp *app,
 }
 
 /**
- * appstream_app_set_pkgname:
+ * appstream_app_add_pkgname:
  */
 void
-appstream_app_set_pkgname (AppstreamApp *app,
+appstream_app_add_pkgname (AppstreamApp *app,
                           const gchar *pkgname,
                           gsize length)
 {
-       app->pkgname = g_strndup (pkgname, length);
+       g_ptr_array_add (app->pkgnames, g_strndup (pkgname, length));
 }
 
 /**
diff --git a/src/plugins/appstream-app.h b/src/plugins/appstream-app.h
index ebc1336..4e8095f 100644
--- a/src/plugins/appstream-app.h
+++ b/src/plugins/appstream-app.h
@@ -52,7 +52,7 @@ void           appstream_app_free                     (AppstreamApp   *app);
 AppstreamApp   *appstream_app_new                      (void);
 
 const gchar    *appstream_app_get_id                   (AppstreamApp   *app);
-const gchar    *appstream_app_get_pkgname              (AppstreamApp   *app);
+GPtrArray      *appstream_app_get_pkgnames             (AppstreamApp   *app);
 gint            appstream_app_get_priority             (AppstreamApp   *app);
 const gchar    *appstream_app_get_name                 (AppstreamApp   *app);
 const gchar    *appstream_app_get_summary              (AppstreamApp   *app);
@@ -72,7 +72,7 @@ AppstreamAppIdKind    appstream_app_get_id_kind       (AppstreamApp   *app);
 void            appstream_app_set_id                   (AppstreamApp   *app,
                                                         const gchar    *id,
                                                         gsize           length);
-void            appstream_app_set_pkgname              (AppstreamApp   *app,
+void            appstream_app_add_pkgname              (AppstreamApp   *app,
                                                         const gchar    *pkgname,
                                                         gsize           length);
 void            appstream_app_set_priority             (AppstreamApp   *app,
diff --git a/src/plugins/appstream-cache.c b/src/plugins/appstream-cache.c
index b7e9f53..7d1bef8 100644
--- a/src/plugins/appstream-cache.c
+++ b/src/plugins/appstream-cache.c
@@ -412,8 +412,10 @@ appstream_cache_add_item (AppstreamCacheHelper *helper)
        AppstreamApp *item;
        AppstreamAppIdKind id_kind;
        AppstreamCachePrivate *priv = helper->cache->priv;
+       GPtrArray *pkgnames;
        const gchar *id;
        const gchar *pkgname;
+       guint i;
 
        /* have we recorded this before? */
        id = appstream_app_get_id (helper->item_temp);
@@ -448,8 +450,9 @@ appstream_cache_add_item (AppstreamCacheHelper *helper)
        g_hash_table_insert (priv->hash_id,
                             (gpointer) appstream_app_get_id (helper->item_temp),
                             helper->item_temp);
-       pkgname = appstream_app_get_pkgname (helper->item_temp);
-       if (pkgname != NULL) {
+       pkgnames = appstream_app_get_pkgnames (helper->item_temp);
+       for (i = 0; i < pkgnames->len; i++) {
+               pkgname = g_ptr_array_index (pkgnames, i);
                g_hash_table_insert (priv->hash_pkgname,
                                     (gpointer) pkgname,
                                     helper->item_temp);
@@ -637,13 +640,7 @@ appstream_cache_text_cb (GMarkupParseContext *context,
                                             "item_temp pkgname invalid");
                        return;
                }
-               if (appstream_app_get_pkgname (helper->item_temp) != NULL) {
-                       g_debug ("multiple pkgname's for %s, ignoring %s",
-                                appstream_app_get_id (helper->item_temp),
-                                text);
-                       return;
-               }
-               appstream_app_set_pkgname (helper->item_temp, text, text_len);
+               appstream_app_add_pkgname (helper->item_temp, text, text_len);
                break;
        case APPSTREAM_TAG_NAME:
                if (helper->item_temp == NULL) {
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index a27826b..a46db07 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -451,6 +451,7 @@ gs_plugin_refine_item (GsPlugin *plugin,
                       GError **error)
 {
        GHashTable *urls;
+       GPtrArray *tmp;
        gboolean ret = TRUE;
 
        /* is an app */
@@ -520,9 +521,10 @@ gs_plugin_refine_item (GsPlugin *plugin,
        if (gs_app_get_id_kind (app) == GS_APP_ID_KIND_UNKNOWN)
                gs_app_set_id_kind (app, appstream_app_get_id_kind (item));
 
-       /* set package name */
-       if (appstream_app_get_pkgname (item) != NULL && gs_app_get_source (app) == NULL)
-               gs_app_set_source (app, appstream_app_get_pkgname (item));
+       /* set package names */
+       tmp = appstream_app_get_pkgnames (item);
+       if (tmp->len > 0 && gs_app_get_sources(app)->len == 0)
+               gs_app_set_sources (app, tmp);
 
        /* set screenshots */
        gs_plugin_refine_add_screenshots (app, item);
@@ -566,20 +568,26 @@ gs_plugin_refine_from_pkgname (GsPlugin *plugin,
                               GsApp *app,
                               GError **error)
 {
+       AppstreamApp *item = NULL;
+       GPtrArray *sources;
        const gchar *pkgname;
        gboolean ret = TRUE;
-       AppstreamApp *item;
+       guint i;
 
        /* find anything that matches the ID */
-       pkgname = gs_app_get_source (app);
-       if (pkgname == NULL)
-               goto out;
-       item = appstream_cache_get_item_by_pkgname (plugin->priv->cache, pkgname);
-       if (item == NULL) {
-               g_debug ("no AppStream match for {pkgname} %s", pkgname);
-               goto out;
+       sources = gs_app_get_sources (app);
+       for (i = 0; i < sources->len && item == NULL; i++) {
+               pkgname = g_ptr_array_index (sources, i);
+               item = appstream_cache_get_item_by_pkgname (plugin->priv->cache,
+                                                           pkgname);
+               if (item == NULL)
+                       g_debug ("no AppStream match for {pkgname} %s", pkgname);
        }
 
+       /* nothing found */
+       if (item == NULL)
+               goto out;
+
        /* set new properties */
        ret = gs_plugin_refine_item (plugin, app, item, error);
        if (!ret)
diff --git a/src/plugins/gs-plugin-datadir-apps.c b/src/plugins/gs-plugin-datadir-apps.c
index e7f41a6..323e32f 100644
--- a/src/plugins/gs-plugin-datadir-apps.c
+++ b/src/plugins/gs-plugin-datadir-apps.c
@@ -109,7 +109,7 @@ gs_plugin_datadir_apps_set_from_cache_item (GsApp *app,
        if (cache_item->name != NULL)
                gs_app_set_name (app, cache_item->name);
        if (cache_item->pkgname != NULL)
-               gs_app_set_source (app, cache_item->pkgname);
+               gs_app_set_source_default (app, cache_item->pkgname);
        if (cache_item->summary != NULL)
                gs_app_set_summary (app, cache_item->summary);
        if (cache_item->pixbuf != NULL)
diff --git a/src/plugins/gs-plugin-desktopdb.c b/src/plugins/gs-plugin-desktopdb.c
index ef344b5..4f8c589 100644
--- a/src/plugins/gs-plugin-desktopdb.c
+++ b/src/plugins/gs-plugin-desktopdb.c
@@ -158,10 +158,12 @@ gs_plugin_refine (GsPlugin *plugin,
                  GCancellable *cancellable,
                  GError **error)
 {
-       const gchar *pkgname;
-       gboolean ret = TRUE;
        GList *l;
+       GPtrArray *sources;
        GsApp *app;
+       const gchar *pkgname;
+       gboolean ret = TRUE;
+       guint i;
 
        /* not loaded yet */
        if (g_once_init_enter (&plugin->priv->loaded)) {
@@ -177,10 +179,11 @@ gs_plugin_refine (GsPlugin *plugin,
                app = GS_APP (l->data);
                if (gs_app_get_metadata_item (app, "DataDir::desktop-filename") != NULL)
                        continue;
-               pkgname = gs_app_get_source (app);
-               if (pkgname == NULL)
-                       continue;
-               gs_plugin_desktopdb_set_metadata (plugin, app, pkgname);
+               sources = gs_app_get_sources (app);
+               for (i = 0; i < sources->len; i++) {
+                       pkgname = g_ptr_array_index (sources, i);
+                       gs_plugin_desktopdb_set_metadata (plugin, app, pkgname);
+               }
        }
 out:
        return ret;
diff --git a/src/plugins/gs-plugin-fedora-tagger.c b/src/plugins/gs-plugin-fedora-tagger.c
index 5fff14e..7071dfa 100644
--- a/src/plugins/gs-plugin-fedora-tagger.c
+++ b/src/plugins/gs-plugin-fedora-tagger.c
@@ -198,41 +198,25 @@ out:
 }
 
 /**
- * gs_plugin_app_set_rating:
+ * gs_plugin_app_set_rating_pkg:
  */
-gboolean
-gs_plugin_app_set_rating (GsPlugin *plugin,
-                         GsApp *app,
-                         GCancellable *cancellable,
-                         GError **error)
+static gboolean
+gs_plugin_app_set_rating_pkg (GsPlugin *plugin,
+                             const gchar *pkgname,
+                             gint rating,
+                             GError **error)
 {
        SoupMessage *msg = NULL;
-       const gchar *pkgname;
-       gboolean ret;
        gchar *data = NULL;
        gchar *error_msg = NULL;
        gchar *uri = NULL;
        guint status_code;
 
-       /* get the package name */
-       pkgname = gs_app_get_source (app);
-       if (pkgname == NULL) {
-               g_warning ("no pkgname for %s", gs_app_get_id (app));
-               goto out;
-       }
-
-       /* ensure networking is set up */
-       ret = gs_plugin_setup_networking (plugin, error);
-       if (!ret)
-               goto out;
-
        /* create the PUT data */
        uri = g_strdup_printf ("%s/api/v1/rating/%s/",
                               GS_PLUGIN_FEDORA_TAGGER_SERVER,
                               pkgname);
-       data = g_strdup_printf ("pkgname=%s&rating=%i",
-                               pkgname,
-                               gs_app_get_rating (app));
+       data = g_strdup_printf ("pkgname=%s&rating=%i", pkgname, rating);
        msg = soup_message_new (SOUP_METHOD_PUT, uri);
        soup_message_set_request (msg, SOUP_FORM_MIME_TYPE_URLENCODED,
                                  SOUP_MEMORY_COPY, data, strlen (data));
@@ -251,12 +235,52 @@ gs_plugin_app_set_rating (GsPlugin *plugin,
        } else {
                g_debug ("Got response: %s", msg->response_body->data);
        }
-out:
+
        g_free (error_msg);
        g_free (data);
        g_free (uri);
        if (msg != NULL)
                g_object_unref (msg);
+       return TRUE;
+}
+
+/**
+ * gs_plugin_app_set_rating:
+ */
+gboolean
+gs_plugin_app_set_rating (GsPlugin *plugin,
+                         GsApp *app,
+                         GCancellable *cancellable,
+                         GError **error)
+{
+       GPtrArray *sources;
+       const gchar *pkgname;
+       gboolean ret = TRUE;
+       guint i;
+
+       /* get the package name */
+       sources = gs_app_get_sources (app);
+       if (sources->len == 0) {
+               g_warning ("no pkgname for %s", gs_app_get_id (app));
+               goto out;
+       }
+
+       /* ensure networking is set up */
+       ret = gs_plugin_setup_networking (plugin, error);
+       if (!ret)
+               goto out;
+
+       /* set rating for each package */
+       for (i = 0; i < sources->len; i++) {
+               pkgname = g_ptr_array_index (sources, i);
+               ret = gs_plugin_app_set_rating_pkg (plugin,
+                                                   pkgname,
+                                                   gs_app_get_rating (app),
+                                                   error);
+               if (!ret)
+                       goto out;
+       }
+out:
        return ret;
 }
 
@@ -528,9 +552,12 @@ gs_plugin_refine (GsPlugin *plugin,
                  GError **error)
 {
        GList *l;
+       GPtrArray *sources;
        GsApp *app;
+       const gchar *pkgname;
        gboolean ret = TRUE;
        gint rating;
+       guint i;
 
        /* nothing to do here */
        if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING) == 0)
@@ -549,13 +576,15 @@ gs_plugin_refine (GsPlugin *plugin,
                app = GS_APP (l->data);
                if (gs_app_get_rating (app) != -1)
                        continue;
-               if (gs_app_get_source (app) == NULL)
-                       continue;
-               rating = gs_plugin_resolve_app (plugin, gs_app_get_source (app));
-               if (rating != -1) {
-                       g_debug ("fedora-tagger setting rating on %s to %i",
-                                gs_app_get_source (app), rating);
-                       gs_app_set_rating (app, rating);
+               sources = gs_app_get_sources (app);
+               for (i = 0; i < sources->len; i++) {
+                       pkgname = g_ptr_array_index (sources, i);
+                       rating = gs_plugin_resolve_app (plugin, pkgname);
+                       if (rating != -1) {
+                               g_debug ("fedora-tagger setting rating on %s to %i",
+                                        pkgname, rating);
+                               gs_app_set_rating (app, rating);
+                       }
                }
        }
 out:
diff --git a/src/plugins/gs-plugin-packagekit-history.c b/src/plugins/gs-plugin-packagekit-history.c
index e67139c..bcf9132 100644
--- a/src/plugins/gs-plugin-packagekit-history.c
+++ b/src/plugins/gs-plugin-packagekit-history.c
@@ -176,7 +176,7 @@ gs_plugin_packagekit_refine (GsPlugin *plugin,
        package_names = g_new0 (const gchar *, g_list_length (list) + 1);
        for (l = list; l != NULL; l = l->next) {
                app = GS_APP (l->data);
-               package_names[i++] = gs_app_get_source (app);
+               package_names[i++] = gs_app_get_source_default (app);
        }
 
        g_debug ("getting history for %i packages", g_list_length (list));
@@ -227,7 +227,7 @@ gs_plugin_packagekit_refine (GsPlugin *plugin,
        for (l = list; l != NULL; l = l->next) {
                app = GS_APP (l->data);
                ret = g_variant_lookup (tuple,
-                                       gs_app_get_source (app),
+                                       gs_app_get_source_default (app),
                                        "@aa{sv}",
                                        &value);
                if (!ret) {
@@ -279,6 +279,7 @@ gs_plugin_refine (GsPlugin *plugin,
        GList *l;
        GList *packages = NULL;
        GsApp *app;
+       GPtrArray *sources;
 
        if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_HISTORY) == 0)
                goto out;
@@ -286,7 +287,8 @@ gs_plugin_refine (GsPlugin *plugin,
        /* add any missing history data */
        for (l = list; l != NULL; l = l->next) {
                app = GS_APP (l->data);
-               if (gs_app_get_source (app) == NULL)
+               sources = gs_app_get_sources (app);
+               if (sources->len == 0)
                        continue;
                if (gs_app_get_install_date (app) != 0)
                        continue;
diff --git a/src/plugins/gs-plugin-packagekit-offline.c b/src/plugins/gs-plugin-packagekit-offline.c
index bbfc79a..69850d3 100644
--- a/src/plugins/gs-plugin-packagekit-offline.c
+++ b/src/plugins/gs-plugin-packagekit-offline.c
@@ -101,7 +101,7 @@ gs_plugin_add_updates_historical (GsPlugin *plugin,
        for (i = 0; package_ids[i] != NULL; i++) {
                app = gs_app_new (NULL);
                split = g_strsplit (package_ids[i], ";", 4);
-               gs_app_set_source (app, split[0]);
+               gs_app_set_source_default (app, split[0]);
                gs_app_set_update_version (app, split[1]);
                gs_app_set_management_plugin (app, "PackageKit");
                gs_app_set_metadata (app, "PackageKit::package-id", package_ids[i]);
diff --git a/src/plugins/gs-plugin-packagekit-refine.c b/src/plugins/gs-plugin-packagekit-refine.c
index 49b9ad7..75c2791 100644
--- a/src/plugins/gs-plugin-packagekit-refine.c
+++ b/src/plugins/gs-plugin-packagekit-refine.c
@@ -113,33 +113,36 @@ gs_plugin_packagekit_resolve_packages (GsPlugin *plugin,
                                       GCancellable *cancellable,
                                       GError **error)
 {
-       const gchar *pkgname;
-       gboolean ret = TRUE;
-       const gchar **package_ids;
        GList *l;
        GPtrArray *array = NULL;
+       GPtrArray *package_ids;
        GPtrArray *packages = NULL;
+       GPtrArray *sources;
        GsApp *app;
-       guint number_installed = 0;
-       guint number_available = 0;
-       guint i = 0;
-       guint size;
        PkError *error_code = NULL;
        PkPackage *package;
        PkResults *results = NULL;
+       const gchar *pkgname;
+       gboolean ret = TRUE;
+       guint i = 0;
+       guint number_available = 0;
+       guint number_installed = 0;
 
-       size = g_list_length (list);
-       package_ids = g_new0 (const gchar *, size + 1);
+       package_ids = g_ptr_array_new_with_free_func (g_free);
        for (l = list; l != NULL; l = l->next) {
                app = GS_APP (l->data);
-               pkgname = gs_app_get_source (app);
-               package_ids[i++] = pkgname;
+               sources = gs_app_get_sources (app);
+               for (i = 0; i < sources->len; i++) {
+                       pkgname = g_ptr_array_index (sources, i);
+                       g_ptr_array_add (package_ids, g_strdup (pkgname));
+               }
        }
+       g_ptr_array_add (package_ids, NULL);
 
        /* resolve them all at once */
        results = pk_client_resolve (plugin->priv->client,
                                     pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST, PK_FILTER_ENUM_ARCH, -1),
-                                    (gchar **) package_ids,
+                                    (gchar **) package_ids->pdata,
                                     cancellable,
                                     gs_plugin_packagekit_progress_cb, plugin,
                                     error);
@@ -165,7 +168,10 @@ gs_plugin_packagekit_resolve_packages (GsPlugin *plugin,
        packages = pk_results_get_package_array (results);
        for (l = list; l != NULL; l = l->next) {
                app = GS_APP (l->data);
-               pkgname = gs_app_get_source (app);
+               // FIXME: This needs some unit tests to ensure that we only mark
+               //        the application as installed if it has all the packages
+               //        listed as sources.
+               pkgname = gs_app_get_source_default (app);
 
                /* find any packages that match the package name */
                number_installed = 0;
@@ -208,7 +214,7 @@ gs_plugin_packagekit_resolve_packages (GsPlugin *plugin,
                }
        }
 out:
-       g_free (package_ids);
+       g_ptr_array_unref (package_ids);
        if (packages != NULL)
                g_ptr_array_unref (packages);
        if (error_code != NULL)
@@ -566,12 +572,13 @@ gs_plugin_refine (GsPlugin *plugin,
                  GCancellable *cancellable,
                  GError **error)
 {
-       gboolean ret = TRUE;
        GList *l;
-       GsApp *app;
-       const gchar *tmp;
        GList *resolve_all = NULL;
        GList *updatedetails_all = NULL;
+       GPtrArray *sources;
+       GsApp *app;
+       const gchar *tmp;
+       gboolean ret = TRUE;
 
        /* can we resolve in one go? */
        gs_profile_start_full (plugin->profile, "packagekit-refine[name->id]");
@@ -581,8 +588,8 @@ gs_plugin_refine (GsPlugin *plugin,
                        continue;
                if (gs_app_get_id_kind (app) == GS_APP_ID_KIND_WEBAPP)
                        continue;
-               tmp = gs_app_get_source (app);
-               if (tmp == NULL)
+               sources = gs_app_get_sources (app);
+               if (sources->len == 0)
                        continue;
                if (gs_app_get_state (app) == GS_APP_STATE_UNKNOWN ||
                    gs_plugin_refine_requires_version (app, flags)) {
diff --git a/src/plugins/gs-plugin-packagekit-updates.c b/src/plugins/gs-plugin-packagekit-updates.c
index e15187a..3a1cc8e 100644
--- a/src/plugins/gs-plugin-packagekit-updates.c
+++ b/src/plugins/gs-plugin-packagekit-updates.c
@@ -145,7 +145,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
        for (i = 0; i < array->len; i++) {
                pkg = g_ptr_array_index (array, i);
                app = gs_app_new (NULL);
-               gs_app_set_source (app, pk_package_get_name (pkg));
+               gs_app_set_source_default (app, pk_package_get_name (pkg));
                gs_app_set_update_version (app, pk_package_get_version (pkg));
                gs_app_set_management_plugin (app, "PackageKit");
                gs_app_set_state (app, GS_APP_STATE_UPDATABLE);
diff --git a/src/plugins/gs-plugin-systemd-updates.c b/src/plugins/gs-plugin-systemd-updates.c
index cc50489..5c06412 100644
--- a/src/plugins/gs-plugin-systemd-updates.c
+++ b/src/plugins/gs-plugin-systemd-updates.c
@@ -82,7 +82,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
                                     "PackageKit::package-id",
                                     package_ids[i]);
                split = pk_package_id_split (package_ids[i]);
-               gs_app_set_source (app, split[PK_PACKAGE_ID_NAME]);
+               gs_app_set_source_default (app, split[PK_PACKAGE_ID_NAME]);
                gs_app_set_update_version (app, split[PK_PACKAGE_ID_VERSION]);
                gs_app_set_state (app, GS_APP_STATE_UPDATABLE);
                gs_app_set_kind (app, GS_APP_KIND_PACKAGE);
diff --git a/src/plugins/packagekit-common.c b/src/plugins/packagekit-common.c
index 2863781..15a56c3 100644
--- a/src/plugins/packagekit-common.c
+++ b/src/plugins/packagekit-common.c
@@ -150,7 +150,7 @@ gs_plugin_packagekit_add_results (GsPlugin *plugin,
                gs_app_set_metadata (app,
                                     "PackageKit::package-summary",
                                     pk_package_get_summary (package));
-               gs_app_set_source (app, pk_package_get_name (package));
+               gs_app_set_source_default (app, pk_package_get_name (package));
                gs_app_set_management_plugin (app, "PackageKit");
                gs_app_set_version (app, pk_package_get_version (package));
                switch (pk_package_get_info (package)) {


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