Exemplo n.º 1
0
    def _accept(self):
        """
        Accept new incoming connection.
        """
        conn, addr = self._listen_socket.accept()
        logger.info('New connection %r %r', *addr)

        connection = TelnetConnection(conn,
                                      addr,
                                      self.interact,
                                      self,
                                      encoding=self.encoding,
                                      style=self.style)
        self.connections.add(connection)

        # Run application for this connection.
        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)

        ensure_future(run())
Exemplo n.º 2
0
def do_finish(*event):

    ok, show, item_id, job_id, due = dataview.maybe_finish(text_area.document.cursor_position_row)

    if not ok:
        return

    def coroutine():

        dialog = TextInputDialog(
            title='finish task/job',
            label_text=f"selected: {show}\ndatetime completed:")

        done_str = yield From(show_dialog_as_float(dialog))
        if done_str:
            try:
                done = parse_datetime(done_str)[1]
            except ValueError:
                show_message('Finish task/job?', 'Invalid finished datetime')
            else:
                # valid done
                item.finish_item(item_id, job_id, done, due)
                # dataview.itemcache[item.doc_id] = {}
                if item_id in dataview.itemcache:
                    del dataview.itemcache[item_id]
                loop = get_event_loop()
                loop.call_later(0, data_changed, loop)

    ensure_future(coroutine())
    def wait_for_cpr_responses(self, timeout=1):
        """
        Wait for a CPR response.
        """
        cpr_futures = list(self._waiting_for_cpr_futures)  # Make copy.

        # When there are no CPRs in the queue. Don't do anything.
        if not cpr_futures or self.cpr_support == CPR_Support.NOT_SUPPORTED:
            return Future.succeed(None)

        f = Future()

        # When a CPR has been received, set the result.
        def wait_for_responses():
            for response_f in cpr_futures:
                yield From(response_f)
            if not f.done():
                f.set_result(None)
        ensure_future(wait_for_responses())

        # Timeout.
        def wait_for_timeout():
            time.sleep(timeout)

            # Got timeout.
            if not f.done():
                self._waiting_for_cpr_futures = deque()
                f.set_result(None)

        t = threading.Thread(target=wait_for_timeout)
        t.daemon = True
        t.start()

        return f
Exemplo n.º 4
0
def do_import_file(*event):
    # TODO: add dialog
    msg = ""
    def coroutine():
        global msg
        dialog = TextInputDialog(
            title='import file',
            label_text="""\
It is possible to import data from files with 
one of the following extensions:
  .json  a json file exported from etm 3.2.x 
  .text  a text file with etm entries as lines 
  .ics   an iCalendar file
Enter the path of the file to import:""")

        file_path = yield From(show_dialog_as_float(dialog))

        if file_path:
            msg = import_file(file_path)
            if msg:
                dataview.refreshRelevant()
                dataview.refreshAgenda()
                dataview.refreshCurrent()
                loop = get_event_loop()
                loop.call_later(0, data_changed, loop)
                show_message('import file', msg)
    ensure_future(coroutine())
Exemplo n.º 5
0
def do_reschedule(*event):
    doc_id, instance, job = dataview.get_row_details(text_area.document.cursor_position_row)

    if not doc_id:
        return

    hsh = DBITEM.get(doc_id=doc_id)

    def coroutine():
        dialog = TextInputDialog(
            title='reschedule instance',
            label_text=f"selected: {hsh['itemtype']} {hsh['summary']}\ninstance: {format_datetime(instance)[1]}\n\nnew datetime:")

        new_datetime = yield From(show_dialog_as_float(dialog))

        if not new_datetime:
            return 
        changed = False
        ok, dt, z = parse_datetime(new_datetime)

        if ok:
            changed = item.reschedule(doc_id, instance, dt)
        else:
            show_message('new instance', f"'{new_datetime}' is invalid")

        if changed:
            if doc_id in dataview.itemcache:
                del dataview.itemcache[doc_id]
            application.layout.focus(text_area)
            set_text(dataview.show_active_view())
            loop = get_event_loop()
            loop.call_later(0, data_changed, loop)


    ensure_future(coroutine())
