Пример #1
0
        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()
Пример #2
0
        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))
Пример #3
0
    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)
Пример #4
0
 def run_async():
     with self._auto_refresh_context():
         try:
             self.default_buffer.reset(Document(self.default))
             result = yield From(self.app.run_async())
             raise Return(result)
         finally:
             restore()
Пример #5
0
            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...'))
Пример #6
0
 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)
Пример #7
0
 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)
Пример #8
0
def _do_wait_for_enter(wait_text):
    """
    Create a sub application to wait for the enter key press.
    This has two advantages over using 'input'/'raw_input':
    - This will share the same input/output I/O.
    - This doesn't block the event loop.
    """
    from polymorph.deps.prompt_toolkit.shortcuts import PromptSession

    key_bindings = KeyBindings()

    @key_bindings.add('enter')
    def _(event):
        event.app.exit()

    @key_bindings.add(Keys.Any)
    def _(event):
        " Disallow typing. "
        pass

    session = PromptSession(message=wait_text, key_bindings=key_bindings)
    yield From(session.app.run_async())
Пример #9
0
        def _run_async():
            " Coroutine. "
            loop = get_event_loop()
            f = loop.create_future()
            self.future = f  # XXX: make sure to set this before calling '_redraw'.

            # Counter for cancelling 'flush' timeouts. Every time when a key is
            # pressed, we start a 'flush' timer for flushing our escape key. But
            # when any subsequent input is received, a new timer is started and
            # the current timer will be ignored.
            flush_counter = [0]  # Non local.

            # Reset.
            self.reset()
            self._pre_run(pre_run)

            # Feed type ahead input first.
            self.key_processor.feed_multiple(get_typeahead(self.input))
            self.key_processor.process_keys()

            def read_from_input():
                # Ignore when we aren't running anymore. This callback will
                # removed from the loop next time. (It could be that it was
                # still in the 'tasks' list of the loop.)
                # Except: if we need to process incoming CPRs.
                if not self._is_running and not self.renderer.waiting_for_cpr:
                    return

                # Get keys from the input object.
                keys = self.input.read_keys()

                # Feed to key processor.
                self.key_processor.feed_multiple(keys)
                self.key_processor.process_keys()

                # Quit when the input stream was closed.
                if self.input.closed:
                    f.set_exception(EOFError)
                else:
                    # Increase this flush counter.
                    flush_counter[0] += 1
                    counter = flush_counter[0]

                    # Automatically flush keys.
                    # (_daemon needs to be set, otherwise, this will hang the
                    # application for .5 seconds before exiting.)
                    run_in_executor(lambda: auto_flush_input(counter),
                                    _daemon=True)

            def auto_flush_input(counter):
                # Flush input after timeout.
                # (Used for flushing the enter key.)
                time.sleep(self.ttimeoutlen)

                if flush_counter[0] == counter:
                    call_from_executor(flush_input)

            def flush_input():
                if not self.is_done:
                    # Get keys, and feed to key processor.
                    keys = self.input.flush_keys()
                    self.key_processor.feed_multiple(keys)
                    self.key_processor.process_keys()

                    if self.input.closed:
                        f.set_exception(EOFError)

            # Enter raw mode.
            with self.input.raw_mode():
                with self.input.attach(read_from_input):
                    # Draw UI.
                    self._request_absolute_cursor_position()
                    self._redraw()

                    has_sigwinch = hasattr(signal,
                                           'SIGWINCH') and in_main_thread()
                    if has_sigwinch:
                        previous_winch_handler = loop.add_signal_handler(
                            signal.SIGWINCH, self._on_resize)

                    # Wait for UI to finish.
                    try:
                        result = yield From(f)
                    finally:
                        # In any case, when the application finishes. (Successful,
                        # or because of an error.)
                        try:
                            self._redraw(render_as_done=True)
                        finally:
                            # _redraw has a good chance to fail if it calls widgets
                            # with bad code. Make sure to reset the renderer anyway.
                            self.renderer.reset()

                            # Unset `is_running`, this ensures that possibly
                            # scheduled draws won't paint during the following
                            # yield.
                            self._is_running = False

                            # Wait for CPR responses.
                            if self.input.responds_to_cpr:
                                yield From(
                                    self.renderer.wait_for_cpr_responses())

                            if has_sigwinch:
                                loop.add_signal_handler(
                                    signal.SIGWINCH, previous_winch_handler)

                            # Wait for the run-in-terminals to terminate.
                            previous_run_in_terminal_f = self._running_in_terminal_f

                            if previous_run_in_terminal_f:
                                yield From(previous_run_in_terminal_f)

                            # Store unprocessed input as typeahead for next time.
                            store_typeahead(self.input,
                                            self.key_processor.empty_queue())

                raise Return(result)
Пример #10
0
 def wait_for_responses():
     for response_f in cpr_futures:
         yield From(response_f)
     if not f.done():
         f.set_result(None)