Commits

Rob Lanphier committed a57ba75

Added urwid11-urwid15 patches
urwid15: Removed challenge_batch from Command
urwid14: Added new ui.report method
urwid13: Graceful failover when old version of urwid is installed
urwid12: Added --gui command line switch, and cleaned up urwid import
urwid11: added a password handler for when should_echo==False

  • Participants
  • Parent commits ec38990

Comments (0)

Files changed (6)

 urwid8
 urwid9
 urwid10
+urwid11
+urwid12
+urwid13
+urwid14
+urwid15
+# HG changeset patch
+# Parent 24e70b4ce5a83c6428fdb43126153051f4a7fa71
+added a password handler for when should_echo==False
+
+diff --git a/paste/script/ui/pasteurwid.py b/paste/script/ui/pasteurwid.py
+--- a/paste/script/ui/pasteurwid.py
++++ b/paste/script/ui/pasteurwid.py
+@@ -152,7 +152,19 @@
+         label = urwid.Text(('label', label_text))
+         colon = urwid.Text(('label', ': '))
+ 
+-        if issubclass(challenge.type, str):
++        if issubclass(challenge.type, str) and challenge.should_echo == False:
++            if challenge.default is NoDefault:
++                field = PasswordEdit('', '')
++            else:
++                field = PasswordEdit('', challenge.default)
++            def getter():
++                """ 
++                Closure around urwid.Edit.get_edit_text(), which we'll
++                use to scrape the value out when we're all done.
++                """
++                return field.real_edit_text
++            self._set_getter(challenge.name, getter)
++        elif issubclass(challenge.type, str):
+             if challenge.default is NoDefault:
+                 field = urwid.Edit('', '')
+             else:
+@@ -326,3 +338,30 @@
+         listbox = urwid.ListBox(listwalker)
+         return urwid.AttrWrap(listbox, 'body')
+ 
++
++class PasswordEdit(urwid.Edit):
++    """Simple password editing widget"""
++    def __init__(self, caption="", edit_text="", **kwargs):
++        self.real_edit_text = edit_text
++        edit_text = self._display_text()
++
++        self.__super.__init__(caption=caption, edit_text=edit_text, **kwargs)
++
++    def _display_text(self):
++        """ 
++        Return the text to display in lieu of showing real_edit_text 
++        """
++        return '*' * len(self.real_edit_text)
++
++    def keypress(self, size, key):
++        """
++        Temporarily set self.edit_text long enough to edit the field, then set
++        it right back
++        """
++        self.edit_text = self.real_edit_text
++        unhandled = urwid.Edit.keypress(self, size, key)
++        self.real_edit_text = self.edit_text
++        self.edit_text = self._display_text()
++
++        return unhandled
++
+# HG changeset patch
+# Parent f4e5adc530de4c9de67b2e0752d07a1aadcf3d19
+Added --gui command line switch, and cleaned up urwid import
+
+diff --git a/paste/script/command.py b/paste/script/command.py
+--- a/paste/script/command.py
++++ b/paste/script/command.py
+@@ -150,7 +150,6 @@
+ 
+     def __init__(self, name):
+         self.command_name = name
+-        self.ui = ui.get_user_interface()
+ 
+     max_args = None
+     max_args_error = 'You must provide no more than %(max_args)s arguments'
+@@ -204,6 +203,8 @@
+         self.verbose += self.options.verbose
+         self.verbose -= self.options.quiet
+         self.simulate = getattr(self.options, 'simulate', False)
++        if self.interactive:
++            self.ui = ui.get_user_interface(use_gui=self.options.use_gui)
+ 
+         # For #! situations:
+         if (os.environ.get('PASTE_CONFIG_FILE')
+@@ -331,7 +332,8 @@
+                         no_interactive=False,
+                         simulate=False,
+                         quiet=False,
+-                        overwrite=False):
++                        overwrite=False,
++                        gui=False):
+         """
+         Create a standard ``OptionParser`` instance.
+         
+@@ -374,6 +376,11 @@
+                               dest="overwrite",
+                               action="store_true",
+                               help="Overwrite files (warnings will be emitted for non-matching files otherwise)")
++        if gui:
++            parser.add_option('--gui',
++                              dest='use_gui',
++                              action='store_true',
++                              help="Use a GUI/TUI if one is available")
+         return parser
+ 
+     standard_parser = classmethod(standard_parser)
+diff --git a/paste/script/create_distro.py b/paste/script/create_distro.py
+--- a/paste/script/create_distro.py
++++ b/paste/script/create_distro.py
+@@ -27,7 +27,8 @@
+     """
+ 
+     parser = Command.standard_parser(
+-        simulate=True, no_interactive=True, quiet=True, overwrite=True)
++        simulate=True, no_interactive=True, quiet=True, overwrite=True, 
++        gui=True)
+     parser.add_option('-t', '--template',
+                       dest='templates',
+                       metavar='TEMPLATE',
+diff --git a/paste/script/ui/__init__.py b/paste/script/ui/__init__.py
+--- a/paste/script/ui/__init__.py
++++ b/paste/script/ui/__init__.py
+@@ -3,29 +3,22 @@
+ 
+ from paste.script.pastevars import NoDefault, var
+ 
+-try:
+-    import urwid
+-    import urwid.raw_display
+-except ImportError:
+-    pass
+-
+-
+-from paste.script.ui.pasteurwid import UrwidUI
+-
+-
+-def get_user_interface():
++def get_user_interface(use_gui=False):
+     """
+     Class factory for UserInterface and friends
+     """
+-    try:
+-        import urwid
+-        import urwid.raw_display
+-        has_urwid = True
+-    except ImportError:
+-        has_urwid = False
+     
+-    if has_urwid:
+-        return UrwidUI()
++    userinterface = None
++
++    if use_gui:
++        try:
++            from paste.script.ui.pasteurwid import UrwidUI
++            userinterface = UrwidUI()
++        except ImportError:
++            userinterface = None
++
++    if userinterface is not None:
++        return userinterface
+     else:
+         return BasicUI()
+ 
+diff --git a/paste/script/ui/pasteurwid.py b/paste/script/ui/pasteurwid.py
+--- a/paste/script/ui/pasteurwid.py
++++ b/paste/script/ui/pasteurwid.py
+@@ -3,11 +3,8 @@
+ 
+ from paste.script.pastevars import NoDefault, var
+ 
+-try:
+-    import urwid
+-    import urwid.raw_display
+-except ImportError:
+-    pass
++import urwid
++import urwid.raw_display
+ 
+ 
+ class UrwidUI(object):    
+# HG changeset patch
+# Parent 52d1c2908bc991bd51809ca4a8f2d4c497719496
+Graceful failover when old version of urwid is installed
+
+diff --git a/paste/script/ui/__init__.py b/paste/script/ui/__init__.py
+--- a/paste/script/ui/__init__.py
++++ b/paste/script/ui/__init__.py
+@@ -3,6 +3,7 @@
+ 
+ from paste.script.pastevars import NoDefault, var
+ 
++
+ def get_user_interface(use_gui=False):
+     """
+     Class factory for UserInterface and friends
+@@ -12,8 +13,8 @@
+ 
+     if use_gui:
+         try:
+-            from paste.script.ui.pasteurwid import UrwidUI
+-            userinterface = UrwidUI()
++            from paste.script.ui.pasteurwid import get_urwid_interface
++            userinterface = get_urwid_interface()
+         except ImportError:
+             userinterface = None
+ 
+diff --git a/paste/script/ui/pasteurwid.py b/paste/script/ui/pasteurwid.py
+--- a/paste/script/ui/pasteurwid.py
++++ b/paste/script/ui/pasteurwid.py
+@@ -5,6 +5,15 @@
+ 
+ import urwid
+ import urwid.raw_display
++import sys
++
++
++def get_urwid_interface():
++    if urwid.__version__ >= '0.9.9':
++        return UrwidUI()
++    else:
++        print >> sys.stderr, "Text UI requires Urwid 0.9.9 or greater"
++        return None
+ 
+ 
+ class UrwidUI(object):    
+# HG changeset patch
+# Parent 0a34998e10c744270e2c5f5f949e63ef3fdfcc88
+Added new ui.report method
+
+diff --git a/paste/script/create_distro.py b/paste/script/create_distro.py
+--- a/paste/script/create_distro.py
++++ b/paste/script/create_distro.py
+@@ -75,13 +75,18 @@
+         if self.options.list_variables:
+             return self.list_variables(templates)
+         if self.verbose:
+-            print 'Selected and implied templates:'
++            msg = ""
++            msg += "Selected and implied templates:\n"
+             max_tmpl_name = max([len(tmpl_name) for tmpl_name, tmpl in templates])
+             for tmpl_name, tmpl in templates:
+-                print '  %s%s  %s' % (
++                msg += "  %s%s  %s\n" % (
+                     tmpl_name, ' '*(max_tmpl_name-len(tmpl_name)),
+                     tmpl.summary)
+-            print
++            msg += "\n"
++            if self.interactive:
++                self.ui.report(msg)
++            else:
++                print msg
+         if not self.args:
+             if self.interactive:
+                 dist_name = self.challenge('Enter project name')
+diff --git a/paste/script/ui/__init__.py b/paste/script/ui/__init__.py
+--- a/paste/script/ui/__init__.py
++++ b/paste/script/ui/__init__.py
+@@ -73,5 +73,7 @@
+             print '  %s:%s  %s' % (
+                 name, ' '*(max_var-len(name)), value)
+ 
++    def report(self, msg):
++        print msg
+ 
+ 
+diff --git a/paste/script/ui/pasteurwid.py b/paste/script/ui/pasteurwid.py
+--- a/paste/script/ui/pasteurwid.py
++++ b/paste/script/ui/pasteurwid.py
+@@ -50,6 +50,11 @@
+         display = UrwidDictDisplay(vars)
+         display.header_text = title
+         display.run()
++        
++    def report(self, msg, title="Message:"):
++        display = UrwidMessageDisplay(msg)
++        display.header_text = title
++        display.run()
+ 
+ 
+ class UrwidDialogException(Exception):
+@@ -60,6 +65,27 @@
+     def __init__(self, exit_token=None):
+         self.exit_token = exit_token
+ 
++
++class UrwidMessageDisplay(object):
++    def __init__(self, msg):
++        self.header_text = 'Message:'
++        self.msg = msg
++
++    def get_widgets(self):
++        row = urwid.Text(('field', self.msg))
++        widget = urwid.Padding(row, ('fixed left', 3), ('fixed right', 3))
++        return [widget]
++
++    def get_button_defs(self):
++        return [('ok', {'label':'  OK'}),
++                ('cancel', {'label':'Cancel'})]
++
++    def run(self):
++        dialog = UrwidDialog(self)
++        dialog.header_text = self.header_text
++        UrwidCancelWrapper(dialog).run()
++
++
+ class UrwidDictDisplay(object):
+     def __init__(self, showdict):
+         self.showdict = showdict
+# HG changeset patch
+# Parent 7bb40eccbc769a726bb98c38bfaee7d532d91e51
+Removed challenge_batch from Command
+
+diff --git a/paste/script/command.py b/paste/script/command.py
+--- a/paste/script/command.py
++++ b/paste/script/command.py
+@@ -313,12 +313,6 @@
+         """
+         return self.ui.challenge(prompt, default=default, should_echo=should_echo)
+ 
+-    def challenge_batch(self, challenges):
+-        """
+-        Prompt the user for a set of variables
+-        """
+-        return self.ui.challenge_batch(challenges)
+-
+     def pad(self, s, length, dir='left'):
+         if len(s) >= length:
+             return s
+diff --git a/paste/script/templates.py b/paste/script/templates.py
+--- a/paste/script/templates.py
++++ b/paste/script/templates.py
+@@ -83,7 +83,7 @@
+             else:
+                 converted_vars[var.name] = unused_vars.pop(var.name)
+         if cmd.interactive:
+-            converted_vars = cmd.challenge_batch(challenges)
++            converted_vars = cmd.ui.challenge_batch(challenges)
+         
+         if errors:
+             raise command.BadCommand(