Exemplo n.º 6
0
    def wait_for_cpr_responses(self, timeout=1):
        """
        Wait for a CPR response.
        """
        cpr_futures = list(self._waiting_for_cpr_futures)  # Make copy.

        # When there are no CPRs in the queue. Don't do anything.
        if not cpr_futures or self.cpr_support == CPR_Support.NOT_SUPPORTED:
            return Future.succeed(None)

        f = Future()

        # When a CPR has been received, set the result.
        def wait_for_responses():
            for response_f in cpr_futures:
                yield From(response_f)
            if not f.done():
                f.set_result(None)

        ensure_future(wait_for_responses())

        # Timeout.
        def wait_for_timeout():
            time.sleep(timeout)

            # Got timeout.
            if not f.done():
                self._waiting_for_cpr_futures = deque()
                f.set_result(None)

        t = threading.Thread(target=wait_for_timeout)
        t.daemon = True
        t.start()

        return f
Exemplo n.º 7
0
    def __init__(self, pipe_name, read_callback, done_callback):
        self.pipe_name = pipe_name
        self.read_callback = read_callback
        self.done_callback = done_callback
        self.done = False

        self.handle = windll.kernel32.CreateFileW(pipe_name, GENERIC_READ, 0,
                                                  None, OPEN_EXISTING,
                                                  FILE_FLAG_OVERLAPPED, None)

        if self.handle == INVALID_HANDLE_VALUE:
            error_code = windll.kernel32.GetLastError()
            raise Exception('Invalid pipe handle. Error code=%r.' % error_code)

        # Create overlapped structure and event.
        self._overlapped = OVERLAPPED()
        self._event = windll.kernel32.CreateEventA(
            None,  # Default security attributes.
            BOOL(True),  # Manual reset event.
            BOOL(True),  # initial state = signaled.
            None  # Unnamed event object.
        )
        self._overlapped.hEvent = self._event

        self._reading = Event()

        # Start reader coroutine.
        ensure_future(self._async_reader())
Exemplo n.º 8
0
    def _(event):
        # match R behavior
        editor = roption("editor")
        if not editor or not isinstance(editor, text_type):
            if 'VISUAL' in os.environ:
                editor = os.environ['VISUAL']
            elif 'EDITOR' in os.environ:
                editor = os.environ['EDITOR']
            if not editor:
                editor = "vi"

        buff = event.current_buffer
        if editor:
            orig_visual = os.environ[
                'VISUAL'] if 'VISUAL' in os.environ else None
            os.environ['VISUAL'] = editor

        buff.open_in_editor()

        if editor:

            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))

            ensure_future(run())
Exemplo n.º 9
0
def do_maybe_cancel_timer(*event):
    if not dataview.timer_id:
        return
    item_id = dataview.timer_id
    job_id = dataview.timer_job
    hsh = DBITEM.get(doc_id=item_id)
    item_info = f"{hsh['itemtype']} {hsh['summary']}"

    stopped_timer = False
    now = pendulum.now()
    if dataview.timer_status == 1: #running
        time = dataview.timer_time + (now - dataview.timer_start)
    else:
        time = dataview.timer_time
    completed = pendulum.now()
    completed_str = format_datetime(completed)
    time_str = format_duration(time)

    def coroutine():
        dialog = ConfirmDialog("cancel timer", f"item: {item_info}\nelapsed time: {time_str}\n\nclose timer without recording?")
        record_cancel = yield From(show_dialog_as_float(dialog))
        if record_cancel:
            dataview.timer_clear()
            set_text(dataview.show_active_view())
            get_app().invalidate()

    ensure_future(coroutine())
Exemplo n.º 10
0
def do_maybe_record_timer(*event):
    if not dataview.timer_id:
        return
    item_id = dataview.timer_id
    job_id = dataview.timer_job
    hsh = DBITEM.get(doc_id=item_id)
    item_info = f"{hsh['itemtype']} {hsh['summary']}"

    now = pendulum.now()
    if dataview.timer_status == 1: #running
        time = dataview.timer_time + (now - dataview.timer_start)
    else:
        time = dataview.timer_time
    completed = pendulum.now()
    completed_str = format_datetime(completed)
    time_str = format_duration(time)

    def coroutine():
        dialog = ConfirmDialog("record time", f"item: {item_info}\nelapsed time: {time_str}\n\nrecord time and close timer?")
        record_close = yield From(show_dialog_as_float(dialog))
        if record_close:
            item.record_timer(item_id, job_id, completed, time)
            set_text(dataview.show_active_view())
            dataview.timer_clear()
            if item_id in dataview.itemcache:
                del dataview.itemcache[item_id]
            loop = get_event_loop()
            loop.call_later(0, data_changed, loop)

    ensure_future(coroutine())
