[PATCH 4/4] New purely textual text interface

Vratislav Podzimek vpodzime at redhat.com
Tue Jan 15 13:32:14 UTC 2013


Since Anaconda supports purely textual (no curses-based) interface,
we need to provide it too.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 meh/ui/text.py  | 156 ++++++++++++++++++++++++++++++++++++--------------------
 python-meh.spec |   6 +--
 2 files changed, 104 insertions(+), 58 deletions(-)

diff --git a/meh/ui/text.py b/meh/ui/text.py
index 3cdde37..28e3b7f 100644
--- a/meh/ui/text.py
+++ b/meh/ui/text.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009  Red Hat, Inc.
+# Copyright (C) 2009, 2012  Red Hat, Inc.
 # All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -15,103 +15,149 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 # Author(s): Chris Lumens <clumens at redhat.com>
+#            Vratislav Podzimek <vpodzime at redhat.com>
 #
 from meh import *
 from meh.ui import *
 import report
-from snack import *
+import report.io.TextIO
+from report import LIBREPORT_WAIT, LIBREPORT_RUN_CLI
+
+import os
 
 import gettext
 _ = lambda x: gettext.ldgettext("python-meh", x)
 
+class TextWindow(object):
+    """Helper class providing some common methods needed by all text windows."""
+
+    def __init__(self, title, *args, **kwargs):
+        self._title = title
+
+        # XXX: I know this must be really hard for translators, but there is no
+        #      usable way to include context to the POT file in Python
+        self._yes_answer = _("y")
+        self._no_answer = _("n")
+
+    @property
+    def _usable_width(self):
+        return os.environ.get("COLUMNS", 80) - 1
+
+    def _print_rule(self):
+        rule = self._usable_width * "="
+        print rule
+
+    def print_header(self):
+        print
+        self._print_rule()
+        print self._title
+        self._print_rule()
+
+    def destroy(self):
+        self._print_rule()
+        self._print_rule()
+
 class TextIntf(AbstractIntf):
     def __init__(self, *args, **kwargs):
         AbstractIntf.__init__(self, *args, **kwargs)
         self.screen = kwargs.get("screen", None)
 
+    def enableNetwork(self, *args, **kwargs):
+        """Should be provided by the inheriting class."""
+
+        return False
+
     def exitWindow(self, title, message, *args, **kwargs):
-        win = ExitWindow(title, message, *args, screen = self.screen)
+        win = ExitWindow(title, message, *args, **kwargs)
         win.run()
         win.destroy()
 
     def mainExceptionWindow(self, text, exnFile, *args, **kwargs):
-        win = MainExceptionWindow(text, exnFile, *args, screen = self.screen)
+        win = MainExceptionWindow(text, exnFile, *args, **kwargs)
         return win
 
     def messageWindow(self, title, message, *args, **kwargs):
-        win = MessageWindow(title, message, *args, screen = self.screen)
+        win = MessageWindow(title, message, *args, **kwargs)
         win.run()
         win.destroy()
 
-    def saveExceptionWindow(self, accountManager, signature, *args, **kwargs):
-        win = SaveExceptionWindow(accountManager, signature, screen = self.screen)
+    def saveExceptionWindow(self, signature, *args, **kwargs):
+        win = SaveExceptionWindow(signature, *args, **kwargs)
         win.run()
+        win.destroy()
 
-class SaveExceptionWindow(AbstractSaveExceptionWindow):
-    def __init__(self, accountManager, signature, *args, **kwargs):
-        import report.io.NewtIO
-
-        self.accountManager = accountManager
+class SaveExceptionWindow(TextWindow, AbstractSaveExceptionWindow):
+    def __init__(self, signature, *args, **kwargs):
+        AbstractSaveExceptionWindow.__init__(self, signature,
+                                             *args, **kwargs)
+        TextWindow.__init__(self, _("Save exception"), *args, **kwargs)
         self.signature = signature
-        self.screen = kwargs.get("screen")
-
-        self.io = report.io.NewtIO.NewtIO(self.screen)
 
     def run(self, *args, **kwargs):
         # Don't need to check the return value of report since it will
         # handle all the UI reporting for us.
-        report.report(self.signature, self.io)
+        report.report_problem_in_memory(self.signature,
+                                        LIBREPORT_WAIT|LIBREPORT_RUN_CLI)
 
-class MainExceptionWindow(AbstractMainExceptionWindow):
+class MainExceptionWindow(TextWindow, AbstractMainExceptionWindow):
     def __init__(self, shortTraceback=None, longTraceback=None, *args, **kwargs):
         AbstractMainExceptionWindow.__init__(self, shortTraceback, longTraceback,
                                              *args, **kwargs)
