Пример #1
0
def mock_prompt_input():
    # TODO: remove if prompt-toolkit min version gets bumped
    if PIPE_INPUT_CONTEXT_MANAGER:
        with create_pipe_input() as pipe_input:
            with create_app_session(input=pipe_input, output=DummyOutput()):
                yield pipe_input
    else:
        pipe_input = create_pipe_input()
        try:
            with create_app_session(input=pipe_input, output=DummyOutput()):
                yield pipe_input
        finally:
            pipe_input.close()
Пример #2
0
def test_cli_argument():
    arguments = ['ws-ui']
    with patch.object(sys, 'argv', arguments):
        with create_app_session(input=create_pipe_input(),
                                output=DummyOutput()):
            app = Application()
            asyncio.run(app.main())
Пример #3
0
    async def _interact(self) -> None:
        if self._chan is None:
            # Should not happen.
            raise Exception("`_interact` called before `connection_made`.")

        if hasattr(self._chan,
                   "set_line_mode") and self._chan._editor is not None:
            # Disable the line editing provided by asyncssh. Prompt_toolkit
            # provides the line editing.
            self._chan.set_line_mode(False)

        term = self._chan.get_terminal_type()

        self._output = Vt100_Output(self.stdout,
                                    self._get_size,
                                    term=term,
                                    write_binary=False)
        with create_pipe_input() as self._input:
            with create_app_session(input=self._input,
                                    output=self._output) as session:
                self.app_session = session
                try:
                    await self.interact(self)
                except BaseException:
                    traceback.print_exc()
                finally:
                    # Close the connection.
                    self._chan.close()
                    self._input.close()
Пример #4
0
    def __init__(
        self, interact: Callable[["PromptToolkitSSHSession"],
                                 Awaitable[None]]) -> None:
        self.interact = interact
        self._chan = None
        self.app_session: Optional[AppSession] = None

        # PipInput object, for sending input in the CLI.
        # (This is something that we can use in the prompt_toolkit event loop,
        # but still write date in manually.)
        self._input = create_pipe_input()
        self._output = None

        # Output object. Don't render to the real stdout, but write everything
        # in the SSH channel.
        class Stdout:
            def write(s, data):
                if self._chan is not None:
                    self._chan.write(data.replace("\n", "\r\n"))

            def flush(s):
                pass

            @property
            def encoding(s):
                return self._chan._orig_chan.get_encoding()[0]

        self.stdout = cast(TextIO, Stdout())
Пример #5
0
def app():
    pipe_input = create_pipe_input()
    try:
        with create_app_session(input=pipe_input, output=DummyOutput()):
            config = Config()
            app = App(config=config)
            yield app
    finally:
        pipe_input.close()
Пример #6
0
def mock_input() -> Generator[MockInput, None, None]:
    with create_pipe_input() as pipe_input:
        with create_app_session(input=pipe_input):

            def factory(
                    input_sequence: Sequence[str]) -> None:  # noqa: WPS 430
                pipe_input.send_text("".join(input_sequence))

            yield factory
Пример #7
0
    def __init__(
        self,
        conn: socket.socket,
        addr: Tuple[str, int],
        interact: Callable[["TelnetConnection"], Awaitable[None]],
        server: "TelnetServer",
        encoding: str,
        style: Optional[BaseStyle],
    ) -> None:

        self.conn = conn
        self.addr = addr
        self.interact = interact
        self.server = server
        self.encoding = encoding
        self.style = style
        self._closed = False
        self._ready = asyncio.Event()
        self.vt100_output = None

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

        # Initialize.
        _initialize_telnet(conn)

        # Create input.
        self.vt100_input = create_pipe_input()

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

        self.stdout = cast(TextIO, _ConnectionStdout(conn, encoding=encoding))

        def data_received(data: bytes) -> None:
            """ TelnetProtocolParser 'data_received' callback """
            self.vt100_input.send_bytes(data)

        def size_received(rows: int, columns: int) -> None:
            """ TelnetProtocolParser 'size_received' callback """
            self.size = Size(rows=rows, columns=columns)
            if self.vt100_output is not None:
                get_app()._on_resize()

        def ttype_received(ttype: str) -> None:
            """ TelnetProtocolParser 'ttype_received' callback """
            self.vt100_output = Vt100_Output(self.stdout,
                                             get_size,
                                             term=ttype,
                                             write_binary=False)
            self._ready.set()

        self.parser = TelnetProtocolParser(data_received, size_received,
                                           ttype_received)
        self.context: Optional[contextvars.Context] = None
Пример #8
0
    def test_layout(self):
        input = create_pipe_input()
        with create_app_session(input=input, output=DummyOutput()):
            tui = TerminalUI()
            layout = tui.app.layout
            assert len(list(layout.find_all_windows())) > 1

            children = layout.container.get_children()
            assert len(children) == 2
            assert len(children[0].get_children()) == 2
Пример #9
0
def mock_input():
    pipe_input = create_pipe_input()
    try:
        with create_app_session(
                input=pipe_input,
                output=DummyOutput(),
        ):
            yield pipe_input
    finally:
        pipe_input.close()