Exemplo n.º 11
0
    def handler():
        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)

        ensure_future(coroutine())
Exemplo n.º 12
0
def run_coroutine_in_terminal(async_func, render_cli_done=False):
    """
    Suspend the current application and run this coroutine instead.
    `async_func` can be a coroutine or a function that returns a Future.

    :param async_func: A function that returns either a Future or coroutine
        when called.
    :returns: A `Future`.
    """
    assert callable(async_func)
    loop = get_event_loop()

    # Make sure to run this function in the current `Application`, or if no
    # application is active, run it normally.
    app = get_app(return_none=True)

    if app is None:
        return ensure_future(async_func())
    assert app._is_running

    # When a previous `run_in_terminal` call was in progress. Wait for that
    # to finish, before starting this one. Chain to previous call.
    previous_run_in_terminal_f = app._running_in_terminal_f
    new_run_in_terminal_f = loop.create_future()
    app._running_in_terminal_f = new_run_in_terminal_f

    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)

    return ensure_future(_run_in_t())
Exemplo n.º 13
0
def do_maybe_delete(*event):
    doc_id, instance, job = dataview.get_row_details(text_area.document.cursor_position_row)

    if not doc_id:
        return

    hsh = DBITEM.get(doc_id=doc_id)

    if not instance:
        # not repeating
        def coroutine():
            dialog = ConfirmDialog("Delete", 
                    f"Selected: {hsh['itemtype']} {hsh['summary']}\n\nAre you sure you want to delete this item?\nThis would remove the item from the database\nand cannot be undone.")

            delete = yield From(show_dialog_as_float(dialog))
            if delete:
                item.delete_item(doc_id)
                if doc_id in dataview.itemcache:
                    del dataview.itemcache[doc_id]
                application.layout.focus(text_area)
                set_text(dataview.show_active_view())
                loop = get_event_loop()
                loop.call_later(0, data_changed, loop)

        ensure_future(coroutine())

    if instance:
        # repeating
        def coroutine():

            # radios.current_value will contain the first component of the selected tuple 
            title = "Delete"
            text = f"Selected: {hsh['itemtype']} {hsh['summary']}\nInstance: {format_datetime(instance)[1]}\n\nDelete what?"
            values =[
                (0, 'just this instance'),
                (1, 'the item itself'),
            ]

            dialog = RadioListDialog(
                title=title,
                text=text,
                values=values)

            which = yield From(show_dialog_as_float(dialog))
            if which is not None:
                changed = item.delete_instances(doc_id, instance, which)
                if changed:
                    if doc_id in dataview.itemcache:
                        del dataview.itemcache[doc_id]
                    application.layout.focus(text_area)
                    set_text(dataview.show_active_view())
                    loop = get_event_loop()
                    loop.call_later(0, data_changed, loop)

        ensure_future(coroutine())
Exemplo n.º 14
0
def do_go_to_date(*event):
    def coroutine():
        dialog = TextInputDialog(
            title='Go to date',
            label_text='date:')

        target_date = yield From(show_dialog_as_float(dialog))

        try:
            dataview.dtYrWk(target_date)
        except ValueError:
            show_message('go to date', 'Invalid date')
        else:
            set_text(dataview.show_active_view())
    ensure_future(coroutine())
Exemplo n.º 15
0
def do_go_to():
    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)

    ensure_future(coroutine())
Exemplo n.º 16
0
def bind_and_listen_on_win32_socket(socket_name, accept_callback):
    """
    :param accept_callback: Called with `Win32PipeConnection` when a new
        connection is established.
    """
    assert callable(accept_callback)
    socket_name = r'\\.\pipe\pymux.sock.jonathan.42'

    pipes = [PipeInstance(socket_name, pipe_connection_cb=accept_callback)
             for i in range(INSTANCES)]

    for p in pipes:
        # Start pipe.
        ensure_future(p.handle_pipe())

    return socket_name
Exemplo n.º 17
0
def main():
    loop = get_event_loop()
    f = ensure_future(my_coroutine())

    # Run the event loop, until the coroutine is done.
    loop.run_until_complete(f)
    print(f.result())
def main():
    loop = get_event_loop()
    f = ensure_future(my_coroutine())

    # Run the event loop, until the coroutine is done.
    loop.run_until_complete(f)
    print(f.result())
