Ejemplo n.º 1
0
def main():
    """ x/84 script launch point """

    term, session = getterminal(), getsession()
    session.activity = u'Chatting on IRC'
    session.flush_event('irc')

    # move to bottom of screen, reset attribute
    echo(term.pos(term.height) + term.normal)

    # create a new, empty screen
    echo(u'\r\n' * (term.height + 1))
    echo(term.home + term.clear)

    # set font
    if SYNCTERM_FONT and term.kind.startswith('ansi'):
        echo(syncterm_setfont(SYNCTERM_FONT))

    try:
        client, scrollback = establish_connection(term, session)
    except EOFError:
        # connection failed,
        return clean_up(term)

    # ignore "not in view" warning for AnsiWindow
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        editor = ScrollingEditor(
            width=term.width + 1,
            xloc=-1,
            yloc=term.height,
            colors={'highlight': getattr(term, COLOR_INPUTBAR)},
            max_length=MAX_INPUT
        )

    refresh_event(term, scrollback, editor)

    while True:
        client.reactor.process_once()
        event, data = session.read_events(
            ('irc-quit', 'irc', 'input', 'refresh'), timeout=0.1)
        if event == 'refresh':
            refresh_event(term, scrollback, editor)
            continue
        elif event == 'irc':
            irc_event(term, data, scrollback, editor)
        elif event == 'input':
            session.buffer_input(data, pushback=True)
            if not input_event(term, client, editor):
                break
        elif event == 'irc-quit':
            time.sleep(0.5)
            break
    client.connection.disconnect()
    clean_up(term)
Ejemplo n.º 2
0
def get_inputbar(pager):
    """ Return ScrollingEditor for use as inputbar. """
    from x84.bbs import getterminal, ScrollingEditor
    term = getterminal()
    width = pager.visible_width - 2
    yloc = (pager.yloc + pager.height) - 2
    xloc = pager.xloc + 2
    ibar = ScrollingEditor(width, yloc, xloc)
    ibar.enable_scrolling = True
    ibar.max_length = 512
    ibar.colors['highlight'] = term.cyan_reverse
    return ibar
Ejemplo n.º 3
0
def make_editor_series(winsize, editors):
    colors = {'highlight': u''}
    # prevent horizontal scrolling prior to final column
    margin_pct = 100 - (100 / (winsize.width - 3))
    # scroll at final column
    scroll_pct = 100 / (winsize.width - 3)
    return [
        ScrollingEditor(
            yloc=_yloc, xloc=winsize.xloc, width=winsize.width,
            colors=colors, margin_pct=margin_pct, scroll_pct=scroll_pct,
            content=(u'' if not editors or _idx >= len(editors)
                     else editors[_idx].content),
            max_length=winsize.width
        ) for _idx, _yloc in enumerate(range(
            winsize.yloc, winsize.yloc + winsize.height + -2))]
Ejemplo n.º 4
0
def get_lneditor(lightbar):
    """ Returns editor positioned at location of current selection. """
    term = getterminal()
    width = min(80, max(term.width, 40))
    yloc = (lightbar.yloc + lightbar.ypadding + lightbar.position[0] - 1)
    xloc = max(0, (term.width / 2) - (width / 2))
    lneditor = ScrollingEditor(width=width, yloc=yloc, xloc=xloc)
    lneditor.enable_scrolling = True
    lneditor.max_length = 65534
    lneditor.glyphs['bot-horiz'] = u''
    lneditor.glyphs['top-horiz'] = u''
    lneditor.colors['highlight'] = term.red_reverse
    lneditor.colors['border'] = term.bold_red
    # converts u'xxxxxx\r\n' to 'xxxxxx',
    # or 'zzzz\nxxxxxx\n' to u'zzzz xxxxxx',
    lneditor.update(softwrap_join(wrap_rstrip(lightbar.selection[1])))
    return lneditor
