예제 #1
0
파일: termsess.py 프로젝트: Zekka/webterm
    def start(self, evtcallback, cursorcallback):
        """
        Launches the TerminalSession's process and adds to it the given
        callback to deal with modified lines.

        The callback takes the form callback(line_number, line).
        """
        if self.running:
            raise SessionStateError("TerminalSession already running")

        self.running = True

        self.stream = pyte.ByteStream()
        self.screen = pyte.DiffScreen(self.params["cols"], self.params["rows"])
        # self.screen.set_mode(pyte.modes.LNM) # This treats \ns as \r\ns.
        # Is this necessary/reasonable?
        self.stream.attach(self.screen)

        child_pid, self.child_fd = pty.fork()

        os.chdir(self.working_dir)
        os.environ['HOME'] = self.home_dir
        if not child_pid:  # under what circumstances would it not be 0?
            os.execv(self.cmd, self.args)

        attr = termios.tcgetattr(self.child_fd)
        attr[3] = attr[3] & ~termios.ECHO  # Disable echoing
        termios.tcsetattr(self.child_fd, termios.TCSANOW, attr)

        winsize = struct.pack("HHHH", self.params["rows"], self.params["cols"],
                              0, 0)
        fcntl.ioctl(self.child_fd, termios.TIOCSWINSZ, winsize)  # set size

        self.callback = evtcallback
        self.cursor_callback = cursorcallback
예제 #2
0
 def __init__(self, columns, lines, p_in):
     self.screen = pyte.DiffScreen(columns, lines)
     self.screen.set_mode(pyte.modes.LNM)
     self.screen.write_process_input = \
         lambda data: p_in.write(data.encode())
     self.stream = pyte.ByteStream()
     self.stream.attach(self.screen)
