From 3f9938a45b2fd7705e6fd40ab41231a79aaf5861 Mon Sep 17 00:00:00 2001 From: Vratislav Podzimek Date: Tue, 21 Jul 2015 16:48:27 +0200 Subject: [PATCH 7/7] Better handle and report erroneous states So that users have a chance to find out what happened and fix the issue. Resolves: rhbz#1241064 Signed-off-by: Vratislav Podzimek --- org_fedora_oscap/gui/spokes/oscap.py | 93 ++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/org_fedora_oscap/gui/spokes/oscap.py b/org_fedora_oscap/gui/spokes/oscap.py index 10a7ca7..e5ea225 100644 --- a/org_fedora_oscap/gui/spokes/oscap.py +++ b/org_fedora_oscap/gui/spokes/oscap.py @@ -19,6 +19,7 @@ # import threading +from functools import wraps import gettext _ = lambda x: gettext.ldgettext("oscap-anaconda-addon", x) @@ -46,6 +47,9 @@ from pykickstart.errors import KickstartValueError # pylint: disable-msg=E0611 from gi.repository import Gdk +import logging +log = logging.getLogger("anaconda") + # export only the spoke, no helper functions, classes or constants __all__ = ["OSCAPSpoke"] @@ -105,6 +109,21 @@ def render_message_type(column, renderer, model, itr, user_data=None): else: renderer.set_property("stock-id", "gtk-dialog-question") +def set_ready(func): + @wraps(func) + def decorated(self, *args, **kwargs): + ret = func(self, *args, **kwargs) + + self._unitialized_status = None + self._ready = True + # pylint: disable-msg=E1101 + hubQ.send_ready(self.__class__.__name__, True) + hubQ.send_message(self.__class__.__name__, self.status) + + return ret + + return decorated + class OSCAPSpoke(NormalSpoke): """ Main class of the OSCAP addon spoke that will appear in the Security @@ -182,6 +201,8 @@ class OSCAPSpoke(NormalSpoke): self._fetching = False self._fetch_flag_lock = threading.Lock() + self._error = None + def initialize(self): """ The initialize method that is called after the instance is created. @@ -304,6 +325,7 @@ class OSCAPSpoke(NormalSpoke): target=self._init_after_data_fetch, args=(thread_name,))) + @set_ready def _init_after_data_fetch(self, wait_for): """ Waits for data fetching to be finished, extracts it (if needed), @@ -379,6 +401,7 @@ class OSCAPSpoke(NormalSpoke): # fetching done with self._fetch_flag_lock: self._fetching = False + return if self._using_ds: @@ -403,24 +426,19 @@ class OSCAPSpoke(NormalSpoke): # update the message store with the messages self._update_message_store() - # no more being unitialized - self._unitialized_status = None - self._ready = True - # all initialized, we can now let user set parameters fire_gtk_action(self._main_notebook.set_current_page, SET_PARAMS_PAGE) # and use control buttons fire_gtk_action(really_show, self._control_buttons) - # pylint: disable-msg=E1101 - hubQ.send_ready(self.__class__.__name__, True) - hubQ.send_message(self.__class__.__name__, self.status) - # fetching done with self._fetch_flag_lock: self._fetching = False + # no error + self._error = None + @property def _using_ds(self): return self._content_handling_cls == content_handling.DataStreamHandler @@ -620,39 +638,43 @@ class OSCAPSpoke(NormalSpoke): # update messages according to the newly chosen profile self._update_message_store() + @set_ready + def _set_error(self, msg): + self._error = msg + self.set_error(msg) + @gtk_action_wait def _invalid_content(self): """Callback for informing user about provided content invalidity.""" - self._progress_label.set_markup("%s" % _("Invalid content " - "provided. Enter a different URL, " - "please.")) - self._wrong_content() + msg = _("Invalid content provided. Enter a different URL, please.") + self._progress_label.set_markup("%s" % msg) + self._wrong_content(msg) @gtk_action_wait def _invalid_url(self): """Callback for informing user about provided URL invalidity.""" - self._progress_label.set_markup("%s" % _("Invalid or unsupported content " - "URL, please enter a different one.")) - self._wrong_content() + msg = _("Invalid or unsupported content URL, please enter a different one.") + self._progress_label.set_markup("%s" % msg) + self._wrong_content(msg) @gtk_action_wait def _data_fetch_failed(self): """Adapts the UI if fetching data from entered URL failed""" - self._progress_label.set_markup("%s" % _("Failed to fetch " - "content. Enter a different URL, " - "please.")) - self._wrong_content() + msg = _("Failed to fetch content. Enter a different URL, please.") + self._progress_label.set_markup("%s" % msg) + self._wrong_content(msg) @gtk_action_wait def _network_problem(self): """Adapts the UI if network error was encountered during data fetch""" - self._progress_label.set_markup("%s" % _("Network error encountered when fetching data." - " Please check that network is setup and working.")) - self._wrong_content() + msg = _("Network error encountered when fetching data." + " Please check that network is setup and working.") + self._progress_label.set_markup("%s" % msg) + self._wrong_content(msg) @gtk_action_wait def _integrity_check_failed(self): @@ -660,7 +682,7 @@ class OSCAPSpoke(NormalSpoke): msg = _("The integrity check of the content failed. Cannot use the content.") self._progress_label.set_markup("%s" % msg) - self._wrong_content() + self._wrong_content(msg) @gtk_action_wait def _extraction_failed(self, err_msg): @@ -669,17 +691,18 @@ class OSCAPSpoke(NormalSpoke): msg = _("Failed to extract content (%s). Enter a different URL, " "please.") % err_msg self._progress_label.set_markup("%s" % msg) - self._wrong_content() + self._wrong_content(msg) @gtk_action_wait - def _wrong_content(self): - self._addon_data.content_url = "" - self._addon_data.content_type = "" + def _wrong_content(self, msg): + self._addon_data.clear_all() really_hide(self._progress_spinner) self._fetch_button.set_sensitive(True) self._content_url_entry.set_sensitive(True) self._content_url_entry.grab_focus() self._content_url_entry.select_region(0, -1) + self._content_handling_cls == None + self._set_error(msg) @gtk_action_wait def _switch_dry_run(self, dry_run): @@ -792,6 +815,10 @@ class OSCAPSpoke(NormalSpoke): """ + if not self._addon_data.content_defined or not self._active_profile: + # no errors for no content or no profile + self._error = None + # store currently selected values to the addon data attributes if self._using_ds: self._addon_data.datastream_id = self._current_ds_id @@ -838,8 +865,8 @@ class OSCAPSpoke(NormalSpoke): """ # no error message in the store - return all(row[0] != common.MESSAGE_TYPE_FATAL - for row in self._message_store) + return not self._error and all(row[0] != common.MESSAGE_TYPE_FATAL + for row in self._message_store) @property @gtk_action_wait @@ -854,6 +881,9 @@ class OSCAPSpoke(NormalSpoke): """ + if self._error: + return _("Error fetching and loading content") + if self._unitialized_status: # not initialized return self._unitialized_status @@ -951,9 +981,10 @@ class OSCAPSpoke(NormalSpoke): really_show(self._progress_spinner) if not data_fetch.can_fetch_from(url): + msg = _("Invalid or unsupported URL") # cannot start fetching - self._progress_label.set_markup("%s" % _("Invalid or unsupported URL")) - self._wrong_content() + self._progress_label.set_markup("%s" % msg) + self._wrong_content(msg) return self._progress_label.set_text(_("Fetching content...")) -- 2.4.3