diff options
Diffstat (limited to 'lib/gs-plugin-job.c')
-rw-r--r-- | lib/gs-plugin-job.c | 618 |
1 files changed, 618 insertions, 0 deletions
diff --git a/lib/gs-plugin-job.c b/lib/gs-plugin-job.c new file mode 100644 index 0000000..1ce320f --- /dev/null +++ b/lib/gs-plugin-job.c @@ -0,0 +1,618 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2017-2018 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2018 Kalev Lember <klember@redhat.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "config.h" + +#include <glib.h> + +#include "gs-plugin-private.h" +#include "gs-plugin-job-private.h" + +struct _GsPluginJob +{ + GObject parent_instance; + GsPluginRefineFlags refine_flags; + GsPluginRefineFlags filter_flags; + GsAppListFilterFlags dedupe_flags; + gboolean interactive; + guint max_results; + guint timeout; + guint64 age; + GsPlugin *plugin; + GsPluginAction action; + GsAppListSortFunc sort_func; + gpointer sort_func_data; + gchar *search; + GsApp *app; + GsAppList *list; + GFile *file; + GsCategory *category; + AsReview *review; + gint64 time_created; +}; + +enum { + PROP_0, + PROP_ACTION, + PROP_AGE, + PROP_SEARCH, + PROP_REFINE_FLAGS, + PROP_FILTER_FLAGS, + PROP_DEDUPE_FLAGS, + PROP_INTERACTIVE, + PROP_APP, + PROP_LIST, + PROP_FILE, + PROP_CATEGORY, + PROP_REVIEW, + PROP_MAX_RESULTS, + PROP_TIMEOUT, + PROP_LAST +}; + +G_DEFINE_TYPE (GsPluginJob, gs_plugin_job, G_TYPE_OBJECT) + +gchar * +gs_plugin_job_to_string (GsPluginJob *self) +{ + GString *str = g_string_new (NULL); + gint64 time_now = g_get_monotonic_time (); + g_string_append_printf (str, "running %s", + gs_plugin_action_to_string (self->action)); + if (self->plugin != NULL) { + g_string_append_printf (str, " on plugin=%s", + gs_plugin_get_name (self->plugin)); + } + 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->dedupe_flags > 0) + g_string_append_printf (str, " with dedupe-flags=%" G_GUINT64_FORMAT, self->dedupe_flags); + 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); + } + if (self->interactive) + g_string_append_printf (str, " with interactive=True"); + if (self->timeout > 0) + g_string_append_printf (str, " with timeout=%u", self->timeout); + if (self->max_results > 0) + g_string_append_printf (str, " with max-results=%u", self->max_results); + if (self->age != 0) { + if (self->age == G_MAXUINT) { + g_string_append (str, " with cache age=any"); + } else { + g_string_append_printf (str, " with cache age=%" G_GUINT64_FORMAT, + self->age); + } + } + if (self->search != NULL) { + g_string_append_printf (str, " with search=%s", + self->search); + } + if (self->category != NULL) { + GsCategory *parent = gs_category_get_parent (self->category); + if (parent != NULL) { + g_string_append_printf (str, " with category=%s/%s", + gs_category_get_id (parent), + gs_category_get_id (self->category)); + } else { + g_string_append_printf (str, " with category=%s", + gs_category_get_id (self->category)); + } + } + if (self->review != NULL) { + g_string_append_printf (str, " with review=%s", + as_review_get_id (self->review)); + } + if (self->file != NULL) { + g_autofree gchar *path = g_file_get_path (self->file); + g_string_append_printf (str, " with file=%s", path); + } + if (self->list != NULL && gs_app_list_length (self->list) > 0) { + g_autofree const gchar **unique_ids = NULL; + g_autofree gchar *unique_ids_str = NULL; + unique_ids = g_new0 (const gchar *, gs_app_list_length (self->list) + 1); + for (guint i = 0; i < gs_app_list_length (self->list); i++) { + GsApp *app = gs_app_list_index (self->list, i); + unique_ids[i] = gs_app_get_unique_id (app); + } + unique_ids_str = g_strjoinv (",", (gchar**) unique_ids); + g_string_append_printf (str, " on apps %s", unique_ids_str); + } + if (time_now - self->time_created > 1000) { + g_string_append_printf (str, ", elapsed time since creation %" G_GINT64_FORMAT "ms", + (time_now - self->time_created) / 1000); + } + return g_string_free (str, FALSE); +} + +void +gs_plugin_job_set_refine_flags (GsPluginJob *self, GsPluginRefineFlags refine_flags) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + 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; +} + +void +gs_plugin_job_set_dedupe_flags (GsPluginJob *self, GsAppListFilterFlags dedupe_flags) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->dedupe_flags = dedupe_flags; +} + +GsPluginRefineFlags +gs_plugin_job_get_refine_flags (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0); + 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; +} + +GsAppListFilterFlags +gs_plugin_job_get_dedupe_flags (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0); + return self->dedupe_flags; +} + +gboolean +gs_plugin_job_has_refine_flags (GsPluginJob *self, GsPluginRefineFlags refine_flags) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), FALSE); + return (self->refine_flags & refine_flags) > 0; +} + +void +gs_plugin_job_add_refine_flags (GsPluginJob *self, GsPluginRefineFlags refine_flags) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->refine_flags |= refine_flags; +} + +void +gs_plugin_job_remove_refine_flags (GsPluginJob *self, GsPluginRefineFlags refine_flags) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->refine_flags &= ~refine_flags; +} + +void +gs_plugin_job_set_interactive (GsPluginJob *self, gboolean interactive) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->interactive = interactive; +} + +gboolean +gs_plugin_job_get_interactive (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), FALSE); + return self->interactive; +} + +void +gs_plugin_job_set_max_results (GsPluginJob *self, guint max_results) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->max_results = max_results; +} + +guint +gs_plugin_job_get_max_results (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0); + return self->max_results; +} + +void +gs_plugin_job_set_timeout (GsPluginJob *self, guint timeout) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->timeout = timeout; +} + +guint +gs_plugin_job_get_timeout (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0); + return self->timeout; +} + +void +gs_plugin_job_set_age (GsPluginJob *self, guint64 age) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->age = age; +} + +guint64 +gs_plugin_job_get_age (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0); + return self->age; +} + +void +gs_plugin_job_set_action (GsPluginJob *self, GsPluginAction action) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->action = action; +} + +GsPluginAction +gs_plugin_job_get_action (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0); + return self->action; +} + +void +gs_plugin_job_set_sort_func (GsPluginJob *self, GsAppListSortFunc sort_func) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->sort_func = sort_func; +} + +GsAppListSortFunc +gs_plugin_job_get_sort_func (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), 0); + return self->sort_func; +} + +void +gs_plugin_job_set_sort_func_data (GsPluginJob *self, gpointer sort_func_data) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + self->sort_func_data = sort_func_data; +} + +gpointer +gs_plugin_job_get_sort_func_data (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL); + return self->sort_func_data; +} + +void +gs_plugin_job_set_search (GsPluginJob *self, const gchar *search) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + g_free (self->search); + self->search = g_strdup (search); +} + +const gchar * +gs_plugin_job_get_search (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL); + return self->search; +} + +void +gs_plugin_job_set_app (GsPluginJob *self, GsApp *app) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + g_set_object (&self->app, app); + + /* ensure we can always operate on a list object */ + if (self->list != NULL && app != NULL && gs_app_list_length (self->list) == 0) + gs_app_list_add (self->list, self->app); +} + +GsApp * +gs_plugin_job_get_app (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL); + return self->app; +} + +void +gs_plugin_job_set_list (GsPluginJob *self, GsAppList *list) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + if (list == NULL) + g_warning ("trying to set list to NULL, not a good idea"); + g_set_object (&self->list, list); +} + +GsAppList * +gs_plugin_job_get_list (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL); + return self->list; +} + +void +gs_plugin_job_set_file (GsPluginJob *self, GFile *file) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + g_set_object (&self->file, file); +} + +GFile * +gs_plugin_job_get_file (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL); + return self->file; +} + +void +gs_plugin_job_set_plugin (GsPluginJob *self, GsPlugin *plugin) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + g_set_object (&self->plugin, plugin); +} + +GsPlugin * +gs_plugin_job_get_plugin (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL); + return self->plugin; +} + +void +gs_plugin_job_set_category (GsPluginJob *self, GsCategory *category) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + g_set_object (&self->category, category); +} + +GsCategory * +gs_plugin_job_get_category (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL); + return self->category; +} + +void +gs_plugin_job_set_review (GsPluginJob *self, AsReview *review) +{ + g_return_if_fail (GS_IS_PLUGIN_JOB (self)); + g_set_object (&self->review, review); +} + +AsReview * +gs_plugin_job_get_review (GsPluginJob *self) +{ + g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL); + return self->review; +} + +static void +gs_plugin_job_get_property (GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GsPluginJob *self = GS_PLUGIN_JOB (obj); + + switch (prop_id) { + case PROP_ACTION: + g_value_set_uint (value, self->action); + break; + case PROP_AGE: + g_value_set_uint64 (value, self->age); + break; + 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_DEDUPE_FLAGS: + g_value_set_uint64 (value, self->dedupe_flags); + break; + case PROP_INTERACTIVE: + g_value_set_boolean (value, self->interactive); + break; + case PROP_SEARCH: + g_value_set_string (value, self->search); + break; + case PROP_APP: + g_value_set_object (value, self->app); + break; + case PROP_LIST: + g_value_set_object (value, self->list); + break; + case PROP_FILE: + g_value_set_object (value, self->file); + break; + case PROP_CATEGORY: + g_value_set_object (value, self->category); + break; + case PROP_REVIEW: + g_value_set_object (value, self->review); + break; + case PROP_MAX_RESULTS: + g_value_set_uint (value, self->max_results); + break; + case PROP_TIMEOUT: + g_value_set_uint (value, self->timeout); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); + break; + } +} + +static void +gs_plugin_job_set_property (GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GsPluginJob *self = GS_PLUGIN_JOB (obj); + + switch (prop_id) { + case PROP_ACTION: + gs_plugin_job_set_action (self, g_value_get_uint (value)); + break; + case PROP_AGE: + gs_plugin_job_set_age (self, g_value_get_uint64 (value)); + break; + 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_DEDUPE_FLAGS: + gs_plugin_job_set_dedupe_flags (self, g_value_get_uint64 (value)); + break; + case PROP_INTERACTIVE: + gs_plugin_job_set_interactive (self, g_value_get_boolean (value)); + break; + case PROP_SEARCH: + gs_plugin_job_set_search (self, g_value_get_string (value)); + break; + case PROP_APP: + gs_plugin_job_set_app (self, g_value_get_object (value)); + break; + case PROP_LIST: + gs_plugin_job_set_list (self, g_value_get_object (value)); + break; + case PROP_FILE: + gs_plugin_job_set_file (self, g_value_get_object (value)); + break; + case PROP_CATEGORY: + gs_plugin_job_set_category (self, g_value_get_object (value)); + break; + case PROP_REVIEW: + gs_plugin_job_set_review (self, g_value_get_object (value)); + break; + case PROP_MAX_RESULTS: + gs_plugin_job_set_max_results (self, g_value_get_uint (value)); + break; + case PROP_TIMEOUT: + gs_plugin_job_set_timeout (self, g_value_get_uint (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); + break; + } +} + +static void +gs_plugin_job_finalize (GObject *obj) +{ + GsPluginJob *self = GS_PLUGIN_JOB (obj); + g_free (self->search); + g_clear_object (&self->app); + g_clear_object (&self->list); + g_clear_object (&self->file); + g_clear_object (&self->plugin); + g_clear_object (&self->category); + g_clear_object (&self->review); + G_OBJECT_CLASS (gs_plugin_job_parent_class)->finalize (obj); +} + +static void +gs_plugin_job_class_init (GsPluginJobClass *klass) +{ + GParamSpec *pspec; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = gs_plugin_job_finalize; + object_class->get_property = gs_plugin_job_get_property; + object_class->set_property = gs_plugin_job_set_property; + + pspec = g_param_spec_uint ("action", NULL, NULL, + GS_PLUGIN_ACTION_UNKNOWN, + GS_PLUGIN_ACTION_LAST, + GS_PLUGIN_ACTION_UNKNOWN, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_ACTION, pspec); + + pspec = g_param_spec_uint64 ("age", NULL, NULL, + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_AGE, pspec); + + pspec = g_param_spec_uint64 ("refine-flags", NULL, NULL, + 0, G_MAXUINT64, 0, + 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 ("dedupe-flags", NULL, NULL, + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_DEDUPE_FLAGS, pspec); + + pspec = g_param_spec_boolean ("interactive", NULL, NULL, + FALSE, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, PROP_INTERACTIVE, pspec); + + pspec = g_param_spec_string ("search", NULL, NULL, + NULL, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_SEARCH, pspec); + + pspec = g_param_spec_object ("app", NULL, NULL, + GS_TYPE_APP, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_APP, pspec); + + pspec = g_param_spec_object ("list", NULL, NULL, + GS_TYPE_APP_LIST, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_LIST, pspec); + + pspec = g_param_spec_object ("file", NULL, NULL, + G_TYPE_FILE, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_FILE, pspec); + + pspec = g_param_spec_object ("category", NULL, NULL, + GS_TYPE_CATEGORY, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_CATEGORY, pspec); + + pspec = g_param_spec_object ("review", NULL, NULL, + AS_TYPE_REVIEW, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_REVIEW, pspec); + + pspec = g_param_spec_uint ("max-results", NULL, NULL, + 0, G_MAXUINT, 0, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_MAX_RESULTS, pspec); + + pspec = g_param_spec_uint ("timeout", NULL, NULL, + 0, G_MAXUINT, 60, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + g_object_class_install_property (object_class, PROP_TIMEOUT, pspec); +} + +static void +gs_plugin_job_init (GsPluginJob *self) +{ + self->refine_flags = GS_PLUGIN_REFINE_FLAGS_DEFAULT; + self->filter_flags = GS_PLUGIN_REFINE_FLAGS_DEFAULT; + self->dedupe_flags = GS_APP_LIST_FILTER_FLAG_KEY_ID | + GS_APP_LIST_FILTER_FLAG_KEY_SOURCE | + GS_APP_LIST_FILTER_FLAG_KEY_VERSION; + self->list = gs_app_list_new (); + self->time_created = g_get_monotonic_time (); +} |