Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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()
Ejemplo n.º 4
0
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.
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
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()
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
 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)
Ejemplo n.º 12
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)
Ejemplo n.º 13
0
Archivo: util.py Proyecto: op3/hdtv
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
Ejemplo n.º 14
0
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
Ejemplo n.º 16
0
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()
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
def main():
    session = PromptSession('prompt> ')
    while True:
        session.prompt()
Ejemplo n.º 19
0
    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)
Ejemplo n.º 21
0
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)
Ejemplo n.º 22
0
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)
Ejemplo n.º 24
0
    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()
Ejemplo n.º 25
0
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)
Ejemplo n.º 27
0
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)
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
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)
Ejemplo n.º 30
0
    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)
Ejemplo n.º 31
0
Archivo: cmdline.py Proyecto: op3/hdtv
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)
Ejemplo n.º 32
0
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()
Ejemplo n.º 33
0
#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)