def run(): with context() as ctx_id: self._context_id = ctx_id # Set input/output for all application running in this context. set_default_input(self.vt100_input) set_default_output(self.vt100_output) # Add reader. loop = get_event_loop() loop.add_reader(self.conn, handle_incoming_data) try: obj = self.interact(self) if _is_coroutine(obj): # Got an asyncio coroutine. import asyncio f = asyncio.ensure_future(obj) yield From(Future.from_asyncio_future(f)) else: # Got a prompt_toolkit coroutine. yield From(obj) except Exception as e: print('Got %s' % type(e).__name__, e) import traceback traceback.print_exc() raise finally: self.close()
def coroutine(): listening_dialog = ListeningDialog(mic, recognizer) audio = yield From(show_dialog(listening_dialog)) tokens = recognize(vl_stub, vl_metadata, audio) possible_commands = home.match_command(tokens) text_area.text = ' '.join(tokens) text_area.text = str(home) if not possible_commands: err_msg = 'Unrecognized command: {}'.format(' '.join(tokens)) err_msg_dialog = MessageDialog(err_msg, 'Error') yield From(show_dialog(err_msg_dialog)) elif len(possible_commands) == 1 and possible_commands[0][0] == 0: [(_, _, action)] = possible_commands action() else: choice_dialog = ChoiceDialog( [cmd for _, cmd, _ in possible_commands[:3]]) choice = yield From(show_dialog(choice_dialog)) if choice is not None: _, _, action = possible_commands[choice] action() text_area.text = str(home)
def interact(connection): write = connection.send # When a client is connected, erase the screen from the client and say # Hello. clear() write('Welcome to our chat application!\n') write('All connected clients will receive what you say.\n') name = yield From(prompt(message='Type your name: ', async_=True)) # Random color. color = random.choice(COLORS) _connection_to_color[connection] = color # Send 'connected' message. _send_to_everyone(connection, name, '(connected)', color) # Prompt. prompt_msg = HTML('<reverse fg="{}">[{}]</reverse> > ').format( color, name) _connections.append(connection) try: # Set Application. while True: try: result = yield From(prompt(message=prompt_msg, async_=True)) _send_to_everyone(connection, name, result, color) except KeyboardInterrupt: pass except EOFError: _send_to_everyone(connection, name, '(leaving)', color) finally: _connections.remove(connection)
def loop_until_exit(self): completer = WordCompleter(self.command_parsers.keys()) self.prompt_enter() while True: try: # # TODO: Probably not needed, ultimately. # with patch_stdout(): # Show a prompt, and store the user's input once it's received. shell_input_raw = yield From(self.session.prompt( self.prompt_text, completer=completer, complete_style=CompleteStyle.READLINE_LIKE, async_=True )) # Tokenize the input shell_input_params = shell_input_raw.split() # If it's a blank line, ignore the input and prompt again. if not shell_input_raw: continue # Interpret the first token as the command, and the remainder as args. cmd = shell_input_params.pop(0) # Check whether the command is valid in this context. if cmd not in self.command_parsers: self.println('unknown command %s' % cmd) continue # Run the appropriate argparse on the command. try: args = self.command_parsers[cmd].parse_args(args=shell_input_params) except CommandParseFail as e: self.println(str(e)) continue # If we're here, the command `cmd` has been evaluated by the appropriate # argparse, so we know it's valid. The constructor has done the required # introspection and assertions to make sure that all the below derived # function names exist as methods on this class. So here we go! # TODO: Does the thing where it will accept a fragment break us here? cmd_method = getattr(self, '_do_%s' % cmd) # TODO TODO TODO horrible hack if cmd in ['access', 'enable']: yield From(cmd_method(args)) else: cmd_method(args) except EOFError: # An EOFError is raised when it's time to leave this level. break self.prompt_exit()
def read_message_bytes_from_pipe(pipe_handle): """ (coroutine) Read message from this pipe. Return bytes. """ overlapped = OVERLAPPED() overlapped.hEvent = create_event() try: buff = create_string_buffer(BUFSIZE + 1) c_read = DWORD() success = windll.kernel32.ReadFile(pipe_handle, buff, DWORD(BUFSIZE), byref(c_read), byref(overlapped)) if success: buff[c_read.value] = b'\0' raise Return(buff.value) error_code = windll.kernel32.GetLastError() if error_code == ERROR_IO_PENDING: yield From(wait_for_event(overlapped.hEvent)) success = windll.kernel32.GetOverlappedResult( pipe_handle, byref(overlapped), byref(c_read), BOOL(False)) if success: buff[c_read.value] = b'\0' raise Return(buff.value) else: error_code = windll.kernel32.GetLastError() if error_code == ERROR_BROKEN_PIPE: raise BrokenPipeError elif error_code == ERROR_MORE_DATA: more_data = yield From( read_message_bytes_from_pipe(pipe_handle)) raise Return(buff.value + more_data) else: raise Exception( 'reading overlapped IO failed. error_code=%r' % error_code) elif error_code == ERROR_BROKEN_PIPE: raise BrokenPipeError elif error_code == ERROR_MORE_DATA: more_data = yield From(read_message_bytes_from_pipe(pipe_handle)) raise Return(buff.value + more_data) else: raise Exception('Reading pipe failed, error_code=%s' % error_code) finally: windll.kernel32.CloseHandle(overlapped.hEvent)
def _async_generator(): " Simple asynchronous generator. " # await. result = yield From(Future.succeed(1)) # yield yield AsyncGeneratorItem(result + 1) # await. result = yield From(Future.succeed(10)) # yield yield AsyncGeneratorItem(result + 1)
def run(): # Try to use the same input/output file descriptors as the one, # used to run this application. try: input_fd = self.input.fileno() except AttributeError: input_fd = sys.stdin.fileno() try: output_fd = self.output.fileno() except AttributeError: output_fd = sys.stdout.fileno() # Run sub process. def run_command(): self.print_text(display_before_text) p = Popen(command, shell=True, stdin=input_fd, stdout=output_fd) p.wait() yield run_in_executor(run_command) # Wait for the user to press enter. if wait_for_enter: yield From(_do_wait_for_enter(wait_text))
def write_message_bytes_to_pipe(pipe_handle, data): overlapped = OVERLAPPED() overlapped.hEvent = create_event() try: c_written = DWORD() success = windll.kernel32.WriteFile(pipe_handle, create_string_buffer(data), len(data), byref(c_written), byref(overlapped)) if success: return error_code = windll.kernel32.GetLastError() if error_code == ERROR_IO_PENDING: yield From(wait_for_event(overlapped.hEvent)) success = windll.kernel32.GetOverlappedResult( pipe_handle, byref(overlapped), byref(c_written), BOOL(False)) if not success: error_code = windll.kernel32.GetLastError() if error_code == ERROR_BROKEN_PIPE: raise BrokenPipeError else: raise Exception( 'Writing overlapped IO failed. error_code=%r' % error_code) elif error_code == ERROR_BROKEN_PIPE: raise BrokenPipeError finally: windll.kernel32.CloseHandle(overlapped.hEvent)
def _start_reader(self): """ Read messages from the Win32 pipe server and handle them. """ while True: message = yield From(self.pipe.read_message()) self._process(message)
def _run_in_t(): " Coroutine. " # Wait for the previous `run_in_terminal` to finish. if previous_run_in_terminal_f is not None: yield previous_run_in_terminal_f # Draw interface in 'done' state, or erase. if render_cli_done: app._redraw(render_as_done=True) else: app.renderer.erase() # Disable rendering. app._running_in_terminal = True # Detach input. try: with app.input.detach(): with app.input.cooked_mode(): result = yield From(async_func()) raise Return(result) # Same as: "return result" finally: # Redraw interface again. try: app._running_in_terminal = False app.renderer.reset() app._request_absolute_cursor_position() app._redraw() finally: new_run_in_terminal_f.set_result(None)
def read_message(self): """ (coroutine) Read one single message from the pipe and return as text. """ message = yield From(read_message_from_pipe(self.pipe_handle)) raise Return(message)
def coroutine(): dialog = MessageDialog(title=title, text=text, ok_text=ok_text, width=width, wrap_lines=wrap_lines, scrollbar=scrollbar) yield From(show_dialog(dialog))
def run_async(): with self._auto_refresh_context(): try: self.default_buffer.reset(Document(self.default)) result = yield From(self.app.run_async(pre_run=pre_run)) raise Return(result) finally: restore()
def interact(connection): result = yield From( yes_no_dialog(title='Yes/no dialog demo', text='Press yes or no', async_=True)) connection.send('You said: {}\n'.format(result)) connection.send('Bye.\n')
def run(): def cleanup(): if orig_visual: os.environ['VISUAL'] = orig_visual else: del os.environ['VISUAL'] yield From(run_in_terminal(cleanup, in_executor=True))
def read_message_from_pipe(pipe_handle): """ (coroutine) Read message from this pipe. Return text. """ data = yield From(read_message_bytes_from_pipe(pipe_handle)) assert isinstance(data, bytes) raise Return(data.decode('utf-8', 'ignore'))
def print_exception(): # Print output. Similar to 'loop.default_exception_handler', # but don't use logger. (This works better on Python 2.) print('\nUnhandled exception in event loop:') print(formatted_tb) print('Exception %s' % (context.get('exception'), )) yield From(_do_wait_for_enter('Press ENTER to continue...'))
def run(): logger.info('Starting interaction %r %r', *addr) try: yield From(connection.run_application()) except Exception as e: print(e) finally: self.connections.remove(connection) logger.info('Stopping interaction %r %r', *addr)
def _run_async2(): self._is_running = True with set_app(self): try: f = From(_run_async()) result = yield f finally: assert not self._is_running raise Return(result)
def interact(connection): clear() connection.send('Welcome!\n') # Ask for input. result = yield From(prompt(message='Say something: ', async_=True)) # Send output. connection.send('You said: {}\n'.format(result)) connection.send('Bye.\n')
def coroutine(): dialog = YesNoDialog(title=title, text=text, yes_text=yes_text, no_text=no_text) result = yield From(show_dialog(dialog)) if result == True: yes_func() else: no_func()
def _do_access(self, args): if not self.enabled: self.println('ACCESS DENIED') return elif args.command == 'main' and args.subcommand == 'security' and args.node == 'grid': # ACCESS MAIN SECURITY GRID self.println('ok') yield From(GridPrompt(self.session).loop_until_exit()) else: # poop self.println("command not available")
def _async_reader(self): buffer_size = 65536 c_read = DWORD() buffer = ctypes.create_string_buffer(buffer_size + 1) while True: # Wait until `start_reading` is called. yield From(self._reading.wait()) # Call read. success = windll.kernel32.ReadFile(self.handle, buffer, DWORD(buffer_size), ctypes.byref(c_read), ctypes.byref(self._overlapped)) if success: buffer[c_read.value] = b'\0' self.read_callback(buffer.value.decode('utf-8', 'ignore')) else: error_code = windll.kernel32.GetLastError() # Pending I/O. Wait for it to finish. if error_code == ERROR_IO_PENDING: # Wait for event. yield From(self._wait_for_event()) # Get pending data. success = windll.kernel32.GetOverlappedResult( self.handle, ctypes.byref(self._overlapped), ctypes.byref(c_read), BOOL(False)) if success: buffer[c_read.value] = b'\0' self.read_callback( buffer.value.decode('utf-8', 'ignore')) elif error_code == ERROR_BROKEN_PIPE: self.stop_reading() self.done_callback() self.done = False return
def _handle_client(self): """ Coroutine that connects to a single client and handles that. """ while True: try: # Wait for connection. logger.info('Waiting for connection in pipe instance.') yield From(self._connect_client()) logger.info('Connected in pipe instance') conn = Win32PipeConnection(self) self.pipe_connection_cb(conn) yield From(conn.done_f) logger.info('Pipe instance done.') finally: # Disconnect and reconnect. logger.info('Disconnecting pipe instance.') windll.kernel32.DisconnectNamedPipe(self.pipe_handle)
def coroutine(): dialog = TextInputDialog(title='Go to line', label_text='Line number:') line_number = yield From(show_dialog_as_float(dialog)) try: line_number = int(line_number) except ValueError: show_message('Invalid line number') else: text_field.buffer.cursor_position = \ text_field.buffer.document.translate_row_col_to_index(line_number - 1, 0)
def launch_telnet_session(connection): print('Launching new session') try: session = PromptSession(output=connection.vt100_output, input=connection.vt100_input) yield From( BasePrompt(session, connection=connection).loop_until_exit()) except KeyboardInterrupt: pass except socket.error as e: print('Socket error %s. Shutting down session.' % e.errno) except: print('Other error. Shutting down session.')
def _run_async2(): self._is_running = True with set_app(self): try: f = From(_run_async()) result = yield f finally: # Set the `_is_running` flag to `False`. Normally this # happened already in the finally block in `run_async` # above, but in case of exceptions, that's not always the # case. self._is_running = False raise Return(result)
def _start_reading(self): while True: try: data = yield From(self.pipe_connection.read()) self._process(data) except BrokenPipeError: self.detach_and_close() break except Exception as e: import traceback traceback.print_stack() print('got exception ', repr(e)) break
def write(self, message): """ (coroutine) Write a single message into the pipe. """ if self.done_f.done(): raise BrokenPipeError try: yield From( write_message_to_pipe(self.pipe_instance.pipe_handle, message)) except BrokenPipeError: self.done_f.set_result(None) raise
def _run_in_t(): " Coroutine. " # Wait for the previous `run_in_terminal` to finish. if previous_run_in_terminal_f is not None: yield previous_run_in_terminal_f # Wait for all CPRs to arrive. We don't want to detach the input until # all cursor position responses have been arrived. Otherwise, the tty # will echo its input and can show stuff like ^[[39;1R. if app.input.responds_to_cpr: yield From(app.renderer.wait_for_cpr_responses()) # Draw interface in 'done' state, or erase. if render_cli_done: app._redraw(render_as_done=True) else: app.renderer.erase() # Disable rendering. app._running_in_terminal = True # Detach input. try: with app.input.detach(): with app.input.cooked_mode(): result = yield From(async_func()) raise Return(result) # Same as: "return result" finally: # Redraw interface again. try: app._running_in_terminal = False app.renderer.reset() app._request_absolute_cursor_position() app._redraw() finally: new_run_in_terminal_f.set_result(None)