Exemplo n.º 1
0
    def connected(self):
        # prompt_toolkit internally checks if it's on windows during output rendering but
        # we need to force that we use Vt100_Output not Win32_Output
        from prompt_toolkit import renderer
        renderer.is_windows = lambda: False

        def get_size():
            return self._size

        self._cli = CommandLineInterface(
            application=create_prompt_application(self._shell.prompt),
            eventloop=UnstoppableEventLoop(create_asyncio_eventloop(
                self._loop)),
            input=PatchedStdinInput(sys.stdin),
            output=Vt100_Output(self, get_size))

        self._cb = self._cli.create_eventloop_callbacks()
        self._inputstream = InputStream(self._cb.feed_key)
        # Taken from prompt_toolkit telnet server
        # https://github.com/jonathanslenders/python-prompt-toolkit/blob/99fa7fae61c9b4ed9767ead3b4f9b1318cfa875d/prompt_toolkit/contrib/telnet/server.py#L165
        self._cli._is_running = True

        if self._shell.welcome_message is not None:
            self.send(self._shell.welcome_message.encode())

        self._cli._redraw()
Exemplo n.º 2
0
    def create_output(stdout=None, true_color=False):
        """
        Return an :class:`~prompt_toolkit.output.Output` instance for the command
        line.
        :param true_color: When True, use 24bit colors instead of 256 colors.
            (`bool` or :class:`~prompt_toolkit.filters.SimpleFilter`.)

        Notes
        -----
        This method was forked from the mainline prompt-toolkit repo.
        Copyright (c) 2014, Jonathan Slenders, All rights reserved.
        This is deprecated and slated for removal after a prompt-toolkit
        v0.57+ release.
        """
        stdout = stdout or sys.__stdout__
        true_color = to_simple_filter(true_color)

        if is_windows():
            if is_conemu_ansi():
                return ConEmuOutput(stdout)
            else:
                return Win32Output(stdout)
        else:
            term = os.environ.get('TERM', '')
            if PY2:
                term = term.decode('utf-8')

            return Vt100_Output.from_pty(stdout,
                                         true_color=true_color)  #, term=term)
Exemplo n.º 3
0
    def create_output(stdout=None, true_color=False):
        """
        Return an :class:`~prompt_toolkit.output.Output` instance for the command
        line.
        :param true_color: When True, use 24bit colors instead of 256 colors.
            (`bool` or :class:`~prompt_toolkit.filters.SimpleFilter`.)

        Notes
        -----
        This method was forked from the mainline prompt-toolkit repo.
        Copyright (c) 2014, Jonathan Slenders, All rights reserved.
        This is deprecated and slated for removal after a prompt-toolkit
        v0.57+ release.
        """
        stdout = stdout or sys.__stdout__
        true_color = to_simple_filter(true_color)

        if is_windows():
            if is_conemu_ansi():
                return ConEmuOutput(stdout)
            else:
                return Win32Output(stdout)
        else:
            term = os.environ.get('TERM', '')
            if PY2:
                term = term.decode('utf-8')

            return Vt100_Output.from_pty(stdout, true_color=true_color)#, term=term)
