263 lines
9.0 KiB
Diff
263 lines
9.0 KiB
Diff
From 27a2c75409c7abae68c4ad3af99d8e90927af803 Mon Sep 17 00:00:00 2001
|
|
From: Jakub Filak <jfilak@redhat.com>
|
|
Date: Mon, 28 Apr 2014 13:57:05 +0200
|
|
Subject: [LIBREPORT PATCH 03/10] Worklflow: order workflows according to their
|
|
priority
|
|
|
|
Higher number -> higher priority -> more visible place in UI
|
|
|
|
Introduce 'priority' element in XML workflow definition:
|
|
- child of 'workflow' element
|
|
- the type is signed integer
|
|
- optional value, if not present, 0 is used
|
|
|
|
Related to #259
|
|
|
|
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
|
|
mmilata: fix DTD in manual page
|
|
---
|
|
doc/report-gtk.txt | 8 +++++++-
|
|
src/cli/cli-report.c | 32 ++++++++++++++++++--------------
|
|
src/gui-wizard-gtk/wizard.c | 10 ++++++----
|
|
src/include/workflow.h | 10 ++++++++++
|
|
src/lib/workflow.c | 21 +++++++++++++++++++++
|
|
src/lib/workflow_xml_parser.c | 20 +++++++++++++++++++-
|
|
6 files changed, 81 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/doc/report-gtk.txt b/doc/report-gtk.txt
|
|
index e7611de..f39c77c 100644
|
|
--- a/doc/report-gtk.txt
|
|
+++ b/doc/report-gtk.txt
|
|
@@ -64,11 +64,12 @@ These configuration files are placed in /usr/share/libreport/workflows.
|
|
Each file has XML formatting with the following DTD:
|
|
|
|
------------
|
|
-<!ELEMENT workflow (name+,description+,events*)>
|
|
+<!ELEMENT workflow (name+,description+,priority?,events*)>
|
|
<!ELEMENT name (#PCDATA)>
|
|
<!ATTLIST name xml:lang CDATA #IMPLIED>
|
|
<!ELEMENT description (#PCDATA)>
|
|
<!ATTLIST description xml:lang CDATA #IMPLIED>
|
|
+<!ELEMENT priority = (#PCDATA)>
|
|
<!ELEMENT events = (event)+>
|
|
<!ELEMENT event = (#PCDATA)>
|
|
------------
|
|
@@ -79,6 +80,10 @@ name::
|
|
description::
|
|
User visible description
|
|
|
|
+priority::
|
|
+ Priority of the workflow. Higher number means a more visible place in UI.
|
|
+ If not provided, 0 is used. The value is signed integer.
|
|
+
|
|
events::
|
|
List of executed events
|
|
|
|
@@ -98,6 +103,7 @@ Simple reporting work flow
|
|
<name xml:lang="cs">Příklad</name>
|
|
<description xml:lang="en">Example description</description>
|
|
<description xml:lang="cs">Příklad popisu</description>
|
|
+ <priority>10</priority>
|
|
<evetns>
|
|
<event>analyze_example</event>
|
|
<event>collect_example</event>
|
|
diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c
|
|
index 68baa8b..9cc7613 100644
|
|
--- a/src/cli/cli-report.c
|
|
+++ b/src/cli/cli-report.c
|
|
@@ -824,32 +824,36 @@ int run_event_chain(const char *dump_dir_name, GList *chain, int interactive)
|
|
|
|
static workflow_t *select_workflow(GHashTable *workflows)
|
|
{
|
|
- GHashTableIter iter;
|
|
- gpointer key = NULL;
|
|
- workflow_t *value = NULL;
|
|
+ GList *wf_list = g_hash_table_get_values(workflows);
|
|
|
|
- g_hash_table_iter_init(&iter, workflows);
|
|
-
|
|
- if (!g_hash_table_iter_next(&iter, &key, (gpointer *)&value))
|
|
+ if (wf_list == NULL)
|
|
{
|
|
error_msg("No workflow suitable for this problem was found!");
|
|
return NULL;
|
|
}
|
|
|
|
- if (g_hash_table_size(workflows) == 1)
|
|
+ const guint wf_cnt = g_list_length(wf_list);
|
|
+ if (wf_cnt == 1)
|
|
{
|
|
- log_notice("autoselected workflow: '%s'", (char *)key);
|
|
- return value;
|
|
+ workflow_t *wf_selected = (workflow_t *)wf_list->data;
|
|
+ log_notice("autoselected workflow: '%s'", (char *)wf_get_name(wf_selected));
|
|
+ g_list_free(wf_list);
|
|
+ return wf_selected;
|
|
}
|
|
|
|
- workflow_t *help_wf_array[g_hash_table_size(workflows)];
|
|
+ wf_list = g_list_sort(wf_list, (GCompareFunc)wf_priority_compare);
|
|
+
|
|
+ workflow_t *help_wf_array[wf_cnt];
|
|
unsigned count = 0;
|
|
- do
|
|
+
|
|
+ for(GList *wf_iter = wf_list; wf_iter; wf_iter = g_list_next(wf_iter))
|
|
{
|
|
- help_wf_array[count] = value;
|
|
- printf("%d %s\n %s\n\n", ++count, wf_get_screen_name(value), wf_get_description(value));
|
|
+ workflow_t *wf = (workflow_t *)wf_iter->data;
|
|
+ help_wf_array[count] = wf;
|
|
+ printf("%d %s\n %s\n\n", ++count, wf_get_screen_name(wf), wf_get_description(wf));
|
|
}
|
|
- while (g_hash_table_iter_next(&iter, &key, (gpointer *)&value));
|
|
+
|
|
+ g_list_free(wf_list);
|
|
|
|
const unsigned picked = choose_number_from_range(1, count, _("Select a workflow to run: "));
|
|
return help_wf_array[picked - 1];
|
|
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
|
|
index 82bdf3e..e6f6ee7 100644
|
|
--- a/src/gui-wizard-gtk/wizard.c
|
|
+++ b/src/gui-wizard-gtk/wizard.c
|
|
@@ -2736,10 +2736,12 @@ static void add_workflow_buttons(GtkBox *box, GHashTable *workflows, GCallback f
|
|
list_possible_events_glist(g_dump_dir_name, "workflow"),
|
|
WORKFLOWS_DIR);
|
|
|
|
- GList *keys = g_hash_table_get_keys(workflow_table);
|
|
- while(keys)
|
|
+ GList *wf_list = g_hash_table_get_values(workflow_table);
|
|
+ wf_list = g_list_sort(wf_list, (GCompareFunc)wf_priority_compare);
|
|
+
|
|
+ for (GList *wf_iter = wf_list; wf_iter; wf_iter = g_list_next(wf_iter))
|
|
{
|
|
- workflow_t *w = g_hash_table_lookup(workflow_table, keys->data);
|
|
+ workflow_t *w = (workflow_t *)wf_iter->data;
|
|
char *btn_label = xasprintf("<b>%s</b>\n%s", wf_get_screen_name(w), wf_get_description(w));
|
|
GtkWidget *button = gtk_button_new_with_label(btn_label);
|
|
GList *children = gtk_container_get_children(GTK_CONTAINER(button));
|
|
@@ -2756,9 +2758,9 @@ static void add_workflow_buttons(GtkBox *box, GHashTable *workflows, GCallback f
|
|
free(btn_label);
|
|
g_signal_connect(button, "clicked", func, w);
|
|
gtk_box_pack_start(box, button, true, false, 2);
|
|
- keys = g_list_next(keys);
|
|
}
|
|
|
|
+ g_list_free(wf_list);
|
|
}
|
|
|
|
static char *setup_next_processed_event(GList **events_list)
|
|
diff --git a/src/include/workflow.h b/src/include/workflow.h
|
|
index 66bbdaf..d79708e 100644
|
|
--- a/src/include/workflow.h
|
|
+++ b/src/include/workflow.h
|
|
@@ -39,11 +39,21 @@ GList *wf_get_event_names(workflow_t *w);
|
|
const char *wf_get_screen_name(workflow_t *w);
|
|
const char *wf_get_description(workflow_t *w);
|
|
const char *wf_get_long_desc(workflow_t *w);
|
|
+int wf_get_priority(workflow_t *w);
|
|
|
|
void wf_set_screen_name(workflow_t *w, const char* screen_name);
|
|
void wf_set_description(workflow_t *w, const char* description);
|
|
void wf_set_long_desc(workflow_t *w, const char* long_desc);
|
|
void wf_add_event(workflow_t *w, event_config_t *ec);
|
|
+void wf_set_priority(workflow_t *w, int priority);
|
|
+
|
|
+/*
|
|
+ * Returns a negative integer if the first value comes before the second, 0 if
|
|
+ * they are equal, or a positive integer if the first value comes after the
|
|
+ * second.
|
|
+ */
|
|
+int wf_priority_compare(const workflow_t *first, const workflow_t *second);
|
|
+
|
|
GHashTable *load_workflow_config_data_from_list(GList *wf_names, const char *path);
|
|
|
|
#endif
|
|
diff --git a/src/lib/workflow.c b/src/lib/workflow.c
|
|
index 52ad924..c6eedf4 100644
|
|
--- a/src/lib/workflow.c
|
|
+++ b/src/lib/workflow.c
|
|
@@ -24,6 +24,7 @@
|
|
struct workflow
|
|
{
|
|
config_item_info_t *info;
|
|
+ int priority; // direct correlation: higher number -> higher priority
|
|
|
|
GList *events; //list of event_option_t
|
|
};
|
|
@@ -193,6 +194,11 @@ const char *wf_get_long_desc(workflow_t *w)
|
|
return ci_get_long_desc(workflow_get_config_info(w));
|
|
}
|
|
|
|
+int wf_get_priority(workflow_t *w)
|
|
+{
|
|
+ return w->priority;
|
|
+}
|
|
+
|
|
void wf_set_screen_name(workflow_t *w, const char* screen_name)
|
|
{
|
|
ci_set_screen_name(workflow_get_config_info(w), screen_name);
|
|
@@ -213,3 +219,18 @@ void wf_add_event(workflow_t *w, event_config_t *ec)
|
|
w->events = g_list_append(w->events, ec);
|
|
log_info("added to ev list: '%s'", ec_get_screen_name(ec));
|
|
}
|
|
+
|
|
+void wf_set_priority(workflow_t *w, int priority)
|
|
+{
|
|
+ w->priority = priority;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Returns a negative integer if the first value comes before the second, 0 if
|
|
+ * they are equal, or a positive integer if the first value comes after the
|
|
+ * second.
|
|
+ */
|
|
+int wf_priority_compare(const workflow_t *first, const workflow_t *second)
|
|
+{
|
|
+ return second->priority - first->priority;
|
|
+}
|
|
diff --git a/src/lib/workflow_xml_parser.c b/src/lib/workflow_xml_parser.c
|
|
index 0efc733..f216c18 100644
|
|
--- a/src/lib/workflow_xml_parser.c
|
|
+++ b/src/lib/workflow_xml_parser.c
|
|
@@ -26,6 +26,7 @@
|
|
#define EVENT_ELEMENT "event"
|
|
#define DESCRIPTION_ELEMENT "description"
|
|
#define NAME_ELEMENT "name"
|
|
+#define PRIORITY_ELEMENT "priority"
|
|
|
|
static void start_element(GMarkupParseContext *context,
|
|
const gchar *element_name,
|
|
@@ -134,9 +135,26 @@ static void text(GMarkupParseContext *context,
|
|
}
|
|
}
|
|
}
|
|
-
|
|
}
|
|
|
|
+ else if(strcmp(inner_element, PRIORITY_ELEMENT) == 0)
|
|
+ {
|
|
+ log_debug("workflow priority:'%s'", text);
|
|
+
|
|
+ char *end = NULL;
|
|
+ long long val = strtoll(text, &end, 10);
|
|
+
|
|
+ if (text == end || end[0] != '\0'
|
|
+ || (errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN))
|
|
+ || (val > INT_MAX || val < INT_MIN)
|
|
+ || (errno != 0 && val == 0))
|
|
+ {
|
|
+ error_msg("Workflow's priority is not a number in range <%d,%d>", INT_MIN, INT_MAX);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ wf_set_priority(workflow, (int)val);
|
|
+ }
|
|
}
|
|
|
|
// Called for strings that should be re-saved verbatim in this same
|
|
--
|
|
1.8.3.1
|
|
|