[gnome-software] Limit the number of category results to 50



commit 0300a78c088a50cd77bc76c4edabdf9ca9e3f6fe
Author: Richard Hughes <richard hughsie com>
Date:   Wed Aug 30 15:44:51 2017 +0100

    Limit the number of category results to 50
    
    As we're sorting by rating we have to 'pre-refine' the list with anything that
    the filter func is going to use for sorting, in this case, the star rating.

 lib/gs-plugin-job-private.h |    1 +
 lib/gs-plugin-job.c         |   32 ++++++++++++
 lib/gs-plugin-job.h         |    2 +
 lib/gs-plugin-loader.c      |  117 +++++++++++++++++++++++++++---------------
 src/gs-category-page.c      |   12 ++++-
 5 files changed, 120 insertions(+), 44 deletions(-)
---
diff --git a/lib/gs-plugin-job-private.h b/lib/gs-plugin-job-private.h
index 447e21d..f238213 100644
--- a/lib/gs-plugin-job-private.h
+++ b/lib/gs-plugin-job-private.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
 
 GsPluginAction          gs_plugin_job_get_action               (GsPluginJob    *self);
 GsPluginRefreshFlags    gs_plugin_job_get_refresh_flags        (GsPluginJob    *self);
+GsPluginRefineFlags     gs_plugin_job_get_filter_flags         (GsPluginJob    *self);
 GsPluginRefineFlags     gs_plugin_job_get_refine_flags         (GsPluginJob    *self);
 gboolean                gs_plugin_job_has_refine_flags         (GsPluginJob    *self,
                                                                 GsPluginRefineFlags refine_flags);