Пример #10
0
def mock_app(mocker):
    app = Application(
        input=create_pipe_input(),
        output=DummyOutput(),
    )
    mocker.patch('upsies.uis.tui.tui.TUI._make_app', Mock(return_value=app))
    mocker.patch('upsies.uis.tui.tui.TUI._jobs_container',
                 Mock(children=[]),
                 create=True)
    mocker.patch('upsies.uis.tui.tui.TUI._layout', Mock(), create=True)
Пример #11
0
def prompt(monkeypatch):
    monkeypatch.setattr('getpass.getpass', lambda _: 'mock_password')
    pipe = create_pipe_input()
    try:
        session = PromptSession(
            input=pipe,
            output=DummyOutput(),
        )
        yield Prompt(session, pipe)
    finally:
        pipe.close()
Пример #12
0
def ptk_shell(xonsh_execer):
    from prompt_toolkit.input import create_pipe_input
    from prompt_toolkit.output import DummyOutput
    from xonsh.ptk_shell.shell import PromptToolkitShell

    inp = create_pipe_input()
    out = DummyOutput()
    shell = PromptToolkitShell(
        execer=xonsh_execer, ctx={}, ptk_args={"input": inp, "output": out}
    )
    yield inp, out, shell
    inp.close()
Пример #13
0
    def test_completer(self):
        text = 'server \t\r'

        inp = create_pipe_input()

        try:
            inp.send_text(text)
            session = PromptSession(
                input=inp,
                output=DummyOutput(),
                editing_mode=EditingMode.VI,
                completer=DshellCompleter.from_nested_dict(nested_dict))

            result = session.prompt()
        finally:
            inp.close()
Пример #14
0
    def __init__(self,
                 get_globals: _GetNamespace,
                 get_locals: Optional[_GetNamespace] = None) -> None:
        self._chan = None

        def _globals() -> dict:
            data = get_globals()
            data.setdefault("print", self._print)
            return data

        # PipInput object, for sending input in the CLI.
        # (This is something that we can use in the prompt_toolkit event loop,
        # but still write date in manually.)
        self._input_pipe = create_pipe_input()

        # Output object. Don't render to the real stdout, but write everything
        # in the SSH channel.
        class Stdout:
            def write(s, data: str) -> None:
                if self._chan is not None:
                    data = data.replace("\n", "\r\n")
                    self._chan.write(data)

            def flush(s) -> None:
                pass

        self.repl = PythonRepl(
            get_globals=_globals,
            get_locals=get_locals or _globals,
            input=self._input_pipe,
            output=Vt100_Output(cast(TextIO, Stdout()), self._get_size),
        )

        # Disable open-in-editor and system prompt. Because it would run and
        # display these commands on the server side, rather than in the SSH
        # client.
        self.repl.enable_open_in_editor = False
        self.repl.enable_system_bindings = False
Пример #15
0
        async def run() -> None:
            try:
                with create_pipe_input() as vt100_input:
                    connection = TelnetConnection(
                        conn,
                        addr,
                        self.interact,
                        self,
                        encoding=self.encoding,
                        style=self.style,
                        vt100_input=vt100_input,
                    )
                    self.connections.add(connection)

                    logger.info("Starting interaction %r %r", *addr)
                    try:
                        await connection.run_application()
                    finally:
                        self.connections.remove(connection)
                        logger.info("Stopping interaction %r %r", *addr)
            except EOFError:
                # Happens either when the connection is closed by the client
                # (e.g., when the user types 'control-]', then 'quit' in the
                # telnet client) or when the user types control-d in a prompt
                # and this is not handled by the interact function.
                logger.info("Unhandled EOFError in telnet application.")
            except KeyboardInterrupt:
                # Unhandled control-c propagated by a prompt.
                logger.info(
                    "Unhandled KeyboardInterrupt in telnet application.")
            except BaseException as e:
                print("Got %s" % type(e).__name__, e)
                import traceback

                traceback.print_exc()
            finally:
                self._application_tasks.remove(task)
Пример #16
0
def _feed_cli_with_input(
    text,
    editing_mode=None,
    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()
Пример #17
0
    def __init__(
        self, interact: Callable[["PromptToolkitSSHSession"],
                                 Awaitable[None]]) -> None:
        self.interact = interact
        self.interact_task: Optional[asyncio.Task[None]] = None
        self._chan: Optional[Any] = None
        self.app_session: Optional[AppSession] = None

        # PipInput object, for sending input in the CLI.
        # (This is something that we can use in the prompt_toolkit event loop,
        # but still write date in manually.)
        self._input = create_pipe_input()
        self._output: Optional[Vt100_Output] = None

        # Output object. Don't render to the real stdout, but write everything
        # in the SSH channel.
        class Stdout:
            def write(s, data: str) -> None:
                try:
                    if self._chan is not None:
                        self._chan.write(data.replace("\n", "\r\n"))
                except BrokenPipeError:
                    pass  # Channel not open for sending.

            def isatty(s) -> bool:
                return True

            def flush(s) -> None:
                pass

            @property
            def encoding(s) -> str:
                assert self._chan is not None
                return str(self._chan._orig_chan.get_encoding()[0])

        self.stdout = cast(TextIO, Stdout())
Пример #18
0
 def setUp(self):
     self.inp = create_pipe_input()
Пример #19
0
 def _enter_tree(self):
     self.input = create_pipe_input()