async def test_ziplatest(assert_run, event_loop):
    with event_loop.assert_cleanup():
        xs = stream.range(0, 5, 2, interval=2)
        ys = stream.range(1, 5, 2, interval=2) | pipe.delay(1)
        zs = stream.ziplatest(xs, ys, default="▲")
        await assert_run(zs, [(0, "▲"), (0, 1), (2, 1), (2, 3), (4, 3)])
        assert event_loop.steps == [1, 1, 1, 1]

    with event_loop.assert_cleanup():
        xs = stream.range(0, 5, 2, interval=2)
        ys = stream.range(1, 5, 2, interval=2) | pipe.delay(1)
        zs = stream.ziplatest(xs, ys, partial=False)
        await assert_run(zs, [(0, 1), (2, 1), (2, 3), (4, 3)])
        assert event_loop.steps == [1, 1, 1, 1]
Exemple #2
0
async def test_ziplatest(assert_run, event_loop):
    with event_loop.assert_cleanup():
        xs = stream.range(0, 5, 2, interval=2)
        ys = stream.range(1, 5, 2, interval=2) | pipe.delay(1)
        zs = stream.ziplatest(xs, ys, default='▲')
        await assert_run(zs, [(0, '▲'), (0, 1), (2, 1), (2, 3), (4, 3)])
        assert event_loop.steps == [1, 1, 1, 1]

    with event_loop.assert_cleanup():
        xs = stream.range(0, 5, 2, interval=2)
        ys = stream.range(1, 5, 2, interval=2) | pipe.delay(1)
        zs = stream.ziplatest(xs, ys, partial=False)
        await assert_run(zs, [(0, 1), (2, 1), (2, 3), (4, 3)])
        assert event_loop.steps == [1, 1, 1, 1]
Exemple #3
0
async def input(ic, name):
    field = ic.md.input_fields[name]

    owner = ic.user
    restart = field['can_read']

    while restart:
        restart = False
        src = [await arg_stream(ic, owner, pathlib.Path(field['name']))]

        if 'owner' in field['args']:
            src.append(await arg_stream(ic, ic.user, field['args']['owner']))

        s = stream.ziplatest(*src, partial=False)
        last = None

        async with core.streamcontext(s) as streamer:
            async for i in streamer:
                if 'owner' in field['args']:
                    if i[1] is None:
                        continue

                    o = i[1]['val']
                    if o.pk != owner.pk:
                        owner = o
                        restart = True
                        break

                out = dict(type='input', id=field['name'], disabled=True)
                out['owner'] = None if ic.user == owner else owner.username
                out['val'] = '' if i[0] is None or i[0]['val'] is None else str(
                    i[0]['val'])
                out['disabled'] = not (field['can_write'] is True or
                                       (field['can_write'] is None
                                        and out['owner'] is None))

                if last == out:
                    continue
                last = out

                if field['args']['type'] in ['file', 'files', 'select-user']:
                    out['val'] = None

                if i[0] is not None and field['args']['type'] != i[0]['type']:
                    logger.warning(
                        f"field type error: {field['args']['type']} != {i[0]['type']}"
                    )

                yield out
Exemple #4
0
async def from_streams(base_reader):
    '''
    Asyncio coroutine task to read from all streams &
    detect and then execute the command based on the confirmation tap
    '''
    try:
        # Wait for half a second before processing the events
        await asyncio.sleep(0.5)
        # Grab the touchpad to draw gesture until this coroutine is cancelled
        base_reader.grab()
        # Init all the readers
        x_movement_reader = Reader(base_reader)
        y_movement_reader = Reader(base_reader)
        tap_detector_reader = Reader(base_reader)

        # Reload gesture command map
        reload_config()

        # Store the received coordinates
        coordinates_set = []
        start_time = end_time = 0

        # Zip the X and Y axis events for clarity.
        # It is processed separtely though when sanitizing the input
        zip_xy = ziplatest(y_movement(x_movement_reader),
                           x_movement(y_movement_reader))
        # Read the tap events as well to indicate
        # the start and end of gesture drawing
        merge_tap_xy = merge(zip_xy,
                             tap_detector(tap_detector_reader))

        async with merge_tap_xy.stream() as merged:
            async for event in merged:
                # The zip_xy events are in the form of tuples
                # while the tap events are evdev event objects
                if not isinstance(event, tuple):
                    if event.value == 1:
                        start_time = event.timestamp()
                    elif event.value == 0:
                        end_time = event.timestamp()
                        # If the draw is too short, ignore and reset
                        # cause it's not meaningful
                        if (end_time - start_time) < 0.3:
                            coordinates_set = []
                            continue

                        detected_gesture = sanitize_and_notify(coordinates_set)
                        # print(f'Detected gesture :- {detected_gesture}')

                        coordinates_set = []
                        if detected_gesture is None:
                            continue
                        # If gesture detected then wait for a confirmation tap
                        tapped, event = await confirmation_tap(base_reader)

                        if tapped:
                            notify(f"Confirmed. Running- {detected_gesture}")
                            execute_command(detected_gesture)
                        else:
                            notify("Clearing gestures")
                else:
                    coordinates_set.append(event)

    except asyncio.CancelledError:
        # Exit all readers from the base_reader once they are done
        x_movement_reader.exit()
        y_movement_reader.exit()
        tap_detector_reader.exit()
        # Ungrab and yield control of touchpad to the user
        base_reader.ungrab()