Exemplo n.º 19
0
def save_before_quit(*event):
    def coroutine():
        dialog = ConfirmDialog("unsaved changes", "Save them before closing?")

        save_changes = yield From(show_dialog_as_float(dialog))
        if save_changes:
            if item.doc_id is not None:
                # del dataview.itemcache[item.doc_id]
                dataview.itemcache[item.doc_id] = {}
            dataview.is_editing = False
            application.layout.focus(text_area)
            set_text(dataview.show_active_view())
            loop = get_event_loop()
            loop.call_later(0, item_changed, loop)

    ensure_future(coroutine())
Exemplo n.º 20
0
    def _send_packet(self, data):
        """
        Send packet to client.
        """
        if self._closed:
            return

        data = json.dumps(data)

        def send():
            try:
                yield From(self.pipe_connection.write(data))
            except BrokenPipeError:
                self.detach_and_close()

        ensure_future(send())
Exemplo n.º 21
0
def do_go_to():
    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)

    ensure_future(coroutine())
Exemplo n.º 22
0
def bind_and_listen_on_win32_socket(socket_name, accept_callback):
    """
    :param accept_callback: Called with `Win32PipeConnection` when a new
        connection is established.
    """
    assert callable(accept_callback)
    socket_name = r'\\.\pipe\pymux.sock.jonathan.42'

    pipes = [
        PipeInstance(socket_name, pipe_connection_cb=accept_callback)
        for i in range(INSTANCES)
    ]

    for p in pipes:
        # Start pipe.
        ensure_future(p.handle_pipe())

    return socket_name
Exemplo n.º 23
0
def do_open_file():
    def coroutine():
        global current_path
        open_dialog = TextInputDialog(title='Open file',
                                      label_text='Enter the path of a file:',
                                      completer=PathCompleter())

        path = yield From(show_dialog_as_float(open_dialog))
        current_path = path

        if path is not None:
            try:
                with open(path, 'rb') as f:
                    text_field.text = f.read().decode('utf-8', errors='ignore')
            except IOError as e:
                show_message('Error', '{}'.format(e))

    ensure_future(coroutine())
Exemplo n.º 24
0
def do_open_file():
    def coroutine():
        global current_path
        open_dialog = TextInputDialog(
            title='Open file',
            label_text='Enter the path of a file:',
            completer=PathCompleter())

        path = yield From(show_dialog_as_float(open_dialog))
        current_path = path

        if path is not None:
            try:
                with open(path, 'rb') as f:
                    text_field.text = f.read().decode('utf-8', errors='ignore')
            except IOError as e:
                show_message('Error', '{}'.format(e))

    ensure_future(coroutine())
Exemplo n.º 25
0
def message_dialog(title='',
                   text='',
                   ok_text='Ok',
                   width=None,
                   wrap_lines=True,
                   scrollbar=None):
    """
    Display a simple message box and wait until the user presses enter.
    """
    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))

    ensure_future(coroutine())
Exemplo n.º 26
0
    def __init__(self, pymux, pipe_connection):
        self.pymux = pymux

        self.pipe_connection = pipe_connection

        self.size = Size(rows=20, columns=80)
        self._closed = False

        self._recv_buffer = b''
        self.client_state = None

        def feed_key(key):
            self.client_state.app.key_processor.feed(key)
            self.client_state.app.key_processor.process_keys()

        self._inputstream = Vt100Parser(feed_key)
        self._pipeinput = _ClientInput(self._send_packet)

        ensure_future(self._start_reading())
Exemplo n.º 27
0
def input_dialog(title='',
                 text='',
                 ok_text='OK',
                 cancel_text='Cancel',
                 completer=None,
                 password=False):
    """
    Display a text input box.
    Return the given text, or None when cancelled.
    """
    output_text = ''

    def coroutine():
        global output_text
        open_dialog = TextInputDialog(title, text, completer)

        output_text = yield From(show_dialog(open_dialog))

    ensure_future(coroutine())
    return output_text
Exemplo n.º 28
0
def datetime_calculator(*event):
    def coroutine():
        prompt = """\
Enter an expression of the form:
    x [+-] y
where x is a datetime and y is either
    [+] a timeperiod
    [-] a datetime or a timeperiod
Be sure to surround [+-] with spaces.
Timezones can be appended to x and y.
        """
        dialog = InteractiveInputDialog(
            title='datetime calculator',
            help_text=prompt,
            evaluator=datetime_calculator,
            padding=4,
            )
        yield From(show_dialog_as_float(dialog))

    ensure_future(coroutine())
