[gnome-software] Save the application type when parsing the AppStream metadata



commit aa1f872fc550a3ea37b7379ff1cc718791adda68
Author: Richard Hughes <richard hughsie com>
Date:   Wed Oct 16 14:07:34 2013 +0100

    Save the application type when parsing the AppStream metadata

 src/gs-app.c                      |   42 +++++++++++++++++++++++++++
 src/gs-app.h                      |   13 ++++++++
 src/plugins/appstream-app.c       |   20 +++++++++++++
 src/plugins/appstream-app.h       |   12 ++++++++
 src/plugins/appstream-cache.c     |   57 ++++++++++++++++++++++++++++++++++++-
 src/plugins/gs-plugin-appstream.c |    4 ++
 6 files changed, 147 insertions(+), 1 deletions(-)
---
diff --git a/src/gs-app.c b/src/gs-app.c
index 62c7645..6b0c6d1 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -74,6 +74,7 @@ struct GsAppPrivate
        gint                     rating;
        guint64                  size;
        GsAppKind                kind;
+       GsAppIdKind              id_kind;
        GsAppState               state;
        GHashTable              *metadata;
        GdkPixbuf               *pixbuf;
@@ -161,6 +162,25 @@ gs_app_state_to_string (GsAppState state)
 }
 
 /**
+ * gs_app_id_kind_to_string:
+ **/
+const gchar *
+gs_app_id_kind_to_string (GsAppIdKind id_kind)
+{
+       if (id_kind == GS_APP_ID_KIND_UNKNOWN)
+               return "unknown";
+       if (id_kind == GS_APP_ID_KIND_DESKTOP)
+               return "desktop";
+       if (id_kind == GS_APP_ID_KIND_INPUT_METHOD)
+               return "input-method";
+       if (id_kind == GS_APP_ID_KIND_FONT)
+               return "font";
+       if (id_kind == GS_APP_ID_KIND_CODEC)
+               return "codec";
+       return NULL;
+}
+
+/**
  * gs_app_to_string:
  **/
 gchar *
@@ -177,6 +197,8 @@ gs_app_to_string (GsApp *app)
        str = g_string_new ("GsApp:\n");
        g_string_append_printf (str, "\tkind:\t%s\n",
                                gs_app_kind_to_string (priv->kind));
+       g_string_append_printf (str, "\tid-kind:\t%s\n",
+                               gs_app_id_kind_to_string (priv->id_kind));
        g_string_append_printf (str, "\tstate:\t%s\n",
                                gs_app_state_to_string (priv->state));
        if (priv->id != NULL)
@@ -419,6 +441,26 @@ gs_app_set_kind (GsApp *app, GsAppKind kind)
 }
 
 /**
+ * gs_app_get_id_kind:
+ */
+GsAppIdKind
+gs_app_get_id_kind (GsApp *app)
+{
+       g_return_val_if_fail (GS_IS_APP (app), GS_APP_KIND_UNKNOWN);
+       return app->priv->id_kind;
+}
+
+/**
+ * gs_app_set_id_kind:
+ */
+void
+gs_app_set_id_kind (GsApp *app, GsAppIdKind id_kind)
+{
+       g_return_if_fail (GS_IS_APP (app));
+       app->priv->id_kind = id_kind;
+}
+
+/**
  * gs_app_get_name:
  */
 const gchar *
diff --git a/src/gs-app.h b/src/gs-app.h
index a10afd2..b5f1eb4 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -75,6 +75,15 @@ typedef enum {
        GS_APP_STATE_LAST
 } GsAppState;
 
+typedef enum {
+       GS_APP_ID_KIND_UNKNOWN,
+       GS_APP_ID_KIND_DESKTOP,
+       GS_APP_ID_KIND_INPUT_METHOD,
+       GS_APP_ID_KIND_FONT,
+       GS_APP_ID_KIND_CODEC,
+       GS_APP_ID_KIND_LAST
+} GsAppIdKind;
+
 #define        GS_APP_INSTALL_DATE_UNKNOWN             1 /* 1s past the epoch */
 
 GQuark          gs_app_error_quark             (void);
@@ -83,6 +92,7 @@ GType          gs_app_get_type                (void);
 GsApp          *gs_app_new                     (const gchar    *id);
 gchar          *gs_app_to_string               (GsApp          *app);
 const gchar    *gs_app_kind_to_string          (GsAppKind       kind);