Exemplo n.º 4
0
    def attach(self, detach_other_clients=False, true_color=False):
        """
        Attach client user interface.
        """
        assert isinstance(detach_other_clients, bool)
        assert isinstance(true_color, bool)

        self._send_size()
        self._send_packet(
            {
                "cmd": "start-gui",
                "detach-others": detach_other_clients,
                "true-color": true_color,
                "term": os.environ.get("TERM", ""),
                "data": "",
            }
        )

        with raw_mode(sys.stdin.fileno()):
            data_buffer = b""

            stdin_fd = sys.stdin.fileno()
            socket_fd = self.socket.fileno()
            current_timeout = INPUT_TIMEOUT  # Timeout, used to flush escape sequences.

            with call_on_sigwinch(self._send_size):
                while True:
                    r, w, x = _select([stdin_fd, socket_fd], [], [], current_timeout)

                    if socket_fd in r:
                        # Received packet from server.
                        data = self.socket.recv(1024)

                        if data == b"":
                            # End of file. Connection closed.
                            # Reset terminal
                            o = Vt100_Output.from_pty(sys.stdout)
                            o.quit_alternate_screen()
                            o.disable_mouse_support()
                            o.disable_bracketed_paste()
                            o.reset_attributes()
                            o.flush()
                            return
                        else:
                            data_buffer += data

                            while b"\0" in data_buffer:
                                pos = data_buffer.index(b"\0")
                                self._process(data_buffer[:pos])
                                data_buffer = data_buffer[pos + 1 :]

                    elif stdin_fd in r:
                        # Got user input.
                        self._process_stdin()
                        current_timeout = INPUT_TIMEOUT

                    else:
                        # Timeout. (Tell the server to flush the vt100 Escape.)
                        self._send_packet({"cmd": "flush-input"})
                        current_timeout = None
Exemplo n.º 5
0
    def attach(self, detach_other_clients=False, ansi_colors_only=False, true_color=False):
        """
        Attach client user interface.
        """
        assert isinstance(detach_other_clients, bool)
        assert isinstance(ansi_colors_only, bool)
        assert isinstance(true_color, bool)

        self._send_size()
        self._send_packet({
            'cmd': 'start-gui',
            'detach-others': detach_other_clients,
            'ansi-colors-only': ansi_colors_only,
            'true-color': true_color,
            'term': os.environ.get('TERM', ''),
            'data': ''
        })

        with raw_mode(sys.stdin.fileno()):
            data_buffer = b''

            stdin_fd = sys.stdin.fileno()
            socket_fd = self.socket.fileno()
            current_timeout = INPUT_TIMEOUT  # Timeout, used to flush escape sequences.

            with call_on_sigwinch(self._send_size):
                while True:
                    r = select_fds([stdin_fd, socket_fd], current_timeout)

                    if socket_fd in r:
                        # Received packet from server.
                        data = self.socket.recv(1024)

                        if data == b'':
                            # End of file. Connection closed.
                            # Reset terminal
                            o = Vt100_Output.from_pty(sys.stdout)
                            o.quit_alternate_screen()
                            o.disable_mouse_support()
                            o.disable_bracketed_paste()
                            o.reset_attributes()
                            o.flush()
                            return
                        else:
                            data_buffer += data

                            while b'\0' in data_buffer:
                                pos = data_buffer.index(b'\0')
                                self._process(data_buffer[:pos])
                                data_buffer = data_buffer[pos + 1:]

                    elif stdin_fd in r:
                        # Got user input.
                        self._process_stdin()
                        current_timeout = INPUT_TIMEOUT

                    else:
                        # Timeout. (Tell the server to flush the vt100 Escape.)
                        self._send_packet({'cmd': 'flush-input'})
                        current_timeout = None
Exemplo n.º 6
0
    def attach(self, detach_other_clients=False, true_color=False):
        """
        Attach client user interface.
        """
        assert isinstance(detach_other_clients, bool)
        assert isinstance(true_color, bool)

        self._send_size()
        self._send_packet({
            'cmd': 'start-gui',
            'detach-others': detach_other_clients,
            'true-color': true_color,
            'term': os.environ.get('TERM', ''),
            'data': ''
        })

        with raw_mode(sys.stdin.fileno()):
            data_buffer = b''

            stdin_fd = sys.stdin.fileno()
            socket_fd = self.socket.fileno()
            current_timeout = INPUT_TIMEOUT  # Timeout, used to flush escape sequences.

            with call_on_sigwinch(self._send_size):
                while True:
                    r, w, x = _select([stdin_fd, socket_fd], [], [],
                                      current_timeout)

                    if socket_fd in r:
                        # Received packet from server.
                        data = self.socket.recv(1024)

                        if data == b'':
                            # End of file. Connection closed.
                            # Reset terminal
                            o = Vt100_Output.from_pty(sys.stdout)
                            o.quit_alternate_screen()
                            o.disable_mouse_support()
                            o.disable_bracketed_paste()
                            o.reset_attributes()
                            o.flush()
                            return
                        else:
                            data_buffer += data

                            while b'\0' in data_buffer:
                                pos = data_buffer.index(b'\0')
                                self._process(data_buffer[:pos])
                                data_buffer = data_buffer[pos + 1:]

                    elif stdin_fd in r:
                        # Got user input.
                        self._process_stdin()
                        current_timeout = INPUT_TIMEOUT

                    else:
                        # Timeout. (Tell the server to flush the vt100 Escape.)
                        self._send_packet({'cmd': 'flush-input'})
                        current_timeout = None