Exemplo n.º 29
0
def do_go_to_line(*event):
    def coroutine():
        default = ''
        if dataview.current_row:
            default = dataview.current_row + 1 
        dialog = TextInputDialog(
            title='Go to line',
            label_text='Line number:',
            default=str(default))

        line_number = yield From(show_dialog_as_float(dialog))
        if line_number:
            try:
                line_number = int(line_number)
            except ValueError:
                show_message('go to line', 'Invalid line number')
            else:
                text_area.buffer.cursor_position = \
                    text_area.buffer.document.translate_row_col_to_index(line_number - 1, 0)

    ensure_future(coroutine())
Exemplo n.º 30
0
def test_empty_async_generator():
    " Test asynchronous generator. "
    items = []
    f = ensure_future(consume_async_generator(
        _empty_async_generator(), lambda: False, items.append))

    # Run the event loop until all items are collected.
    get_event_loop().run_until_complete(f)
    assert items == []

    # Check that `consume_async_generator` didn't fail.
    assert f.result() is None
Exemplo n.º 31
0
def yes_no_dialog(title='',
                  text='',
                  yes_text='Yes',
                  yes_func=func_pass,
                  no_text='No',
                  no_func=func_pass):
    """
    Display a Yes/No dialog.
    Execute a passed function.
    """
    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()

    ensure_future(coroutine())
Exemplo n.º 32
0
    def run_coroutine_in_terminal(self, async_func, render_cli_done=False):
        """
        `async_func` can be a coroutine or a function that returns a Future.

        :param async_func: A function that returns either a Future or coroutine
            when called.
        :returns: A `Future`.
        """
        assert callable(async_func)
        loop = get_event_loop()

        # When a previous `run_in_terminal` call was in progress. Wait for that
        # to finish, before starting this one. Chain to previous call.
        previous_run_in_terminal_f = self._running_in_terminal_f
        new_run_in_terminal_f = loop.create_future()
        self._running_in_terminal_f = new_run_in_terminal_f

        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:
                self._redraw(render_as_done=True)
            else:
                self.renderer.erase()

            # Disable rendering.
            self._running_in_terminal = True

            # Detach input.
            try:
                with self.input.detach():
                    with self.input.cooked_mode():
                        result = yield From(async_func())

                raise Return(result)  # Same as: "return result"
            finally:
                # Redraw interface again.
                try:
                    self._running_in_terminal = False
                    self.renderer.reset()
                    self._request_absolute_cursor_position()
                    self._redraw()
                finally:
                    new_run_in_terminal_f.set_result(None)

        return ensure_future(_run_in_t())
Exemplo n.º 33
0
    def attach(self, detach_other_clients=False, color_depth=ColorDepth.DEPTH_8_BIT):
        assert isinstance(detach_other_clients, bool)
        self._send_size()
        self._send_packet({
            'cmd': 'start-gui',
            'detach-others': detach_other_clients,
            'color-depth': color_depth,
            'term': os.environ.get('TERM', ''),
            'data': ''
        })

        f = ensure_future(self._start_reader())
        with self._input.attach(self._input_ready):
            # Run as long as we have a connection with the server.
            get_event_loop().run_until_complete(f)  # Run forever.
Exemplo n.º 34
0
def test_generator_to_async_generator():
    """
    Test conversion of sync to asycn generator.
    This should run the synchronous parts in a background thread.
    """
    async_gen = generator_to_async_generator(_sync_generator)

    items = []
    f = ensure_future(consume_async_generator(
        async_gen, lambda: False, items.append))

    # Run the event loop until all items are collected.
    get_event_loop().run_until_complete(f)
    assert items == [1, 10]

    # Check that `consume_async_generator` didn't fail.
    assert f.result() is None
