There's no good reason to have multiple places where we define message constants and helper functions, when we could just create a class that does all the hard work for us. --- pyanaconda/install.py | 12 +++--- pyanaconda/packaging/livepayload.py | 8 ++-- pyanaconda/packaging/yumpayload.py | 20 +++++----- pyanaconda/progress.py | 42 +++++--------------- pyanaconda/queue.py | 76 ++++++++++++++++++++++++++++++++++++ pyanaconda/ui/communication.py | 48 ++++------------------- pyanaconda/ui/gui/hubs/__init__.py | 10 ++--- pyanaconda/ui/gui/hubs/progress.py | 14 +++---- pyanaconda/ui/gui/spokes/custom.py | 4 +- pyanaconda/ui/gui/spokes/network.py | 4 +- pyanaconda/ui/gui/spokes/software.py | 29 ++++++-------- pyanaconda/ui/gui/spokes/source.py | 34 +++++++--------- pyanaconda/ui/gui/spokes/storage.py | 23 +++++------ pyanaconda/ui/tui/hubs/progress.py | 12 +++--- pyanaconda/ui/tui/simpleline/base.py | 8 ++-- 15 files changed, 177 insertions(+), 167 deletions(-) create mode 100644 pyanaconda/queue.py
diff --git a/pyanaconda/install.py b/pyanaconda/install.py index 08b3966..4b4adaf 100644 --- a/pyanaconda/install.py +++ b/pyanaconda/install.py @@ -23,7 +23,7 @@ from pyanaconda.constants import ROOT_PATH from blivet import turnOnFilesystems from pyanaconda.bootloader import writeBootLoader -from pyanaconda.progress import progress_report +from pyanaconda.progress import progress_report, progressQ from pyanaconda.users import createLuserConf, getPassAlgo, Users from pyanaconda import flags from pyanaconda import timezone @@ -49,10 +49,9 @@ def _writeKS(ksdata): os.chmod(path, 0600)
def doConfiguration(storage, payload, ksdata, instClass): - from pyanaconda import progress from pyanaconda.kickstart import runPostScripts
- progress.send_init(5) + progressQ.send_init(5)
# Now run the execute methods of ksdata that require an installed system # to be present first. @@ -90,7 +89,7 @@ def doConfiguration(storage, payload, ksdata, instClass): # kickstart file over if one exists). _writeKS(ksdata)
- progress.send_complete() + progressQ.send_complete()
def doInstall(storage, payload, ksdata, instClass): """Perform an installation. This method takes the ksdata as prepared by @@ -98,7 +97,6 @@ def doInstall(storage, payload, ksdata, instClass): The two main tasks for this are putting filesystems onto disks and installing packages onto those filesystems. """ - from pyanaconda import progress from pyanaconda.kickstart import runPostScripts
# First save system time to HW clock. @@ -110,7 +108,7 @@ def doInstall(storage, payload, ksdata, instClass): steps = len(storage.devicetree.findActions(type="create", object="format")) + \ len(storage.devicetree.findActions(type="resize", object="format")) steps += 5 # pre setup phase, packages setup, packages, bootloader, post install - progress.send_init(steps) + progressQ.send_init(steps)
with progress_report(_("Setting up the installation environment")): ksdata.addons.setup(storage, ksdata, instClass) @@ -142,4 +140,4 @@ def doInstall(storage, payload, ksdata, instClass): with progress_report(_("Installing bootloader")): writeBootLoader(storage, payload, instClass, ksdata)
- progress.send_complete() + progressQ.send_complete() diff --git a/pyanaconda/packaging/livepayload.py b/pyanaconda/packaging/livepayload.py index 676a18b..1fdfff2 100644 --- a/pyanaconda/packaging/livepayload.py +++ b/pyanaconda/packaging/livepayload.py @@ -45,7 +45,7 @@ import logging log = logging.getLogger("anaconda")
from pyanaconda.errors import * -from pyanaconda import progress +from pyanaconda.progress import progressQ from blivet.size import Size import blivet.util from pyanaconda.threads import threadMgr, AnacondaThread @@ -69,7 +69,7 @@ class LiveImagePayload(ImagePayload): def preInstall(self, packages=None, groups=None): """ Perform pre-installation tasks. """ super(LiveImagePayload, self).preInstall(packages=packages, groups=groups) - progress.send_message(_("Installing software") + (" %d%%") % (0,)) + progressQ.send_message(_("Installing software") + (" %d%%") % (0,))
def progress(self): """Monitor the amount of disk space used on the target and source and @@ -87,7 +87,7 @@ class LiveImagePayload(ImagePayload): with self.pct_lock: self.pct = int(100 * dest_size / source_size)
- progress.send_message(_("Installing software") + (" %d%%") % (min(100,self.pct),)) + progressQ.send_message(_("Installing software") + (" %d%%") % (min(100,self.pct),)) sleep(0.777)
def install(self): @@ -127,7 +127,7 @@ class LiveImagePayload(ImagePayload):
def postInstall(self): """ Perform post-installation tasks. """ - progress.send_message(_("Performing post-installation setup tasks")) + progressQ.send_message(_("Performing post-installation setup tasks")) blivet.util.umount(INSTALL_TREE)
super(LiveImagePayload, self).postInstall() diff --git a/pyanaconda/packaging/yumpayload.py b/pyanaconda/packaging/yumpayload.py index 4fc6177..ecd5598 100644 --- a/pyanaconda/packaging/yumpayload.py +++ b/pyanaconda/packaging/yumpayload.py @@ -85,7 +85,7 @@ _ = lambda x: gettext.ldgettext("anaconda", x)
from pyanaconda.errors import * from pyanaconda.packaging import NoSuchGroup, NoSuchPackage -import pyanaconda.progress as progress +from pyanaconda.progress import progressQ
from pyanaconda.localization import expand_langs import itertools @@ -1261,7 +1261,7 @@ reposdir=%s # still continue for a bit before the quit message is processed. # Doing a sys.exit also ensures the running thread quits before # it can do anything else. - progress.send_quit(1) + progressQ.send_quit(1) sys.exit(1)
def _applyYumSelections(self): @@ -1387,7 +1387,7 @@ reposdir=%s def preInstall(self, packages=None, groups=None): """ Perform pre-installation tasks. """ super(YumPayload, self).preInstall() - progress.send_message(_("Starting package installation process")) + progressQ.send_message(_("Starting package installation process"))
self._requiredPackages = packages self._requiredGroups = groups @@ -1406,7 +1406,7 @@ reposdir=%s self.checkSoftwareSelection() except DependencyError as e: if errorHandler.cb(e) == ERROR_RAISE: - progress.send_quit(1) + progressQ.send_quit(1) sys.exit(1)
# doPreInstall @@ -1500,7 +1500,7 @@ reposdir=%s self._yum.ts.setFlags(rpm.RPMTRANS_FLAG_TEST)
log.info("running transaction") - progress.send_step() + progressQ.send_step() try: self._yum.runTransaction(cb=rpmcb) except PackageSackError as e: @@ -1512,7 +1512,7 @@ reposdir=%s log.error("error [2] running transaction: %s" % e) exn = PayloadInstallError(self._transactionErrors(e.errors)) if errorHandler.cb(exn) == ERROR_RAISE: - progress.send_quit(1) + progressQ.send_quit(1) sys.exit(1) except YumBaseError as e: log.error("error [3] running transaction: %s" % e) @@ -1523,7 +1523,7 @@ reposdir=%s raise exn else: log.info("transaction complete") - progress.send_step() + progressQ.send_step() finally: self._yum.ts.close() iutil.resetRpmDb() @@ -1623,7 +1623,7 @@ class RPMCallback(object): """ Yum install callback. """ if event == rpm.RPMCALLBACK_TRANS_START: if amount == 6: - progress.send_message(_("Preparing transaction from installation source")) + progressQ.send_message(_("Preparing transaction from installation source")) self.total_actions = total self.completed_actions = 0 elif event == rpm.RPMCALLBACK_TRANS_PROGRESS: @@ -1663,7 +1663,7 @@ class RPMCallback(object): self.install_log.write(log_msg+"\n") self.install_log.flush()
- progress.send_message(progress_msg) + progressQ.send_message(progress_msg)
self.package_file = None repo = self._yum.repos.getRepo(txmbr.po.repoid) @@ -1719,7 +1719,7 @@ class RPMCallback(object): # take a very long time. So when it closes the last package, just # display the message. if self.completed_actions == self.total_actions: - progress.send_message(_("Performing post-installation setup tasks")) + progressQ.send_message(_("Performing post-installation setup tasks")) elif event == rpm.RPMCALLBACK_UNINST_START: # update status that we're cleaning up %key #progress.set_text(_("Cleaning up %s" % key)) diff --git a/pyanaconda/progress.py b/pyanaconda/progress.py index 433d205..c29b355 100644 --- a/pyanaconda/progress.py +++ b/pyanaconda/progress.py @@ -24,6 +24,8 @@ log = logging.getLogger("anaconda") from contextlib import contextmanager import Queue
+from pyanaconda.queue import QueueFactory + # A queue to be used for communicating progress information between a subthread # doing all the hard work and the main thread that does the GTK updates. This # queue should have elements of the following format pushed into it: @@ -31,44 +33,20 @@ import Queue # (PROGRESS_CODE_*, [arguments]) # # Arguments vary based on the code given. See below. -progressQ = Queue.Queue() - -# Arguments: -# -# _INIT - [num_steps] -# _STEP - [] -# _MESSAGE - [string] -# _COMPLETE - [] -# _QUIT - [exit_code] -PROGRESS_CODE_INIT = 0 -PROGRESS_CODE_STEP = 1 -PROGRESS_CODE_MESSAGE = 2 -PROGRESS_CODE_COMPLETE = 3 -PROGRESS_CODE_QUIT = 4 - -# Convenience methods to put things into the queue without the user having to -# know the details of the queue. -def send_init(n_steps): - progressQ.put((PROGRESS_CODE_INIT, [n_steps])) - -def send_step(): - progressQ.put((PROGRESS_CODE_STEP, [])) - -def send_message(message): - progressQ.put((PROGRESS_CODE_MESSAGE, [message])) - -def send_complete(): - progressQ.put((PROGRESS_CODE_COMPLETE, [])) +progressQ = QueueFactory("progress")
-def send_quit(code): - progressQ.put((PROGRESS_CODE_QUIT, [code])) +progressQ.addMessage("init", 1) # num_steps +progressQ.addMessage("step", 0) +progressQ.addMessage("message", 1) # message +progressQ.addMessage("complete", 0) +progressQ.addMessage("quit", 1) # exit_code
# Surround a block of code with progress updating. Before the code runs, the # message is updated so the user can tell what's about to take so long. # Afterwards, the progress bar is updated to reflect that the task is done. @contextmanager def progress_report(message): - send_message(message) + progressQ.send_message(message) log.info(message) yield - send_step() + progressQ.send_step() diff --git a/pyanaconda/queue.py b/pyanaconda/queue.py new file mode 100644 index 0000000..67a2aeb --- /dev/null +++ b/pyanaconda/queue.py @@ -0,0 +1,76 @@ +# +# queue.py: factory for creating communications channels +# +# Copyright (C) 2013 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# Author(s): Chris Lumens clumens@redhat.com + +import Queue + +class QueueFactory(object): + """Constructs a new object wrapping a Queue.Queue, complete with constants + and sending functions for each type of message that can be put into the + queue. + + Creating a new object using this class is done like so: + + q = QueueFactory("progress") + + And then adding messages to it is done like so: + + q.addMessage("init", 0) + q.addMessage("step", 1) + + The first call will create a new constant named PROGRESS_CODE_INIT and a + method named send_init that takes zero arguments. The second call will + create a new constant named PROGRESS_CODE_STEP and a method named send_step + that takes one argument. + + Reusing names within the same class is not allowed. + """ + def __init__(self, name): + self.name = name + + self.__counter = 0 + self.__names = [] + + self.q = Queue.Queue() + + def _makeMethod(self, constant, methodName, argc): + def __method(*args): + if len(args) != argc: + raise TypeError("%s() takes exactly %d arguments (%d given)" % (methodName, argc, len(args))) + + self._q.put((constant, args)) + + __method.__name__ = methodName + return __method + + def addMessage(self, name, argc): + if name in self.__names: + raise AttributeError("%s queue already has a message named %s" % (self.name, name)) + + # Add a constant. + const_name = self.name.upper() + "_CODE_" + name.upper() + setattr(self, const_name, self.__counter) + self.__counter += 1 + + # Add a convenience method for putting things into the queue. + method_name = "send_" + name.lower() + method = self._makeMethod(getattr(self, const_name), method_name, argc) + setattr(self, method_name, method) + + self.__names.append(name) diff --git a/pyanaconda/ui/communication.py b/pyanaconda/ui/communication.py index 6c4565b..655a54e 100644 --- a/pyanaconda/ui/communication.py +++ b/pyanaconda/ui/communication.py @@ -20,6 +20,8 @@
import Queue
+from pyanaconda.queue import QueueFactory + # A queue to be used for communicating information from a spoke back to its # hub. This information includes things like marking spokes as ready and # updating the status line to tell the user why a spoke is not yet available. @@ -30,44 +32,10 @@ import Queue # Arguments vary based on the code given, but the first argument must always # be the name of the class of the spoke to be acted upon. See below for more # details. -hubQ = Queue.Queue() - -# Arguments: -# -# _READY - [spoke_name, justUpdate] -# _NOT_READY - [spoke_name] -# _MESSAGE - [spoke_name, string] -# _INPUT - [string] -# _EXCEPTION - [exc] -HUB_CODE_READY = 0 -HUB_CODE_NOT_READY = 1 -HUB_CODE_MESSAGE = 2 -HUB_CODE_INPUT = 3 -HUB_CODE_EXCEPTION = 4 - -# Convenience methods to put things into the queue without the user having to -# know the details of the queue. -def send_ready(spoke, justUpdate=False): - """Tell the hub that a spoke given by the name "spoke" has become ready, - and that it should be made sensitive on the hub. Some processing may - also occur after a spoke has become ready. However, if the justUpdate - parameter is True, no processing will occur. - """ - hubQ.put((HUB_CODE_READY, [spoke, justUpdate])) - -def send_not_ready(spoke): - hubQ.put((HUB_CODE_NOT_READY, [spoke])) - -def send_message(spoke, msg): - hubQ.put((HUB_CODE_MESSAGE, [spoke, msg])) - -def send_input(data): - """This message represents an async input string from the user.""" - hubQ.put((HUB_CODE_INPUT, [data])) +hubQ = QueueFactory("hub")
-def send_exception(exception): - """This message contains the exception which happened somewhere, - usually used to report thread failures to the main thread so - python-meh can handle it properly. - """ - hubQ.put((HUB_CODE_EXCEPTION, [exception])) +hubQ.addMessage("ready", 2) # spoke_name, justUpdate +hubQ.addMessage("not_ready", 1) # spoke_name +hubQ.addMessage("message", 2) # spoke_name, string +hubQ.addMessage("input", 1) # string +hubQ.addMessage("exception", 1) # exception diff --git a/pyanaconda/ui/gui/hubs/__init__.py b/pyanaconda/ui/gui/hubs/__init__.py index 75e0309..446f168 100644 --- a/pyanaconda/ui/gui/hubs/__init__.py +++ b/pyanaconda/ui/gui/hubs/__init__.py @@ -282,10 +282,10 @@ class Hub(GUIObject, common.Hub): self.continueButton.set_sensitive(self.continuePossible)
def _update_spokes(self): - from pyanaconda.ui import communication + from pyanaconda.ui.communication import hubQ import Queue
- q = communication.hubQ + q = hubQ.q
# Grab all messages that may have appeared since last time this method ran. while True: @@ -301,7 +301,7 @@ class Hub(GUIObject, common.Hub): q.task_done() continue
- if code == communication.HUB_CODE_NOT_READY: + if code == hubQ.HUB_CODE_NOT_READY: self._updateCompleteness(spoke)
if spoke not in self._notReadySpokes: @@ -309,7 +309,7 @@ class Hub(GUIObject, common.Hub):
self._updateContinueButton() log.info("spoke is not ready: %s" % spoke) - elif code == communication.HUB_CODE_READY: + elif code == hubQ.HUB_CODE_READY: self._updateCompleteness(spoke)
if spoke in self._notReadySpokes: @@ -336,7 +336,7 @@ class Hub(GUIObject, common.Hub): elif self._autoContinue and q.empty(): # enqueue the emit to the Gtk message queue gtk_call_once(self.continueButton.emit, "clicked") - elif code == communication.HUB_CODE_MESSAGE: + elif code == hubQ.HUB_CODE_MESSAGE: spoke.selector.set_property("status", args[1]) log.info("setting %s status to: %s" % (spoke, args[1]))
diff --git a/pyanaconda/ui/gui/hubs/progress.py b/pyanaconda/ui/gui/hubs/progress.py index a1da2fd..3cf2a44 100644 --- a/pyanaconda/ui/gui/hubs/progress.py +++ b/pyanaconda/ui/gui/hubs/progress.py @@ -78,10 +78,10 @@ class ProgressHub(Hub): self._rnotes_id = GLib.timeout_add_seconds(60, self._cycle_rnotes)
def _update_progress(self, callback = None): - from pyanaconda import progress + from pyanaconda.progress import progressQ import Queue
- q = progress.progressQ + q = progressQ.q
# Grab all messages may have appeared since last time this method ran. while True: @@ -92,13 +92,13 @@ class ProgressHub(Hub): except Queue.Empty: break
- if code == progress.PROGRESS_CODE_INIT: + if code == progressQ.PROGRESS_CODE_INIT: self._init_progress_bar(args[0]) - elif code == progress.PROGRESS_CODE_STEP: + elif code == progressQ.PROGRESS_CODE_STEP: self._step_progress_bar() - elif code == progress.PROGRESS_CODE_MESSAGE: + elif code == progressQ.PROGRESS_CODE_MESSAGE: self._update_progress_message(args[0]) - elif code == progress.PROGRESS_CODE_COMPLETE: + elif code == progressQ.PROGRESS_CODE_COMPLETE: # There shouldn't be any more progress bar updates, so return False # to indicate this method should be removed from the idle loop. Also, # stop the rnotes cycling and display the finished message. @@ -109,7 +109,7 @@ class ProgressHub(Hub): callback()
return False - elif code == progress.PROGRESS_CODE_QUIT: + elif code == progressQ.PROGRESS_CODE_QUIT: sys.exit(args[0])
q.task_done() diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index a8fda8c..d41a232 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -71,7 +71,7 @@ from blivet.errors import MDRaidError from blivet.devicelibs import mdraid from blivet.devices import LUKSDevice
-from pyanaconda.ui import communication +from pyanaconda.ui.communication import hubQ from pyanaconda.ui.gui import GUIObject from pyanaconda.ui.gui.spokes import NormalSpoke from pyanaconda.ui.gui.spokes.storage import StorageChecker @@ -482,7 +482,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
StorageChecker.errors = [] StorageChecker.run(self) - communication.send_ready("StorageSpoke", justUpdate=True) + hubQ.send_ready("StorageSpoke", True)
@property def indirect(self): diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index ec5e076..2133915 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -35,7 +35,7 @@ from gi.repository import Gtk, AnacondaWidgets
from pyanaconda.flags import flags from pyanaconda import constants -from pyanaconda.ui import communication +from pyanaconda.ui.communication import hubQ from pyanaconda.ui.gui import GUIObject from pyanaconda.ui.gui.spokes import NormalSpoke, StandaloneSpoke from pyanaconda.ui.gui.categories.software import SoftwareCategory @@ -1204,7 +1204,7 @@ class NetworkSpoke(NormalSpoke): gtk_call_once(self._update_status)
def _update_status(self): - communication.send_message(self.__class__.__name__, self.status) + hubQ.send_message(self.__class__.__name__, self.status)
def _update_hostname(self): if self.network_control_box.hostname == network.DEFAULT_HOSTNAME: diff --git a/pyanaconda/ui/gui/spokes/software.py b/pyanaconda/ui/gui/spokes/software.py index 5c51301..e9cf708 100644 --- a/pyanaconda/ui/gui/spokes/software.py +++ b/pyanaconda/ui/gui/spokes/software.py @@ -28,7 +28,7 @@ from pyanaconda.packaging import MetadataError from pyanaconda.threads import threadMgr, AnacondaThread from pyanaconda import constants
-from pyanaconda.ui import communication +from pyanaconda.ui.communication import hubQ from pyanaconda.ui.gui.spokes import NormalSpoke from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog from pyanaconda.ui.gui.utils import enlightbox, gtk_action_wait @@ -87,8 +87,8 @@ class SoftwareSelectionSpoke(NormalSpoke): self._origAddons = addons self._origEnvironment = self.environment
- communication.send_not_ready(self.__class__.__name__) - communication.send_not_ready("SourceSpoke") + hubQ.send_not_ready(self.__class__.__name__) + hubQ.send_not_ready("SourceSpoke") threadMgr.add(AnacondaThread(name=constants.THREAD_CHECK_SOFTWARE, target=self.checkSoftwareSelection))
@@ -98,21 +98,19 @@ class SoftwareSelectionSpoke(NormalSpoke):
def checkSoftwareSelection(self): from pyanaconda.packaging import DependencyError - communication.send_message(self.__class__.__name__, - _("Checking software dependencies...")) + hubQ.send_message(self.__class__.__name__, _("Checking software dependencies...")) try: self.payload.checkSoftwareSelection() except DependencyError as e: self._errorMsgs = "\n".join(sorted(e.message)) - communication.send_message(self.__class__.__name__, - _("Error checking software dependencies")) + hubQ.send_message(self.__class__.__name__, _("Error checking software dependencies")) self._tx_id = None else: self._errorMsgs = None self._tx_id = self.payload.txID finally: - communication.send_ready(self.__class__.__name__) - communication.send_ready("SourceSpoke") + hubQ.send_ready(self.__class__.__name__, False) + hubQ.send_ready("SourceSpoke", False)
@property def completed(self): @@ -173,11 +171,11 @@ class SoftwareSelectionSpoke(NormalSpoke): target=self._initialize))
def _initialize(self): - communication.send_message(self.__class__.__name__, _("Downloading package metadata...")) + hubQ.send_message(self.__class__.__name__, _("Downloading package metadata..."))
threadMgr.wait(constants.THREAD_PAYLOAD)
- communication.send_message(self.__class__.__name__, _("Downloading group metadata...")) + hubQ.send_message(self.__class__.__name__, _("Downloading group metadata..."))
# we have no way to select environments with kickstart right now # so don't try. @@ -193,8 +191,8 @@ class SoftwareSelectionSpoke(NormalSpoke): self.payload.environments self.payload.groups except MetadataError: - communication.send_message(self.__class__.__name__, - _("No installation source available")) + hubQ.send_message(self.__class__.__name__, + _("No installation source available")) return
# And then having done all that slow downloading, we need to do the first @@ -206,7 +204,7 @@ class SoftwareSelectionSpoke(NormalSpoke):
self.payload.release()
- communication.send_ready(self.__class__.__name__) + hubQ.send_ready(self.__class__.__name__, False)
# If packages were provided by an input kickstart file (or some other means), # we should do dependency solving here. @@ -218,8 +216,7 @@ class SoftwareSelectionSpoke(NormalSpoke): self.refresh() return True except MetadataError: - communication.send_message(self.__class__.__name__, - _("No installation source available")) + hubQ.send_message(self.__class__.__name__, _("No installation source available")) return False
def refresh(self): diff --git a/pyanaconda/ui/gui/spokes/source.py b/pyanaconda/ui/gui/spokes/source.py index 71f47e0..f7a2103 100644 --- a/pyanaconda/ui/gui/spokes/source.py +++ b/pyanaconda/ui/gui/spokes/source.py @@ -34,7 +34,7 @@ from gi.repository import AnacondaWidgets, GLib, Gtk
from pyanaconda.flags import flags from pyanaconda.image import opticalInstallMedia, potentialHdisoSources -from pyanaconda.ui import communication +from pyanaconda.ui.communication import hubQ from pyanaconda.ui.gui import GUIObject from pyanaconda.ui.gui.spokes import NormalSpoke from pyanaconda.ui.gui.categories.software import SoftwareCategory @@ -405,10 +405,9 @@ class SourceSpoke(NormalSpoke): return True
def getRepoMetadata(self): - communication.send_not_ready("SoftwareSelectionSpoke") - communication.send_not_ready(self.__class__.__name__) - communication.send_message(self.__class__.__name__, - _(BASEREPO_SETUP_MESSAGE)) + hubQ.send_not_ready("SoftwareSelectionSpoke") + hubQ.send_not_ready(self.__class__.__name__) + hubQ.send_message(self.__class__.__name__, _(BASEREPO_SETUP_MESSAGE)) # this sleep is lame, but without it the message above doesn't seem # to get processed by the hub in time, and is never shown. # FIXME this should get removed when we figure out how to ensure @@ -420,22 +419,19 @@ class SourceSpoke(NormalSpoke): except PayloadError as e: log.error("PayloadError: %s" % (e,)) self._error = True - communication.send_message(self.__class__.__name__, - _("Failed to set up installation source")) + hubQ.send_message(self.__class__.__name__, _("Failed to set up installation source")) if not self.data.method.proxy: gtk_call_once(self.set_warning, _("Failed to set up installation source; check the repo url")) else: gtk_call_once(self.set_warning, _("Failed to set up installation source; check the repo url and proxy settings")) else: self._error = False - communication.send_message(self.__class__.__name__, - _(METADATA_DOWNLOAD_MESSAGE)) + hubQ.send_message(self.__class__.__name__, _(METADATA_DOWNLOAD_MESSAGE)) self.payload.gatherRepoMetadata() self.payload.release() if not self.payload.baseRepo: - communication.send_message(self.__class__.__name__, - _(METADATA_ERROR_MESSAGE)) - communication.send_ready(self.__class__.__name__) + hubQ.send_message(self.__class__.__name__, _(METADATA_ERROR_MESSAGE)) + hubQ.send_ready(self.__class__.__name__, False) self._error = True gtk_call_once(self.set_warning, _("Failed to set up installation source; check the repo url")) else: @@ -448,12 +444,12 @@ class SourceSpoke(NormalSpoke): e = self.payload.environments g = self.payload.groups except MetadataError: - communication.send_message("SoftwareSelectionSpoke", - _("No installation source available")) + hubQ.send_message("SoftwareSelectionSpoke", + _("No installation source available")) else: - communication.send_ready("SoftwareSelectionSpoke") + hubQ.send_ready("SoftwareSelectionSpoke", False) finally: - communication.send_ready(self.__class__.__name__) + hubQ.send_ready(self.__class__.__name__, False)
@property def completed(self): @@ -549,11 +545,11 @@ class SourceSpoke(NormalSpoke): def _initialize(self): from pyanaconda.threads import threadMgr
- communication.send_message(self.__class__.__name__, _("Probing storage...")) + hubQ.send_message(self.__class__.__name__, _("Probing storage..."))
threadMgr.wait(constants.THREAD_STORAGE)
- communication.send_message(self.__class__.__name__, _(METADATA_DOWNLOAD_MESSAGE)) + hubQ.send_message(self.__class__.__name__, _(METADATA_DOWNLOAD_MESSAGE))
threadMgr.wait(constants.THREAD_PAYLOAD)
@@ -592,7 +588,7 @@ class SourceSpoke(NormalSpoke): # FIXME
self._ready = True - communication.send_ready(self.__class__.__name__) + hubQ.send_ready(self.__class__.__name__, False)
def refresh(self): NormalSpoke.refresh(self) diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py index fac660a..22cab62 100644 --- a/pyanaconda/ui/gui/spokes/storage.py +++ b/pyanaconda/ui/gui/spokes/storage.py @@ -40,7 +40,7 @@
from gi.repository import Gdk, GLib, Gtk from gi.repository import AnacondaWidgets -from pyanaconda.ui import communication +from pyanaconda.ui.communication import hubQ from pyanaconda.ui.lib.disks import getDisks, isLocalDisk, size_str from pyanaconda.ui.gui import GUIObject from pyanaconda.ui.gui.spokes import NormalSpoke @@ -287,16 +287,15 @@ class StorageChecker(object): _mainSpokeClass = "StorageSpoke"
def run(self): - communication.send_not_ready(self._mainSpokeClass) + hubQ.send_not_ready(self._mainSpokeClass) threadMgr.add(AnacondaThread(name=constants.THREAD_CHECK_STORAGE, target=self.checkStorage))
def checkStorage(self): - communication.send_message(self._mainSpokeClass, - _("Checking storage configuration...")) + hubQ.send_message(self._mainSpokeClass, _("Checking storage configuration...")) (StorageChecker.errors, StorageChecker.warnings) = self.storage.sanityCheck() - communication.send_ready(self._mainSpokeClass, justUpdate=True) + hubQ.send_ready(self._mainSpokeClass, True) for e in StorageChecker.errors: log.error(e) for w in StorageChecker.warnings: @@ -381,16 +380,14 @@ class StorageSpoke(NormalSpoke, StorageChecker):
def _doExecute(self): self._ready = False - communication.send_not_ready(self.__class__.__name__) - communication.send_message(self.__class__.__name__, - _("Saving storage configuration...")) + hubQ.send_not_ready(self.__class__.__name__) + hubQ.send_message(self.__class__.__name__, _("Saving storage configuration...")) try: doKickstartStorage(self.storage, self.data, self.instclass) except StorageError as e: log.error("storage configuration failed: %s" % e) StorageChecker.errors = str(e).split("\n") - communication.send_message(self.__class__.__name__, - _("Failed to save storage configuration...")) + hubQ.send_message(self.__class__.__name__, _("Failed to save storage configuration...")) self.data.ignoredisk.drives = [] self.data.ignoredisk.onlyuse = [] self.storage.config.update(self.data) @@ -406,7 +403,7 @@ class StorageSpoke(NormalSpoke, StorageChecker): self.run() finally: self._ready = True - communication.send_ready(self.__class__.__name__, justUpdate=True) + hubQ.send_ready(self.__class__.__name__, False)
@property def completed(self): @@ -586,7 +583,7 @@ class StorageSpoke(NormalSpoke, StorageChecker): self._update_summary()
def _initialize(self): - communication.send_message(self.__class__.__name__, _("Probing storage...")) + hubQ.send_message(self.__class__.__name__, _("Probing storage..."))
threadMgr.wait(constants.THREAD_STORAGE) threadMgr.wait(constants.THREAD_CUSTOM_STORAGE_INIT) @@ -603,7 +600,7 @@ class StorageSpoke(NormalSpoke, StorageChecker): self._add_disk_overview(disk, self.local_disks_box)
self._ready = True - communication.send_ready(self.__class__.__name__) + hubQ.send_ready(self.__class__.__name__, False)
def _update_summary(self): """ Update the summary based on the UI. """ diff --git a/pyanaconda/ui/tui/hubs/progress.py b/pyanaconda/ui/tui/hubs/progress.py index 3e22619..a7d8c1b 100644 --- a/pyanaconda/ui/tui/hubs/progress.py +++ b/pyanaconda/ui/tui/hubs/progress.py @@ -44,10 +44,10 @@ class ProgressHub(TUIHub): def _update_progress(self): """Handle progress updates from install thread."""
- from pyanaconda import progress + from pyanaconda.progress import progressQ import Queue
- q = progress.progressQ + q = progressQ.q
# Grab all messages may have appeared since last time this method ran. while True: @@ -65,10 +65,10 @@ class ProgressHub(TUIHub): finally: self.app.process_events()
- if code == progress.PROGRESS_CODE_INIT: + if code == progressQ.PROGRESS_CODE_INIT: # Text mode doesn't have a finite progress bar pass - elif code == progress.PROGRESS_CODE_STEP: + elif code == progressQ.PROGRESS_CODE_STEP: # Instead of updating a progress bar, we just print a pip # but print it without a new line. sys.stdout.write('.') @@ -76,14 +76,14 @@ class ProgressHub(TUIHub): # Use _stepped as an indication to if we need a newline before # the next message self._stepped = True - elif code == progress.PROGRESS_CODE_MESSAGE: + elif code == progressQ.PROGRESS_CODE_MESSAGE: # This should already be translated if self._stepped: # Get a new line in case we've done a step before self._stepped = False print('') print(args[0]) - elif code == progress.PROGRESS_CODE_COMPLETE: + elif code == progressQ.PROGRESS_CODE_COMPLETE: # There shouldn't be any more progress updates, so return q.task_done()
diff --git a/pyanaconda/ui/tui/simpleline/base.py b/pyanaconda/ui/tui/simpleline/base.py index a8e588e..7faa8a4 100644 --- a/pyanaconda/ui/tui/simpleline/base.py +++ b/pyanaconda/ui/tui/simpleline/base.py @@ -25,7 +25,7 @@ import readline import Queue import getpass from pyanaconda.threads import threadMgr, AnacondaThread -from pyanaconda.ui.communication import HUB_CODE_EXCEPTION, HUB_CODE_INPUT +from pyanaconda.ui.communication import hubQ from pyanaconda import constants
import gettext @@ -33,7 +33,7 @@ _ = lambda x: gettext.ldgettext("anaconda", x) N_ = lambda x: x
def send_exception(queue, ex): - queue.put((HUB_CODE_EXCEPTION, [ex])) + queue.put((hubQ.HUB_CODE_EXCEPTION, [ex]))
class ExitMainLoop(Exception): @@ -148,7 +148,7 @@ class App(object): else: data = raw_input(prompt)
- queue.put((HUB_CODE_INPUT, [data])) + queue.put((hubQ.HUB_CODE_INPUT, [data]))
def switch_screen(self, ui, args = None): """Schedules a screen to replace the current one. @@ -401,7 +401,7 @@ class App(object): args=(self.queue, prompt, hidden)) input_thread.daemon = True threadMgr.add(input_thread) - event = self.process_events(return_at=HUB_CODE_INPUT) + event = self.process_events(return_at=hubQ.HUB_CODE_INPUT) return event[1][0] # return the user input
def input(self, args, key):
On Thu, 2013-03-28 at 10:08 -0400, Chris Lumens wrote:
There's no good reason to have multiple places where we define message constants and helper functions, when we could just create a class that does all the hard work for us.
Great idea, straightforward implementation. Nice! Just one minor comment:
- def _makeMethod(self, constant, methodName, argc):
def __method(*args):
if len(args) != argc:
raise TypeError("%s() takes exactly %d arguments (%d given)" % (methodName, argc, len(args)))
Could you please split this line into two?
Otherwise this looks good to me.
- def _makeMethod(self, constant, methodName, argc):
def __method(*args):
if len(args) != argc:
raise TypeError("%s() takes exactly %d arguments (%d given)" % (methodName, argc, len(args)))
Could you please split this line into two?
Otherwise this looks good to me.
Done.
- Chris
anaconda-patches@lists.fedorahosted.org