### # Copyright (c) 2002-2004, Jeremiah Fincher # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions, and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions, and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the author of this software nor the name of # contributors to this software may be used to endorse or promote products # derived from this software without specific prior written consent. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. ### """Handles interactive questions; useful for wizards and whatnot.""" __revision__ = "$Id$" import sys import textwrap from getpass import getpass as getPass import supybot.ansi as ansi import supybot.utils as utils useBold = False def output(s, unformatted=True, fd=sys.stdout): if unformatted: s = textwrap.fill(utils.normalizeWhitespace(s), width=65) print >>fd, s print >>fd def expect(prompt, possibilities, recursed=False, default=None, acceptEmpty=False, fd=sys.stdout): """Prompt the user with prompt, allow them to choose from possibilities. If possibilities is empty, allow anything. """ prompt = utils.normalizeWhitespace(prompt) originalPrompt = prompt if recursed: output('Sorry, that response was not an option.') if useBold: choices = '[%s%%s%s]' % (ansi.RESET, ansi.BOLD) else: choices = '[%s]' if possibilities: prompt = '%s %s' % (originalPrompt, choices % '/'.join(possibilities)) if len(prompt) > 70: prompt = '%s %s' % (originalPrompt, choices % '/ '.join(possibilities)) if default is not None: prompt = '%s (default: %s)' % (prompt, default) prompt = textwrap.fill(prompt) prompt = prompt.replace('/ ', '/') prompt = prompt.strip() + ' ' if useBold: print >>fd, ansi.BOLD, s = raw_input(prompt) if useBold: print >>fd, ansi.RESET s = s.strip() print >>fd if possibilities: if s in possibilities: return s elif not s and default is not None: return default elif not s and acceptEmpty: return s else: return expect(originalPrompt, possibilities, recursed=True, default=default) else: if not s and default is not None: return default return s.strip() def anything(prompt): """Allow anything from the user.""" return expect(prompt, []) def something(prompt, default=None): """Allow anything *except* nothing from the user.""" s = expect(prompt, [], default=default) while not s: output('Sorry, you must enter a value.') s = expect(prompt, [], default=default) return s def yn(prompt, default=None): """Allow only 'y' or 'n' from the user.""" if default is not None: if default: default = 'y' else: default = 'n' s = expect(prompt, ['y', 'n'], default=default) if s is 'y': return True else: return False def getpass(prompt='Enter password: ', secondPrompt='Re-enter password: '): """Prompt the user for a password.""" password = '' secondPassword = ' ' # Note that this should be different than password. assert prompt if not prompt[-1].isspace(): prompt += ' ' while True: if useBold: sys.stdout.write(ansi.BOLD) password = getPass(prompt) secondPassword = getPass(secondPrompt) if useBold: print ansi.RESET if password != secondPassword: output('Passwords don\'t match.') else: break return password # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: