[gnome-software] Store all kinds of URL in the GsApp



commit 900f5f13c2529ffa79eeb1a251de3d09049e6d97
Author: Richard Hughes <richard hughsie com>
Date:   Wed Oct 16 17:14:33 2013 +0100

    Store all kinds of URL in the GsApp
    
    We'll need this for future functionality.

 src/gs-app.c                              |   36 +++++++++++----------------
 src/gs-app.h                              |    6 ++++-
 src/gs-shell-details.c                    |    4 +-
 src/plugins/appstream-app.c               |   22 ++++++++++-------
 src/plugins/appstream-app.h               |    5 ++-
 src/plugins/appstream-cache.c             |   37 +++++++++++++++++++++++++----
 src/plugins/gs-plugin-appdata.c           |    4 +-
 src/plugins/gs-plugin-appstream.c         |   18 +++++++++++--
 src/plugins/gs-plugin-dummy.c             |    2 +-
 src/plugins/gs-plugin-packagekit-refine.c |   13 ++++++----
 10 files changed, 96 insertions(+), 51 deletions(-)
---
diff --git a/src/gs-app.c b/src/gs-app.c
index ae6a6ab..db1af70 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -65,7 +65,7 @@ struct GsAppPrivate
        gchar                   *description;
        GPtrArray               *screenshots;
        GPtrArray               *categories;
-       gchar                   *url;
+       GHashTable              *urls;
        gchar                   *licence;
        gchar                   *menu_path;
        gchar                   *update_version;
@@ -92,7 +92,6 @@ enum {
        PROP_VERSION,
        PROP_SUMMARY,
        PROP_DESCRIPTION,
-       PROP_URL,
        PROP_RATING,
        PROP_KIND,
        PROP_STATE,
@@ -223,8 +222,9 @@ gs_app_to_string (GsApp *app)
                g_string_append_printf (str, "\tscreenshot-%02i:\t%s\n",
                                        i, gs_screenshot_get_url (ss, G_MAXUINT, G_MAXUINT));
        }
-       if (priv->url != NULL)
-               g_string_append_printf (str, "\turl:\t%s\n", priv->url);
+       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);
        if (priv->licence != NULL)
                g_string_append_printf (str, "\tlicence:\t%s\n", priv->licence);
        if (priv->summary_missing != NULL)
@@ -811,10 +811,10 @@ gs_app_set_description (GsApp *app, const gchar *description)
  * gs_app_get_url:
  */
 const gchar *
-gs_app_get_url (GsApp *app)
+gs_app_get_url (GsApp *app, const gchar *kind)
 {
        g_return_val_if_fail (GS_IS_APP (app), NULL);
-       return app->priv->url;
+       return g_hash_table_lookup (app->priv->urls, kind);
 }
 
 /**
@@ -823,11 +823,12 @@ gs_app_get_url (GsApp *app)
  * @summary:   The home page URL, e.g. "http://www.foo.com/gcalctool/";
  */
 void
-gs_app_set_url (GsApp *app, const gchar *url)
+gs_app_set_url (GsApp *app, const gchar *kind, const gchar *url)
 {
        g_return_if_fail (GS_IS_APP (app));
-       g_free (app->priv->url);
-       app->priv->url = g_strdup (url);
+       g_hash_table_insert (app->priv->urls,
+                            g_strdup (kind),
+                            g_strdup (url));
 }
 
 /**
@@ -1187,9 +1188,6 @@ gs_app_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *
        case PROP_DESCRIPTION:
                g_value_set_string (value, priv->description);
                break;
-       case PROP_URL:
-               g_value_set_string (value, priv->url);
-               break;
        case PROP_RATING:
                g_value_set_uint (value, priv->rating);
                break;
@@ -1232,9 +1230,6 @@ gs_app_set_property (GObject *object, guint prop_id, const GValue *value, GParam
        case PROP_DESCRIPTION:
                gs_app_set_description (app, g_value_get_string (value));
                break;
-       case PROP_URL:
-               gs_app_set_url (app, g_value_get_string (value));
-               break;
        case PROP_RATING:
                gs_app_set_rating (app, g_value_get_int (value));
                break;
@@ -1303,11 +1298,6 @@ gs_app_class_init (GsAppClass *klass)
                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
        g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec);
 
-       pspec = g_param_spec_string ("url", NULL, NULL,
-                                    NULL,
-                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
-       g_object_class_install_property (object_class, PROP_URL, pspec);
-
        /**
         * GsApp:rating:
         */