예제 #3
0
    def __init__(self,
                 manager=None,
                 id=None,
                 command=None,
                 autoclose=False,
                 autoclose_retain=5):
        self.width = 80
        self.height = 25
        self.id = id
        self.manager = manager
        self.autoclose = autoclose
        self.autoclose_retain = autoclose_retain
        self.output = BroadcastQueue()

        env = {}
        env.update(os.environ)
        env['TERM'] = 'linux'
        env['COLUMNS'] = str(self.width)
        env['LINES'] = str(self.height)
        env['LC_ALL'] = 'en_US.UTF8'

        self.command = command
        if not self.command:
            shell = os.environ.get('SHELL', None)
            if not shell:
                for sh in ['zsh', 'bash', 'sh']:
                    try:
                        shell = subprocess.check_output(['which', sh])
                        break
                    except:
                        pass
            self.command = shell

        args = ['sh', '-c', self.command]
        exe = 'sh'

        logging.info('Activating new terminal: %s', self.command)

        self.pid, self.fd = pty.fork()
        if self.pid == 0:
            setproctitle.setproctitle('%s terminal session #%i' %
                                      (sys.argv[0], os.getpid()))
            os.execvpe(exe, args, env)

        logging.info('Subprocess PID %s', self.pid)

        self.dead = False

        fl = fcntl.fcntl(self.fd, fcntl.F_GETFL)
        fcntl.fcntl(self.fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

        self.stream_in = os.fdopen(self.fd, 'rb', 0)
        self.stream_out = os.fdopen(self.fd, 'wb', 0)
        self.pyte_stream = pyte.Stream()
        self.screen = pyte.DiffScreen(self.width, self.height)
        self.pyte_stream.attach(self.screen)

        self.last_cursor_position = None

        self.reader = gevent.spawn(self.reader_fn)
예제 #4
0
파일: test_diff.py 프로젝트: zed/pyte
def test_mark_whole_screen():
    # .. this is straightforward -- make sure we have a dirty attribute
    # and whole screen is marked as dirty on initialization, reset,
    # resize etc.
    screen = pyte.DiffScreen(80, 24)

    # a) init.
    assert hasattr(screen, "dirty")
    assert isinstance(screen.dirty, set)
    assert screen.dirty == set(range(screen.lines))

    # b) reset().
    screen.dirty.clear()
    screen.reset()
    assert screen.dirty == set(range(screen.lines))

    # c) resize().
    screen.dirty.clear()
    screen.resize(130, 24)
    assert screen.dirty == set(range(screen.lines))

    # d) alignment_display().
    screen.dirty.clear()
    screen.alignment_display()
    assert screen.dirty == set(range(screen.lines))
예제 #5
0
    def __init__(self, command=None, autoclose=False, **kwargs):
        self.protocol = None
        self.width = 160
        self.height = 35
        self.autoclose = autoclose

        env = {}
        env.update(os.environ)
        env['TERM'] = 'linux'
        env['COLUMNS'] = str(self.width)
        env['LINES'] = str(self.height)
        env['LC_ALL'] = 'en_US.UTF8'

        shell = os.environ.get('SHELL', None)
        if not shell:
            for sh in ['zsh', 'bash', 'sh']:
                try:
                    shell = subprocess.check_output(['which', sh])
                    break
                except:
                    pass
        command = ['sh', '-c', command or shell]

        logging.info('Terminal: %s' % command)

        pid, master = pty.fork()
        if pid == 0:
            os.execvpe('sh', command, env)

        self.screen = pyte.DiffScreen(self.width, self.height)
        self.protocol = PTYProtocol(pid, master, self.screen, **kwargs)
예제 #6
0
    def __init__(self, command=None, autoclose=False):
        self.protocol = None
        self.width = 160
        self.height = 35
        self.autoclose = autoclose

        env = {}
        env.update(os.environ)
        env['TERM'] = 'linux'
        env['COLUMNS'] = str(self.width)
        env['LINES'] = str(self.height)
        env['LC_ALL'] = 'en_US.UTF8'

        command = command or 'sh -c \"$SHELL\"',
        pid, master = pty.fork()
        if pid == 0:
            p = sp.Popen(
                command,
                shell=True,
                stdin=None,
                stdout=None,
                stderr=None,
                close_fds=True,
                env=env,
            )
            p.wait()
            ajenti.exit()
            return
        self.screen = pyte.DiffScreen(self.width, self.height)
        self.protocol = PTYProtocol(pid, master, self.screen)
예제 #7
0
파일: test_diff.py 프로젝트: zed/pyte
def test_insert_delete_lines():
    screen = pyte.DiffScreen(80, 24)
    screen.cursor_to_line(screen.lines // 2)

    for method in ["insert_lines", "delete_lines"]:
        screen.dirty.clear()
        getattr(screen, method)()
        assert screen.dirty == set(range(screen.cursor.y, screen.lines))
예제 #8
0
파일: test_diff.py 프로젝트: zed/pyte
def test_modes():
    # Making sure `DECSCNM` triggers a screen to be fully re-drawn.
    screen = pyte.DiffScreen(80, 24)

    screen.dirty.clear()
    screen.set_mode(mo.DECSCNM >> 5, private=True)
    assert screen.dirty == set(range(screen.lines))

    screen.dirty.clear()
    screen.reset_mode(mo.DECSCNM >> 5, private=True)
    assert screen.dirty == set(range(screen.lines))
예제 #9
0
파일: test_diff.py 프로젝트: zed/pyte
def test_index():
    screen = pyte.DiffScreen(80, 24)
    screen.dirty.clear()

    # a) not at the bottom margin -- nothing is marked dirty.
    screen.index()
    assert not screen.dirty

    # b) whole screen is dirty.
    screen.cursor_to_line(24)
    screen.index()
    assert screen.dirty == set(range(screen.lines))
예제 #10
0
파일: test_diff.py 프로젝트: zed/pyte
def test_reverse_index():
    screen = pyte.DiffScreen(80, 24)
    screen.dirty.clear()

    # a) not at the top margin -- whole screen is dirty.
    screen.reverse_index()
    assert screen.dirty == set(range(screen.lines))

    # b) nothing is marked dirty.
    screen.dirty.clear()
    screen.cursor_to_line(screen.lines // 2)
    screen.reverse_index()
    assert not screen.dirty
예제 #11
0
    def __init__(self, proc, stream):
        self.data = ''
        self.proc = proc
        self.master = stream

        fd = self.master
        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

        self.mstream = os.fdopen(self.master, 'r+')
        gevent.sleep(2)
        self.term = pyte.DiffScreen(TERM_W, TERM_H)
        self.stream = pyte.Stream()
        self.stream.attach(self.term)
        self.data = ''
        self.unblock()
예제 #12
0
파일: test_diff.py 프로젝트: zed/pyte
def test_draw_wrap():
    screen = pyte.DiffScreen(80, 24)
    screen.set_mode(mo.DECAWM)

    # fill every character cell on the first row
    for _ in range(80):
        screen.draw("g")
    assert screen.cursor.y == 0
    screen.dirty.clear()

    # now write one more character which should cause wrapping
    screen.draw("h")
    assert screen.cursor.y == 1
    # regression test issue #36 where the wrong line was marked as
    # dirty
    assert screen.dirty == set([0, 1])
예제 #13
0
def test_erase_in_display():
    screen = pyte.DiffScreen(80, 24)
    screen.cursor_to_line(screen.lines // 2)

    # a) from cursor to the end of the screen.
    screen.dirty.clear()
    screen.erase_in_display()
    assert screen.dirty == set(range(screen.cursor.y, screen.lines))

    # b) from the begining of the screen to cursor.
    screen.dirty.clear()
    screen.erase_in_display(1)
    assert screen.dirty == set(range(0, screen.cursor.y + 1))

    # c) whole screen.
    screen.dirty.clear()
    screen.erase_in_display(2)
    assert screen.dirty == set(range(0, screen.lines))
예제 #14
0
파일: test_diff.py 프로젝트: zed/pyte
def test_mark_single_line():
    screen = pyte.DiffScreen(80, 24)

    # a) draw().
    screen.dirty.clear()
    screen.draw("f")
    assert len(screen.dirty) == 1
    assert screen.cursor.y in screen.dirty

    # b) rest ...
    for method in [
            "insert_characters", "delete_characters", "erase_characters",
            "erase_in_line"
    ]:
        screen.dirty.clear()
        getattr(screen, method)()
        assert len(screen.dirty) == 1
        assert screen.cursor.y in screen.dirty
예제 #15
0
    def __init__(self, command=None, autoclose=False, **kwargs):
        self.protocol = None
        self.width = 160
        self.height = 35
        self.autoclose = autoclose

        env = {}
        env.update(os.environ)
        env['TERM'] = 'linux'
        env['COLUMNS'] = str(self.width)
        env['LINES'] = str(self.height)
        env['LC_ALL'] = 'en_US.UTF8'

        command = ['sh', '-c', command or 'sh']

        pid, master = pty.fork()
        if pid == 0:
            os.execvpe('sh', command, env)

        self.screen = pyte.DiffScreen(self.width, self.height)
        self.protocol = PTYProtocol(pid, master, self.screen, **kwargs)
예제 #16
0
    def __call__(self, window):
        # Don't wait for input when calling getch.
        window.nodelay(1)
        # Don't interpret escape sequences, we want to send them on.
        window.keypad(0)
        self.window = window

        # Set up terminal
        y, x = window.getmaxyx()
        self.screen = pyte.DiffScreen(x - 1, y)
        self.screen_stream = pyte.ByteStream()
        self.screen_stream.attach(self.screen)
        window.addstr(
            0, 0, "Welcome to uterm. If a program is running you'll "
            "want to hit ctrl-c.")
        window.move(1, 0)

        while self.running:
            try:
                self.loop()
            except KeyboardInterrupt:
                if not self.accept_input:
                    raise
                self.tx(b'\x03')
예제 #17
0
파일: terminal.py 프로젝트: Mu-L/ajenti
    def __init__(self,
                 manager=None,
                 id=None,
                 command=None,
                 autoclose=False,
                 autoclose_retain=5,
                 redirect=None):
        """
        Setup the environment for a new terminal.

        :param manager: TerminalManager object
        :type manager: TerminalManager
        :param id: Id fo the terminal
        :type id: hex
        :param command: Command to run
        :type command: string
        :param autoclose: Parameter to close the terminal after the command
        :type autoclose: bool
        :param autoclose_retain: Time to wait before closing in seconds
        :type autoclose_retain: integer
        :param redirect: Default redirect URL after closing
        :type redirect: string
        """

        self.width = 80
        self.height = 25
        self.id = id
        self.manager = manager
        self.autoclose = autoclose
        self.autoclose_retain = autoclose_retain
        if redirect:
            self.redirect = redirect
        else:
            self.redirect = '/view/terminal'
        self.output = BroadcastQueue()

        env = {}
        env.update(os.environ)
        env['TERM'] = 'linux'
        env['COLUMNS'] = str(self.width)
        env['LINES'] = str(self.height)
        env['LC_ALL'] = 'en_US.UTF8'

        self.command = command
        if not self.command:
            shell = os.environ.get('SHELL', None)
            if not shell:
                for sh in ['zsh', 'bash', 'sh']:
                    try:
                        shell = subprocess.check_output(['which', sh])
                        break
                    except Exception as e:
                        pass
            self.command = shell

        args = ['sh', '-c', self.command]
        exe = 'sh'

        logging.info(f'Activating new terminal: {self.command}')

        self.pid, self.fd = pty.fork()
        if self.pid == 0:
            setproctitle.setproctitle(
                f'{sys.argv[0]} terminal session #{os.getpid():d}')
            os.execvpe(exe, args, env)

        logging.info(f'Subprocess PID {self.pid}')

        self.dead = False

        fl = fcntl.fcntl(self.fd, fcntl.F_GETFL)
        fcntl.fcntl(self.fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

        self.stream_in = os.fdopen(self.fd, 'rb', 0)
        self.stream_out = os.fdopen(self.fd, 'wb', 0)
        self.pyte_stream = pyte.Stream()
        self.screen = pyte.DiffScreen(self.width, self.height)
        self.pyte_stream.attach(self.screen)

        self.last_cursor_position = None

        self.reader = gevent.spawn(self.reader_fn)
예제 #18
0
 def __init__(self, columns, lines):
     self.screen = pyte.DiffScreen(columns, lines)
     self.stream = pyte.ByteStream()
     self.stream.attach(self.screen)