Ejemplo n.º 1
0
def test_accept_default():
    """
    Test `prompt(accept_default=True)`.
    """
    inp = PipeInput()

    session = PromptSession(input=PipeInput(), 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.º 2
0
    def __init__(self, conn, addr, interact, server, encoding, style):
        assert isinstance(addr, tuple)  # (addr, port) tuple
        assert callable(interact)
        assert isinstance(server, TelnetServer)
        assert isinstance(encoding, text_type)  # e.g. 'utf-8'
        assert isinstance(style, BaseStyle)

        self.conn = conn
        self.addr = addr
        self.interact = interact
        self.server = server
        self.encoding = encoding
        self.style = style
        self._closed = False

        # Execution context.
        self._context_id = None

        # Create "Output" object.
        self.size = Size(rows=40, columns=79)

        # Initialize.
        _initialize_telnet(conn)

        # Create input.
        self.vt100_input = PipeInput()

        # Create output.
        def get_size():
            return self.size

        self.stdout = _ConnectionStdout(conn, encoding=encoding)
        self.vt100_output = Vt100_Output(self.stdout,
                                         get_size,
                                         write_binary=False)

        def data_received(data):
            """ TelnetProtocolParser 'data_received' callback """
            assert isinstance(data, binary_type)
            self.vt100_input.send_bytes(data)

        def size_received(rows, columns):
            """ TelnetProtocolParser 'size_received' callback """
            self.size = Size(rows=rows, columns=columns)
            get_app()._on_resize()

        self.parser = TelnetProtocolParser(data_received, size_received)
Ejemplo n.º 3
0
def set_dummy_app():
    """
    Return a context manager that makes sure that this dummy application is
    active. This is important, because we need an `Application` with
    `is_done=False` flag, otherwise no keys will be processed.
    """
    app = Application(
        layout=Layout(Window()),
        output=DummyOutput(),
        input=PipeInput())
    return set_app(app)
Ejemplo n.º 4
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 = PipeInput()

    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.º 5
0
class TelnetConnection(object):
    """
    Class that represents one Telnet connection.
    """
    def __init__(self, conn, addr, interact, server, encoding, style):
        assert isinstance(addr, tuple)  # (addr, port) tuple
        assert callable(interact)
        assert isinstance(server, TelnetServer)
        assert isinstance(encoding, text_type)  # e.g. 'utf-8'

        self.conn = conn
        self.addr = addr
        self.interact = interact
        self.server = server
        self.encoding = encoding
        self.style = style
        self._closed = False

        # Execution context.
        self._context_id = None

        # Create "Output" object.
        self.size = Size(rows=40, columns=79)

        # Initialize.
        _initialize_telnet(conn)

        # Create input.
        self.vt100_input = PipeInput()

        # Create output.
        def get_size():
            return self.size

        self.stdout = _ConnectionStdout(conn, encoding=encoding)
        self.vt100_output = Vt100_Output(self.stdout,
                                         get_size,
                                         write_binary=False)

        def data_received(data):
            """ TelnetProtocolParser 'data_received' callback """
            assert isinstance(data, binary_type)
            self.vt100_input.send_bytes(data)

        def size_received(rows, columns):
            """ TelnetProtocolParser 'size_received' callback """
            self.size = Size(rows=rows, columns=columns)
            get_app()._on_resize()

        self.parser = TelnetProtocolParser(data_received, size_received)

    def run_application(self):
        """
        Run application.
        """
        def handle_incoming_data():
            data = self.conn.recv(1024)
            if data:
                self.feed(data)
            else:
                # Connection closed by client.
                logger.info('Connection closed by client. %r %r' % self.addr)
                self.close()

        def run():
            with context() as ctx_id:
                self._context_id = ctx_id

                # Set input/output for all application running in this context.
                set_default_input(self.vt100_input)
                set_default_output(self.vt100_output)

                # Add reader.
                loop = get_event_loop()
                loop.add_reader(self.conn, handle_incoming_data)

                try:
                    obj = self.interact(self)
                    if _is_coroutine(obj):
                        # Got an asyncio coroutine.
                        import asyncio
                        f = asyncio.ensure_future(obj)
                        yield From(Future.from_asyncio_future(f))
                    else:
                        # Got a prompt_toolkit coroutine.
                        yield From(obj)
                except Exception as e:
                    print('Got %s' % type(e).__name__, e)
                    import traceback
                    traceback.print_exc()
                    raise
                finally:
                    self.close()

        return ensure_future(run())

    def feed(self, data):
        """
        Handler for incoming data. (Called by TelnetServer.)
        """
        assert isinstance(data, binary_type)
        self.parser.feed(data)

    def close(self):
        """
        Closed by client.
        """
        if not self._closed:
            self._closed = True

            self.vt100_input.close()
            get_event_loop().remove_reader(self.conn)
            self.conn.close()

    def send(self, formatted_text):
        """
        Send text to the client.
        """
        formatted_text = to_formatted_text(formatted_text)
        print_formatted_text(self.vt100_output, formatted_text, self.style
                             or DummyStyle())

    def send_above_prompt(self, formatted_text):
        """
        Send text to the client.
        This is asynchronous, returns a `Future`.
        """
        formatted_text = to_formatted_text(formatted_text)
        return self._run_in_terminal(lambda: self.send(formatted_text))

    def _run_in_terminal(self, func):
        # Make sure that when an application was active for this connection,
        # that we print the text above the application.
        with context(self._context_id):
            return run_in_terminal(func)

    def erase_screen(self):
        """
        Erase the screen and move the cursor to the top.
        """
        self.vt100_output.erase_screen()
        self.vt100_output.cursor_goto(0, 0)
        self.vt100_output.flush()