@@ -1366,6 +1356,10 @@ gs_app_init (GsApp *app)
                                                     g_str_equal,
                                                     g_free,
                                                     g_free);
+       app->priv->urls = g_hash_table_new_full (g_str_hash,
+                                                g_str_equal,
+                                                g_free,
+                                                g_free);
 }
 
 /**
@@ -1380,7 +1374,7 @@ gs_app_finalize (GObject *object)
 
        g_free (priv->id);
        g_free (priv->name);
-       g_free (priv->url);
+       g_hash_table_unref (priv->urls);
        g_free (priv->licence);
        g_free (priv->menu_path);
        g_free (priv->source);
diff --git a/src/gs-app.h b/src/gs-app.h
index f192c96..81fcfa1 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -88,6 +88,8 @@ typedef enum {
 #define        GS_APP_SIZE_UNKNOWN                     0
 #define        GS_APP_SIZE_MISSING                     1
 
+#define        GS_APP_URL_KIND_HOMEPAGE                "homepage"
+
 GQuark          gs_app_error_quark             (void);
 GType           gs_app_get_type                (void);
 
@@ -131,8 +133,10 @@ void                gs_app_set_summary_missing     (GsApp          *app,
 const gchar    *gs_app_get_description         (GsApp          *app);
 void            gs_app_set_description         (GsApp          *app,
                                                 const gchar    *description);
-const gchar    *gs_app_get_url                 (GsApp          *app);
+const gchar    *gs_app_get_url                 (GsApp          *app,
+                                                const gchar    *kind);
 void            gs_app_set_url                 (GsApp          *app,
+                                                const gchar    *kind,
                                                 const gchar    *url);
 const gchar    *gs_app_get_licence             (GsApp          *app);
 void            gs_app_set_licence             (GsApp          *app,
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index 8e28b52..955c610 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -294,7 +294,7 @@ gs_shell_details_website_cb (GtkWidget *widget, GsShellDetails *shell_details)
        const gchar *url;
        gboolean ret;
 
-       url = gs_app_get_url (priv->app);
+       url = gs_app_get_url (priv->app, GS_APP_URL_KIND_HOMEPAGE);
        ret = gtk_show_uri (NULL, url, GDK_CURRENT_TIME, &error);
        if (!ret) {
                g_warning ("spawn of '%s' failed", url);
@@ -399,7 +399,7 @@ gs_shell_details_refresh_all (GsShellDetails *shell_details)
                gtk_widget_set_visible (widget, FALSE);
        }
 
-       tmp = gs_app_get_url (priv->app);
+       tmp = gs_app_get_url (priv->app, GS_APP_URL_KIND_HOMEPAGE);
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_details_website"));
        if (tmp != NULL && tmp[0] != '\0') {
                gtk_widget_set_visible (widget, TRUE);
diff --git a/src/plugins/appstream-app.c b/src/plugins/appstream-app.c
index cc1b239..69a909d 100644
--- a/src/plugins/appstream-app.c
+++ b/src/plugins/appstream-app.c
@@ -37,7 +37,7 @@ struct AppstreamApp
        guint                    summary_value;
        gchar                   *description;
        guint                    description_value;
-       gchar                   *url;
+       GHashTable              *urls;
        gchar                   *licence;
        gchar                   *project_group;
        gchar                   *icon;
@@ -59,7 +59,7 @@ appstream_app_free (AppstreamApp *app)
 {
        g_free (app->id);
        g_free (app->pkgname);
-       g_free (app->url);
+       g_hash_table_unref (app->urls);
        g_free (app->licence);
        g_free (app->project_group);
        g_free (app->icon);
@@ -108,6 +108,7 @@ appstream_app_new (void)
        app->keywords = 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);
        app->name_value = G_MAXUINT;
        app->summary_value = G_MAXUINT;
        app->description_value = G_MAXUINT;
@@ -153,12 +154,12 @@ appstream_app_get_summary (AppstreamApp *app)
 }
 
 /**
- * appstream_app_get_url:
+ * appstream_app_get_urls:
  */