+const gchar    *gs_app_id_kind_to_string       (GsAppIdKind     id_kind);
 const gchar    *gs_app_state_to_string         (GsAppState      state);
 
 const gchar    *gs_app_get_id                  (GsApp          *app);
@@ -91,6 +101,9 @@ void          gs_app_set_id                  (GsApp          *app,
 GsAppKind       gs_app_get_kind                (GsApp          *app);
 void            gs_app_set_kind                (GsApp          *app,
                                                 GsAppKind       kind);
+GsAppIdKind     gs_app_get_id_kind             (GsApp          *app);
+void            gs_app_set_id_kind             (GsApp          *app,
+                                                GsAppIdKind     id_kind);
 GsAppState      gs_app_get_state               (GsApp          *app);
 void            gs_app_set_state               (GsApp          *app,
                                                 GsAppState      state);
diff --git a/src/plugins/appstream-app.c b/src/plugins/appstream-app.c
index 0c18fa1..cc1b239 100644
--- a/src/plugins/appstream-app.c
+++ b/src/plugins/appstream-app.c
@@ -42,6 +42,7 @@ struct AppstreamApp
        gchar                   *project_group;
        gchar                   *icon;
        AppstreamAppIconKind     icon_kind;
+       AppstreamAppIdKind       id_kind;
        GPtrArray               *appcategories; /* of gchar* */
        GPtrArray               *keywords;
        GPtrArray               *desktop_core;
@@ -111,6 +112,7 @@ appstream_app_new (void)
        app->summary_value = G_MAXUINT;
        app->description_value = G_MAXUINT;
        app->icon_kind = APPSTREAM_APP_ICON_KIND_UNKNOWN;
+       app->id_kind = APPSTREAM_APP_ID_KIND_UNKNOWN;
        return app;
 }
 
@@ -205,6 +207,15 @@ appstream_app_get_icon_kind (AppstreamApp *app)
 }
 
 /**
+ * appstream_app_get_id_kind:
+ */
+AppstreamAppIdKind
+appstream_app_get_id_kind (AppstreamApp *app)
+{
+       return app->id_kind;
+}
+
+/**
  * appstream_app_has_category:
  */
 gboolean
@@ -413,6 +424,15 @@ appstream_app_set_icon_kind (AppstreamApp *app,
 }
 
 /**
+ * appstream_app_set_id_kind:
+ */
+void
+appstream_app_set_id_kind (AppstreamApp *app, AppstreamAppIdKind id_kind)
+{
+       app->id_kind = id_kind;
+}
+
+/**
  * appstream_app_add_screenshot:
  */
 void
diff --git a/src/plugins/appstream-app.h b/src/plugins/appstream-app.h
index 9c47b1e..8c52333 100644
--- a/src/plugins/appstream-app.h
+++ b/src/plugins/appstream-app.h
@@ -35,6 +35,15 @@ typedef enum {
        APPSTREAM_APP_ICON_KIND_LAST
 } AppstreamAppIconKind;
 
+typedef enum {
+       APPSTREAM_APP_ID_KIND_UNKNOWN,
+       APPSTREAM_APP_ID_KIND_DESKTOP,
+       APPSTREAM_APP_ID_KIND_INPUT_METHOD,
+       APPSTREAM_APP_ID_KIND_FONT,
+       APPSTREAM_APP_ID_KIND_CODEC,
+       APPSTREAM_APP_ID_KIND_LAST
+} AppstreamAppIdKind;
+
 typedef struct AppstreamApp    AppstreamApp;
 
 void            appstream_app_free                     (AppstreamApp   *app);