Exemplo n.º 35
0
    def run_application(self):
        """
        Run application.
        """
        def handle_incoming_data():
            data = self.conn.recv(1024)
            if data:
                self.feed(data)
            else:
                # Connection closed by client.
                logger.info('Connection closed by client. %r %r' % self.addr)
                self.close()
                raise Exception("Dirty connection close.")

        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()

        return ensure_future(run())
    def prompt(
            self,
            # When any of these arguments are passed, this value is overwritten
            # in this PromptSession.
            message=None,  # `message` should go first, because people call it
                           # as positional argument.
            editing_mode=None, refresh_interval=None, vi_mode=None, lexer=None,
            completer=None, complete_in_thread=None, is_password=None,
            key_bindings=None, bottom_toolbar=None, style=None,
            color_depth=None, include_default_pygments_style=None,
            style_transformation=None, swap_light_and_dark_colors=None,
            rprompt=None, multiline=None, prompt_continuation=None,
            wrap_lines=None, enable_history_search=None,
            search_ignore_case=None, complete_while_typing=None,
            validate_while_typing=None, complete_style=None, auto_suggest=None,
            validator=None, clipboard=None, mouse_support=None,
            input_processors=None, reserve_space_for_menu=None,
            enable_system_prompt=None, enable_suspend=None,
            enable_open_in_editor=None, tempfile_suffix=None, inputhook=None,

            # Following arguments are specific to the current `prompt()` call.
            async_=False, default='', accept_default=False, pre_run=None):
        """
        Display the prompt. All the arguments are a subset of the
        :class:`~.PromptSession` class itself.

        This will raise ``KeyboardInterrupt`` when control-c has been pressed
        (for abort) and ``EOFError`` when control-d has been pressed (for
        exit).

        Additional arguments, specific for this prompt:

        :param async_: When `True` return a `Future` instead of waiting for the
            prompt to finish.
        :param default: The default input text to be shown. (This can be edited
            by the user).
        :param accept_default: When `True`, automatically accept the default
            value without allowing the user to edit the input.
        :param pre_run: Callable, called at the start of `Application.run`.
        """
        assert isinstance(default, text_type)

        # NOTE: We used to create a backup of the PromptSession attributes and
        #       restore them after exiting the prompt. This code has been
        #       removed, because it was confusing and didn't really serve a use
        #       case. (People were changing `Application.editing_mode`
        #       dynamically and surprised that it was reset after every call.)

        # Take settings from 'prompt'-arguments.
        for name in self._fields:
            value = locals()[name]
            if value is not None:
                setattr(self, name, value)

        if vi_mode:
            self.editing_mode = EditingMode.VI

        def pre_run2():
            if pre_run:
                pre_run()

            if accept_default:
                # Validate and handle input. We use `call_from_executor` in
                # order to run it "soon" (during the next iteration of the
                # event loop), instead of right now. Otherwise, it won't
                # display the default value.
                get_event_loop().call_from_executor(
                    self.default_buffer.validate_and_handle)

        def run_sync():
            with self._auto_refresh_context():
                self.default_buffer.reset(Document(default))
                return self.app.run(inputhook=self.inputhook, pre_run=pre_run2)

        def run_async():
            with self._auto_refresh_context():
                self.default_buffer.reset(Document(default))
                result = yield From(self.app.run_async(pre_run=pre_run2))
                raise Return(result)

        if async_:
            return ensure_future(run_async())
        else:
            return run_sync()
Exemplo n.º 37
0
    def prompt(
            self,
            message=None,
            # When any of these arguments are passed, this value is overwritten
            # for the current prompt.
            default='',
            editing_mode=None,
            refresh_interval=None,
            vi_mode=None,
            lexer=None,
            completer=None,
            is_password=None,
            extra_key_bindings=None,
            bottom_toolbar=None,
            style=None,
            rprompt=None,
            multiline=None,
            prompt_continuation=None,
            wrap_lines=None,
            history=None,
            enable_history_search=None,
            complete_while_typing=None,
            validate_while_typing=None,
            complete_style=None,
            auto_suggest=None,
            validator=None,
            clipboard=None,
            mouse_support=None,
            extra_input_processor=None,
            reserve_space_for_menu=None,
            enable_system_prompt=None,
            enable_suspend=None,
            enable_open_in_editor=None,
            tempfile_suffix=None,
            async_=False):
        """
        Display the prompt.

        :param _async: When `True` return a `Future` instead of waiting for the
            prompt to finish.
        """
        # Backup original settings.
        backup = dict((name, getattr(self, name)) for name in self._fields)

        # Take settings from 'prompt'-arguments.
        for name in self._fields:
            value = locals()[name]
            if value is not None:
                setattr(self, name, value)

        if vi_mode:
            self.editing_mode = EditingMode.VI

        def restore():
            " Restore original settings. "
            for name in self._fields:
                setattr(self, name, backup[name])

        def run_sync():
            with self._auto_refresh_context():
                try:
                    self._default_buffer.reset(Document(self.default))
                    return self.app.run()
                finally:
                    restore()

        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()

        if async_:
            return ensure_future(run_async())
        else:
            return run_sync()
Exemplo n.º 38
0
def show_message(title, text):
    def coroutine():
        dialog = MessageDialog(title, text)
        yield From(show_dialog_as_float(dialog))

    ensure_future(coroutine())