Exemplo n.º 7
0
 def _create_cli(self, true_color=False):
     """
     Create CommandLineInterface for this client.
     Called when the client wants to attach the UI to the server.
     """
     output = Vt100_Output(_SocketStdout(self._send_packet),
                           lambda: self.size,
                           true_color=true_color)
     input = _ClientInput(self._send_packet)
     self.cli = self.pymux.create_cli(self, output, input)
Exemplo n.º 8
0
 def run_standalone(self, true_color=False):
     """
     Run pymux standalone, rather than using a client/server architecture.
     This is mainly useful for debugging.
     """
     self._runs_standalone = True
     cli = self.create_cli(connection=None,
                           output=Vt100_Output.from_pty(
                               sys.stdout, true_color=true_color))
     cli._is_running = False
     cli.run()
Exemplo n.º 9
0
 def run_standalone(self, true_color=False):
     """
     Run pymux standalone, rather than using a client/server architecture.
     This is mainly useful for debugging.
     """
     self._runs_standalone = True
     cli = self.create_cli(
         connection=None,
         output=Vt100_Output.from_pty(sys.stdout, true_color=true_color))
     cli._is_running = False
     cli.run()
Exemplo n.º 10
0
    def __init__(self, get_globals, get_locals=None):
        assert callable(get_globals)
        assert get_locals is None or callable(get_locals)

        self._chan = None

        def _globals():
            data = get_globals()
            data.setdefault('print', self._print)
            return data

        repl = PythonRepl(get_globals=_globals,
                          get_locals=get_locals or _globals)

        # 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.
        repl.enable_open_in_editor = False
        repl.enable_system_bindings = False

        # 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 = PipeInput()

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

            def flush(s):
                pass

        # Create command line interface.
        self.cli = CommandLineInterface(application=repl.create_application(),
                                        eventloop=create_asyncio_eventloop(),
                                        input=self._input_pipe,
                                        output=Vt100_Output(
                                            Stdout(), self._get_size))

        self._callbacks = self.cli.create_eventloop_callbacks()
Exemplo n.º 11
0
    def __init__(self, conn, addr, application, server, encoding):
        assert isinstance(addr, tuple)  # (addr, port) tuple
        assert isinstance(application, TelnetApplication)
        assert isinstance(server, TelnetServer)
        assert isinstance(encoding, text_type)  # e.g. 'utf-8'

        self.conn = conn
        self.addr = addr
        self.application = application
        self.closed = False
        self.handling_command = True
        self.server = server
        self.encoding = encoding
        self.callback = None  # Function that handles the CLI result.

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

        # Initialize.
        _initialize_telnet(conn)

        # 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)

        # Create an eventloop (adaptor) for the CommandLineInterface.
        self.eventloop = _TelnetEventLoopInterface(server)

        # Set default CommandLineInterface.
        self.set_application(create_prompt_application())

        # Call client_connected
        application.client_connected(self)

        # Draw for the first time.
        self.handling_command = False
        self.cli._redraw()