def input(self, question, password=False): """ Ask the user a question and return the answer. Works like raw_input(), but returns a unicode string instead of ASCII. Unlike raw_input, this function automatically adds a space after the question. """ # sound the terminal bell to notify the user if config.ring_bell: sys.stdout.write('\07') # TODO: make sure this is logged as well self.output(question + ' ') try: if password: # Python 3 requires that stderr gets flushed, otherwise is the # message only visible after the query. self.stderr.flush() text = getpass.getpass('') else: text = self._raw_input() except KeyboardInterrupt: raise pywikibot.QuitKeyboardInterrupt() if sys.version_info[0] == 2: text = text.decode(self.encoding) return text
def _input_reraise_cntl_c(self, password): """Input and decode, and re-raise Control-C.""" try: if password: # Python 3 requires that stderr gets flushed, otherwise is the # message only visible after the query. self.stderr.flush() text = getpass.getpass('') else: text = self._raw_input() except KeyboardInterrupt: raise pywikibot.QuitKeyboardInterrupt() if sys.version_info[0] == 2: text = text.decode(self.encoding) return text
def input_choice(self, question, options, default=None, return_shortcut=True, automatic_quit=True, force=False): """ Ask the user and returns a value from the options. @param question: The question, without trailing whitespace. @type question: basestring @param options: All available options. Each entry contains the full length answer and a shortcut of only one character. The shortcut must not appear in the answer. @type options: iterable containing iterables of length 2 @param default: The default answer if no was entered. None to require an answer. @type default: basestring @param return_shortcut: Whether the shortcut or the index in the option should be returned. @type return_shortcut: bool @param automatic_quit: Adds the option 'Quit' ('q') and throw a L{QuitKeyboardInterrupt} if selected. If it's an integer it doesn't add the option but throw the exception when the option was selected. @type automatic_quit: bool or int @param force: Automatically use the default @type force: bool @return: If return_shortcut the shortcut of options or the value of default (if it's not None). Otherwise the index of the answer in options. If default is not a shortcut, it'll return -1. @rtype: int (if not return_shortcut), lowercased basestring (otherwise) """ options = list(options) if len(options) == 0: raise ValueError(u'No options are given.') if automatic_quit is True: options += [('Quit', 'q')] quit_index = len(options) - 1 elif automatic_quit is not False: quit_index = automatic_quit else: quit_index = None if default: default = default.lower() valid = {} default_index = -1 formatted_options = [] for i, option in enumerate(options): if len(option) != 2: raise ValueError(u'Option #{0} does not consist of an option ' u'and shortcut.'.format(i)) option, shortcut = option if option.lower() in valid: raise ValueError( u'Multiple identical options ({0}).'.format(option)) shortcut = shortcut.lower() if shortcut in valid: raise ValueError( u'Multiple identical shortcuts ({0}).'.format(shortcut)) valid[option.lower()] = i valid[shortcut] = i index = option.lower().find(shortcut) if shortcut == default: default_index = i shortcut = shortcut.upper() if index >= 0: option = u'{0}[{1}]{2}'.format(option[:index], shortcut, option[index + len(shortcut):]) else: option = u'{0} [{1}]'.format(option, shortcut) formatted_options += [option] question = u'{0} ({1})'.format(question, ', '.join(formatted_options)) answer = None while answer is None: if force: self.output(question + '\n') else: answer = self.input(question) if default and not answer: # nothing entered answer = default_index else: answer = valid.get(answer.lower(), None) if quit_index == answer: raise pywikibot.QuitKeyboardInterrupt() elif not return_shortcut: return answer elif answer < 0: return default else: return options[answer][1].lower()