def GatherContractDetails(function_code): print("Please fill out the following contract details:") from neo.bin.prompt import PromptInterface session = PromptSession(completer=PromptInterface.prompt_completer, history=PromptInterface.history) name = session.prompt("[Contract Name] > ") version = session.prompt("[Contract Version] > ") author = session.prompt("[Contract Author] > ") email = session.prompt("[Contract Email] > ") description = session.prompt("[Contract Description] > ") print("Creating smart contract....") print(" Name: %s " % name) print(" Version: %s" % version) print(" Author: %s " % author) print(" Email: %s " % email) print(" Description: %s " % description) print(" Needs Storage: %s " % function_code.HasStorage) print(" Needs Dynamic Invoke: %s " % function_code.HasDynamicInvoke) print(json.dumps(function_code.ToJson(), indent=4)) return generate_deploy_script(function_code.Script, name, version, author, email, description, function_code.ContractProperties, function_code.ReturnTypeBigInteger, function_code.ParameterList)
def test_accept_default(): """ Test `prompt(accept_default=True)`. """ with create_pipe_input() as inp: session = PromptSession(input=inp, output=DummyOutput()) result = session.prompt(default="hello", accept_default=True) assert result == "hello" # Test calling prompt() for a second time. (We had an issue where the # prompt reset between calls happened at the wrong time, breaking this.) result = session.prompt(default="world", accept_default=True) assert result == "world"
def test_accept_default(): """ Test `prompt(accept_default=True)`. """ inp = create_pipe_input() session = PromptSession(input=inp, output=DummyOutput()) result = session.prompt(default='hello', accept_default=True) assert result == 'hello' # Test calling prompt() for a second time. (We had an issue where the # prompt reset between calls happened at the wrong time, breaking this.) result = session.prompt(default='world', accept_default=True) assert result == 'world' inp.close()
def run_repl(): global todos global selected update_todos() cooee_completer = CooeeCompleter() cooee_validator = CooeeValidator() def get_rprompt(): global selected if selected is None: return "" if "location" in selected: url: str = selected["location"] parts: ParseResult = urllib.parse.urlparse(url) return parts.hostname + parts.path elif "message" in selected: return selected["message"] return f"{selected}" def bottom_toolbar(): update_todos() num = len(todos) if todos is not None else 0 todo_text = f'Todos: ({num})' loading_text = f' Loading completions... ' if cooee_completer.loading > 0 else '' return todo_text + loading_text history_file = os.path.expanduser("~/.cooee/repl.hist") session = PromptSession( '> ', completer=ThreadedCompleter(cooee_completer), complete_while_typing=False, bottom_toolbar=bottom_toolbar, complete_style=CompleteStyle.MULTI_COLUMN, history=FileHistory(history_file), refresh_interval=5, rprompt=get_rprompt, validator=ThreadedValidator(cooee_validator), validate_while_typing=True, ) while True: try: text = session.prompt() if text != "": launch(text) else: update_todos() print_formatted_text("Todos") for t in todos: print_formatted_text(todo_string(t)) selected = {"message": "Todos"} except KeyboardInterrupt: continue # Control-C pressed. Try again. except EOFError: break # Control-D pressed.
def test_accept_default(): """ Test `prompt(accept_default=True)`. """ inp = create_pipe_input() session = PromptSession(input=inp, output=DummyOutput()) result = session.prompt(default='hello', accept_default=True) assert result == 'hello' # Test calling prompt() for a second time. (We had an issue where the # prompt reset between calls happened at the wrong time, breaking this.) result = session.prompt(default='world', accept_default=True) assert result == 'world' inp.close()
def _feed_cli_with_input(text, editing_mode=EditingMode.EMACS, clipboard=None, history=None, multiline=False, check_line_ending=True, key_bindings=None): """ Create a Prompt, feed it with the given user input and return the CLI object. This returns a (result, Application) tuple. """ # If the given text doesn't end with a newline, the interface won't finish. if check_line_ending: assert text.endswith('\r') inp = create_pipe_input() try: inp.send_text(text) session = PromptSession(input=inp, output=DummyOutput(), editing_mode=editing_mode, history=history, multiline=multiline, clipboard=clipboard, key_bindings=key_bindings) result = session.prompt() return session.default_buffer.document, session.app finally: inp.close()
def _feed_cli_with_input( text, editing_mode=EditingMode.EMACS, clipboard=None, history=None, multiline=False, check_line_ending=True, key_bindings=None): """ Create a Prompt, feed it with the given user input and return the CLI object. This returns a (result, Application) tuple. """ # If the given text doesn't end with a newline, the interface won't finish. if check_line_ending: assert text.endswith('\r') inp = create_pipe_input() try: inp.send_text(text) session = PromptSession( input=inp, output=DummyOutput(), editing_mode=editing_mode, history=history, multiline=multiline, clipboard=clipboard, key_bindings=key_bindings) result = session.prompt() return session.default_buffer.document, session.app finally: inp.close()
class TwitchIRC: def __init__(self, username, client_id, token, channel): self.running = True self.username = username self.client_id = client_id self.token = 'oauth:{}'.format(token) self.channel = channel self.bot = TwitchBot(self.username, self.client_id, self.token, self.channel) self.bot._connect() self.session = PromptSession('ME: ') th1 = Thread(target=self.irc_bot, args=(self, )) th1.start() th2 = Thread(target=self.interactive_shell, args=(self, )) th2.start() def irc_bot(self, data): while self.running: self.bot.reactor.process_once(0.2) def interactive_shell(self, data): while self.running: with patch_stdout(): command = self.session.prompt() if command == 'quit()': self.running = False self.bot.reactor.disconnect_all() else: self.bot.connection.privmsg('#{}'.format(self.channel), command)
def main(type, url): try: backend = backends.load(type, url) except ValueError as ex: print(ex.args[0]) backends.list() return completer = sql.SQLCompleter(tables=backend.get_tables()) bindings = KeyBindings() @bindings.add(" ") def _(event): buffer = event.app.current_buffer word = buffer.document.get_word_before_cursor() if word is not None: for comp in sql.keywords: if Levenshtein.ratio(word.lower(), comp.lower()) >= 0.75: buffer.delete_before_cursor(count=len(word)) buffer.insert_text(comp) break buffer.insert_text(" ") history = FileHistory(".sqlmojo_history") session = PromptSession( ">", lexer=PygmentsLexer(sql.SQLLexer), completer=completer, complete_while_typing=False, history=history, validator=sql.SQLValidator(), validate_while_typing=False, bottom_toolbar=HTML(f"{backend.name}: <b>{url}</b>"), key_bindings=bindings, style=style, ) while True: try: stmt = session.prompt("eSQL> ").rstrip(";") if not stmt.strip(): continue ir_dct = yacc.parse(stmt) ir_dct["raw"] = stmt result = backend.query(ir_dct) render(result) except EOFError: break
def run(self, file_script=None): """ Main loop, waiting for user input. :return: """ session = PromptSession() # This parts is used to automate test by passing file script if file_script is not None: file_script = Path(file_script) if file_script.is_file(): with file_script.open() as f: commands = f.readlines() for command in commands: command = session.prompt(self.prompt, style=self.prompt_style, default=command.strip(), accept_default=True) self.dispatcher.handle(self, command) self.update_prompt() else: self.logger.handle("File does not exist or it is not a file", self.logger.ERROR) # Normal mode waiting for user_input while True: try: command = session.prompt(self.prompt, style=self.prompt_style, completer=self.console_completer, complete_while_typing=False) self.dispatcher.handle(self, command) self.update_prompt() except KeyboardInterrupt: self.logger.handle( "Please use 'exit' command or ctrl+D key to properly quit the framework", Logger.INFO) except EOFError: exit(0)
def main(): # Create user interface. hello_world_window() # Enable threading in GTK. (Otherwise, GTK will keep the GIL.) gtk.gdk.threads_init() # Read input from the command line, using an event loop with this hook. # We use `patch_stdout`, because clicking the button will print something; # and that should print nicely 'above' the input line. with patch_stdout(): session = PromptSession('Python >>> ', inputhook=inputhook, lexer=PygmentsLexer(PythonLexer)) result = session.prompt() print('You said: %s' % result)
def main(): # Create user interface. hello_world_window() # Enable threading in GTK. (Otherwise, GTK will keep the GIL.) gtk.gdk.threads_init() # Read input from the command line, using an event loop with this hook. # We use `patch_stdout`, because clicking the button will print something; # and that should print nicely 'above' the input line. with patch_stdout(): session = PromptSession('Python >>> ', inputhook=inputhook, lexer=PygmentsLexer(PythonLexer)) result = session.prompt() print('You said: %s' % result)
def user_save_file(filename, force=False): """ Make sure filename is not in use. Offer to backup existing file unless force is True. Returns filename if successful or False if aborted. """ filename = os.path.expanduser(filename) if not force and os.path.exists(filename): hdtv.ui.warning(f"This file already exists: {filename}") bindings = KeyBindings() @bindings.add("y") @bindings.add("Y") def yes(event): session.default_buffer.text = "y" event.app.exit(result=filename) @bindings.add("n") @bindings.add("N") def no(event): session.default_buffer.text = "n" event.app.exit(result=False) @bindings.add("b") @bindings.add("B") @bindings.add(Keys.Enter) def backup(event): session.default_buffer.text = "b" backup_file(filename) event.app.exit(result=filename) @bindings.add(Keys.Any) def _(event): pass session = PromptSession( "Replace [y/n] or backup [B] existing file? ", key_bindings=bindings ) filename = session.prompt() return filename
def main(args): """ins is a command-line client for Insight""" loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) tasks = loop.run_until_complete(get_tasks()) task_table(tasks) task_names_complete = {task.hash(): None for task in tasks} completer = NestedCompleter.from_nested_dict({ "ls": None, "ls -a": None, "info": task_names_complete, "exit": None, }) text = PromptSession(completer=completer) while True: action = text.prompt("action> ") arguments = action.split(" ")[1:] if action == "exit": return elif action == "ls": task_table(tasks) elif action.startswith("info"): if len(arguments) != 1: print("usage: info <name>") continue task_table([task for task in tasks if task.hash() == arguments[0]], False) elif action == "ls -a": task_table(tasks, short=False)
class TerminalInteractiveShell(InteractiveShell): space_for_menu = Integer(6, help='Number of line at the bottom of the screen ' 'to reserve for the completion menu' ).tag(config=True) pt_app = None debugger_history = None simple_prompt = Bool(_use_simple_prompt, help="""Use `raw_input` for the REPL, without completion and prompt colors. Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are: IPython own testing machinery, and emacs inferior-shell integration through elpy. This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT` environment variable is set, or the current terminal is not a tty.""" ).tag(config=True) @property def debugger_cls(self): return Pdb if self.simple_prompt else TerminalPdb confirm_exit = Bool(True, help=""" Set to confirm when you try to exit IPython with an EOF (Control-D in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a direct exit without any confirmation.""", ).tag(config=True) editing_mode = Unicode('emacs', help="Shortcut style to use at the prompt. 'vi' or 'emacs'.", ).tag(config=True) mouse_support = Bool(False, help="Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)" ).tag(config=True) # We don't load the list of styles for the help string, because loading # Pygments plugins takes time and can cause unexpected errors. highlighting_style = Union([Unicode('legacy'), Type(klass=Style)], help="""The name or class of a Pygments style to use for syntax highlighting. To see available styles, run `pygmentize -L styles`.""" ).tag(config=True) @validate('editing_mode') def _validate_editing_mode(self, proposal): if proposal['value'].lower() == 'vim': proposal['value']= 'vi' elif proposal['value'].lower() == 'default': proposal['value']= 'emacs' if hasattr(EditingMode, proposal['value'].upper()): return proposal['value'].lower() return self.editing_mode @observe('editing_mode') def _editing_mode(self, change): u_mode = change.new.upper() if self.pt_app: self.pt_app.editing_mode = u_mode @observe('highlighting_style') @observe('colors') def _highlighting_style_changed(self, change): self.refresh_style() def refresh_style(self): self._style = self._make_style_from_name_or_cls(self.highlighting_style) highlighting_style_overrides = Dict( help="Override highlighting format for specific tokens" ).tag(config=True) true_color = Bool(False, help=("Use 24bit colors instead of 256 colors in prompt highlighting. " "If your terminal supports true color, the following command " "should print 'TRUECOLOR' in orange: " "printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"") ).tag(config=True) editor = Unicode(get_default_editor(), help="Set the editor used by IPython (default to $EDITOR/vi/notepad)." ).tag(config=True) prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True) prompts = Instance(Prompts) @default('prompts') def _prompts_default(self): return self.prompts_class(self) # @observe('prompts') # def _(self, change): # self._update_layout() @default('displayhook_class') def _displayhook_class_default(self): return RichPromptDisplayHook term_title = Bool(True, help="Automatically set the terminal title" ).tag(config=True) term_title_format = Unicode("IPython: {cwd}", help="Customize the terminal title format. This is a python format string. " + "Available substitutions are: {cwd}." ).tag(config=True) display_completions = Enum(('column', 'multicolumn','readlinelike'), help= ( "Options for displaying tab completions, 'column', 'multicolumn', and " "'readlinelike'. These options are for `prompt_toolkit`, see " "`prompt_toolkit` documentation for more information." ), default_value='multicolumn').tag(config=True) highlight_matching_brackets = Bool(True, help="Highlight matching brackets.", ).tag(config=True) extra_open_editor_shortcuts = Bool(False, help="Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. " "This is in addition to the F2 binding, which is always enabled." ).tag(config=True) handle_return = Any(None, help="Provide an alternative handler to be called when the user presses " "Return. This is an advanced option intended for debugging, which " "may be changed or removed in later releases." ).tag(config=True) enable_history_search = Bool(True, help="Allows to enable/disable the prompt toolkit history search" ).tag(config=True) prompt_includes_vi_mode = Bool(True, help="Display the current vi mode (when using vi editing mode)." ).tag(config=True) @observe('term_title') def init_term_title(self, change=None): # Enable or disable the terminal title. if self.term_title: toggle_set_term_title(True) set_term_title(self.term_title_format.format(cwd=abbrev_cwd())) else: toggle_set_term_title(False) def init_display_formatter(self): super(TerminalInteractiveShell, self).init_display_formatter() # terminal only supports plain text self.display_formatter.active_types = ['text/plain'] # disable `_ipython_display_` self.display_formatter.ipython_display_formatter.enabled = False def init_prompt_toolkit_cli(self): if self.simple_prompt: # Fall back to plain non-interactive output for tests. # This is very limited. def prompt(): prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens()) lines = [input(prompt_text)] prompt_continuation = "".join(x[1] for x in self.prompts.continuation_prompt_tokens()) while self.check_complete('\n'.join(lines))[0] == 'incomplete': lines.append( input(prompt_continuation) ) return '\n'.join(lines) self.prompt_for_code = prompt return # Set up keyboard shortcuts key_bindings = create_ipython_shortcuts(self) # Pre-populate history from IPython's history database history = InMemoryHistory() last_cell = u"" for __, ___, cell in self.history_manager.get_tail(self.history_load_length, include_latest=True): # Ignore blank lines and consecutive duplicates cell = cell.rstrip() if cell and (cell != last_cell): history.append_string(cell) last_cell = cell self._style = self._make_style_from_name_or_cls(self.highlighting_style) self.style = DynamicStyle(lambda: self._style) editing_mode = getattr(EditingMode, self.editing_mode.upper()) self.pt_app = PromptSession( editing_mode=editing_mode, key_bindings=key_bindings, history=history, completer=IPythonPTCompleter(shell=self), enable_history_search = self.enable_history_search, style=self.style, include_default_pygments_style=False, mouse_support=self.mouse_support, enable_open_in_editor=self.extra_open_editor_shortcuts, color_depth=self.color_depth, **self._extra_prompt_options()) def _make_style_from_name_or_cls(self, name_or_cls): """ Small wrapper that make an IPython compatible style from a style name We need that to add style for prompt ... etc. """ style_overrides = {} if name_or_cls == 'legacy': legacy = self.colors.lower() if legacy == 'linux': style_cls = get_style_by_name('monokai') style_overrides = _style_overrides_linux elif legacy == 'lightbg': style_overrides = _style_overrides_light_bg style_cls = get_style_by_name('pastie') elif legacy == 'neutral': # The default theme needs to be visible on both a dark background # and a light background, because we can't tell what the terminal # looks like. These tweaks to the default theme help with that. style_cls = get_style_by_name('default') style_overrides.update({ Token.Number: '#007700', Token.Operator: 'noinherit', Token.String: '#BB6622', Token.Name.Function: '#2080D0', Token.Name.Class: 'bold #2080D0', Token.Name.Namespace: 'bold #2080D0', Token.Prompt: '#009900', Token.PromptNum: '#ansibrightgreen bold', Token.OutPrompt: '#990000', Token.OutPromptNum: '#ansibrightred bold', }) # Hack: Due to limited color support on the Windows console # the prompt colors will be wrong without this if os.name == 'nt': style_overrides.update({ Token.Prompt: '#ansidarkgreen', Token.PromptNum: '#ansigreen bold', Token.OutPrompt: '#ansidarkred', Token.OutPromptNum: '#ansired bold', }) elif legacy =='nocolor': style_cls=_NoStyle style_overrides = {} else : raise ValueError('Got unknown colors: ', legacy) else : if isinstance(name_or_cls, str): style_cls = get_style_by_name(name_or_cls) else: style_cls = name_or_cls style_overrides = { Token.Prompt: '#009900', Token.PromptNum: '#ansibrightgreen bold', Token.OutPrompt: '#990000', Token.OutPromptNum: '#ansibrightred bold', } style_overrides.update(self.highlighting_style_overrides) style = merge_styles([ style_from_pygments_cls(style_cls), style_from_pygments_dict(style_overrides), ]) return style @property def pt_complete_style(self): return { 'multicolumn': CompleteStyle.MULTI_COLUMN, 'column': CompleteStyle.COLUMN, 'readlinelike': CompleteStyle.READLINE_LIKE, }[self.display_completions] @property def color_depth(self): return (ColorDepth.TRUE_COLOR if self.true_color else None) def _extra_prompt_options(self): """ Return the current layout option for the current Terminal InteractiveShell """ def get_message(): return PygmentsTokens(self.prompts.in_prompt_tokens()) return { 'complete_in_thread': False, 'lexer':IPythonPTLexer(), 'reserve_space_for_menu':self.space_for_menu, 'message': get_message, 'prompt_continuation': ( lambda width, lineno, is_soft_wrap: PygmentsTokens(self.prompts.continuation_prompt_tokens(width))), 'multiline': True, 'complete_style': self.pt_complete_style, # Highlight matching brackets, but only when this setting is # enabled, and only when the DEFAULT_BUFFER has the focus. 'input_processors': [ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() & Condition(lambda: self.highlight_matching_brackets))], 'inputhook': self.inputhook, } def prompt_for_code(self): if self.rl_next_input: default = self.rl_next_input self.rl_next_input = None else: default = '' with patch_stdout(raw=True): text = self.pt_app.prompt( default=default, # pre_run=self.pre_prompt,# reset_current_buffer=True, **self._extra_prompt_options()) return text def enable_win_unicode_console(self): if sys.version_info >= (3, 6): # Since PEP 528, Python uses the unicode APIs for the Windows # console by default, so WUC shouldn't be needed. return import win_unicode_console win_unicode_console.enable() def init_io(self): if sys.platform not in {'win32', 'cli'}: return self.enable_win_unicode_console() import colorama colorama.init() # For some reason we make these wrappers around stdout/stderr. # For now, we need to reset them so all output gets coloured. # https://github.com/ipython/ipython/issues/8669 # io.std* are deprecated, but don't show our own deprecation warnings # during initialization of the deprecated API. with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) io.stdout = io.IOStream(sys.stdout) io.stderr = io.IOStream(sys.stderr) def init_magics(self): super(TerminalInteractiveShell, self).init_magics() self.register_magics(TerminalMagics) def init_alias(self): # The parent class defines aliases that can be safely used with any # frontend. super(TerminalInteractiveShell, self).init_alias() # Now define aliases that only make sense on the terminal, because they # need direct access to the console in a way that we can't emulate in # GUI or web frontend if os.name == 'posix': for cmd in ('clear', 'more', 'less', 'man'): self.alias_manager.soft_define_alias(cmd, cmd) def __init__(self, *args, **kwargs): super(TerminalInteractiveShell, self).__init__(*args, **kwargs) self.init_prompt_toolkit_cli() self.init_term_title() self.keep_running = True self.debugger_history = InMemoryHistory() def ask_exit(self): self.keep_running = False rl_next_input = None def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED): if display_banner is not DISPLAY_BANNER_DEPRECATED: warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2) self.keep_running = True while self.keep_running: print(self.separate_in, end='') try: code = self.prompt_for_code() except EOFError: if (not self.confirm_exit) \ or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'): self.ask_exit() else: if code: self.run_cell(code, store_history=True) def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED): # An extra layer of protection in case someone mashing Ctrl-C breaks # out of our internal code. if display_banner is not DISPLAY_BANNER_DEPRECATED: warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2) while True: try: self.interact() break except KeyboardInterrupt as e: print("\n%s escaped interact()\n" % type(e).__name__) finally: # An interrupt during the eventloop will mess up the # internal state of the prompt_toolkit library. # Stopping the eventloop fixes this, see # https://github.com/ipython/ipython/pull/9867 if hasattr(self, '_eventloop'): self._eventloop.stop() _inputhook = None def inputhook(self, context): if self._inputhook is not None: self._inputhook(context) active_eventloop = None def enable_gui(self, gui=None): if gui: self.active_eventloop, self._inputhook =\ get_inputhook_name_and_func(gui) else: self.active_eventloop = self._inputhook = None # Run !system commands directly, not through pipes, so terminal programs # work correctly. system = InteractiveShell.system_raw def auto_rewrite_input(self, cmd): """Overridden from the parent class to use fancy rewriting prompt""" if not self.show_rewritten_input: return tokens = self.prompts.rewrite_prompt_tokens() if self.pt_app: print_formatted_text(PygmentsTokens(tokens), end='', style=self.pt_app.app.style) print(cmd) else: prompt = ''.join(s for t, s in tokens) print(prompt, cmd, sep='') _prompts_before = None def switch_doctest_mode(self, mode): """Switch prompts to classic for %doctest_mode""" if mode: self._prompts_before = self.prompts self.prompts = ClassicPrompts(self) elif self._prompts_before: self.prompts = self._prompts_before self._prompts_before = None
class ConfirmPrompt(BaseSimplePrompt): """Create a prompt that provides 2 options (confirm/deny) and controlled via single keypress. A wrapper class around :class:`~prompt_toolkit.shortcuts.PromptSession`. Args: message: The question to ask the user. Refer to :ref:`pages/dynamic:message` documentation for more details. style: An :class:`InquirerPyStyle` instance. Refer to :ref:`Style <pages/style:Alternate Syntax>` documentation for more details. vi_mode: Used for compatibility . default: Set the default value of the prompt, should be either `True` or `False`. This affects the value returned when user directly hit `enter` key. Refer to :ref:`pages/dynamic:default` documentation for more details. qmark: Question mark symbol. Custom symbol that will be displayed infront of the question before its answered. amark: Answer mark symbol. Custom symbol that will be displayed infront of the question after its answered. instruction: Short instruction to display next to the question. long_instruction: Long instructions to display at the bottom of the prompt. transformer: A function which performs additional transformation on the value that gets printed to the terminal. Different than `filter` parameter, this is only visual effect and won’t affect the actual value returned by :meth:`~InquirerPy.base.simple.BaseSimplePrompt.execute`. Refer to :ref:`pages/dynamic:transformer` documentation for more details. filter: A function which performs additional transformation on the result. This affects the actual value returned by :meth:`~InquirerPy.base.simple.BaseSimplePrompt.execute`. Refer to :ref:`pages/dynamic:filter` documentation for more details. keybindings: Customise the builtin keybindings. Refer to :ref:`pages/kb:Keybindings` for more details. wrap_lines: Soft wrap question lines when question exceeds the terminal width. confirm_letter: Letter used to confirm the prompt. A keybinding will be created for this letter. Default is `y` and pressing `y` will answer the prompt with value `True`. reject_letter: Letter used to reject the prompt. A keybinding will be created for this letter. Default is `n` and pressing `n` will answer the prompt with value `False`. raise_keyboard_interrupt: Raise the :class:`KeyboardInterrupt` exception when `ctrl-c` is pressed. If false, the result will be `None` and the question is skiped. mandatory: Indicate if the prompt is mandatory. If True, then the question cannot be skipped. mandatory_message: Error message to show when user attempts to skip mandatory prompt. session_result: Used internally for :ref:`index:Classic Syntax (PyInquirer)`. input: Used internally and will be removed in future updates. output: Used internally and will be removed in future updates. Examples: >>> from InquirerPy import inquirer >>> result = inquirer.confirm(message="Confirm?").execute() >>> print(result) True """ def __init__( self, message: InquirerPyMessage, style: InquirerPyStyle = None, default: InquirerPyDefault = False, vi_mode: bool = False, qmark: str = "?", amark: str = "?", instruction: str = "", long_instruction: str = "", transformer: Callable[[bool], Any] = None, filter: Callable[[bool], Any] = None, keybindings: InquirerPyKeybindings = None, wrap_lines: bool = True, confirm_letter: str = "y", reject_letter: str = "n", raise_keyboard_interrupt: bool = True, mandatory: bool = True, mandatory_message: str = "Mandatory prompt", session_result: InquirerPySessionResult = None, input: "Input" = None, output: "Output" = None, ) -> None: vi_mode = False super().__init__( message=message, style=style, vi_mode=vi_mode, qmark=qmark, amark=amark, instruction=instruction, transformer=transformer, filter=filter, default=default, wrap_lines=wrap_lines, raise_keyboard_interrupt=raise_keyboard_interrupt, mandatory=mandatory, mandatory_message=mandatory_message, session_result=session_result, ) if not isinstance(self._default, bool): raise InvalidArgument( f"{type(self).__name__} argument default should be type of bool" ) self._confirm_letter = confirm_letter self._reject_letter = reject_letter if not keybindings: keybindings = {} self.kb_maps = { "confirm": [ { "key": self._confirm_letter }, { "key": self._confirm_letter.upper() }, ], "reject": [ { "key": self._reject_letter }, { "key": self._reject_letter.upper() }, ], "any": [{ "key": Keys.Any }], **keybindings, } self.kb_func_lookup = { "confirm": [{ "func": self._handle_confirm }], "reject": [{ "func": self._handle_reject }], "any": [{ "func": lambda _: None }], } self._keybinding_factory() self._session = PromptSession( message=self._get_prompt_message, key_bindings=self._kb, style=self._style, wrap_lines=self._wrap_lines, bottom_toolbar=[("class:long_instruction", long_instruction)] if long_instruction else None, input=input, output=output, ) def _set_error(self, message: str) -> None: self._session.default_buffer.validation_state = ValidationState.INVALID self._session.default_buffer.validation_error = ValidationError( message=message) def _handle_reject(self, event) -> None: self._session.default_buffer.text = "" self.status["answered"] = True self.status["result"] = False event.app.exit(result=False) def _handle_confirm(self, event) -> None: self._session.default_buffer.text = "" self.status["answered"] = True self.status["result"] = True event.app.exit(result=True) def _handle_enter(self, event) -> None: self.status["answered"] = True self.status["result"] = self._default event.app.exit(result=self._default) def _get_prompt_message(self) -> List[Tuple[str, str]]: """Get message to display infront of the input buffer. Returns: Formatted text in list of tuple format. """ if not self.instruction: pre_answer = ( "class:instruction", " (%s/%s) " % (self._confirm_letter.upper(), self._reject_letter) if self._default else " (%s/%s) " % (self._confirm_letter, self._reject_letter.upper()), ) else: pre_answer = ("class:instruction", " %s " % self.instruction) post_answer = ("class:answer", " Yes" if self.status["result"] else " No") return super()._get_prompt_message(pre_answer, post_answer) def _run(self) -> bool: return self._session.prompt() async def _run_async(self) -> Any: return await self._session.prompt_async()
class TerminalInteractiveShell(InteractiveShell): mime_renderers = Dict().tag(config=True) space_for_menu = Integer(6, help='Number of line at the bottom of the screen ' 'to reserve for the tab completion menu, ' 'search history, ...etc, the height of ' 'these menus will at most this value. ' 'Increase it is you prefer long and skinny ' 'menus, decrease for short and wide.' ).tag(config=True) pt_app = None debugger_history = None debugger_history_file = Unicode( "~/.pdbhistory", help="File in which to store and read history" ).tag(config=True) simple_prompt = Bool(_use_simple_prompt, help="""Use `raw_input` for the REPL, without completion and prompt colors. Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are: IPython own testing machinery, and emacs inferior-shell integration through elpy. This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT` environment variable is set, or the current terminal is not a tty.""" ).tag(config=True) @property def debugger_cls(self): return Pdb if self.simple_prompt else TerminalPdb confirm_exit = Bool(True, help=""" Set to confirm when you try to exit IPython with an EOF (Control-D in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a direct exit without any confirmation.""", ).tag(config=True) editing_mode = Unicode('emacs', help="Shortcut style to use at the prompt. 'vi' or 'emacs'.", ).tag(config=True) emacs_bindings_in_vi_insert_mode = Bool( True, help="Add shortcuts from 'emacs' insert mode to 'vi' insert mode.", ).tag(config=True) modal_cursor = Bool( True, help=""" Cursor shape changes depending on vi mode: beam in vi insert mode, block in nav mode, underscore in replace mode.""", ).tag(config=True) ttimeoutlen = Float( 0.01, help="""The time in milliseconds that is waited for a key code to complete.""", ).tag(config=True) timeoutlen = Float( 0.5, help="""The time in milliseconds that is waited for a mapped key sequence to complete.""", ).tag(config=True) autoformatter = Unicode( None, help="Autoformatter to reformat Terminal code. Can be `'black'`, `'yapf'` or `None`", allow_none=True ).tag(config=True) auto_match = Bool( False, help=""" Automatically add/delete closing bracket or quote when opening bracket or quote is entered/deleted. Brackets: (), [], {} Quotes: '', \"\" """, ).tag(config=True) mouse_support = Bool(False, help="Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)" ).tag(config=True) # We don't load the list of styles for the help string, because loading # Pygments plugins takes time and can cause unexpected errors. highlighting_style = Union([Unicode('legacy'), Type(klass=Style)], help="""The name or class of a Pygments style to use for syntax highlighting. To see available styles, run `pygmentize -L styles`.""" ).tag(config=True) @validate('editing_mode') def _validate_editing_mode(self, proposal): if proposal['value'].lower() == 'vim': proposal['value']= 'vi' elif proposal['value'].lower() == 'default': proposal['value']= 'emacs' if hasattr(EditingMode, proposal['value'].upper()): return proposal['value'].lower() return self.editing_mode @observe('editing_mode') def _editing_mode(self, change): if self.pt_app: self.pt_app.editing_mode = getattr(EditingMode, change.new.upper()) def _set_formatter(self, formatter): if formatter is None: self.reformat_handler = lambda x:x elif formatter == 'black': self.reformat_handler = black_reformat_handler elif formatter == "yapf": self.reformat_handler = yapf_reformat_handler else: raise ValueError @observe("autoformatter") def _autoformatter_changed(self, change): formatter = change.new self._set_formatter(formatter) @observe('highlighting_style') @observe('colors') def _highlighting_style_changed(self, change): self.refresh_style() def refresh_style(self): self._style = self._make_style_from_name_or_cls(self.highlighting_style) highlighting_style_overrides = Dict( help="Override highlighting format for specific tokens" ).tag(config=True) true_color = Bool(False, help="""Use 24bit colors instead of 256 colors in prompt highlighting. If your terminal supports true color, the following command should print ``TRUECOLOR`` in orange:: printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\" """, ).tag(config=True) editor = Unicode(get_default_editor(), help="Set the editor used by IPython (default to $EDITOR/vi/notepad)." ).tag(config=True) prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True) prompts = Instance(Prompts) @default('prompts') def _prompts_default(self): return self.prompts_class(self) # @observe('prompts') # def _(self, change): # self._update_layout() @default('displayhook_class') def _displayhook_class_default(self): return RichPromptDisplayHook term_title = Bool(True, help="Automatically set the terminal title" ).tag(config=True) term_title_format = Unicode("IPython: {cwd}", help="Customize the terminal title format. This is a python format string. " + "Available substitutions are: {cwd}." ).tag(config=True) display_completions = Enum(('column', 'multicolumn','readlinelike'), help= ( "Options for displaying tab completions, 'column', 'multicolumn', and " "'readlinelike'. These options are for `prompt_toolkit`, see " "`prompt_toolkit` documentation for more information." ), default_value='multicolumn').tag(config=True) highlight_matching_brackets = Bool(True, help="Highlight matching brackets.", ).tag(config=True) extra_open_editor_shortcuts = Bool(False, help="Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. " "This is in addition to the F2 binding, which is always enabled." ).tag(config=True) handle_return = Any(None, help="Provide an alternative handler to be called when the user presses " "Return. This is an advanced option intended for debugging, which " "may be changed or removed in later releases." ).tag(config=True) enable_history_search = Bool(True, help="Allows to enable/disable the prompt toolkit history search" ).tag(config=True) autosuggestions_provider = Unicode( "AutoSuggestFromHistory", help="Specifies from which source automatic suggestions are provided. " "Can be set to `'AutoSuggestFromHistory`' or `None` to disable" "automatic suggestions. Default is `'AutoSuggestFromHistory`'.", allow_none=True, ).tag(config=True) def _set_autosuggestions(self, provider): if provider is None: self.auto_suggest = None elif provider == "AutoSuggestFromHistory": self.auto_suggest = AutoSuggestFromHistory() else: raise ValueError("No valid provider.") if self.pt_app: self.pt_app.auto_suggest = self.auto_suggest @observe("autosuggestions_provider") def _autosuggestions_provider_changed(self, change): provider = change.new self._set_autosuggestions(provider) prompt_includes_vi_mode = Bool(True, help="Display the current vi mode (when using vi editing mode)." ).tag(config=True) @observe('term_title') def init_term_title(self, change=None): # Enable or disable the terminal title. if self.term_title: toggle_set_term_title(True) set_term_title(self.term_title_format.format(cwd=abbrev_cwd())) else: toggle_set_term_title(False) def restore_term_title(self): if self.term_title: restore_term_title() def init_display_formatter(self): super(TerminalInteractiveShell, self).init_display_formatter() # terminal only supports plain text self.display_formatter.active_types = ["text/plain"] def init_prompt_toolkit_cli(self): if self.simple_prompt: # Fall back to plain non-interactive output for tests. # This is very limited. def prompt(): prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens()) lines = [input(prompt_text)] prompt_continuation = "".join(x[1] for x in self.prompts.continuation_prompt_tokens()) while self.check_complete('\n'.join(lines))[0] == 'incomplete': lines.append( input(prompt_continuation) ) return '\n'.join(lines) self.prompt_for_code = prompt return # Set up keyboard shortcuts key_bindings = create_ipython_shortcuts(self) # Pre-populate history from IPython's history database history = PtkHistoryAdapter(self) self._style = self._make_style_from_name_or_cls(self.highlighting_style) self.style = DynamicStyle(lambda: self._style) editing_mode = getattr(EditingMode, self.editing_mode.upper()) self.pt_loop = asyncio.new_event_loop() self.pt_app = PromptSession( auto_suggest=self.auto_suggest, editing_mode=editing_mode, key_bindings=key_bindings, history=history, completer=IPythonPTCompleter(shell=self), enable_history_search=self.enable_history_search, style=self.style, include_default_pygments_style=False, mouse_support=self.mouse_support, enable_open_in_editor=self.extra_open_editor_shortcuts, color_depth=self.color_depth, tempfile_suffix=".py", **self._extra_prompt_options() ) def _make_style_from_name_or_cls(self, name_or_cls): """ Small wrapper that make an IPython compatible style from a style name We need that to add style for prompt ... etc. """ style_overrides = {} if name_or_cls == 'legacy': legacy = self.colors.lower() if legacy == 'linux': style_cls = get_style_by_name('monokai') style_overrides = _style_overrides_linux elif legacy == 'lightbg': style_overrides = _style_overrides_light_bg style_cls = get_style_by_name('pastie') elif legacy == 'neutral': # The default theme needs to be visible on both a dark background # and a light background, because we can't tell what the terminal # looks like. These tweaks to the default theme help with that. style_cls = get_style_by_name('default') style_overrides.update({ Token.Number: '#ansigreen', Token.Operator: 'noinherit', Token.String: '#ansiyellow', Token.Name.Function: '#ansiblue', Token.Name.Class: 'bold #ansiblue', Token.Name.Namespace: 'bold #ansiblue', Token.Name.Variable.Magic: '#ansiblue', Token.Prompt: '#ansigreen', Token.PromptNum: '#ansibrightgreen bold', Token.OutPrompt: '#ansired', Token.OutPromptNum: '#ansibrightred bold', }) # Hack: Due to limited color support on the Windows console # the prompt colors will be wrong without this if os.name == 'nt': style_overrides.update({ Token.Prompt: '#ansidarkgreen', Token.PromptNum: '#ansigreen bold', Token.OutPrompt: '#ansidarkred', Token.OutPromptNum: '#ansired bold', }) elif legacy =='nocolor': style_cls=_NoStyle style_overrides = {} else : raise ValueError('Got unknown colors: ', legacy) else : if isinstance(name_or_cls, str): style_cls = get_style_by_name(name_or_cls) else: style_cls = name_or_cls style_overrides = { Token.Prompt: '#ansigreen', Token.PromptNum: '#ansibrightgreen bold', Token.OutPrompt: '#ansired', Token.OutPromptNum: '#ansibrightred bold', } style_overrides.update(self.highlighting_style_overrides) style = merge_styles([ style_from_pygments_cls(style_cls), style_from_pygments_dict(style_overrides), ]) return style @property def pt_complete_style(self): return { 'multicolumn': CompleteStyle.MULTI_COLUMN, 'column': CompleteStyle.COLUMN, 'readlinelike': CompleteStyle.READLINE_LIKE, }[self.display_completions] @property def color_depth(self): return (ColorDepth.TRUE_COLOR if self.true_color else None) def _extra_prompt_options(self): """ Return the current layout option for the current Terminal InteractiveShell """ def get_message(): return PygmentsTokens(self.prompts.in_prompt_tokens()) if self.editing_mode == 'emacs': # with emacs mode the prompt is (usually) static, so we call only # the function once. With VI mode it can toggle between [ins] and # [nor] so we can't precompute. # here I'm going to favor the default keybinding which almost # everybody uses to decrease CPU usage. # if we have issues with users with custom Prompts we can see how to # work around this. get_message = get_message() options = { 'complete_in_thread': False, 'lexer':IPythonPTLexer(), 'reserve_space_for_menu':self.space_for_menu, 'message': get_message, 'prompt_continuation': ( lambda width, lineno, is_soft_wrap: PygmentsTokens(self.prompts.continuation_prompt_tokens(width))), 'multiline': True, 'complete_style': self.pt_complete_style, # Highlight matching brackets, but only when this setting is # enabled, and only when the DEFAULT_BUFFER has the focus. 'input_processors': [ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() & Condition(lambda: self.highlight_matching_brackets))], } if not PTK3: options['inputhook'] = self.inputhook return options def prompt_for_code(self): if self.rl_next_input: default = self.rl_next_input self.rl_next_input = None else: default = '' # In order to make sure that asyncio code written in the # interactive shell doesn't interfere with the prompt, we run the # prompt in a different event loop. # If we don't do this, people could spawn coroutine with a # while/true inside which will freeze the prompt. policy = asyncio.get_event_loop_policy() old_loop = get_asyncio_loop() # FIXME: prompt_toolkit is using the deprecated `asyncio.get_event_loop` # to get the current event loop. # This will probably be replaced by an attribute or input argument, # at which point we can stop calling the soon-to-be-deprecated `set_event_loop` here. if old_loop is not self.pt_loop: policy.set_event_loop(self.pt_loop) try: with patch_stdout(raw=True): text = self.pt_app.prompt( default=default, **self._extra_prompt_options()) finally: # Restore the original event loop. if old_loop is not None and old_loop is not self.pt_loop: policy.set_event_loop(old_loop) return text def enable_win_unicode_console(self): # Since IPython 7.10 doesn't support python < 3.6 and PEP 528, Python uses the unicode APIs for the Windows # console by default, so WUC shouldn't be needed. warn("`enable_win_unicode_console` is deprecated since IPython 7.10, does not do anything and will be removed in the future", DeprecationWarning, stacklevel=2) def init_io(self): if sys.platform not in {'win32', 'cli'}: return import colorama colorama.init() def init_magics(self): super(TerminalInteractiveShell, self).init_magics() self.register_magics(TerminalMagics) def init_alias(self): # The parent class defines aliases that can be safely used with any # frontend. super(TerminalInteractiveShell, self).init_alias() # Now define aliases that only make sense on the terminal, because they # need direct access to the console in a way that we can't emulate in # GUI or web frontend if os.name == 'posix': for cmd in ('clear', 'more', 'less', 'man'): self.alias_manager.soft_define_alias(cmd, cmd) def __init__(self, *args, **kwargs): super(TerminalInteractiveShell, self).__init__(*args, **kwargs) self._set_autosuggestions(self.autosuggestions_provider) self.init_prompt_toolkit_cli() self.init_term_title() self.keep_running = True self._set_formatter(self.autoformatter) def ask_exit(self): self.keep_running = False rl_next_input = None def interact(self): self.keep_running = True while self.keep_running: print(self.separate_in, end='') try: code = self.prompt_for_code() except EOFError: if (not self.confirm_exit) \ or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'): self.ask_exit() else: if code: self.run_cell(code, store_history=True) def mainloop(self): # An extra layer of protection in case someone mashing Ctrl-C breaks # out of our internal code. while True: try: self.interact() break except KeyboardInterrupt as e: print("\n%s escaped interact()\n" % type(e).__name__) finally: # An interrupt during the eventloop will mess up the # internal state of the prompt_toolkit library. # Stopping the eventloop fixes this, see # https://github.com/ipython/ipython/pull/9867 if hasattr(self, '_eventloop'): self._eventloop.stop() self.restore_term_title() # try to call some at-exit operation optimistically as some things can't # be done during interpreter shutdown. this is technically inaccurate as # this make mainlool not re-callable, but that should be a rare if not # in existent use case. self._atexit_once() _inputhook = None def inputhook(self, context): if self._inputhook is not None: self._inputhook(context) active_eventloop = None def enable_gui(self, gui=None): if gui and (gui != 'inline') : self.active_eventloop, self._inputhook =\ get_inputhook_name_and_func(gui) else: self.active_eventloop = self._inputhook = None # For prompt_toolkit 3.0. We have to create an asyncio event loop with # this inputhook. if PTK3: import asyncio from prompt_toolkit.eventloop import new_eventloop_with_inputhook if gui == 'asyncio': # When we integrate the asyncio event loop, run the UI in the # same event loop as the rest of the code. don't use an actual # input hook. (Asyncio is not made for nesting event loops.) self.pt_loop = get_asyncio_loop() elif self._inputhook: # If an inputhook was set, create a new asyncio event loop with # this inputhook for the prompt. self.pt_loop = new_eventloop_with_inputhook(self._inputhook) else: # When there's no inputhook, run the prompt in a separate # asyncio event loop. self.pt_loop = asyncio.new_event_loop() # Run !system commands directly, not through pipes, so terminal programs # work correctly. system = InteractiveShell.system_raw def auto_rewrite_input(self, cmd): """Overridden from the parent class to use fancy rewriting prompt""" if not self.show_rewritten_input: return tokens = self.prompts.rewrite_prompt_tokens() if self.pt_app: print_formatted_text(PygmentsTokens(tokens), end='', style=self.pt_app.app.style) print(cmd) else: prompt = ''.join(s for t, s in tokens) print(prompt, cmd, sep='') _prompts_before = None def switch_doctest_mode(self, mode): """Switch prompts to classic for %doctest_mode""" if mode: self._prompts_before = self.prompts self.prompts = ClassicPrompts(self) elif self._prompts_before: self.prompts = self._prompts_before self._prompts_before = None
def main(): session = PromptSession('prompt> ') while True: session.prompt()
def run(self): dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks) dbloop_deferred = dbloop.start(.1) dbloop_deferred.addErrback(self.on_looperror) tokens = [("class:neo", 'NEO'), ("class:default", ' cli. Type '), ("class:command", '\'help\' '), ("class:default", 'to get started')] print_formatted_text(FormattedText(tokens), style=self.token_style) print('\n') while self.go_on: session = PromptSession( "neo> ", completer=self.get_completer(), history=self.history, bottom_toolbar=self.get_bottom_toolbar, style=self.token_style, refresh_interval=3, ) try: result = session.prompt() except EOFError: # Control-D pressed: quit return self.quit() except KeyboardInterrupt: # Control-C pressed: do nothing continue except Exception as e: logger.error("Exception handling input: %s " % e) try: command, arguments = self.input_parser.parse_input(result) if command is not None and len(command) > 0: command = command.lower() if command == 'quit' or command == 'exit': self.quit() elif command == 'help': self.help() elif command == 'create': self.do_create(arguments) elif command == 'open': self.do_open(arguments) elif command == 'build': self.do_build(arguments) elif command == 'load_run': self.do_load_n_run(arguments) elif command == 'import': self.do_import(arguments) elif command == 'export': self.do_export(arguments) elif command == 'wallet': self.show_wallet(arguments) elif command == 'send': self.do_send(arguments) elif command == 'sign': self.do_sign(arguments) elif command == 'block': self.show_block(arguments) elif command == 'tx': self.show_tx(arguments) elif command == 'header': self.show_header(arguments) elif command == 'account': self.show_account_state(arguments) elif command == 'asset': self.show_asset_state(arguments) elif command == 'contract': self.show_contract_state(arguments) elif command == 'testinvoke': self.test_invoke_contract(arguments) elif command == 'withdraw_request': self.make_withdraw_request(arguments) elif command == 'withdraw': self.do_withdraw(arguments) elif command == 'notifications': self.do_notifications(arguments) elif command == 'mem': self.show_mem() elif command == 'nodes' or command == 'node': self.show_nodes() elif command == 'state': self.show_state() elif command == 'debugstorage': self.handle_debug_storage(arguments) elif command == 'config': self.configure(arguments) elif command == 'pause': Blockchain.Default().Pause() elif command == 'resume': Blockchain.Default().Resume() elif command is None: print("Please specify a command") else: print("Command %s not found" % command) except Exception as e: print("Could not execute command: %s" % e) traceback.print_stack() traceback.print_exc()
class InteractiveCliMixin(object): """ This mixin provides methods to handle console input and output. :author: direct Netware Group et al. :copyright: (C) direct Netware Group - All rights reserved :package: dpt :subpackage: interactive_cli :since: v1.0.0 :license: https://www.direct-netware.de/redirect?licenses;mpl2 Mozilla Public License, v. 2.0 """ def __init__(self): """ Constructor __init__(InteractiveCliMixin) :since: v1.0.00 """ self.prompt_session = None """ prompt_toolkit based input prompt session """ self.output_pid = os.getpid() """ PID used for output separation """ self.prompt_session = PromptSession(mouse_support = True) # @property def output_stream(self): """ Returns the current output stream pointer in use. :param prompt: Inline prompt :return: (int) Stream pointer number :since: v1.0.0 """ return get_default_output().fileno() # @output_stream.setter def output_stream(self, pointer): """ Sets the output stream pointer to use. :param pointer: Stream pointer number :since: v1.0.0 """ set_default_output(create_output(pointer)) # def error(self, _exception): """ Prints the stack trace on this error event. :param _exception: Inner exception :since: v1.0.0 """ if (isinstance(_exception, TracedException)): _exception.print_stack_trace(self.output_stream) else: TracedException.print_current_stack_trace(self.output_stream) # def input(self, prompt): """ Reads one line of input. :param prompt: Inline prompt :return: (str) Cli input :since: v1.0.0 """ return self.prompt_session.prompt(prompt) # def output(self, line, *args): """ Outputs the given line. Additional positional arguments are used for string formatting. :param line: Output line :since: v1.0.0 """ output = (line.format(*args) if (len(args) > 0) else line ) print_formatted_text(output) # def output_error(self, line, *args): """ Outputs the given error line. Additional positional arguments are used for string formatting. :param line: Output line :since: v1.0.0 """ line = (line.format(*args) if (len(args) > 0) else line ) self.output_formatted("<small>[{0}({1:d}) {2}]</small> <strong>{3}</strong>", self.__class__.__name__, self.output_pid, ctime(), line ) # def output_formatted(self, line, *args): """ Outputs the given HTML-formatted line. Additional positional arguments are used for string formatting. :param line: Output line :since: v1.0.0 """ output = HTML(line.format(*args) if (len(args) > 0) else line ) print_formatted_text(output) # def output_info(self, line, *args): """ Outputs the given informational line. Additional positional arguments are used for string formatting. :param line: Output line :since: v1.0.0 """ line = (line.format(*args) if (len(args) > 0) else line ) self.output_formatted("<small>[{0}({1:d}) {2}]</small> {3}", self.__class__.__name__, self.output_pid, ctime(), line ) # def secure_input(self, prompt): """ Reads one line of input without showing the user what he typed. :param prompt: Inline prompt :return: (str) Cli input :since: v1.0.0 """ return self.prompt_session.prompt(prompt, is_password = True)
class ClickCmd(Cmd, object): """A custom Cmd implemenation that delegates commands to click and handles prompt_toolkit/readline functions""" # Cmd string overrides identchars = Cmd.identchars + '-' nohelp = "No help on %s" nocommand = "\n\t{}Command not found: {}%s{}".format( colors.COMMAND_NOT_FOUND_TEXT_STYLE, colors.COMMAND_NOT_FOUND_TEXT_FORE, Style.RESET_ALL) def __init__(self, ctx: click.Context = None, on_finished=None, hist_file=None, before_start=None, readline=None, complete_while_typing=True, fuzzy_completion=True, mouse_support=False, lexer=True, *args, **kwargs): self._stdout = kwargs.get('stdout') super(ClickCmd, self).__init__(*args, **kwargs) # readline overrides self.old_completer = None self.old_delims = None self.readline = readline # Prompt Toolkit Settings self.complete_while_typing = complete_while_typing self.fuzzy_completion = fuzzy_completion self.mouse_support = mouse_support self.lexer = lexer self._pipe_input = create_pipe_input() if not self.readline else None # A callback function that will be excuted before loading up the shell. # By default this changes the color to 0a on a Windows machine self.before_start = before_start # Save the click.Context and callback for when the shell completes self.ctx = ctx self.on_finished = on_finished # Define the history file hist_file = hist_file or os.path.join(os.path.expanduser('~'), globs.HISTORY_FILENAME) self.hist_file = os.path.abspath(hist_file) if not os.path.isdir(os.path.dirname(self.hist_file)): os.makedirs(os.path.dirname(self.hist_file)) self.history = FileHistory(self.hist_file) self.history.load_history_strings() def clear_history(self) -> bool: try: if self.readline: readline.clear_history() else: if not len(self.prompter.history._loaded_strings): return True os.remove(self.hist_file) self.prompter.history._loaded_strings = [] return True except Exception as e: return False # ---------------------------------------------------------------------------------------------- # ANCHOR Cmd Loop Overrides # ---------------------------------------------------------------------------------------------- def preloop(self): if self.readline: # Read history file when cmdloop() begins try: readline.read_history_file(self.hist_file) except IOError: pass def postloop(self): if self.readline: # Write history before cmdloop() returns try: readline.set_history_length(1000) readline.write_history_file(self.hist_file) except IOError: pass # Invoke callback before shell closes if self.on_finished: self.on_finished(self.ctx) def cmdloop(self, intro=None): self.preloop() # Readline Handling if self.readline: if self.completekey and readline: self.old_completer = readline.get_completer() self.old_delims = readline.get_completer_delims() readline.set_completer(self.complete) readline.set_completer_delims(' \n\t') to_parse = self.completekey + ': complete' if readline.__doc__ and 'libedit' in readline.__doc__: # Mac OSX to_parse = 'bind ^I rl_complete' readline.parse_and_bind(to_parse) try: # Call an optional callback function before writing the intro and initializing/starting the shell if self.before_start: if callable(self.before_start): self.before_start() # Write an intro for the shell application if intro is not None: self.intro = intro if self.intro: click.echo(self.intro, file=self._stdout) stop = None if not self.readline: # Initialize Completion Tree for Master Shell if globs.__MASTER_SHELL__ == self.ctx.command.name: BuildCompletionTree(self.ctx) # Initialize Prompter try: from ._lexer import ShellLexer except: pass from prompt_toolkit.output.color_depth import ColorDepth message = [ ('class:name', self.get_prompt()), ('class:prompt', PROMPT_SYMBOL), ] self.prompter = PromptSession( message, style=colors.prompt_style, color_depth=ColorDepth.TRUE_COLOR, history=self.history, enable_history_search=not self.complete_while_typing, mouse_support=self.mouse_support, completer=get_completer(self.fuzzy_completion), complete_in_thread=self.complete_while_typing, complete_while_typing=self.complete_while_typing, lexer=PygmentsLexer(ShellLexer) if self.lexer else None) self.piped_prompter = PromptSession( message, style=colors.prompt_style, color_depth=ColorDepth.TRUE_COLOR, input=self._pipe_input, key_bindings=None, is_password=True, lexer=PygmentsLexer(ShellLexer) if self.lexer else None) # Start Shell Application Loop while not stop: if self.cmdqueue: line = self.cmdqueue.pop(0) else: try: if self.readline: line = get_input(self.get_prompt() + PROMPT_SYMBOL) else: if not globs.__IS_REPEAT_EOF__: line = self.prompter.prompt() elif self._pipe_input: if not globs.__IS_EXITING__: line = self.piped_prompter.prompt() else: return except EOFError: if not globs.__IS_REPEAT_EOF__: # Exits the Shell Application when stdin stream ends click.echo(file=self._stdout) break else: # Swap STDIN from Programmatic Input back to User Input globs.__IS_REPEAT_EOF__ = False if self.readline: sys.stdin = globs.__PREV_STDIN__ # Prevent empty lines from being created from null input print('\n' + IGNORE_LINE) continue except KeyboardInterrupt: # Do not exit the shell on a keyboard interrupt try: if line != '': click.echo(file=self._stdout) continue except: pass # Prevent empty lines from being created from null input if not self.readline: click.echo(IGNORE_LINE) else: print('\n' + IGNORE_LINE) continue # Safely handle calling command and pretty-displaying output / errors if line.strip(): if globs.__IS_REPEAT__: if not globs.__IS_EXITING__: # If stream source is from the 'repeat' command, display the "visible" repeated command click.echo(globs.__LAST_COMMAND_VISIBLE__) def fixTupleSpacing(val): if '[' in val or ']' in val: val = re.sub(r"(\[[\s])", '[', val) val = re.sub(r"([\s]\])", ']', val) val = re.sub(r"(\[,)", ']', val) val = re.sub(r"(,\])", ']', val) if ',' in val: val = re.sub(r"(\",\")", "\", \"", val) val = re.sub(r"([,]{1,999}.(?<=,))", ',', val) return val line = fixTupleSpacing(line) globs.__CURRENT_LINE__ = line try: line = self.precmd(line) stop = self.onecmd(line) stop = self.postcmd(stop, line) if not stop and not globs.__IS_EXITING__: line = '' click.echo(file=self._stdout) except KeyboardInterrupt: click.echo(file=self._stdout) continue finally: # Will tell the next loop to switch stdin back to user input after completing a "repeated" command if line[0:6] != 'repeat' and globs.__IS_REPEAT__: globs.__IS_REPEAT__ = False globs.__IS_REPEAT_EOF__ = True if (not self.readline) and self._pipe_input: if globs.__LAST_COMMAND__ and not globs.__IS_EXITING__: self._pipe_input.send_text( globs.__LAST_COMMAND__ + '\r') elif self._pipe_input and globs.__IS_REPEAT_EOF__: globs.__IS_REPEAT_EOF__ = False else: # Prevent empty lines from being created from null input if not self.readline: click.echo(IGNORE_LINE) else: print(IGNORE_LINE) continue finally: self.postloop() if self.completekey: try: if self.readline: readline.set_completer(self.old_completer) readline.set_completer_delims(self.old_delims) except IOError: pass # ---------------------------------------------------------------------------------------------- # ANCHOR Default Handling & Click Forwards # ---------------------------------------------------------------------------------------------- def get_prompt(self): if callable(self.prompt): kwargs = {} if hasattr(inspect, 'signature'): sig = inspect.signature(self.prompt) if 'ctx' in sig.parameters: kwargs['ctx'] = self.ctx return self.prompt(**kwargs) else: return self.prompt def emptyline(self): return False def default(self, line): self.VerifyCommand(line) def get_names(self): return dir(self) def VerifyCommand(self, line): commands = [] names = self.get_names() for key in names: if not '--' in key: if 'do_' in key[0:3]: if not 'hidden_{}'.format(key[3:]) in names: commands.append(key[3:]) elif 'orig_{}'.format(key[3:]) in names: commands.append(key[3:]) suggest = utils.suggest(commands, line) if len(commands) else None click.echo(self.nocommand % line if not suggest else (self.nocommand % line) + '.\n\n\t{}{}Did you mean "{}{}{}"?{}'.format( colors.SUGGEST_TEXT_STYLE, colors.SUGGEST_TEXT_COLOR, colors.SUGGEST_ITEMS_STYLE, suggest, colors.SUGGEST_TEXT_COLOR, Style.RESET_ALL), file=self._stdout) # ---------------------------------------------------------------------------------------------- # ANCHOR Explicit Command definitions # ---------------------------------------------------------------------------------------------- # Can be overrided by defined commands of the same name def do_exit(self, arg): return True def do_help(self, arg): if not arg: super(ClickCmd, self).do_help(arg) return try: func = getattr(self, 'help_' + arg) except AttributeError: try: do_fun = getattr(self, 'do_' + arg, None) if do_fun is None: self.VerifyCommand(arg) return doc = do_fun.__doc__ if doc: click.echo(doc, file=self._stdout) return except AttributeError: pass click.echo(self.nohelp % arg, file=self._stdout) return func() # ---------------------------------------------------------------------------------------------- # ANCHOR Default "Help" Overrides # ---------------------------------------------------------------------------------------------- def __strip_hidden(self, cmds) -> List[str]: ret: List[str] = [] for cmd in cmds: try: hidden: bool = getattr(self, 'hidden_' + cmd) if not hidden: ret.append(cmd) except AttributeError: ret.append(cmd) return ret def print_topics(self, header, cmds, cmdlen, maxcol): if header is not None: if cmds: click.echo(header, file=self._stdout) if Cmd.doc_header in header or Cmd.undoc_header in header: cmds = self.__strip_hidden(cmds) if self.ruler: click.echo(str(self.ruler * len(header)), file=self._stdout) self.columnize(cmds, maxcol - 1) click.echo(file=self._stdout)
def main(): session = PromptSession("prompt> ") while True: session.prompt()
#!/usr/bin/env python """ For testing: test to make sure that everything still works when gevent monkey patches are applied. """ from __future__ import unicode_literals from gevent.monkey import patch_all from prompt_toolkit.shortcuts import PromptSession from prompt_toolkit.eventloop.defaults import create_event_loop if __name__ == '__main__': # Apply patches. patch_all() # There were some issues in the past when the event loop had an input hook. def dummy_inputhook(*a): pass eventloop = create_event_loop(inputhook=dummy_inputhook) # Ask for input. session = PromptSession('Give me some input: ', loop=eventloop) answer = session.prompt() print('You said: %s' % answer)
def run(self): dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks) dbloop_deferred = dbloop.start(.1) dbloop_deferred.addErrback(self.on_looperror) tokens = [("class:neo", 'NEO'), ("class:default", ' cli. Type '), ("class:command", '\'help\' '), ("class:default", 'to get started')] print_formatted_text(FormattedText(tokens), style=token_style) print('\n') while self.go_on: session = PromptSession( "neo> ", completer=self.get_completer(), history=self.history, bottom_toolbar=self.get_bottom_toolbar, style=token_style, refresh_interval=3, ) try: result = session.prompt() except EOFError: # Control-D pressed: quit return self.quit() except KeyboardInterrupt: # Control-C pressed: do nothing continue except Exception as e: logger.error("Exception handling input: %s " % e) try: command, arguments = self.input_parser.parse_input(result) if command is not None and len(command) > 0: command = command.lower() if command in self.commands: cmd = self.commands[command] if len(arguments) > 0 and arguments[-1] == 'help': cmd.handle_help(arguments) else: cmd.execute(arguments) else: if command == 'quit' or command == 'exit': self.quit() elif command == 'help': self.help() elif command is None: print("Please specify a command") else: print("Command '%s' not found" % command) except Exception as e: print("Could not execute command: %s" % e) traceback.print_stack() traceback.print_exc()
class REPL: """Clase para crear un chat simpl con NTP.""" prompt = '(NTP) ' nickname = 'IP' def __init__( self, transfer: Transfer, cmds: Dict[Text, Callable[[List[Text]], Tuple[bytes, Text, Text]]] = None, ) -> None: """Constructor. :transfer: Es la clase con el protocolo. """ self.t = transfer self.cmd = cmds # Crear el indicador. self.p = PromptSession( self.prompt, # Indicador. history=InMemoryHistory(), # Historial en memoria. auto_suggest=AutoSuggestFromHistory(), # Sugerencias basadas en ) # el historial. # Indicador para guardar archivos. self.pf = PromptSession('Ruta donde desea guardar el archivo: ') def main_loop(self) -> None: """Inicia una sesión en el intérprete.""" while True: try: usr = self.p.prompt() # Solicitar una entrada. except KeyboardInterrupt: continue # Si presiona CTRL-C, pasar. except EOFError: # Con CTRL-D, cerrar el chat. print('Cerrando Chat...') break # Ejecutar el comando. self.one_cmd(usr) # Recibir algún mensaje. self.receive() def one_cmd(self, cmd: Text) -> None: """Ejecuta una línea. Este puede ser sobre-instanciado por una sub-clase. """ if cmd and cmd[0].startswith( '#'): # Ejecutar en caso de ser un comando. cmd = cmd[1:] # Eliminar el carácter #. args = split(cmd) # Separar. if args[0] in self.cmd: cmd = self.cmd[args[0]] try: data, mime, encoding = cmd(args) except: print('Error mientras se procesaba el comando.') else: self.t.send(data, mime, encoding) finally: data = mime = encoding = '' return else: print(f'{cmd.title()}: No se reconoce el comando.') return # Enviar el mensaje. self.t.send(bytes(cmd, 'utf-8'), 'text/plain') def print(self, text: Text) -> None: """Imprime un mensaje en pantalla. Puede ser sobre-instanciado por una sub-clase. """ style = FormattedText([ ('red', f'{self.nickname}: '), # Mostrar de color rojo el usuario. ('gray', text), # Mostrar de color gris el mensaje. ]) # Imprimir el mensaje. print(style) def receive(self): rec = self.t.receive( confirm=self.confirm, per_cent=self.progress_bar) # Recibir el mensaje en crudo. # Recibir un archivo, si no es texto. if rec[1]['mime'] != 'text/plain' and rec[0] is not None: path = self.pf.prompt() if path == '#cancel': return # Si el usuario cancela el archivo. with open(path, 'wb') as fp: fp.write(rec[0]) # Guardar el archivo. elif rec[0] is None: pass # Mostrar el mensaje. else: self.print(rec[0].decode(rec[1]['encoding'])) def confirm(self, header): """Pregunta al usuario si dsea descargar algún archivo.""" self._file = False # Variable para verificar archivos. if header['mime'] != 'text/plain': # Si es diferente de texto plano. self._file = True size = header['size'] # Tamaño en bytes. if size > 1024: # KiloByte. size = size / 1024 size_str = f'{size:.2f} KiB' if int(size) > 1024: # MegaByte. size = size / 1024 size_str = f'{size:.2f} MiB' else: # Byte. size_str = f'{size} B' yes_no = confirm(f'¿Desea recibir este archivo ({size_str})?', ' ([y] Sí | [n] No): ') if yes_no == False: self._file = False return yes_no else: return True def progress_bar(self, pc): """Muestra una barra de progreso.""" # Verificar que sea un archivo. if self._file == False: return else: try: self.pb # Verificar que no exista una barra de progreso. except AttributeError: self._pb = ProgressBar() # Inicializar la barra. self._pb = self._pb.__enter__() # Crear la barra. self.pb = self._pb(range(100)) # Añadir la capacidad máxima. self.pb.items_completed = int(pc) # Fijar porcentaje. self.pb.progress_bar.invalidate() # Mostrar porcentaje. if pc == 100: # Si la barra está llena. self.pb.done = True # Fija hecho a vedadero. self._pb.__exit__() # Eliminar la barra. del self._pb, self.pb # Liberar memoria.
#!/usr/bin/env python """ For testing: test to make sure that everything still works when gevent monkey patches are applied. """ from gevent.monkey import patch_all from prompt_toolkit.eventloop.defaults import create_event_loop from prompt_toolkit.shortcuts import PromptSession if __name__ == "__main__": # Apply patches. patch_all() # There were some issues in the past when the event loop had an input hook. def dummy_inputhook(*a): pass eventloop = create_event_loop(inputhook=dummy_inputhook) # Ask for input. session = PromptSession("Give me some input: ", loop=eventloop) answer = session.prompt() print("You said: %s" % answer)
def main(): # Read config file first, to provide defaults conf = {} configpath = config.get_config_file() if configpath is not None: cfgparser = configparser.ConfigParser() cfgparser.read(configpath) conf = dict(cfgparser["mreg"].items()) parser = argparse.ArgumentParser(description="The MREG cli") connect_args = parser.add_argument_group('connection settings') connect_args.add_argument( '--url', default=conf.get('url', config.get_default_url()), help="use mreg server at %(metavar)s (default: %(default)s)", metavar='URL', ) connect_args.add_argument( '-u', '--user', default=conf.get('user', getpass.getuser()), help="authenticate as %(metavar)s (default: %(default)s)", metavar='USER', ) mreg_args = parser.add_argument_group('mreg settings') mreg_args.add_argument( '-d', '--domain', default=conf.get('domain', config.get_default_domain()), help="default %(metavar)s (default: %(default)s)", metavar='DOMAIN', ) mreg_args.add_argument( '-p', '--prompt', default="mreg", help="default %(metavar)s (default: %(default)s)", metavar='PROMPT', ) output_args = parser.add_argument_group('output settings') output_args.add_argument( '-v', '--verbosity', dest='verbosity', action='count', default=None, help="show debug messages on stderr", ) output_args.add_argument( '-l', '--logfile', dest='logfile', help="write log to %(metavar)s", metavar='LOGFILE', ) output_args.add_argument( '--show-token', dest='show_token', action='store_true', help="show API token after login", ) args = parser.parse_args() setup_logging(args.verbosity) logger.debug(f'args: {args}') conf = {k: v for k, v in vars(args).items() if v} util.set_config(conf) if 'logfile' in conf: log.logfile = conf['logfile'] if "user" not in conf: print("Username not set in config or as argument") return elif "url" not in conf: print("mreg url not set in config or as argument") return try: util.login1(conf["user"], conf["url"]) except (EOFError, KeyboardInterrupt): print('') raise SystemExit() if args.show_token: print(util.session.headers["Authorization"]) # Must import the commands, for the side effects of creating the commands # when importing. from . import dhcp # noqa: F401 from . import history # noqa: F401 from . import group # noqa: F401 from . import host # noqa: F401 from . import network # noqa: F401 from . import permission # noqa: F401 from . import policy # noqa: F401 from . import zone # noqa: F401 # session is a PromptSession object from prompt_toolkit which handles # some configurations of the prompt for us: the text of the prompt; the # completer; and other visual things. session = PromptSession(message=HTML(f'<b>{args.prompt}</b>> '), search_ignore_case=True, completer=cli, complete_while_typing=True, complete_style=CompleteStyle.MULTI_COLUMN) # Welcome text for the app print('Type -h for help.') # The app runs in an infinite loop and is expected to exit using sys.exit() while True: try: lines = session.prompt() except KeyboardInterrupt: continue except EOFError: raise SystemExit() try: for line in lines.splitlines(): cli.parse(shlex.split(line)) except ValueError as e: print(e)
class TerminalInteractiveShell(InteractiveShell): space_for_menu = Integer( 6, help='Number of line at the bottom of the screen ' 'to reserve for the completion menu').tag(config=True) pt_app = None debugger_history = None simple_prompt = Bool( _use_simple_prompt, help= """Use `raw_input` for the REPL, without completion and prompt colors. Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are: IPython own testing machinery, and emacs inferior-shell integration through elpy. This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT` environment variable is set, or the current terminal is not a tty.""" ).tag(config=True) @property def debugger_cls(self): return Pdb if self.simple_prompt else TerminalPdb confirm_exit = Bool( True, help=""" Set to confirm when you try to exit IPython with an EOF (Control-D in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit', you can force a direct exit without any confirmation.""", ).tag(config=True) editing_mode = Unicode( 'emacs', help="Shortcut style to use at the prompt. 'vi' or 'emacs'.", ).tag(config=True) autoformatter = Unicode( None, help= "Autoformatter to reformat Terminal code. Can be `'black'` or `None`", allow_none=True).tag(config=True) mouse_support = Bool( False, help= "Enable mouse support in the prompt\n(Note: prevents selecting text with the mouse)" ).tag(config=True) # We don't load the list of styles for the help string, because loading # Pygments plugins takes time and can cause unexpected errors. highlighting_style = Union( [Unicode('legacy'), Type(klass=Style)], help="""The name or class of a Pygments style to use for syntax highlighting. To see available styles, run `pygmentize -L styles`.""" ).tag(config=True) @validate('editing_mode') def _validate_editing_mode(self, proposal): if proposal['value'].lower() == 'vim': proposal['value'] = 'vi' elif proposal['value'].lower() == 'default': proposal['value'] = 'emacs' if hasattr(EditingMode, proposal['value'].upper()): return proposal['value'].lower() return self.editing_mode @observe('editing_mode') def _editing_mode(self, change): u_mode = change.new.upper() if self.pt_app: self.pt_app.editing_mode = u_mode @observe('autoformatter') def _autoformatter_changed(self, change): formatter = change.new if formatter is None: self.reformat_handler = lambda x: x elif formatter == 'black': self.reformat_handler = black_reformat_handler else: raise ValueError @observe('highlighting_style') @observe('colors') def _highlighting_style_changed(self, change): self.refresh_style() def refresh_style(self): self._style = self._make_style_from_name_or_cls( self.highlighting_style) highlighting_style_overrides = Dict( help="Override highlighting format for specific tokens").tag( config=True) true_color = Bool( False, help=("Use 24bit colors instead of 256 colors in prompt highlighting. " "If your terminal supports true color, the following command " "should print 'TRUECOLOR' in orange: " "printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"")).tag( config=True) editor = Unicode( get_default_editor(), help="Set the editor used by IPython (default to $EDITOR/vi/notepad)." ).tag(config=True) prompts_class = Type( Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag( config=True) prompts = Instance(Prompts) @default('prompts') def _prompts_default(self): return self.prompts_class(self) # @observe('prompts') # def _(self, change): # self._update_layout() @default('displayhook_class') def _displayhook_class_default(self): return RichPromptDisplayHook term_title = Bool( True, help="Automatically set the terminal title").tag(config=True) term_title_format = Unicode( "IPython: {cwd}", help= "Customize the terminal title format. This is a python format string. " + "Available substitutions are: {cwd}.").tag(config=True) display_completions = Enum( ('column', 'multicolumn', 'readlinelike'), help= ("Options for displaying tab completions, 'column', 'multicolumn', and " "'readlinelike'. These options are for `prompt_toolkit`, see " "`prompt_toolkit` documentation for more information."), default_value='multicolumn').tag(config=True) highlight_matching_brackets = Bool( True, help="Highlight matching brackets.", ).tag(config=True) extra_open_editor_shortcuts = Bool( False, help= "Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. " "This is in addition to the F2 binding, which is always enabled.").tag( config=True) handle_return = Any( None, help="Provide an alternative handler to be called when the user presses " "Return. This is an advanced option intended for debugging, which " "may be changed or removed in later releases.").tag(config=True) enable_history_search = Bool( True, help="Allows to enable/disable the prompt toolkit history search").tag( config=True) prompt_includes_vi_mode = Bool( True, help="Display the current vi mode (when using vi editing mode).").tag( config=True) @observe('term_title') def init_term_title(self, change=None): # Enable or disable the terminal title. if self.term_title: toggle_set_term_title(True) set_term_title(self.term_title_format.format(cwd=abbrev_cwd())) else: toggle_set_term_title(False) def restore_term_title(self): if self.term_title: restore_term_title() def init_display_formatter(self): super(TerminalInteractiveShell, self).init_display_formatter() # terminal only supports plain text self.display_formatter.active_types = ['text/plain'] # disable `_ipython_display_` self.display_formatter.ipython_display_formatter.enabled = False def init_prompt_toolkit_cli(self): if self.simple_prompt: # Fall back to plain non-interactive output for tests. # This is very limited. def prompt(): prompt_text = "".join(x[1] for x in self.prompts.in_prompt_tokens()) lines = [input(prompt_text)] prompt_continuation = "".join( x[1] for x in self.prompts.continuation_prompt_tokens()) while self.check_complete('\n'.join(lines))[0] == 'incomplete': lines.append(input(prompt_continuation)) return '\n'.join(lines) self.prompt_for_code = prompt return # Set up keyboard shortcuts key_bindings = create_ipython_shortcuts(self) # Pre-populate history from IPython's history database history = InMemoryHistory() last_cell = u"" for __, ___, cell in self.history_manager.get_tail( self.history_load_length, include_latest=True): # Ignore blank lines and consecutive duplicates cell = cell.rstrip() if cell and (cell != last_cell): history.append_string(cell) last_cell = cell self._style = self._make_style_from_name_or_cls( self.highlighting_style) self.style = DynamicStyle(lambda: self._style) editing_mode = getattr(EditingMode, self.editing_mode.upper()) self.pt_app = PromptSession( editing_mode=editing_mode, key_bindings=key_bindings, history=history, completer=IPythonPTCompleter(shell=self), enable_history_search=self.enable_history_search, style=self.style, include_default_pygments_style=False, mouse_support=self.mouse_support, enable_open_in_editor=self.extra_open_editor_shortcuts, color_depth=self.color_depth, **self._extra_prompt_options()) def _make_style_from_name_or_cls(self, name_or_cls): """ Small wrapper that make an IPython compatible style from a style name We need that to add style for prompt ... etc. """ style_overrides = {} if name_or_cls == 'legacy': legacy = self.colors.lower() if legacy == 'linux': style_cls = get_style_by_name('monokai') style_overrides = _style_overrides_linux elif legacy == 'lightbg': style_overrides = _style_overrides_light_bg style_cls = get_style_by_name('pastie') elif legacy == 'neutral': # The default theme needs to be visible on both a dark background # and a light background, because we can't tell what the terminal # looks like. These tweaks to the default theme help with that. style_cls = get_style_by_name('default') style_overrides.update({ Token.Number: '#007700', Token.Operator: 'noinherit', Token.String: '#BB6622', Token.Name.Function: '#2080D0', Token.Name.Class: 'bold #2080D0', Token.Name.Namespace: 'bold #2080D0', Token.Prompt: '#009900', Token.PromptNum: '#ansibrightgreen bold', Token.OutPrompt: '#990000', Token.OutPromptNum: '#ansibrightred bold', }) # Hack: Due to limited color support on the Windows console # the prompt colors will be wrong without this if os.name == 'nt': style_overrides.update({ Token.Prompt: '#ansidarkgreen', Token.PromptNum: '#ansigreen bold', Token.OutPrompt: '#ansidarkred', Token.OutPromptNum: '#ansired bold', }) elif legacy == 'nocolor': style_cls = _NoStyle style_overrides = {} else: raise ValueError('Got unknown colors: ', legacy) else: if isinstance(name_or_cls, str): style_cls = get_style_by_name(name_or_cls) else: style_cls = name_or_cls style_overrides = { Token.Prompt: '#009900', Token.PromptNum: '#ansibrightgreen bold', Token.OutPrompt: '#990000', Token.OutPromptNum: '#ansibrightred bold', } style_overrides.update(self.highlighting_style_overrides) style = merge_styles([ style_from_pygments_cls(style_cls), style_from_pygments_dict(style_overrides), ]) return style @property def pt_complete_style(self): return { 'multicolumn': CompleteStyle.MULTI_COLUMN, 'column': CompleteStyle.COLUMN, 'readlinelike': CompleteStyle.READLINE_LIKE, }[self.display_completions] @property def color_depth(self): return (ColorDepth.TRUE_COLOR if self.true_color else None) def _extra_prompt_options(self): """ Return the current layout option for the current Terminal InteractiveShell """ def get_message(): return PygmentsTokens(self.prompts.in_prompt_tokens()) if self.editing_mode == 'emacs': # with emacs mode the prompt is (usually) static, so we call only # the function once. With VI mode it can toggle between [ins] and # [nor] so we can't precompute. # here I'm going to favor the default keybinding which almost # everybody uses to decrease CPU usage. # if we have issues with users with custom Prompts we can see how to # work around this. get_message = get_message() return { 'complete_in_thread': False, 'lexer': IPythonPTLexer(), 'reserve_space_for_menu': self.space_for_menu, 'message': get_message, 'prompt_continuation': (lambda width, lineno, is_soft_wrap: PygmentsTokens( self.prompts.continuation_prompt_tokens(width))), 'multiline': True, 'complete_style': self.pt_complete_style, # Highlight matching brackets, but only when this setting is # enabled, and only when the DEFAULT_BUFFER has the focus. 'input_processors': [ ConditionalProcessor( processor=HighlightMatchingBracketProcessor( chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() & Condition(lambda: self.highlight_matching_brackets)) ], 'inputhook': self.inputhook, } def prompt_for_code(self): if self.rl_next_input: default = self.rl_next_input self.rl_next_input = None else: default = '' with patch_stdout(raw=True): text = self.pt_app.prompt( default=default, # pre_run=self.pre_prompt,# reset_current_buffer=True, **self._extra_prompt_options()) return text def enable_win_unicode_console(self): # Since IPython 7.10 doesn't support python < 3.6 and PEP 528, Python uses the unicode APIs for the Windows # console by default, so WUC shouldn't be needed. from warnings import warn warn( "`enable_win_unicode_console` is deprecated since IPython 7.10, does not do anything and will be removed in the future", DeprecationWarning, stacklevel=2) def init_io(self): if sys.platform not in {'win32', 'cli'}: return import colorama colorama.init() # For some reason we make these wrappers around stdout/stderr. # For now, we need to reset them so all output gets coloured. # https://github.com/ipython/ipython/issues/8669 # io.std* are deprecated, but don't show our own deprecation warnings # during initialization of the deprecated API. with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) io.stdout = io.IOStream(sys.stdout) io.stderr = io.IOStream(sys.stderr) def init_magics(self): super(TerminalInteractiveShell, self).init_magics() self.register_magics(TerminalMagics) def init_alias(self): # The parent class defines aliases that can be safely used with any # frontend. super(TerminalInteractiveShell, self).init_alias() # Now define aliases that only make sense on the terminal, because they # need direct access to the console in a way that we can't emulate in # GUI or web frontend if os.name == 'posix': for cmd in ('clear', 'more', 'less', 'man'): self.alias_manager.soft_define_alias(cmd, cmd) def __init__(self, *args, **kwargs): super(TerminalInteractiveShell, self).__init__(*args, **kwargs) self.init_prompt_toolkit_cli() self.init_term_title() self.keep_running = True self.debugger_history = InMemoryHistory() def ask_exit(self): self.keep_running = False rl_next_input = None def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED): if display_banner is not DISPLAY_BANNER_DEPRECATED: warn( 'interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2) self.keep_running = True while self.keep_running: print(self.separate_in, end='') try: code = self.prompt_for_code() except EOFError: if (not self.confirm_exit) \ or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'): self.ask_exit() else: if code: self.run_cell(code, store_history=True) def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED): # An extra layer of protection in case someone mashing Ctrl-C breaks # out of our internal code. if display_banner is not DISPLAY_BANNER_DEPRECATED: warn( 'mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2) while True: try: self.interact() break except KeyboardInterrupt as e: print("\n%s escaped interact()\n" % type(e).__name__) finally: # An interrupt during the eventloop will mess up the # internal state of the prompt_toolkit library. # Stopping the eventloop fixes this, see # https://github.com/ipython/ipython/pull/9867 if hasattr(self, '_eventloop'): self._eventloop.stop() self.restore_term_title() _inputhook = None def inputhook(self, context): if self._inputhook is not None: self._inputhook(context) active_eventloop = None def enable_gui(self, gui=None): if gui: self.active_eventloop, self._inputhook =\ get_inputhook_name_and_func(gui) else: self.active_eventloop = self._inputhook = None # Run !system commands directly, not through pipes, so terminal programs # work correctly. system = InteractiveShell.system_raw def auto_rewrite_input(self, cmd): """Overridden from the parent class to use fancy rewriting prompt""" if not self.show_rewritten_input: return tokens = self.prompts.rewrite_prompt_tokens() if self.pt_app: print_formatted_text(PygmentsTokens(tokens), end='', style=self.pt_app.app.style) print(cmd) else: prompt = ''.join(s for t, s in tokens) print(prompt, cmd, sep='') _prompts_before = None def switch_doctest_mode(self, mode): """Switch prompts to classic for %doctest_mode""" if mode: self._prompts_before = self.prompts self.prompts = ClassicPrompts(self) elif self._prompts_before: self.prompts = self._prompts_before self._prompts_before = None
def main(): # Read config file first, to provide defaults conf = {} configpath = config.get_config_file() if configpath is not None: cfgparser = configparser.ConfigParser() cfgparser.read(configpath) conf = dict(cfgparser["mreg"].items()) parser = argparse.ArgumentParser(description="The MREG cli") connect_args = parser.add_argument_group('connection settings') connect_args.add_argument( '--url', default=conf.get('url', config.get_default_url()), help="use mreg server at %(metavar)s (default: %(default)s)", metavar='URL', ) connect_args.add_argument( '-u', '--user', default=conf.get('user', getpass.getuser()), help="authenticate as %(metavar)s (default: %(default)s)", metavar='USER', ) mreg_args = parser.add_argument_group('mreg settings') mreg_args.add_argument( '-d', '--domain', default=conf.get('domain', config.get_default_domain()), help="default %(metavar)s (default: %(default)s)", metavar='DOMAIN', ) mreg_args.add_argument( '-p', '--prompt', default="mreg", help="default %(metavar)s (default: %(default)s)", metavar='PROMPT', ) output_args = parser.add_argument_group('output settings') output_args.add_argument( '-v', '--verbosity', dest='verbosity', action='count', default=None, help="show debug messages on stderr", ) output_args.add_argument( '-l', '--logfile', dest='logfile', help="write log to %(metavar)s", metavar='LOGFILE', ) output_args.add_argument( '--show-token', dest='show_token', action='store_true', help="show API token after login", ) output_args.add_argument( '--record', dest='record_traffic', help="Record all server/client traffic to %(metavar)s", metavar='RECFILE', ) output_args.add_argument( '--playback', dest='mock_traffic', help= "Run commands and mock all server/client traffic with data from %(metavar)s", metavar='MOCKFILE', ) args = parser.parse_args() setup_logging(args.verbosity) logger.debug(f'args: {args}') conf = {k: v for k, v in vars(args).items() if v} util.set_config(conf) if 'logfile' in conf: log.logfile = conf['logfile'] m = mocktraffic.MockTraffic() if 'mock_traffic' in conf: if 'record_traffic' in conf: print( "You can't use both the playback and record options at the same time!" ) raise SystemExit() m.start_playback(conf['mock_traffic']) elif 'record_traffic' in conf: m.start_recording(conf['record_traffic']) if m.is_playback(): util.mregurl = "http://127.0.0.1:8000/" util.username = "******" else: if "user" not in conf: print("Username not set in config or as argument") return elif "url" not in conf: print("mreg url not set in config or as argument") return try: util.login1(conf["user"], conf["url"]) except (EOFError, KeyboardInterrupt): print('') raise SystemExit() if args.show_token: print(util.session.headers["Authorization"]) # Must import the commands, for the side effects of creating the commands # when importing. from . import dhcp # noqa: F401 from . import history # noqa: F401 from . import group # noqa: F401 from . import host # noqa: F401 from . import label from . import network # noqa: F401 from . import permission # noqa: F401 from . import policy # noqa: F401 from . import zone # noqa: F401 from . import bacnet # must be imported after host # session is a PromptSession object from prompt_toolkit which handles # some configurations of the prompt for us: the text of the prompt; the # completer; and other visual things. session = PromptSession(message=HTML(f'<b>{args.prompt}</b>> '), search_ignore_case=True, completer=cli, complete_while_typing=True, complete_style=CompleteStyle.MULTI_COLUMN) # Welcome text for the app print('Type -h for help.') # If playing back traffic, just run through the data and exit afterwards. if m.is_playback(): while True: line = mocktraffic.MockTraffic().get_next_command() if not line: raise SystemExit() print(">", line) cli.parse(shlex.split(line)) # The app runs in an infinite loop and is expected to exit using sys.exit() while True: try: lines = session.prompt() except KeyboardInterrupt: continue except EOFError: raise SystemExit() try: for line in lines.splitlines(): # If recording commands, submit the command line. # Don't record the "source" command itself. if m.is_recording() and not line.lstrip().startswith("source"): m.record_command(line) # Run the command cli.parse(shlex.split(line)) except ValueError as e: print(e)
def MainLoop(self): #self.fPyMode = False #self.fPyMore = False def message(): """Choose correct prompt for current mode.""" if self.fPyMore: return '... > ' elif self.fPyMode: return 'py>>> ' else: return 'hdtv> ' completer = HDTVCompleter(self.command_tree, self) bindings = KeyBindings() @bindings.add(':') def _(event): if event.app.editing_mode == EditingMode.VI: event.app.editing_mode = EditingMode.EMACS else: event.app.editing_mode = EditingMode.VI session = PromptSession(message, history=self.history, completer=completer, complete_while_typing=False, complete_style=CompleteStyle.MULTI_COLUMN) def set_vi_mode(vi_mode): session.editing_mode = (EditingMode.VI if vi_mode.value else EditingMode.EMACS) hdtv.options.RegisterOption( 'cli.vi_mode', hdtv.options.Option(default=False, parse=hdtv.options.parse_bool, changeCallback=set_vi_mode)) while (self.fKeepRunning): # Read a command from the user # Read the command try: line = session.prompt() except EOFError: # Ctrl-D exits in command mode self.EOFHandler() continue except KeyboardInterrupt: # The SIGINT signal (which Python turns into a # KeyboardInterrupt exception) is used for asynchronous # exit, i.e. if another thread (e.g. the GUI thread) # wants to exit the application. if not self.fKeepRunning: break # If we get here, we assume the KeyboardInterrupt is # due to the user hitting Ctrl-C. # Ctrl-C can be used to abort the entry of a (multi-line) # command. If no command is being entered, we assume the # user wants to exit and explain how to do that correctly. if self.fPyMore: self._py_console.resetbuffer() self.fPyMore = False else: hdtv.ui.msg(r"KeyboardInterrupt: Use 'Ctrl-D' to exit") continue # Execute the command self.DoLine(line)
class CommandLine(object): """ Class implementing the HDTV command line, including switching between command and Python mode. """ cmds = dict() cmds["__name__"] = "hdtv" def __init__(self, command_tree): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.command_tree = command_tree self.history = None # TODO: Replace by IPython (call InteractiveShell.run_code or similar) self._py_console = code.InteractiveConsole(self.cmds) self.fPyMode = False self.fPyMore = False self.session = None self.fKeepRunning = True self.exit_handlers = [] if os.sep == "\\": eof = "Ctrl-Z plus Return" else: eof = "Ctrl-D (i.e. EOF)" def SetHistory(self, path): if not os.access(path, os.W_OK): hdtv.ui.error(f"History file '{path}' is read-only, will be discarded") self.history = FileHistory(path) def RegisterInteractive(self, name, ref): self.cmds[name] = ref def Unescape(self, s): "Recognize special command prefixes" s = s.lstrip() if len(s) == 0: return (CMDType.hdtv, s) if s[0] == ":": return (CMDType.python, s[1:]) elif s[0] == "@": return (CMDType.cmdfile, s[1:]) elif s[0] == "!": return (CMDType.shell, s[1:]) elif s[0] == "%": return (CMDType.magic, s[1:]) else: return (CMDType.hdtv, s) def Clear(self, args): """Clear the screen""" clear() def EnterPython(self, args=None): if os.sep == "\\": eof = "Ctrl-Z plus Return" else: eof = "Ctrl-D (i.e. EOF)" hdtv.ui.msg( "Python {}. Return to hdtv with {}.".format(platform.python_version(), eof), end="", ) # self.fPyMode = True from traitlets.config import Config c = Config() c.InteractiveShell.confirm_exit = False c.TerminalInteractiveShell.simple_prompt = False c.TerminalInteractiveShell.colors = "LightBG" c.TerminalInteractiveShell.autoindent = True c.TerminalIPythonApp.display_banner = False c.InteractiveShell.ipython_dir = "/tmp" from IPython import start_ipython start_ipython([], config=c, user_ns=self.cmds) def EnterShell(self, args=None): "Execute a subshell" if "SHELL" in os.environ: shell = os.environ["SHELL"] else: shell = getpwuid(os.getuid()).pw_shell subprocess.call(shell) def Exit(self, args=None): self.fKeepRunning = False for handler in self.exit_handlers: handler() # Dirty hack to prevent segfaults because of root garbage collection # trying to free the same memory from two threads (asyncio related) __main__.spectra.viewport.LockUpdate() __main__.spectra.Clear() def AsyncExit(self): "Asynchronous exit; to be called from another thread" # self.Exit() # self.session.app.exit(style="class:exiting") self.loop.call_soon_threadsafe(self.Exit) self.loop.call_soon_threadsafe( lambda: self.session.app.exit(style="class:exiting") ) def EOFHandler(self): self.Exit() def GetCompleteOptions(self, document, complete_event): if self.fPyMode or self.fPyMore: cmd_type = CMDType.python else: (cmd_type, cmd) = self.Unescape(document.text) default_style = "fg:#000000" default_selected_style = "bg:white fg:ansired" if cmd_type == CMDType.hdtv: yield from self.command_tree.GetCompleteOptions(document, complete_event) elif cmd_type == CMDType.cmdfile: (filepath, word_before_cursor) = os.path.split(cmd) options = self.command_tree.GetFileCompleteOptions( filepath or ".", word_before_cursor ) for option in options: yield Completion( option, -len(word_before_cursor), style=default_style, selected_style=default_selected_style, ) else: # No completion support for shell and python commands return [] def ExecCmdfile(self, fname): """ Execute a command file with hdtv commands (aka batch file) """ hdtv.ui.msg(f"Execute file: {fname}") try: file = hdtv.util.TxtFile(fname) file.read() except IOError as msg: hdtv.ui.error("%s" % msg) for line in file.lines: hdtv.ui.msg("file> " + line) self.DoLine(line) # TODO: HACK: How should I teach this micky mouse language that a # python statement (e.g. "for ...:") has ended??? if self.fPyMore: self.fPyMore = self._py_console.push("") if not self.fKeepRunning: break def ExecCmdfileCmd(self, args): for path in args.batchfile: for filename in glob.glob(path): self.ExecCmdfile(filename) def ExecShell(self, cmd): subprocess.call(cmd, shell=True) def DoLine(self, line): """ Deal with one line of input """ try: # In Python mode, all commands need to be Python commands ... if self.fPyMode or self.fPyMore: cmd_type = CMDType.python cmd = line # ... otherwise, the prefix decides. else: (cmd_type, cmd) = self.Unescape(line) # Execute as appropriate type if cmd_type == CMDType.hdtv: self.command_tree.ExecCommand(cmd) elif cmd_type == CMDType.python: # The push() function returns a boolean indicating # whether further input from the user is required. # We set the python mode accordingly. self.fPyMore = self._py_console.push(cmd) elif cmd_type == CMDType.shell: subprocess.run(cmd, shell=True) elif cmd_type == CMDType.cmdfile: self.ExecCmdfile(cmd) except KeyboardInterrupt: hdtv.ui.warning("Aborted") except HDTVCommandError as msg: hdtv.ui.error("%s" % str(msg)) except SystemExit: self.Exit() except Exception: hdtv.ui.error("Unhandled exception:") traceback.print_exc() def CreateSession(self): # self.fPyMode = False # self.fPyMore = False def message(): """Choose correct prompt for current mode.""" if self.fPyMore: return "... > " elif self.fPyMode: return "py>>> " else: return "hdtv> " completer = HDTVCompleter(self.command_tree, self) bindings = KeyBindings() # @bindings.add(':') # def _(event): # if event.app.editing_mode == EditingMode.VI: # event.app.editing_mode = EditingMode.EMACS # else: # event.app.editing_mode = EditingMode.VI @bindings.add("pageup") def _(event): event.current_buffer.enable_history_search = lambda: True event.current_buffer.history_backward(count=event.arg) event.current_buffer.enable_history_search = lambda: False @bindings.add("pagedown") def _(event): event.current_buffer.enable_history_search = lambda: True event.current_buffer.history_forward(count=event.arg) event.current_buffer.enable_history_search = lambda: False self.session = PromptSession( message, history=self.history, completer=completer, complete_while_typing=False, key_bindings=bindings, complete_style=CompleteStyle.MULTI_COLUMN, ) def MainLoop(self): try: self.CreateSession() except UnicodeDecodeError: hdtv.ui.debug("Rewriting malformed history file") with open(self.history.filename, "r+", errors="replace") as history: history_fixed = history.read() history.seek(0) history.write(history_fixed) self.SetHistory(self.history.filename) self.CreateSession() def set_vi_mode(vi_mode): self.session.editing_mode = ( EditingMode.VI if vi_mode.value else EditingMode.EMACS ) hdtv.options.RegisterOption( "cli.vi_mode", hdtv.options.Option( default=False, parse=hdtv.options.parse_bool, changeCallback=set_vi_mode ), ) while self.fKeepRunning: # Read a command from the user # Read the command try: line = self.session.prompt() except EOFError: # Ctrl-D exits in command mode self.EOFHandler() continue except KeyboardInterrupt: # The SIGINT signal (which Python turns into a # KeyboardInterrupt exception) is used for asynchronous # exit, i.e. if another thread (e.g. the GUI thread) # wants to exit the application. if not self.fKeepRunning: break # If we get here, we assume the KeyboardInterrupt is # due to the user hitting Ctrl-C. # Ctrl-C can be used to abort the entry of a (multi-line) # command. If no command is being entered, we assume the # user wants to exit and explain how to do that correctly. if self.fPyMore: self._py_console.resetbuffer() self.fPyMore = False else: hdtv.ui.msg(r"KeyboardInterrupt: Use 'Ctrl-D' to exit") continue # Execute the command if line: self.DoLine(line)
def interactive_shell(reqFile, tls, os, help, definedCommand, pattern, firstOccurence): global osCommands global customCommand bindings = KeyBindings() # Operating system if args.os.lower() == 'windows': osCommands = WordCompleter(commands.commandsToComplete, ignore_case=True, sentence=True) elif args.os.lower() == 'linux': osCommands = WordCompleter(commands.commandsToCompleteBB, ignore_case=True, sentence=True) else: help() sys.exit(1) # customCommand if definedCommand != None: customCommand = definedCommand # if custom pattern if pattern != None: extractString = re.compile(pattern+'(.*?)'+pattern, re.DOTALL) # perform burp parsing request = parseBurpRequest(reqFile) prompt = "ez > " history = InMemoryHistory() session = PromptSession(completer=osCommands, history=history, auto_suggest=AutoSuggestFromHistory(), mouse_support=True, validate_while_typing=True, complete_while_typing=True, #complete_style=CompleteStyle.READLINE_LIKE, search_ignore_case=True) while True: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if request["port"] != None: port = int(request["port"]) elif tls: port = 443 elif not tls: port = 80 s.connect((request["host"], port)) if tls: context = ssl.create_default_context() conn = context.wrap_socket(s, server_hostname=request["host"]) else: conn = s try: command = session.prompt(message="%s " % prompt, key_bindings=bindings) except KeyboardInterrupt: continue # Control-C, try again. except EOFError: if tls: conn.close() s.close() break # Control-D, kill session. if len(command) <= 0: continue with conn: if (command == "EzHelp"): ez_help() continue elif (command == "clear") or (command == "cls"): clear() continue elif (command.lower() == "quit"): if tls: conn.close() s.close() sys.exit() preparedCommand = str.encode(prep_request(command, request["requestDecoded"])) conn.send(preparedCommand) recv = conn.recv(4096) soup = bs(recv.decode(errors='ignore'), features="html.parser").text postHeader = soup.find("\n\n")+2 # print output if pattern != None: try: if not firstOccurence: if VERBOSE: print(soup[:postHeader-2]) print(extractString.findall(soup)[-1]) else: if VERBOSE: print(soup[:postHeader-2]) print(extractString.findall(soup)[0]) except: print("Pattern not found") sys.exit(1) else: if VERBOSE: print(soup) else: print(soup[postHeader:]) if tls: conn.close() s.close()
#style = style_from_pygments_cls(get_style_by_name('native')) style = Style.from_dict({ 'name': 'ansigreen', 'user': '******', 'at': '#FFFFFF', 'host': '#FFFFFF', 'pmt': '#FFFFFF', '': '#aaaaaa', 'bottom': 'bg:#222222 #aaaaaa', }) #def bottom_toolbar(): # return [('class:bottom', '[F4] Print Help xugu database console')] bottom_toolbar = [('class:bottom', '[F4] Print Help xugu database console')] xprompt = [ ('class:name', 'xugusql '), ('class:user', 'root'), ('class:at', '@'), ('class:host', '127.0.0.1'), ('class:pmt', '> '), ] while True: text = session.prompt(xprompt, lexer=PygmentsLexer(SqlLexer), \ style=style, completer=mycompleter, auto_suggest=AutoSuggestFromHistory(), \ bottom_toolbar=bottom_toolbar) if text == 'exit': break print('%s' % text)