Exemplo n.º 39
0
def help_handler():
    def coroutine():
        dialog = MessageDialog(HELP, 'HELP')
        yield From(show_dialog(dialog))

    ensure_future(coroutine())
Exemplo n.º 40
0
    def prompt(
            self,
            message=None,
            # When any of these arguments are passed, this value is overwritten
            # for the current prompt.
            default='',
            editing_mode=None,
            refresh_interval=None,
            vi_mode=None,
            lexer=None,
            completer=None,
            complete_in_thread=None,
            is_password=None,
            key_bindings=None,
            bottom_toolbar=None,
            style=None,
            color_depth=None,
            include_default_pygments_style=None,
            rprompt=None,
            multiline=None,
            prompt_continuation=None,
            wrap_lines=None,
            enable_history_search=None,
            search_ignore_case=None,
            complete_while_typing=None,
            validate_while_typing=None,
            complete_style=None,
            auto_suggest=None,
            validator=None,
            clipboard=None,
            mouse_support=None,
            input_processors=None,
            reserve_space_for_menu=None,
            enable_system_prompt=None,
            enable_suspend=None,
            enable_open_in_editor=None,
            tempfile_suffix=None,
            inputhook=None,
            async_=False):
        """
        Display the prompt. All the arguments are a subset of the
        :class:`~.PromptSession` class itself.

        This will raise ``KeyboardInterrupt`` when control-c has been pressed
        (for abort) and ``EOFError`` when control-d has been pressed (for
        exit).

        :param async_: When `True` return a `Future` instead of waiting for the
            prompt to finish.
        """
        # Backup original settings.
        backup = dict((name, getattr(self, name)) for name in self._fields)

        # Take settings from 'prompt'-arguments.
        for name in self._fields:
            value = locals()[name]
            if value is not None:
                setattr(self, name, value)

        if vi_mode:
            self.editing_mode = EditingMode.VI

        def restore():
            " Restore original settings. "
            for name in self._fields:
                setattr(self, name, backup[name])

        def run_sync():
            with self._auto_refresh_context():
                try:
                    self.default_buffer.reset(Document(self.default))
                    return self.app.run(inputhook=self.inputhook)
                finally:
                    restore()

        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()

        if async_:
            return ensure_future(run_async())
        else:
            return run_sync()
    def run_async(self, pre_run=None):
        """
        Run asynchronous. Return a prompt_toolkit
        :class:`~prompt_toolkit.eventloop.Future` object.

        If you wish to run on top of asyncio, remember that a prompt_toolkit
        `Future` needs to be converted to an asyncio `Future`. The cleanest way
        is to call :meth:`~prompt_toolkit.eventloop.Future.to_asyncio_future`.
        Also make sure to tell prompt_toolkit to use the asyncio event loop.

        .. code:: python

            from prompt_toolkit.eventloop import use_asyncio_event_loop
            from asyncio import get_event_loop

            use_asyncio_event_loop()
            get_event_loop().run_until_complete(
                application.run_async().to_asyncio_future())

        """
        assert not self._is_running, 'Application is already running.'

        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

                            # Detach event handlers for invalidate events.
                            # (Important when a UIControl is embedded in
                            # multiple applications, like ptterm in pymux. An
                            # invalidate should not trigger a repaint in
                            # terminated applications.)
                            for ev in self._invalidate_events:
                                ev -= self._invalidate_handler
                            self._invalidate_events = []

                            # 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)

        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)

        return ensure_future(_run_async2())
Exemplo n.º 42
0
 def _send_packet(self, data):
     " Send to server. "
     data = json.dumps(data)
     ensure_future(self.pipe.write_message(data))
Exemplo n.º 43
0
    def run_async(self, pre_run=None):
        """
        Run asynchronous. Return a prompt_toolkit
        :class:`~prompt_toolkit.eventloop.Future` object.

        If you wish to run on top of asyncio, remember that a prompt_toolkit
        `Future` needs to be converted to an asyncio `Future`. The cleanest way
        is to call :meth:`~prompt_toolkit.eventloop.Future.to_asyncio_future`.
        Also make sure to tell prompt_toolkit to use the asyncio event loop.

        .. code:: python

            from prompt_toolkit.eventloop import use_asyncio_event_loop
            from asyncio import get_event_loop

            use_asyncio_event_loop()
            get_event_loop().run_until_complete(
                application.run_async().to_asyncio_future())

        """
        assert not self._is_running

        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

                            # Detach event handlers for invalidate events.
                            # (Important when a UIControl is embedded in
                            # multiple applications, like ptterm in pymux. An
                            # invalidate should not trigger a repaint in
                            # terminated applications.)
                            for ev in self._invalidate_events:
                                ev -= self.invalidate
                            self._invalidate_events = []

                            # 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)

        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)

        return ensure_future(_run_async2())
