Пример #1
0
class Command(Component):

    channel = "cmd"

    def __init__(self, request, response, command, channel=channel):
        super(Command, self).__init__(channel=channel)

        self._request = request
        self._response = response
        self._command = command

        self._state = BUFFERING
        self._buffer = None

        self._p = Popen(
            command, shell=True, stdout=PIPE, stderr=PIPE,
            close_fds=True, preexec_fn=os.setsid
        )

        self._stdin = None
        if self._p.stdin is not None:
            self._stdin = File(self._p.stdin, channel="%s.stdin" % channel)
            self._stdin.register(self)

        self._stdout = File(self._p.stdout, channel="%s.stdout" % channel)
        self.addHandler(
            handler("eof", channel="%s.stdout" % channel)(self._on_stdout_eof)
        )
        self.addHandler(
            handler("read", channel="%s.stdout" % channel)(
                self._on_stdout_read
            )
        )
        self._stdout.register(self)

    @handler("disconnect", channel="web")
    def disconnect(self, sock):
        if sock == self._request.sock:
            self.fire(kill(), self)

    @handler("response", channel="web", priority=-1)
    def response(self, response):
        if response == self._response:
            self._state = STREAMING

    def kill(self):
        os.killpg(self._p.pid, signal.SIGINT)
        self.unregister()

    def input(self, data):
        if self._stdin is not None:
            self.fire(write(data), self._stdin)

    @staticmethod
    def _on_stdout_eof(self):
        if self._buffer is not None:
            self._buffer.flush()
            data = self._buffer.getvalue()
            self.fire(stream(self._response, data), "web")
        self.fire(stream(self._response, None), "web")
        self.fire(kill())

    @staticmethod
    def _on_stdout_read(self, data):
        if self._state == BUFFERING:
            if self._buffer is None:
                self._buffer = StringIO()
            self._buffer.write(data)
        elif self._state == STREAMING:
            if self._buffer is not None:
                self._buffer.write(data)
                self._buffer.flush()
                data = self._buffer.getvalue()
                self._buffer = None
                self.fire(stream(self._response, data), "web")
            else:
                self.fire(stream(self._response, data), "web")
Пример #2
0
class Command(Component):

    channel = "cmd"

    def __init__(self, request, response, command, channel=channel):
        super(Command, self).__init__(channel=channel)

        self._request = request
        self._response = response
        self._command = command

        self._state = BUFFERING
        self._buffer = None

        self._p = Popen(
            command, shell=True, stdout=PIPE, stderr=PIPE,
            close_fds=True, preexec_fn=os.setsid
        )

        self._stdin = None
        if self._p.stdin is not None:
            self._stdin = File(self._p.stdin, channel="%s.stdin" % channel)
            self._stdin.register(self)

        self._stdout = File(self._p.stdout, channel="%s.stdout" % channel)
        self.addHandler(
            handler("eof", channel="%s.stdout" % channel)(self._on_stdout_eof)
        )
        self.addHandler(
            handler("read", channel="%s.stdout" % channel)(
                self._on_stdout_read
            )
        )
        self._stdout.register(self)

    @handler("disconnect", channel="web")
    def disconnect(self, sock):
        if sock == self._request.sock:
            self.fire(kill(), self)

    @handler("response", channel="web", priority=-1)
    def response(self, response):
        if response == self._response:
            self._state = STREAMING

    def kill(self):
        os.killpg(self._p.pid, signal.SIGINT)
        self.unregister()

    def input(self, data):
        if self._stdin is not None:
            self.fire(write(data), self._stdin)

    @staticmethod
    def _on_stdout_eof(self):
        if self._buffer is not None:
            self._buffer.flush()
            data = self._buffer.getvalue()
            self.fire(stream(self._response, data), "web")
        self.fire(stream(self._response, None), "web")
        self.fire(kill())

    @staticmethod
    def _on_stdout_read(self, data):
        if self._state == BUFFERING:
            if self._buffer is None:
                self._buffer = StringIO()
            self._buffer.write(data)
        elif self._state == STREAMING:
            if self._buffer is not None:
                self._buffer.write(data)
                self._buffer.flush()
                data = self._buffer.getvalue()
                self._buffer = None
                self.fire(stream(self._response, data), "web")
            else:
                self.fire(stream(self._response, data), "web")