-
-        self.text = "%s\n\n" % shortTraceback
-        self.screen = kwargs.get("screen", None)
-
-        self.buttons=[_("OK"), _("Save"), _("Debug")]
-
-    def destroy(self, *args, **kwargs):
-        self.screen.popWindow()
-        self.screen.refresh()
+        TextWindow.__init__(self, _("An unknown error has occurred"),
+                            *args, **kwargs)
+        self._short_traceback = shortTraceback
+        self._menu_items = [(_("Report Bug"), MAIN_RESPONSE_SAVE),
+                            (_("Debug"), MAIN_RESPONSE_DEBUG),
+                            (_("Quit"), MAIN_RESPONSE_QUIT)]
 
     def run(self, *args, **kwargs):
-        response = ButtonChoiceWindow(self.screen, _("Exception Occurred"),
-                                     self.text, self.buttons)
-
-        if response == string.lower(_("Debug")):
-            return MAIN_RESPONSE_DEBUG
-        elif response == string.lower(_("Save")):
-            return MAIN_RESPONSE_SAVE
-        else:
-            return MAIN_RESPONSE_QUIT
-
-class MessageWindow(AbstractMessageWindow):
+        self.print_header()
+        print self._short_traceback
+        print _("What do you want to do now?")
+        for (idx, item) in enumerate(self._menu_items):
+            print "%d) %s" % (idx + 1, item[0])
+
+        ret = -1
+        num_menu_items = len(self._menu_items)
+        print
+        while not (0 < ret <= num_menu_items):
+            ret = raw_input(_("Please make your choice from above: "))
+            try:
+                ret = int(ret)
+            except ValueError:
+                ret = -1
+
+        return self._menu_items[ret - 1][1]
+
+class MessageWindow(TextWindow, AbstractMessageWindow):
     def __init__(self, title, text, *args, **kwargs):
         AbstractMessageWindow.__init__(self, title, text, *args, **kwargs)
-        self.screen = kwargs.get("screen", None)
-        self.title = title
-        self.text = text
+        TextWindow.__init__(self, title, *args, **kwargs)
+        self._text = text
 
     def run(self, *args, **kwargs):
-        self.rc = ButtonChoiceWindow(self.screen, self.title, self.text,
-                                     width=60, buttons=[_("OK")])
-
-    def destroy(self, *args, **kwargs):
-        self.screen.popWindow()
-        self.screen.refresh()
+        self.print_header()
+        print self._text
+        print
+        raw_input(_("Hit ENTER to continue"))
 
 class ExitWindow(MessageWindow):
     def __init__(self, title, text, *args, **kwargs):
-        self.screen = kwargs.get("screen", None)
-        self.title = title
-        self.text = text
+        MessageWindow.__init__(self, title, text, *args, **kwargs)
 
     def run(self, *args, **kwargs):
-        self.rc = ButtonChoiceWindow(self.screen, self.title, self.text,
-                                     width=60, buttons=[_("Exit")])
-
-    def destroy(self, *args, **kwargs):
-        self.screen.popWindow()
-        self.screen.refresh()
+        self.print_header()
+        print self._text
+        print
+        answer = raw_input(_("Are you sure you want to exit? [%(yes)s/%(no)s]") %
+                          { "yes": self._yes_answer,
+                            "no": self._no_answer.upper() })
+
+        # no answer means accepting the default (self._no_answer) and the answer
+        # is case insensitive
+        answer = answer.lower() or self._no_answer
+
+        if answer in (self._yes_answer, self._no_answer):
+            return answer == self._yes_answer
+        else:
+            self.run(*args, **kwargs)
diff --git a/python-meh.spec b/python-meh.spec
index 24c1649..21c6676 100644
--- a/python-meh.spec
+++ b/python-meh.spec
@@ -20,10 +20,10 @@ Group: System Environment/Libraries
 BuildArch: noarch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: python-devel, gettext, python-setuptools-devel, intltool
-BuildRequires: dbus-python, libreport-gtk >= %{libreportver}, libreport-newt >= %{libreportver}
+BuildRequires: dbus-python, libreport-gtk >= %{libreportver}, libreport-cli >= %{libreportver}
 Requires: python, dbus-python, pygobject3, gtk3
-Requires: openssh-clients, rpm-python, yum, newt-python
-Requires: libreport-gtk >= %{libreportver}, libreport-newt >= %{libreportver}
+Requires: openssh-clients, rpm-python, yum
+Requires: libreport-gtk >= %{libreportver}, libreport-cli >= %{libreportver}
 
 %description
 The python-meh package is a python library for handling, saving, and reporting
-- 
1.7.11.7



More information about the anaconda-patches mailing list