-const gchar *
-appstream_app_get_url (AppstreamApp *app)
+GHashTable *
+appstream_app_get_urls (AppstreamApp *app)
 {
-       return app->url;
+       return app->urls;
 }
 
 /**
@@ -327,14 +328,17 @@ appstream_app_set_summary (AppstreamApp *app,
 }
 
 /**
- * appstream_app_set_url:
+ * appstream_app_add_url:
  */
 void
-appstream_app_set_url (AppstreamApp *app,
+appstream_app_add_url (AppstreamApp *app,
+                      const gchar *kind,
                       const gchar *url,
                       gsize length)
 {
-       app->url = g_strndup (url, length);
+       g_hash_table_insert (app->urls,
+                            g_strdup (kind),
+                            g_strndup (url, length));
 }
 
 /**
diff --git a/src/plugins/appstream-app.h b/src/plugins/appstream-app.h
index 8c52333..e183e45 100644
--- a/src/plugins/appstream-app.h
+++ b/src/plugins/appstream-app.h
@@ -54,7 +54,7 @@ const gchar   *appstream_app_get_pkgname              (AppstreamApp   *app);
 const gchar    *appstream_app_get_name                 (AppstreamApp   *app);
 const gchar    *appstream_app_get_summary              (AppstreamApp   *app);
 const gchar    *appstream_app_get_project_group        (AppstreamApp   *app);
-const gchar    *appstream_app_get_url                  (AppstreamApp   *app);
+GHashTable     *appstream_app_get_urls                 (AppstreamApp   *app);
 const gchar    *appstream_app_get_licence              (AppstreamApp   *app);
 const gchar    *appstream_app_get_description          (AppstreamApp   *app);
 const gchar    *appstream_app_get_icon                 (AppstreamApp   *app);
@@ -79,7 +79,8 @@ void           appstream_app_set_summary              (AppstreamApp   *app,
                                                         const gchar    *lang,
                                                         const gchar    *summary,
                                                         gsize           length);
-void            appstream_app_set_url                  (AppstreamApp   *app,
+void            appstream_app_add_url                  (AppstreamApp   *app,
+                                                        const gchar    *kind,
                                                         const gchar    *summary,
                                                         gsize           length);
 void            appstream_app_set_licence              (AppstreamApp   *app,
diff --git a/src/plugins/appstream-cache.c b/src/plugins/appstream-cache.c
index 1ddb512..3e5e07e 100644
--- a/src/plugins/appstream-cache.c
+++ b/src/plugins/appstream-cache.c
@@ -111,7 +111,8 @@ appstream_cache_icon_kind_from_string (const gchar *kind_str)
 typedef struct {
        const gchar             *path_icons;
        AppstreamApp            *item_temp;
-       char                    *lang_temp;
+       gchar                   *lang_temp;
+       gchar                   *url_type_temp;
        AppstreamCache          *cache;
        AppstreamTag             tag;
        AppstreamImage          *image;
@@ -298,8 +299,29 @@ appstream_cache_start_element_cb (GMarkupParseContext *context,
                        }
                }
                break;
-       case APPSTREAM_TAG_PKGNAME:
        case APPSTREAM_TAG_URL:
+               if (helper->item_temp == NULL ||
+                   helper->tag != APPSTREAM_TAG_APPLICATION) {
+                       g_set_error (error,
+                                    APPSTREAM_CACHE_ERROR,
+                                    APPSTREAM_CACHE_ERROR_FAILED,
+                                    "XML start %s invalid, tag %s",
+                                    element_name,
+                                    appstream_tag_to_string (helper->tag));
+                       return;
+               }
+
+               /* get the url kind */
+               for (i = 0; attribute_names[i] != NULL; i++) {
+                       if (g_strcmp0 (attribute_names[i], "type") == 0) {
+                               helper->url_type_temp = g_strdup (attribute_values[i]);
+                               break;
+                       }
+               }
+               if (helper->url_type_temp == NULL)
+                       helper->url_type_temp = g_strdup ("homepage");
+               break;
+       case APPSTREAM_TAG_PKGNAME:
        case APPSTREAM_TAG_LICENCE:
        case APPSTREAM_TAG_PROJECT_GROUP:
                if (helper->item_temp == NULL ||
@@ -424,11 +446,14 @@ appstream_cache_end_element_cb (GMarkupParseContext *context,
        case APPSTREAM_TAG_APPCATEGORIES:
        case APPSTREAM_TAG_COMPULSORY_FOR_DESKTOP:
        case APPSTREAM_TAG_KEYWORDS:
-       case APPSTREAM_TAG_URL:
        case APPSTREAM_TAG_LICENCE:
        case APPSTREAM_TAG_ICON:
                helper->tag = APPSTREAM_TAG_APPLICATION;
                break;
+       case APPSTREAM_TAG_URL:
+               g_free (helper->url_type_temp);
+               helper->tag = APPSTREAM_TAG_APPLICATION;
+               break;
        case APPSTREAM_TAG_NAME:
        case APPSTREAM_TAG_SUMMARY:
        case APPSTREAM_TAG_PROJECT_GROUP:
@@ -548,14 +573,16 @@ appstream_cache_text_cb (GMarkupParseContext *context,
                break;
        case APPSTREAM_TAG_URL:
                if (helper->item_temp == NULL ||
-                   appstream_app_get_url (helper->item_temp) != NULL) {
+                   helper->url_type_temp == NULL) {
                        g_set_error_literal (error,
                                             APPSTREAM_CACHE_ERROR,
                                             APPSTREAM_CACHE_ERROR_FAILED,
                                             "item_temp url invalid");
                        return;
                }
-               appstream_app_set_url (helper->item_temp, text, text_len);
+               appstream_app_add_url (helper->item_temp,
+                                      helper->url_type_temp,
+                                      text, text_len);
                break;
        case APPSTREAM_TAG_LICENCE:
                if (helper->item_temp == NULL ||
diff --git a/src/plugins/gs-plugin-appdata.c b/src/plugins/gs-plugin-appdata.c
index eb7487e..7496bb6 100644
--- a/src/plugins/gs-plugin-appdata.c
+++ b/src/plugins/gs-plugin-appdata.c
@@ -411,12 +411,12 @@ appdata_parse_text_cb (GMarkupParseContext *context,
                }
                break;
        case APPSTREAM_TAG_URL:
-               if (gs_app_get_url (helper->app) == NULL) {
+               if (gs_app_get_url (helper->app, GS_APP_URL_KIND_HOMEPAGE) == NULL) {
                        tmp = appdata_xml_unmunge (text, text_len);
                        if (tmp == NULL)
                                break;
                        g_debug ("AppData: Setting URL: %s", tmp);
-                       gs_app_set_url (helper->app, tmp);
+                       gs_app_set_url (helper->app, GS_APP_URL_KIND_HOMEPAGE, tmp);
                }
                break;
        case APPSTREAM_TAG_PROJECT_GROUP:
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 581f100..ba7845f 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -431,6 +431,7 @@ gs_plugin_refine_item (GsPlugin *plugin,
                       AppstreamApp *item,
                       GError **error)
 {
+       GHashTable *urls;
        gboolean ret = TRUE;
 
        /* is an app */
@@ -450,9 +451,20 @@ gs_plugin_refine_item (GsPlugin *plugin,
        if (appstream_app_get_summary (item) != NULL && gs_app_get_summary (app) == NULL)
                gs_app_set_summary (app, appstream_app_get_summary (item));
 
-       /* set url */
-       if (appstream_app_get_url (item) != NULL && gs_app_get_url (app) == NULL)
-               gs_app_set_url (app, appstream_app_get_url (item));
+       /* add urls */
+       urls = appstream_app_get_urls (item);
+       if (g_hash_table_size (urls) > 0 &&
+           gs_app_get_url (app, GS_APP_URL_KIND_HOMEPAGE) == NULL) {
+               GList *keys;
+               GList *l;
+               keys = g_hash_table_get_keys (urls);
+               for (l = keys; l != NULL; l = l->next) {
+                       gs_app_set_url (app,
+                                       keys->data,
+                                       g_hash_table_lookup (urls, l->data));
+               }
+               g_list_free (keys);
+       }
 
        /* set licence */
        if (appstream_app_get_licence (item) != NULL && gs_app_get_licence (app) == NULL)
diff --git a/src/plugins/gs-plugin-dummy.c b/src/plugins/gs-plugin-dummy.c
index f198e68..248ce1e 100644
--- a/src/plugins/gs-plugin-dummy.c
+++ b/src/plugins/gs-plugin-dummy.c
@@ -205,7 +205,7 @@ gs_plugin_add_category_apps (GsPlugin *plugin,
        app = gs_app_new ("gnome-boxes");
        gs_app_set_name (app, "Boxes");
        gs_app_set_summary (app, "View and use virtual machines");
-       gs_app_set_url (app, "http://www.box.org";);
+       gs_app_set_url (app, GS_APP_URL_KIND_HOMEPAGE, "http://www.box.org";);
        gs_app_set_kind (app, GS_APP_KIND_NORMAL);
        gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
        gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file 
("/usr/share/icons/hicolor/48x48/apps/gnome-boxes.png", NULL));
diff --git a/src/plugins/gs-plugin-packagekit-refine.c b/src/plugins/gs-plugin-packagekit-refine.c
index 9507cdb..c53947f 100644
--- a/src/plugins/gs-plugin-packagekit-refine.c
+++ b/src/plugins/gs-plugin-packagekit-refine.c
@@ -445,8 +445,11 @@ gs_plugin_packagekit_refine_details (GsPlugin *plugin,
                        }
                        if (gs_app_get_licence (app) == NULL)
                                gs_app_set_licence (app, pk_details_get_license (details));
-                       if (gs_app_get_url (app) == NULL)
-                               gs_app_set_url (app, pk_details_get_url (details));
+                       if (gs_app_get_url (app, GS_APP_URL_KIND_HOMEPAGE) == NULL) {
+                               gs_app_set_url (app,
+                                               GS_APP_URL_KIND_HOMEPAGE,
+                                               pk_details_get_url (details));
+                       }
                        if (gs_app_get_size (app) == 0)
                                gs_app_set_size (app, pk_details_get_size (details));
                        if (gs_app_get_description (app) == NULL &&
@@ -466,9 +469,9 @@ gs_plugin_packagekit_refine_details (GsPlugin *plugin,
                                gs_app_set_licence (app, tmp);
                                g_free (tmp);
                        }
-                       if (gs_app_get_url (app) == NULL) {
+                       if (gs_app_get_url (app, GS_APP_URL_KIND_HOMEPAGE) == NULL) {
                                g_object_get (details, "url", &tmp, NULL);
-                               gs_app_set_licence (app, tmp);
+                               gs_app_set_url (app, GS_APP_URL_KIND_HOMEPAGE, tmp);
                                g_free (tmp);
                        }
                        if (gs_app_get_size (app) == 0) {
@@ -514,7 +517,7 @@ gs_plugin_refine_require_details (GsPlugin *plugin,
        for (l = list; l != NULL; l = l->next) {
                app = GS_APP (l->data);
                if (gs_app_get_licence (app) != NULL &&
-                   gs_app_get_url (app) != NULL &&
+                   gs_app_get_url (app, GS_APP_URL_KIND_HOMEPAGE) != NULL &&
                    gs_app_get_size (app) != 0 &&
                    (gs_app_get_description (app) != NULL ||
                     g_getenv ("GNOME_SOFTWARE_USE_PKG_DESCRIPTIONS") == NULL))


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