Ejemplo n.º 5
0
def do_command(term, session, inp, fields, tgt_user, point):
    """ Perform action by given input. """
    _color1, _color2, _color3 = [
        getattr(term, _color)
        for _color in (color_lowlight, color_highlight, color_field_edit)
    ]

    # discover edit field by matching command key
    field_name = None
    for _fname, field in fields.items():
        if field.key == inp.lower():
            field_name = _fname
            break

    if field_name is None:
        # return False if no field matches this key
        return False

    # only 'sysop' may edit user groups
    if field_name == 'groups' and not session.user.is_sysop:
        return False

    # pylint: disable=W0631
    #         Using possibly undefined loop variable 'field'

    # TODO: we could probably stand to do a bit of a better job of detecting
    # screen resizes and providing ^L full-screen refresh during the remainder
    # of this procedure ... It would require quite the refactor, though.

    # special case; ssh public keys and groups use scrolling editor
    if field_name in ('pubkey', 'groups'):
        editor = ScrollingEditor(
            # issue #161; because of a 'border' (that we don't draw),
            # y must be offset by 1 and height by 2.
            yloc=field.edit_location.y - 1,
            xloc=field.edit_location.x - 1,
            width=field.width + 2,
            colors={'highlight': _color3})
        # limit input to 1K
        editor.max_length = 1024
    else:
        editor = LineEditor(field.width, colors={'highlight': _color3})

    # find width for displaying description text and validation errors
    width = term.width - (point.x * 2)

    # show field description and cancellation
    description = (field.description or u'') + '  Press escape to cancel.'
    description_text = term.wrap(description, width=width)
    for y_offset, txt in enumerate(description_text):
        echo(term.move(point.y + y_offset, point.x))
        echo(_color1(txt) + term.clear_eol)
    echo(term.clear_eos)

    # edit input field (occludes display field).
    echo(term.move(*field.edit_location))
    inp = editor.read()
    if inp is None:
        # escape was pressed
        echo(term.move(*point))
        echo(_color2('Canceled !') + term.clear_eos)
        time.sleep(1)
        return True

    else:
        # validate input
        if field.validate_fn is not None:
            errmsg, _ = field.validate_fn(tgt_user, inp)
            if errmsg:
                # failed validation, display validation error
                errmsg += '  Press any key.'
                for y_offset, txt in enumerate(term.wrap(errmsg, width=width)):
                    echo(term.move(point.y + y_offset, point.x))
                    echo(_color2(txt) + term.clear_eol)
                echo(term.clear_eos)
                term.inkey()
                return True

        # well, it has validated, shall we apply it, then?
        if field_name in (
                'password',
                'location',
                'email',
        ):
            # except for anonymous,
            if tgt_user.handle != 'anonymous':
                setattr(tgt_user, field_name, inp)
        elif field_name in (
                'timeout',
                'pubkey',
        ):
            if field_name == 'timeout':
                # coerce to integer, set, and if tgt_user is our current
                # user, then send new value for as engine event
                try:
                    timeout_val = int(inp)
                except ValueError:
                    return True
                if tgt_user.handle != 'anonymous':
                    tgt_user[field_name] = timeout_val
                if tgt_user.handle == session.user.handle:
                    session.send_event('set-timeout', timeout_val)
            elif field_name == 'pubkey':
                if tgt_user.handle != 'anonymous':
                    tgt_user[field_name] = inp
        elif field_name in ('groups'):
            new_groups = set(
                filter(None, set(map(unicode.strip, inp.split(',')))))
            for old_grp in tgt_user.groups.copy():
                if old_grp not in new_groups:
                    tgt_user.group_del(old_grp)
            for new_grp in new_groups:
                if new_grp not in tgt_user.groups:
                    tgt_user.group_add(new_grp)
        else:
            raise ValueError('unknown field name: {0}'.format(field_name))
    if tgt_user.handle != 'anonymous':
        tgt_user.save()
    return True
Ejemplo n.º 6
0
def prompt_subscription(session, term, yloc, subscription, colors):
    """
    This function is called to assign a new set of subscription
    tags for a user.  If escape is pressed, the existing value
    is used, or '*' is used if not previously set.

    This should be called for first-time users, and optionally
    at any later time to change a subscription.
    """

    if session.user.get('msg_subscription', None) is None:
        # force-display introductory description for first-time users.
        yloc += do_describe_message_system(term, colors)
        echo(u'\r\n\r\n')
        yloc += 2

    # remind ourselves of all available tags
    yloc += do_describe_available_tags(term, colors) + 2

    # for small screens, scroll and leave room for prompt & errors
    if yloc > term.height + 3:
        echo(u'\r\n' * 3)
        yloc = term.height - 3

    # and prompt for setting of message tags
    xloc = max(0, (term.width // 2) - 40)
    input_prefix = u':: subscription tags:'
    echo(u''.join((term.move(yloc, xloc), input_prefix)))

    xloc += len(input_prefix)
    wide = min(40, (term.width - xloc - 2))

    while True:
        editor = ScrollingEditor(xloc=xloc,
                                 yloc=yloc - 1,
                                 width=wide,
                                 colors={'highlight': colors['backlight']},
                                 content=u', '.join(subscription),
                                 max_length=100)

        # Prompt for and evaluate the given input, splitting by comma,
        # removing any empty items, and defaulting to ['*'] on escape.
        inp = editor.read() or u''
        subscription = filter(None, set(map(unicode.strip,
                                            inp.split(',')))) or set([u'*'])

        # Then, reduce to only validate tag patterns, tracking those
        # that do not match any known tags, and display a warning and
        # re-prompt if any are removed.
        removed, subscription = validate_tag_patterns(subscription)

        # clear existing warning, if any
        echo(u''.join((term.normal, u'\r\n\r\n', term.clear_eos)))
        if removed:
            # and display any unmatched tags as a warning, re-prompt
            txt = ''.join(
                (term.bold_red(u"The following patterns are not matched: "),
                 u', '.join(removed)))
            show_description(term, txt, color=None)
            continue

        # otherwise everything is fine,
        # return new subscription set
        return subscription