| 675 | |
| 676 | |
| 677 | class ShellWebSocketClient(SSLEnabledWebSocketBaseClient): |
| 678 | |
| 679 | def __init__(self, state, output, *args, **kwargs): |
| 680 | """Constructor. |
| 681 | |
| 682 | Args: |
| 683 | output: output file object. |
| 684 | """ |
| 685 | super().__init__(state, *args, **kwargs) |
| 686 | self._output = output |
| 687 | self._input_thread = threading.Thread(target=self._FeedInput) |
| 688 | self._stop = threading.Event() |
| 689 | |
| 690 | def handshake_ok(self): |
| 691 | pass |
| 692 | |
| 693 | def _FeedInput(self): |
| 694 | try: |
| 695 | while True: |
| 696 | rd, unused_w, unused_x = select.select([sys.stdin], [], [], 0.5) |
| 697 | if self._stop.is_set(): |
| 698 | break |
| 699 | |
| 700 | if sys.stdin in rd: |
| 701 | data = sys.stdin.buffer.read() |
| 702 | if not data: |
| 703 | self.send(json.dumps({'type': 'stdin_close'})) |
| 704 | break |
| 705 | self.send(data, binary=True) |
| 706 | except (KeyboardInterrupt, RuntimeError): |
| 707 | pass |
| 708 | |
| 709 | def opened(self): |
| 710 | self._input_thread.start() |
| 711 | |
| 712 | def closed(self, code, reason=None): |
| 713 | self._stop.set() |
| 714 | self._input_thread.join() |
| 715 | |
| 716 | def received_message(self, message): |
| 717 | if message.is_binary: |
| 718 | self._output.write(message.data) |
| 719 | self._output.flush() |
| 720 | |
| 721 | |
| 722 | class PersistentShellWebSocketClient(SSLEnabledWebSocketBaseClient): |
no outgoing calls
no test coverage detected