@@ -54,6 +63,7 @@ gboolean       appstream_app_has_category             (AppstreamApp   *app,
 gboolean        appstream_app_get_desktop_core         (AppstreamApp   *app,
                                                         const gchar    *desktop);
 AppstreamAppIconKind   appstream_app_get_icon_kind     (AppstreamApp   *app);
+AppstreamAppIdKind     appstream_app_get_id_kind       (AppstreamApp   *app);
 
 void            appstream_app_set_id                   (AppstreamApp   *app,
                                                         const gchar    *id,
@@ -96,6 +106,8 @@ void          appstream_app_add_desktop_core         (AppstreamApp   *app,
                                                         gsize           length);
 void            appstream_app_set_icon_kind            (AppstreamApp   *app,
                                                         AppstreamAppIconKind icon_kind);
+void            appstream_app_set_id_kind              (AppstreamApp   *app,
+                                                        AppstreamAppIdKind id_kind);
 
 gpointer        appstream_app_get_userdata             (AppstreamApp   *app);
 void            appstream_app_set_userdata             (AppstreamApp   *app,
diff --git a/src/plugins/appstream-cache.c b/src/plugins/appstream-cache.c
index feac444..1ddb512 100644
--- a/src/plugins/appstream-cache.c
+++ b/src/plugins/appstream-cache.c
@@ -119,6 +119,23 @@ typedef struct {
 } AppstreamCacheHelper;
 
 /**
+ * appstream_cache_app_id_kind_from_string:
+ */
+static AppstreamAppIdKind
+appstream_cache_app_id_kind_from_string (const gchar *id_kind)
+{
+       if (g_strcmp0 (id_kind, "desktop") == 0)
+               return APPSTREAM_APP_ID_KIND_DESKTOP;
+       if (g_strcmp0 (id_kind, "inputmethod") == 0)
+               return APPSTREAM_APP_ID_KIND_INPUT_METHOD;
+       if (g_strcmp0 (id_kind, "font") == 0)
+               return APPSTREAM_APP_ID_KIND_FONT;
+       if (g_strcmp0 (id_kind, "codec") == 0)
+               return APPSTREAM_APP_ID_KIND_CODEC;
+       return APPSTREAM_APP_ID_KIND_UNKNOWN;
+}
+
+/**
  * appstream_cache_start_element_cb:
  */
 static void
@@ -148,6 +165,36 @@ appstream_cache_start_element_cb (GMarkupParseContext *context,
        case APPSTREAM_TAG_KEYWORD:
                /* ignore */
                break;
+       case APPSTREAM_TAG_ID:
+               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 id kind */
+               for (i = 0; attribute_names[i] != NULL; i++) {
+                       if (g_strcmp0 (attribute_names[i], "type") == 0) {
+                               tmp = attribute_values[i];
+                               break;
+                       }
+               }
+               if (tmp != NULL) {
+                       AppstreamAppIdKind id_kind;
+                       id_kind = appstream_cache_app_id_kind_from_string (tmp);
+                       appstream_app_set_id_kind (helper->item_temp, id_kind);
+               } else {
+                       g_warning ("no type in <id>, assuming 'desktop'");
+                       appstream_app_set_id_kind (helper->item_temp,
+                                                  APPSTREAM_APP_ID_KIND_DESKTOP);
+               }
+               break;
+
        case APPSTREAM_TAG_SCREENSHOT:
                if (helper->item_temp == NULL ||
                    helper->tag != APPSTREAM_TAG_SCREENSHOTS) {
@@ -251,7 +298,6 @@ appstream_cache_start_element_cb (GMarkupParseContext *context,
                        }
                }
                break;
-       case APPSTREAM_TAG_ID:
        case APPSTREAM_TAG_PKGNAME:
        case APPSTREAM_TAG_URL:
        case APPSTREAM_TAG_LICENCE:
@@ -305,6 +351,7 @@ static void
 appstream_cache_add_item (AppstreamCacheHelper *helper)
 {
        AppstreamApp *item;
+       AppstreamAppIdKind id_kind;
        AppstreamCachePrivate *priv = helper->cache->priv;
        const gchar *id;
 
@@ -317,6 +364,14 @@ appstream_cache_add_item (AppstreamCacheHelper *helper)
                return;
        }
 
+       /* this is a type we don't know how to handle */
+       id_kind = appstream_app_get_id_kind (helper->item_temp);
+       if (id_kind == APPSTREAM_APP_ID_KIND_UNKNOWN) {
+               g_debug ("No idea how to handle AppStream entry: %s", id);
+               appstream_app_free (helper->item_temp);
+               return;
+       }
+
        /* success, add to array */
        g_ptr_array_add (priv->array, helper->item_temp);
        g_hash_table_insert (priv->hash_id,
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 24d83e4..581f100 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -480,6 +480,10 @@ gs_plugin_refine_item (GsPlugin *plugin,
            gs_app_get_kind (app) == GS_APP_KIND_NORMAL)
                gs_app_set_kind (app, GS_APP_KIND_SYSTEM);
 
+       /* set id kind */
+       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));


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