def run_coroutine_in_terminal(async_func, render_cli_done=False):
    """
    Suspend the current application and run this coroutine instead.
    `async_func` can be a coroutine or a function that returns a Future.

    :param async_func: A function that returns either a Future or coroutine
        when called.
    :returns: A `Future`.
    """
    assert callable(async_func)
    loop = get_event_loop()

    # Make sure to run this function in the current `Application`, or if no
    # application is active, run it normally.
    app = get_app(return_none=True)

    if app is None:
        return ensure_future(async_func())
    assert app._is_running

    # When a previous `run_in_terminal` call was in progress. Wait for that
    # to finish, before starting this one. Chain to previous call.
    previous_run_in_terminal_f = app._running_in_terminal_f
    new_run_in_terminal_f = loop.create_future()
    app._running_in_terminal_f = new_run_in_terminal_f

    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)

    return ensure_future(_run_in_t())
Exemplo n.º 45
0
    def prompt(
            self,
            message=None,
            # When any of these arguments are passed, this value is overwritten
            # for the current prompt.
            default='',
            editing_mode=None,
            refresh_interval=None,
            vi_mode=None,
            lexer=None,
            completer=None,
            complete_in_thread=None,
            is_password=None,
            key_bindings=None,
            bottom_toolbar=None,
            style=None,
            color_depth=None,
            include_default_pygments_style=None,
            style_transformation=None,
            swap_light_and_dark_colors=None,
            rprompt=None,
            multiline=None,
            prompt_continuation=None,
            wrap_lines=None,
            enable_history_search=None,
            search_ignore_case=None,
            complete_while_typing=None,
            validate_while_typing=None,
            complete_style=None,
            auto_suggest=None,
            validator=None,
            clipboard=None,
            mouse_support=None,
            input_processors=None,
            reserve_space_for_menu=None,
            enable_system_prompt=None,
            enable_suspend=None,
            enable_open_in_editor=None,
            tempfile_suffix=None,
            inputhook=None,
            async_=False,
            accept_default=False,
            pre_run=None):
        """
        Display the prompt. All the arguments are a subset of the
        :class:`~.PromptSession` class itself.

        This will raise ``KeyboardInterrupt`` when control-c has been pressed
        (for abort) and ``EOFError`` when control-d has been pressed (for
        exit).

        :param async_: When `True` return a `Future` instead of waiting for the
            prompt to finish.
        :param accept_default: When `True`, automatically accept the default
            value without allowing the user to edit the input.
        :param pre_run: Callable, called at the start of `Application.run`.
        """
        # NOTE: We used to create a backup of the PromptSession attributes and
        #       restore them after exiting the prompt. This code has been
        #       removed, because it was confusing and didn't really serve a use
        #       case. (People were changing `Application.editing_mode`
        #       dynamically and surprised that it was reset after every call.)

        # Take settings from 'prompt'-arguments.
        for name in self._fields:
            value = locals()[name]
            if value is not None:
                setattr(self, name, value)

        if vi_mode:
            self.editing_mode = EditingMode.VI

        def pre_run2():
            if pre_run:
                pre_run()

            if accept_default:
                # Validate and handle input. We use `call_from_executor` in
                # order to run it "soon" (during the next iteration of the
                # event loop), instead of right now. Otherwise, it won't
                # display the default value.
                get_event_loop().call_from_executor(
                    self.default_buffer.validate_and_handle)

        def run_sync():
            with self._auto_refresh_context():
                self.default_buffer.reset(Document(self.default))
                return self.app.run(inputhook=self.inputhook, pre_run=pre_run2)

        def run_async():
            with self._auto_refresh_context():
                self.default_buffer.reset(Document(self.default))
                result = yield From(self.app.run_async(pre_run=pre_run2))
                raise Return(result)

        if async_:
            return ensure_future(run_async())
        else:
            return run_sync()
Exemplo n.º 46
0
def show_message(title, text):
    def coroutine():
        dialog = MessageDialog(title, text)
        yield From(show_dialog_as_float(dialog))

    ensure_future(coroutine())