[PATCH jk-tui 2/6] Add a text progress hub to do the install

Jesse Keating jkeating at redhat.com
Tue Aug 14 22:02:09 UTC 2012


This is a pretty simple hub that works with the doInstall function as a
background thread.  In the foreground we sit in a tight loop waiting for
input to the Q and then handle messages or progress bar updates.
Progress bar updates are handled by printing a pip (.) without a new
line to the screen.
---
 po/POTFILES.in                     |   1 +
 pyanaconda/ui/tui/__init__.py      |   3 +-
 pyanaconda/ui/tui/hubs/progress.py | 115 +++++++++++++++++++++++++++++++++++++
 3 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 pyanaconda/ui/tui/hubs/progress.py

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2d3c474..82a6a3f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -60,6 +60,7 @@ pyanaconda/ui/common.py
 pyanaconda/ui/__init__.py
 
 # Text interface
+pyanaconda/ui/tui/hubs/progress.py
 pyanaconda/ui/tui/hubs/summary.py
 pyanaconda/ui/tui/hubs/__init__.py
 pyanaconda/ui/tui/tuiobject.py
diff --git a/pyanaconda/ui/tui/__init__.py b/pyanaconda/ui/tui/__init__.py
index cfd52d2..073e641 100644
--- a/pyanaconda/ui/tui/__init__.py
+++ b/pyanaconda/ui/tui/__init__.py
@@ -23,6 +23,7 @@ from pyanaconda import ui
 from pyanaconda.ui import common
 import simpleline as tui
 from hubs.summary import SummaryHub
+from hubs.progress import ProgressHub
 from spokes import StandaloneSpoke
 
 import os
@@ -132,7 +133,7 @@ class TextUserInterface(ui.UserInterface):
            This method must be provided by all subclasses.
         """
         self._app = tui.App(u"Anaconda", yes_or_no_question = YesNoDialog)
-        self._hubs = [SummaryHub]
+        self._hubs = [SummaryHub, ProgressHub]
 
         # First, grab a list of all the standalone spokes.
         path = os.path.join(os.path.dirname(__file__), "spokes")
diff --git a/pyanaconda/ui/tui/hubs/progress.py b/pyanaconda/ui/tui/hubs/progress.py
new file mode 100644
index 0000000..cbf384d
--- /dev/null
+++ b/pyanaconda/ui/tui/hubs/progress.py
@@ -0,0 +1,115 @@
+# Text progress hub classes
+#
+# Copyright (C) 2012  Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties 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, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Jesse Keating <jkeating at redhat.com>
+#
+
+import time
+import sys
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+from pyanaconda.flags import flags
+from pykickstart.constants import KS_SHUTDOWN, KS_REBOOT
+
+from pyanaconda.ui.tui.hubs import TUIHub
+from pyanaconda.ui.tui.simpleline.base import ExitAllMainLoops
+
+__all__ = ["ProgressHub"]
+
+class ProgressHub(TUIHub):
+    title = _("Installation Hub")
+
+    def __init__(self, app, ksdata, storage, payload, instclass):
+        TUIHub.__init__(self, app, ksdata, storage, payload, instclass)
+        self._stepped = False
+
+    def _update_progress(self):
+        """Handle progress updates from install thread."""
+
+        from pyanaconda import progress
+        import Queue
+
+        q = progress.progressQ
+
+        # Grab all messages may have appeared since last time this method ran.
+        while True:
+            # Attempt to get a message out of the queue for how we should update
+            # the progress bar.  If there's no message, don't error out.
+            try:
+                (code, args) = q.get(False)
+            except Queue.Empty:
+                time.sleep(1)
+                continue
+
+            if code == progress.PROGRESS_CODE_INIT:
+                # Text mode doesn't have a finite progress bar
+                pass
+            elif code == progress.PROGRESS_CODE_STEP:
+                # Instead of updating a progress bar, we just print a pip
+                # but print it without a new line.
+                sys.stdout.write('.')
+                sys.stdout.flush()
+                # Use _stepped as an indication to if we need a newline before
+                # the next message
+                self._stepped = True
+            elif code == progress.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:
+                # There shouldn't be any more progress updates, so return
+                q.task_done()
+
+                # kickstart install, continue automatically if reboot or shutdown selected
+                if flags.automatedInstall and self.data.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
+                    # Just pretend like we got input, and our input doesn't care
+                    # what it gets, it just quits.
+                    self.input(None, None)
+
+                if self._stepped:
+                    print('')
+                return True
+
+            q.task_done()
+        return True
+
+    def refresh(self, args):
+        from pyanaconda.install import doInstall
+        from pyanaconda.threads import threadMgr, AnacondaThread
+
+        # We print this here because we don't really use the window object
+        print(self.title)
+
+        threadMgr.add(AnacondaThread(name="AnaInstallThread", target=doInstall,
+                                     args=(self.storage, self.payload, self.data,
+                                           self.instclass)))
+
+        # This will run until we're all done with the install thread.
+        return self._update_progress()
+
+    def prompt(self, args = None):
+        return(_("\tInstallation complete.  Press return to quit"))
+
+    def input(self, args, key):
+        # There is nothing to do here, just raise to exit the hub
+        raise ExitAllMainLoops()
-- 
1.7.11.2



More information about the anaconda-patches mailing list