Exemple #5
0
async def pprint(ic, args):
    a = [await my_stream.arg_stream(ic, ic.user, arg) for arg in args]
    source = stream.ziplatest(*a, partial=False)

    async with core.streamcontext(source) as streamer:
        async for item in streamer:
            keys = list()
            vals = dict()
            info = list()

            for i, val in enumerate(item):
                if val is None:
                    continue

                if val.get('pk') is not None:
                    info.append(await get_history(val['pk']))

                if val['type'] is None:
                    pass

                elif val['type'] in ['html']:
                    if None not in keys:
                        keys.insert(0, None)
                        vals[None] = [None] * len(item)

                    vals[None][i] = val['val']

                elif val['type'] in [
                        'int', 'float', 'str', 'text', 'textarea', 'files',
                        'stdout', 'error'
                ]:
                    if None not in keys:
                        keys.insert(0, None)
                        vals[None] = [None] * len(item)

                    vals[None][i] = render_to_string(
                        f"wiki/plugins/inputs/pprint.html", context=val)

                elif val['type'] == 'user-list':
                    for u, v in val['val'].items():
                        if u not in keys:
                            keys.append(u)
                            vals[u] = [None] * len(item)

                        vals[u][i] = render_to_string(
                            f"wiki/plugins/inputs/pprint.html", context=v)

                else:
                    logger.error(val)

            if len(keys) == 0:
                yield None
                continue

            if len(keys) == 1 and keys[0] is None:
                html = " ".join(vals[keys[0]])

            else:
                html = "<table>"

                for k in keys:
                    html += "<tr><th>"
                    if k is None:
                        html += "&nbsp;"
                    elif isinstance(k, User):
                        html += f"{k.first_name} {k.last_name}"
                    else:
                        html += str(k)
                    html += "</th>"

                    for v in vals[k]:
                        html += f"<td>{v!s}</td>"

                    html += "</tr>"
                html += "</table>"

            if info:
                html = render_to_string("wiki/plugins/inputs/pprint_full.html",
                                        context={
                                            'html': html,
                                            'info': "".join(info)
                                        })

            yield {'type': 'html', 'val': html}
Exemple #6
0
async def get(ic, args):
    if len(args) < 2:
        yield {
            'type': 'error',
            'val': "⚠ get() requires at least 2 arguments ⚠"
        }
        return

    if not isinstance(args[0], pathlib.Path):
        yield {'type': 'error', 'val': "⚠ get() first argument must be path ⚠"}
        return

    path = misc.normpath(ic, args[0])
    md = await misc.get_markdown_factory().get_markdown(path.parent, ic.user)
    if md is None:
        yield {
            'type': 'error',
            'val': f"⚠ get() article {path.parent} does not exist ⚠"
        }
        return

    field = md.input_fields.get(path.name)
    if field is None:
        yield {
            'type': 'error',
            'val': f"⚠ get() article {path.name} does not exist ⚠"
        }

    q = Q(article=md.article) & Q(name=field['name'])
    if field['can_write'] in [False, None]:
        q &= Q(owner=ic.user)

    users = set()

    while True:
        src = [my_stream.read_field(ic, x, path) for x in users]
        src += [await my_stream.arg_stream(ic, ic.user, x) for x in args[1:]]
        if len(users) == 0:
            src += [my_stream.read_field(ic, ic.user, path)]

        s = stream.ziplatest(*src, partial=False)
        async with core.streamcontext(s) as streamer:
            async for i in streamer:
                users_new, is_list = await db_get_input_users(
                    md, field, q, (i[len(users):])[:len(args[1:])])
                if users_new is None:
                    continue

                if set([u.pk for u in users]) != set([u.pk
                                                      for u in users_new]):
                    users = users_new
                    break

                if is_list:
                    yield {
                        'type':
                        'user-list',
                        'val':
                        dict(zip([u.username for u in users], i[:len(users)])),
                    }
                elif len(users) > 0:
                    yield i[0]
                else:
                    yield {'type': 'None', 'val': None}

            else:
                return