diff --git a/lib/gs-plugin-job.c b/lib/gs-plugin-job.c
index 341d5c0..2c98a6b 100644
--- a/lib/gs-plugin-job.c
+++ b/lib/gs-plugin-job.c
@@ -30,6 +30,7 @@ struct _GsPluginJob
 {
        GObject                  parent_instance;
        GsPluginRefineFlags      refine_flags;
+       GsPluginRefineFlags      filter_flags;
        GsPluginRefreshFlags     refresh_flags;
        GsPluginFailureFlags     failure_flags;
        guint                    max_results;
@@ -56,6 +57,7 @@ enum {
        PROP_AGE,
        PROP_SEARCH,
        PROP_REFINE_FLAGS,
+       PROP_FILTER_FLAGS,
        PROP_REFRESH_FLAGS,
        PROP_FAILURE_FLAGS,
        PROP_AUTH,
@@ -79,6 +81,10 @@ gs_plugin_job_to_string (GsPluginJob *self)
        gint64 time_now = g_get_monotonic_time ();
        g_string_append_printf (str, "running %s",
                                gs_plugin_action_to_string (self->action));
+       if (self->filter_flags > 0) {
+               g_autofree gchar *tmp = gs_plugin_refine_flags_to_string (self->filter_flags);
+               g_string_append_printf (str, " with filter-flags=%s", tmp);
+       }
        if (self->refine_flags > 0) {
                g_autofree gchar *tmp = gs_plugin_refine_flags_to_string (self->refine_flags);
                g_string_append_printf (str, " with refine-flags=%s", tmp);
@@ -159,6 +165,13 @@ gs_plugin_job_set_refine_flags (GsPluginJob *self, GsPluginRefineFlags refine_fl
        self->refine_flags = refine_flags;
 }
 
+void
+gs_plugin_job_set_filter_flags (GsPluginJob *self, GsPluginRefineFlags filter_flags)
+{
+       g_return_if_fail (GS_IS_PLUGIN_JOB (self));
+       self->filter_flags = filter_flags;
+}
+
 GsPluginRefineFlags
 gs_plugin_job_get_refine_flags (GsPluginJob *self)
 {
@@ -166,6 +179,13 @@ gs_plugin_job_get_refine_flags (GsPluginJob *self)
        return self->refine_flags;
 }
 
+GsPluginRefineFlags
+gs_plugin_job_get_filter_flags (GsPluginJob *self)
+{
+       g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0);
+       return self->filter_flags;
+}
+
 void
 gs_plugin_job_set_refresh_flags (GsPluginJob *self, GsPluginRefreshFlags refresh_flags)
 {
@@ -447,6 +467,9 @@ gs_plugin_job_get_property (GObject *obj, guint prop_id, GValue *value, GParamSp
        case PROP_REFINE_FLAGS:
                g_value_set_uint64 (value, self->refine_flags);
                break;
+       case PROP_FILTER_FLAGS:
+               g_value_set_uint64 (value, self->filter_flags);
+               break;
        case PROP_REFRESH_FLAGS:
                g_value_set_uint64 (value, self->refresh_flags);
                break;
@@ -504,6 +527,9 @@ gs_plugin_job_set_property (GObject *obj, guint prop_id, const GValue *value, GP
        case PROP_REFINE_FLAGS:
                gs_plugin_job_set_refine_flags (self, g_value_get_uint64 (value));
                break;
+       case PROP_FILTER_FLAGS:
+               gs_plugin_job_set_filter_flags (self, g_value_get_uint64 (value));
+               break;
        case PROP_REFRESH_FLAGS:
                gs_plugin_job_set_refresh_flags (self, g_value_get_uint64 (value));
                break;
@@ -588,6 +614,11 @@ gs_plugin_job_class_init (GsPluginJobClass *klass)
                                     G_PARAM_READWRITE);
        g_object_class_install_property (object_class, PROP_REFINE_FLAGS, pspec);
 
+       pspec = g_param_spec_uint64 ("filter-flags", NULL, NULL,
+                                    0, G_MAXUINT64, 0,
+                                    G_PARAM_READWRITE);
+       g_object_class_install_property (object_class, PROP_FILTER_FLAGS, pspec);
+
        pspec = g_param_spec_uint64 ("refresh-flags", NULL, NULL,
                                     0, G_MAXUINT64, 0,
                                     G_PARAM_READWRITE);
@@ -654,6 +685,7 @@ gs_plugin_job_init (GsPluginJob *self)
 {
        self->failure_flags = GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY;
        self->refine_flags = GS_PLUGIN_REFINE_FLAGS_DEFAULT;
+       self->filter_flags = GS_PLUGIN_REFINE_FLAGS_DEFAULT;
        self->refresh_flags = GS_PLUGIN_REFRESH_FLAGS_NONE;
        self->list = gs_app_list_new ();
        self->time_created = g_get_monotonic_time ();
diff --git a/lib/gs-plugin-job.h b/lib/gs-plugin-job.h
index a7d72af..2edd285 100644
--- a/lib/gs-plugin-job.h
+++ b/lib/gs-plugin-job.h
@@ -38,6 +38,8 @@ G_DECLARE_FINAL_TYPE (GsPluginJob, gs_plugin_job, GS, PLUGIN_JOB, GObject)
 
 void            gs_plugin_job_set_refine_flags         (GsPluginJob    *self,
                                                         GsPluginRefineFlags refine_flags);
+void            gs_plugin_job_set_filter_flags         (GsPluginJob    *self,
+                                                        GsPluginRefineFlags filter_flags);
 void            gs_plugin_job_set_refresh_flags        (GsPluginJob    *self,
                                                         GsPluginRefreshFlags refresh_flags);
 void            gs_plugin_job_set_failure_flags        (GsPluginJob    *self,
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index bf36d62..9f279e7 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -493,6 +493,7 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
                             GsPlugin *plugin,
                             GsApp *app,
                             GsAppList *list,
+                            GsPluginRefineFlags refine_flags,
                             GCancellable *cancellable,
                             GError **error)
 {
@@ -531,6 +532,8 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
                app = gs_plugin_job_get_app (helper->plugin_job);
        if (list == NULL)
                list = gs_plugin_job_get_list (helper->plugin_job);
+       if (refine_flags == GS_PLUGIN_REFINE_FLAGS_DEFAULT)
+               refine_flags = gs_plugin_job_get_refine_flags (helper->plugin_job);
 
        /* set what plugin is running on the job */
        gs_plugin_job_set_plugin (helper->plugin_job, plugin);
@@ -554,19 +557,13 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
        case GS_PLUGIN_ACTION_REFINE:
                if (g_strcmp0 (helper->function_name, "gs_plugin_refine_wildcard") == 0) {
                        GsPluginRefineWildcardFunc plugin_func = func;
-                       ret = plugin_func (plugin, app, list,
-                                          gs_plugin_job_get_refine_flags (helper->plugin_job),
-                                          cancellable, &error_local);
+                       ret = plugin_func (plugin, app, list, refine_flags, cancellable, &error_local);
                } else if (g_strcmp0 (helper->function_name, "gs_plugin_refine_app") == 0) {
                        GsPluginRefineAppFunc plugin_func = func;
-                       ret = plugin_func (plugin, app,
-                                          gs_plugin_job_get_refine_flags (helper->plugin_job),
-                                          cancellable, &error_local);
+                       ret = plugin_func (plugin, app, refine_flags, cancellable, &error_local);
                } else if (g_strcmp0 (helper->function_name, "gs_plugin_refine") == 0) {
                        GsPluginRefineFunc plugin_func = func;
-                       ret = plugin_func (plugin, list,
-                                          gs_plugin_job_get_refine_flags (helper->plugin_job),
-                                          cancellable, &error_local);
+                       ret = plugin_func (plugin, list, refine_flags, cancellable, &error_local);
                } else {
                        g_critical ("function_name %s invalid for %s",
                                    helper->function_name,
@@ -773,23 +770,16 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
 }
 
 static gboolean
-gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
-                                     GsAppList *list,
-                                     GCancellable *cancellable,
-                                     GError **error)
+gs_plugin_loader_run_refine_filter (GsPluginLoaderHelper *helper,
+                                   GsAppList *list,
+                                   GsPluginRefineFlags refine_flags,
+                                   GCancellable *cancellable,
+                                   GError **error)
 {
        GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (helper->plugin_loader);
-       guint i;
-       guint j;
-       GPtrArray *addons;
-       GPtrArray *related;
-       GsApp *app;
-
-       /* try to adopt each application with a plugin */
-       gs_plugin_loader_run_adopt (helper->plugin_loader, list);
 
        /* run each plugin */
-       for (i = 0; i < priv->plugins->len; i++) {
+       for (guint i = 0; i < priv->plugins->len; i++) {
                g_autoptr(AsProfileTask) ptask = NULL;
                GsPlugin *plugin = g_ptr_array_index (priv->plugins, i);
                g_autoptr(GsAppList) app_list = NULL;
@@ -797,7 +787,7 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
                /* run the batched plugin symbol then the per-app plugin */
                helper->function_name = "gs_plugin_refine";
                if (!gs_plugin_loader_call_vfunc (helper, plugin, NULL, list,
-                                                 cancellable, error)) {
+                                                 refine_flags, cancellable, error)) {
                        return FALSE;
                }
 
@@ -806,27 +796,44 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
                 * (e.g. inserting an app in the list on every call results in
                 * an infinite loop) */
                app_list = gs_app_list_copy (list);
-               for (j = 0; j < gs_app_list_length (app_list); j++) {
-                       app = gs_app_list_index (app_list, j);
+               for (guint j = 0; j < gs_app_list_length (app_list); j++) {
+                       GsApp *app = gs_app_list_index (app_list, j);
                        if (!gs_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX)) {
                                helper->function_name = "gs_plugin_refine_app";
                        } else {
                                helper->function_name = "gs_plugin_refine_wildcard";
                        }
                        if (!gs_plugin_loader_call_vfunc (helper, plugin, app, NULL,
-                                                         cancellable, error)) {
+                                                         refine_flags, cancellable, error)) {
                                return FALSE;
                        }
                }
                gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_FINISHED);
        }
+       return TRUE;
+}
+
+static gboolean
+gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
+                                     GsAppList *list,
+                                     GCancellable *cancellable,
+                                     GError **error)
+{
+       /* try to adopt each application with a plugin */
+       gs_plugin_loader_run_adopt (helper->plugin_loader, list);
+
+       /* run each plugin */
+       if (!gs_plugin_loader_run_refine_filter (helper, list,
+                                                GS_PLUGIN_REFINE_FLAGS_DEFAULT,
+                                                cancellable, error))
+               return FALSE;
 
        /* ensure these are sorted by score */
        if (gs_plugin_job_has_refine_flags (helper->plugin_job,
                                                GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS)) {
                GPtrArray *reviews;
-               for (i = 0; i < gs_app_list_length (list); i++) {
-                       app = gs_app_list_index (list, i);
+               for (guint i = 0; i < gs_app_list_length (list); i++) {
+                       GsApp *app = gs_app_list_index (list, i);
                        reviews = gs_app_get_reviews (app);
                        g_ptr_array_sort (reviews,
                                          gs_plugin_loader_review_score_sort_cb);
@@ -842,10 +849,10 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
                                                   GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS |
                                                   GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS);
                addons_list = gs_app_list_new ();
-               for (i = 0; i < gs_app_list_length (list); i++) {
-                       app = gs_app_list_index (list, i);
-                       addons = gs_app_get_addons (app);
-                       for (j = 0; j < addons->len; j++) {
+               for (guint i = 0; i < gs_app_list_length (list); i++) {
+                       GsApp *app = gs_app_list_index (list, i);
+                       GPtrArray *addons = gs_app_get_addons (app);
+                       for (guint j = 0; j < addons->len; j++) {
                                GsApp *addon = g_ptr_array_index (addons, j);
                                g_debug ("refining app %s addon %s",
                                         gs_app_get_id (app),
@@ -867,9 +874,9 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
        if (gs_plugin_job_has_refine_flags (helper->plugin_job,
                                                GS_PLUGIN_REFINE_FLAGS_REQUIRE_RUNTIME)) {
                g_autoptr(GsAppList) list2 = gs_app_list_new ();
-               for (i = 0; i < gs_app_list_length (list); i++) {
+               for (guint i = 0; i < gs_app_list_length (list); i++) {
                        GsApp *runtime;
-                       app = gs_app_list_index (list, i);
+                       GsApp *app = gs_app_list_index (list, i);
                        runtime = gs_app_get_runtime (app);
                        if (runtime != NULL)
                                gs_app_list_add (list2, runtime);
@@ -891,15 +898,15 @@ gs_plugin_loader_run_refine_internal (GsPluginLoaderHelper *helper,
                gs_plugin_job_remove_refine_flags (helper->plugin_job,
                                                   GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED);
                related_list = gs_app_list_new ();
-               for (i = 0; i < gs_app_list_length (list); i++) {
-                       app = gs_app_list_index (list, i);
-                       related = gs_app_get_related (app);
-                       for (j = 0; j < related->len; j++) {
-                               app = g_ptr_array_index (related, j);
+               for (guint i = 0; i < gs_app_list_length (list); i++) {
+                       GsApp *app = gs_app_list_index (list, i);
+                       GPtrArray *related = gs_app_get_related (app);
+                       for (guint j = 0; j < related->len; j++) {
+                               GsApp *app2 = g_ptr_array_index (related, j);
                                g_debug ("refining related: %s[%s]",
-                                        gs_app_get_id (app),
-                                        gs_app_get_source_default (app));
-                               gs_app_list_add (related_list, app);
+                                        gs_app_get_id (app2),
+                                        gs_app_get_source_default (app2));
+                               gs_app_list_add (related_list, app2);
                        }
                }
                if (gs_app_list_length (related_list) > 0) {
@@ -1081,6 +1088,7 @@ gs_plugin_loader_run_results (GsPluginLoaderHelper *helper,
                        return FALSE;
                }
                if (!gs_plugin_loader_call_vfunc (helper, plugin, NULL, NULL,
+                                                 GS_PLUGIN_REFINE_FLAGS_DEFAULT,
                                                  cancellable, error)) {
                        return FALSE;
                }
@@ -2277,6 +2285,7 @@ gs_plugin_loader_setup_again (GsPluginLoader *plugin_loader)
                                                         NULL);
                        helper = gs_plugin_loader_helper_new (plugin_loader, plugin_job);
                        if (!gs_plugin_loader_call_vfunc (helper, plugin, NULL, NULL,
+                                                         GS_PLUGIN_REFINE_FLAGS_DEFAULT,
                                                          NULL, &error_local)) {
                                g_warning ("resetup of %s failed: %s",
                                           gs_plugin_get_name (plugin),
@@ -2562,6 +2571,7 @@ gs_plugin_loader_setup (GsPluginLoader *plugin_loader,
                g_autoptr(GError) error_local = NULL;
                plugin = g_ptr_array_index (priv->plugins, i);
                if (!gs_plugin_loader_call_vfunc (helper, plugin, NULL, NULL,
+                                                 GS_PLUGIN_REFINE_FLAGS_DEFAULT,
                                                  cancellable, &error_local)) {
                        g_debug ("disabling %s as setup failed: %s",
                                 gs_plugin_get_name (plugin),
@@ -3033,6 +3043,7 @@ gs_plugin_loader_process_thread_cb (GTask *task,
        GsPluginAction action = gs_plugin_job_get_action (helper->plugin_job);
        GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
        GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       GsPluginRefineFlags filter_flags;
        gboolean add_to_pending_array = FALSE;
 
        /* these change the pending count on the installed panel */
@@ -3144,6 +3155,28 @@ gs_plugin_loader_process_thread_cb (GTask *task,
                break;
        }
 
+       /* refine with enough data so that the sort_func can do what it needs */
+       filter_flags = gs_plugin_job_get_filter_flags (helper->plugin_job);
+       if (filter_flags > 0) {
+               g_autoptr(GsPluginLoaderHelper) helper2 = NULL;
+               g_autoptr(GsPluginJob) plugin_job = NULL;
+               plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE,
+                                                "list", list,
+                                                "refine-flags", filter_flags,
+                                                "failure-flags", gs_plugin_job_get_failure_flags 
(helper->plugin_job),
+                                                NULL);
+               helper2 = gs_plugin_loader_helper_new (helper->plugin_loader, plugin_job);
+               helper2->function_name_parent = helper->function_name;
+               g_debug ("running filter flags with early refine");
+               if (!gs_plugin_loader_run_refine_filter (helper2, list,
+                                                        filter_flags,
+                                                        cancellable, &error)) {
+                       gs_utils_error_convert_gio (&error);
+                       g_task_return_error (task, error);
+                       return;
+               }
+       }
+
        /* filter to reduce to a sane set */
        gs_plugin_loader_job_sorted_truncation (helper);
 
diff --git a/src/gs-category-page.c b/src/gs-category-page.c
index dccadc6..6084c67 100644
--- a/src/gs-category-page.c
+++ b/src/gs-category-page.c
@@ -108,6 +108,12 @@ gs_category_page_get_apps_cb (GObject *source_object,
        gs_shell_profile_dump (self->shell);
 }
 
+static gboolean
+_max_results_sort_cb (GsApp *app1, GsApp *app2, gpointer user_data)
+{
+       return gs_app_get_rating (app1) < gs_app_get_rating (app2);
+}
+
 static void
 gs_category_page_reload (GsPage *page)
 {
@@ -147,11 +153,13 @@ gs_category_page_reload (GsPage *page)
 
        plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_CATEGORY_APPS,
                                         "category", self->subcategory,
+                                        "max-results", 50,
+                                        "filter-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING,
                                         "failure-flags", GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS,
                                         "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON |
-                                                        GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION |
-                                                        GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING,
+                                                        GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION,
                                         NULL);
+       gs_plugin_job_set_sort_func (plugin_job, _max_results_sort_cb);
        gs_plugin_loader_job_process_async (self->plugin_loader,
                                            plugin_job,
                                            self->cancellable,


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