[gnome-software] Generates the 'Picks' on the overview automatically



commit 7cdbbbcbf37333fef355aebba12ca58e1ad3a674
Author: Richard Hughes <richard hughsie com>
Date:   Fri Jan 31 14:08:36 2014 +0000

    Generates the 'Picks' on the overview automatically
    
    This uses the AppStream data and any ratings data to choose applications based
    on a primative metric.

 src/gs-plugin-loader.c                       |   45 ++++++++++++++++++++++--
 src/plugins/gs-plugin-appstream.c            |   48 ++++++++++++++++++++++++++
 src/plugins/gs-plugin-hardcoded-categories.c |   21 +++++++++++
 src/plugins/gs-plugin-hardcoded-popular.c    |   14 +++++++
 4 files changed, 125 insertions(+), 3 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 55d9893..a574442 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -1025,12 +1025,45 @@ gs_plugin_loader_get_installed_finish (GsPluginLoader *plugin_loader,
 /******************************************************************************/
 
 /**
+ * gs_plugin_loader_get_popular_filter_cb:
+ */
+static gboolean
+gs_plugin_loader_get_popular_filter_cb (GsApp *app, gpointer user_data)
+{
+       /* dont suggest already installed application */
+       if (gs_app_get_state (app) == GS_APP_STATE_INSTALLED)
+               return FALSE;
+
+       /* only show featured popular applications */
+       if (!gs_app_has_category (app, "featured"))
+               return FALSE;
+
+       /* require long description */
+       if (gs_app_get_description (app) == NULL)
+               return FALSE;
+
+       /* require at least one screenshot */
+       if (gs_app_get_screenshots (app)->len == 0)
+               return FALSE;
+
+       /* don't suggest applications we don't have a lot of confidence in,
+        * just because one user rated the app 100% doesn't make it awesome
+        * compared to an app with 300 votes of 85% */
+       if (gs_app_get_rating_confidence (app) < 90)
+               return FALSE;
+       if (gs_app_get_rating (app) < 75)
+               return FALSE;
+
+       return TRUE;
+}
+
+/**
  * gs_plugin_loader_get_popular_thread_cb:
  **/
 static void
 gs_plugin_loader_get_popular_thread_cb (GSimpleAsyncResult *res,
-                                         GObject *object,
-                                         GCancellable *cancellable)
+                                       GObject *object,
+                                       GCancellable *cancellable)
 {
        GError *error = NULL;
        GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
@@ -1050,6 +1083,9 @@ gs_plugin_loader_get_popular_thread_cb (GSimpleAsyncResult *res,
 
        /* filter package list */
        gs_plugin_list_filter (&state->list, gs_plugin_loader_app_is_valid, NULL);
+       gs_plugin_list_filter (&state->list,
+                              gs_plugin_loader_get_popular_filter_cb,
+                              NULL);
        if (state->list == NULL) {
                g_set_error_literal (&error,
                                     GS_PLUGIN_LOADER_ERROR,
@@ -1060,6 +1096,9 @@ gs_plugin_loader_get_popular_thread_cb (GSimpleAsyncResult *res,
                goto out;
        }
 
+       /* shuffle around the list */
+       gs_plugin_list_randomize (&state->list);
+
        /* success */
        state->ret = TRUE;
        gs_plugin_loader_get_all_state_finish (state, NULL);
@@ -1090,7 +1129,7 @@ gs_plugin_loader_get_popular_async (GsPluginLoader *plugin_loader,
                                                user_data,
                                                gs_plugin_loader_get_popular_async);
        state->plugin_loader = g_object_ref (plugin_loader);
-       state->flags = flags;
+       state->flags = flags | GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING;
        if (cancellable != NULL)
                state->cancellable = g_object_ref (cancellable);
 
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index c0e1a5b..550baae 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -717,6 +717,54 @@ out:
 }
 
 /**
+ * gs_plugin_add_popular:
+ */
+gboolean
+gs_plugin_add_popular (GsPlugin *plugin,
+                      GList **list,
+                      GCancellable *cancellable,
+                      GError **error)
+{
+       AppstreamApp *item;
+       GPtrArray *array;
+       GsApp *app;
+       gboolean ret = TRUE;
+       guint i;
+
+       /* load XML files */
+       if (g_once_init_enter (&plugin->priv->done_init)) {
+               ret = gs_plugin_startup (plugin, cancellable, error);
+               g_once_init_leave (&plugin->priv->done_init, TRUE);
+               if (!ret)
+                       goto out;
+       }
+
+       /* just add the apps without refining */
+       gs_profile_start (plugin->profile, "appstream::add-popular");
+       array = appstream_cache_get_items (plugin->priv->cache);
+       for (i = 0; i < array->len; i++) {
+               item = g_ptr_array_index (array, i);
+               if (appstream_app_get_id (item) == NULL)
+                       continue;
+
+               /* require long description */
+               if (appstream_app_get_description (item) == NULL)
+                       continue;
+
+               /* require at least one screenshot */
+               if (appstream_app_get_screenshots (item)->len == 0)
+                       continue;
+
+               app = gs_app_new (appstream_app_get_id (item));
+               gs_plugin_add_app (list, app);
+               g_object_unref (app);
+       }
+       gs_profile_stop (plugin->profile, "appstream::add-popular");
+out:
+       return ret;
+}
+
+/**
  * gs_plugin_add_category_apps:
  */
 gboolean
diff --git a/src/plugins/gs-plugin-hardcoded-categories.c b/src/plugins/gs-plugin-hardcoded-categories.c
index 324da4b..7becc9f 100644
--- a/src/plugins/gs-plugin-hardcoded-categories.c
+++ b/src/plugins/gs-plugin-hardcoded-categories.c
@@ -170,6 +170,27 @@ gs_plugin_add_categories (GsPlugin *plugin,
        return TRUE;
 }
 
+/**
+ * gs_plugin_add_popular:
+ */
+gboolean
+gs_plugin_add_popular (GsPlugin *plugin,
+                      GList **list,
+                      GCancellable *cancellable,
+                      GError **error)
+{
+       guint i;
+       GsApp *app;
+
+       /* don't bother checking @list, the duplicate GsApp's will be merged */
+       for (i = 0; i < G_N_ELEMENTS (featured); i++) {
+               app = gs_app_new (featured[i].app);
+               gs_app_add_category (app, "featured");
+               gs_plugin_add_app (list, app);
+       }
+       return TRUE;
+}
+
 gboolean
 gs_plugin_add_category_apps (GsPlugin *plugin,
                             GsCategory *category,
diff --git a/src/plugins/gs-plugin-hardcoded-popular.c b/src/plugins/gs-plugin-hardcoded-popular.c
index 23a859d..833700b 100644
--- a/src/plugins/gs-plugin-hardcoded-popular.c
+++ b/src/plugins/gs-plugin-hardcoded-popular.c
@@ -37,6 +37,20 @@ gs_plugin_get_name (void)
 }
 
 /**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+       /* check that we are running on Fedora */
+       if (gs_plugin_check_distro_id (plugin, "fedora")) {
+               gs_plugin_set_enabled (plugin, FALSE);
+               g_debug ("disabling '%s' as we're Fedora and have tagger", plugin->name);
+               return;
+       }
+}
+
+/**
  * gs_plugin_add_popular:
  */
 gboolean


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