def complete(self, text, state): # pylint: disable=unused-argument ''' Tab complete for the current step. ''' if state == 0: parser = StatementParser(self.features) begidx = readline.get_begidx() endidx = readline.get_endidx() line = readline.get_line_buffer() prefix = line[begidx:endidx] if line else '' line = line[:endidx] if self.complete_single_token: # treat the entire line as a single token args = [line] else: # tokenize the line tokens = parser.tokenize(line) tokens = parser.condense(tokens) args = [t.text for t in tokens if isinstance(t, StringToken)] self.completions = self.active_step.complete(self, args, prefix) if state < len(self.completions): return self.completions[state] return None
class PromptWizard(object): def __init__(self, name, description, steps=None): self.name = name self.description = description self.steps = steps self.values = Namespace() self.parser = StatementParser() def run(self, shell): self.old_completer = readline.get_completer() readline.set_completer(self.complete) print( title_str("Entering " + self.name + " Wizard", width=shell.width, box=True, align='center'), '\n', self.description, '\n\n', "To exit, enter either Ctrl+C, Ctrl+D, or 'quit'. For help " "about the current step, enter 'help' or '?'.", sep='' ) running = True for step in self.steps: self.active_step = step valid = False while not valid: raw = None prompt = step.name if step.default is not None: d = step.default if callable(d): d = d(self.values) prompt += ' [{}]'.format(d) prompt += ': ' try: raw = input(prompt) except (KeyboardInterrupt, EOFError): print() print(AnsiCodes.red, "Wizard canceled", AnsiCodes.reset, sep='') readline.set_completer(self.old_completer) return None if raw.lower() == 'quit': print(AnsiCodes.red, "Exiting wizard", AnsiCodes.reset, sep='') readline.set_completer(self.old_completer) return None elif raw.lower() in ('?', 'help'): print(step.help) else: if not raw.strip() and step.default is not None: raw = step.default try: value = step.validate(self.values, raw) except ValueError as e: print(AnsiCodes.red, "Error: ", str(e), AnsiCodes.reset, sep='') print(AnsiCodes.yellow, step.name, ": ", step.help, sep='') else: self.values[step.id] = value valid = True readline.set_completer(self.old_completer) return self.values def complete(self, text, state): if state == 0: begidx = readline.get_begidx() endidx = readline.get_endidx() line = readline.get_line_buffer() prefix = line[begidx:endidx] if line else '' line = line[:endidx] tokens = self.parser.tokenize(line) tokens = self.parser.condense(tokens) args = [t.text for t in tokens if isinstance(t, StringToken)] self.completions = self.active_step.complete(self, args, prefix) return self.completions[state] if state < len(self.completions) else None
class PromptWizard(object): ''' A user input prompt wizards. PromptWizards will walk the user through a series of questions (:class:`WizardStep`) and accept input. The user may at any time enter the ``?`` key to get help regarding the current step. Each step can have validators that determine if a value is valid before proceeding to the next step. Also, each step can have a default value that is saved if the user hits ``Return`` with no input. Once complete, the wizard will return a :class:`~pypsi.namespace.Namespace` object that contains all the user's answers. Each step contains an ``id`` attribute that determines what variable is set in the returned namespace. For example, a step may have an id of ``"ip_addr"``. When the user enters ``"192.168.0.1"`` for this step, the input can be retrieved through the namespace's ``ip_addr`` attribute. ''' def __init__(self, name, description, steps=None): ''' :param str name: the prompt wizard name to display to the user :param str description: a short description of what the wizard does :param list steps: a list of :class:`WizardStep` objects ''' self.name = name self.description = description self.steps = steps self.values = Namespace() self.parser = StatementParser() def run(self, shell, print_header=True): ''' Execute the wizard, prompting the user for input. :param pypsi.shell.Shell shell: the active shell :returns: a :class:`~pypsi.namespace.Namespace` object containing all the answers on success, :const:`None` if the user exited the wizard ''' self.old_completer = readline.get_completer() readline.set_completer(self.complete) if print_header: print(title_str("Entering " + self.name + " Wizard", width=shell.width, box=True, align='center'), '\n', self.description, '\n\n', "To exit, enter either Ctrl+C, Ctrl+D, or 'quit'. For help " "about the current step, enter 'help' or '?'.", sep='') for step in self.steps: self.active_step = step valid = False while not valid: print() raw = None prompt = step.name if step.default is not None: d = step.default if callable(d): d = d(self.values) prompt += ' [{}]'.format(d) prompt += ': ' try: raw = input(prompt) except (KeyboardInterrupt, EOFError): print() print(AnsiCodes.red, "Wizard canceled", AnsiCodes.reset, sep='') readline.set_completer(self.old_completer) return None if raw.lower() == 'quit': print(AnsiCodes.red, "Exiting wizard", AnsiCodes.reset, sep='') readline.set_completer(self.old_completer) return None elif raw.lower() in ('?', 'help'): print(step.help) else: if not raw.strip() and step.default is not None: raw = step.default try: value = step.validate(self.values, raw) except ValueError as e: print(AnsiCodes.red, "Error: ", str(e), AnsiCodes.reset, sep='') print(AnsiCodes.yellow, step.name, ": ", step.help, AnsiCodes.reset, sep='') else: self.values[step.id] = value valid = True readline.set_completer(self.old_completer) return self.values def complete(self, text, state): ''' Tab complete for the current step. ''' if state == 0: begidx = readline.get_begidx() endidx = readline.get_endidx() line = readline.get_line_buffer() prefix = line[begidx:endidx] if line else '' line = line[:endidx] tokens = self.parser.tokenize(line) tokens = self.parser.condense(tokens) args = [t.text for t in tokens if isinstance(t, StringToken)] self.completions = self.active_step.complete(self, args, prefix) if state < len(self.completions): return self.completions[state] else: return None
class PromptWizard(object): ''' A user input prompt wizards. PromptWizards will walk the user through a series of questions (:class:`WizardStep`) and accept input. The user may at any time enter the ``?`` key to get help regarding the current step. Each step can have validators that determine if a value is valid before proceeding to the next step. Also, each step can have a default value that is saved if the user hits ``Return`` with no input. Once complete, the wizard will return a :class:`~pypsi.namespace.Namespace` object that contains all the user's answers. Each step contains an ``id`` attribute that determines what variable is set in the returned namespace. For example, a step may have an id of ``"ip_addr"``. When the user enters ``"192.168.0.1"`` for this step, the input can be retrieved through the namespace's ``ip_addr`` attribute. ''' def __init__(self, name, description, steps=None): ''' :param str name: the prompt wizard name to display to the user :param str description: a short description of what the wizard does :param list steps: a list of :class:`WizardStep` objects ''' self.name = name self.description = description self.steps = steps self.values = Namespace() self.parser = StatementParser() def run(self, shell, print_header=True): ''' Execute the wizard, prompting the user for input. :param pypsi.shell.Shell shell: the active shell :returns: a :class:`~pypsi.namespace.Namespace` object containing all the answers on success, :const:`None` if the user exited the wizard ''' self.old_completer = readline.get_completer() readline.set_completer(self.complete) if print_header: print( title_str("Entering " + self.name + " Wizard", width=shell.width, box=True, align='center'), '\n', self.description, '\n\n', "To exit, enter either Ctrl+C, Ctrl+D, or 'quit'. For help " "about the current step, enter 'help' or '?'.", sep='' ) for step in self.steps: self.active_step = step valid = False while not valid: print() raw = None prompt = step.name if step.default is not None: d = step.default if callable(d): d = d(self.values) prompt += ' [{}]'.format(d) prompt += ': ' try: raw = input(prompt) except (KeyboardInterrupt, EOFError): print() print(AnsiCodes.red, "Wizard canceled", AnsiCodes.reset, sep='') readline.set_completer(self.old_completer) return None if raw.lower() == 'quit': print(AnsiCodes.red, "Exiting wizard", AnsiCodes.reset, sep='') readline.set_completer(self.old_completer) return None elif raw.lower() in ('?', 'help'): print(step.help) else: if not raw.strip() and step.default is not None: raw = step.default try: value = step.validate(self.values, raw) except ValueError as e: print(AnsiCodes.red, "Error: ", str(e), AnsiCodes.reset, sep='') print(AnsiCodes.yellow, step.name, ": ", step.help, AnsiCodes.reset, sep='') else: self.values[step.id] = value valid = True readline.set_completer(self.old_completer) return self.values def complete(self, text, state): ''' Tab complete for the current step. ''' if state == 0: begidx = readline.get_begidx() endidx = readline.get_endidx() line = readline.get_line_buffer() prefix = line[begidx:endidx] if line else '' line = line[:endidx] tokens = self.parser.tokenize(line) tokens = self.parser.condense(tokens) args = [t.text for t in tokens if isinstance(t, StringToken)] self.completions = self.active_step.complete(self, args, prefix) if state < len(self.completions): return self.completions[state] else: return None