Пример #1
0
def process_keystroke(inp, key=None):
    """ Process general keystroke and call routines.  """
    from x84.bbs import getsession, DBProxy, gosub, echo
    session = getsession()
    if inp is None:
        return False
    elif type(inp) is int:
        return False
    elif inp in (u't', u'T') and key is not None:
        bbs = DBProxy('bbslist')[key]
        gosub('telnet', bbs['address'], bbs['port'],)
    elif inp in (u'a', u'A'):
        add_bbs()
    elif inp in (u'c', u'C') and key is not None:
        add_comment(key)
    elif inp in (u'r', u'R') and key is not None:
        rate_bbs(key)
    elif inp in (u'i', u'I') and key is not None:
        echo(get_bbsinfo(key) + '\r\n')
    elif inp in (u'v', u'V') and key is not None:
        view_ansi(key)
    elif inp in (u'd', u'D') and key is not None and (
            'sysop' in session.user.groups):
        del DBProxy('bbslist')[key]
    else:
        return False  # unhandled
    return True
Пример #2
0
def main():
    """ Main menu entry point. """
    from x84.default.common import display_banner
    session, term = getsession(), getterminal()

    text, width, height, dirty = u'', -1, -1, 2
    menu_items = get_menu_items(session)
    editor = get_line_editor(term, menu_items)
    while True:
        if dirty == 2:
            # set syncterm font, if any
            if syncterm_font and term.kind.startswith('ansi'):
                echo(syncterm_setfont(syncterm_font))
        if dirty:
            session.activity = 'main menu'
            top_margin = display_banner(art_file, encoding=art_encoding) + 1
            echo(u'\r\n')
            if width != term.width or height != term.height:
                width, height = term.width, term.height
                text = render_menu_entries(term, top_margin, menu_items)
            echo(u''.join((text, display_prompt(term), editor.refresh())))
            dirty = 0

        event, data = session.read_events(('input', 'refresh'))

        if event == 'refresh':
            dirty = True
            continue

        elif event == 'input':
            session.buffer_input(data, pushback=True)

            # we must loop over inkey(0), we received a 'data'
            # event, though there may be many keystrokes awaiting for our
            # decoding -- or none at all (multibyte sequence not yet complete).
            inp = term.inkey(0)
            while inp:
                if inp.code == term.KEY_ENTER:
                    # find matching menu item,
                    for item in menu_items:
                        if item.inp_key == editor.content.strip():
                            echo(term.normal + u'\r\n')
                            gosub(item.script, *item.args, **item.kwargs)
                            editor.content = u''
                            dirty = 2
                            break
                    else:
                        if editor.content:
                            # command not found, clear prompt.
                            echo(u''.join((
                                (u'\b' * len(editor.content)),
                                (u' ' * len(editor.content)),
                                (u'\b' * len(editor.content)),)))
                            editor.content = u''
                            echo(editor.refresh())
                elif inp.is_sequence:
                    echo(editor.process_keystroke(inp.code))
                else:
                    echo(editor.process_keystroke(inp))
                inp = term.inkey(0)
Пример #3
0
def process_keystroke(inp, key=None):
    """ Process general keystroke and call routines.  """
    from x84.bbs import getsession, DBProxy, gosub, echo
    session = getsession()
    if inp is None:
        return False
    elif type(inp) is int:
        return False
    elif inp in (u't', u'T') and key is not None:
        bbs = DBProxy('bbslist')[key]
        gosub(
            'telnet',
            bbs['address'],
            bbs['port'],
        )
    elif inp in (u'a', u'A'):
        add_bbs()
    elif inp in (u'c', u'C') and key is not None:
        add_comment(key)
    elif inp in (u'r', u'R') and key is not None:
        rate_bbs(key)
    elif inp in (u'i', u'I') and key is not None:
        echo(get_bbsinfo(key) + '\r\n')
    elif inp in (u'v', u'V') and key is not None:
        view_ansi(key)
    elif inp in (u'd', u'D') and key is not None and ('sysop'
                                                      in session.user.groups):
        del DBProxy('bbslist')[key]
    else:
        return False  # unhandled
    return True
Пример #4
0
def playback(sessions):
    """ Prompt for node and gosub ttyplay script for ttyrec of target session.
    """
    from x84.bbs import gosub
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        gosub('ttyplay', tgt_session['ttyrec'])
        return True
Пример #5
0
def edit(sessions):
    """ Prompt for node and gosub profile.py script for user of target session.
    """
    from x84.bbs import gosub
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        gosub('profile', tgt_session['handle'])
        return True
Пример #6
0
def playback(sessions):
    """ Prompt for node and gosub ttyplay script for ttyrec of target session.
    """
    from x84.bbs import gosub
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        gosub('ttyplay', tgt_session['ttyrec'])
        return True
Пример #7
0
def edit(sessions):
    """ Prompt for node and gosub profile.py script for user of target session.
    """
    from x84.bbs import gosub
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        gosub('profile', handle=tgt_session['handle'])
        return True
Пример #8
0
def chat(sessions):
    """
    Prompt for node and page target session for chat.
    Sysop will send session id of -1, indicating the chat is forced.
    """
    from x84.bbs import gosub, getsession
    (_, tgt_session) = get_node(sessions)
    if tgt_session and tgt_session['sid'] != getsession().sid:
        gosub('chat', dial=tgt_session['handle'], other_sid=tgt_session['sid'])
Пример #9
0
def watch(sessions):
    """
    Prompt for node and gosub ttyplay script for ttyrec of target session,
    with 'peek' boolean set to True.
    """
    from x84.bbs import gosub
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        gosub('ttyplay', tgt_session['ttyrec'], True)
        return True
Пример #10
0
def chat(sessions):
    """
    Prompt for node and page target session for chat.
    Sysop will send session id of -1, indicating the chat is forced.
    """
    from x84.bbs import gosub, getsession

    (_, tgt_session) = get_node(sessions)
    if tgt_session and tgt_session["sid"] != getsession().sid:
        gosub("chat", dial=tgt_session["handle"], other_sid=tgt_session["sid"])
Пример #11
0
def watch(sessions):
    """
    Prompt for node and gosub ttyplay script for ttyrec of target session,
    with 'peek' boolean set to True.
    """
    from x84.bbs import gosub
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        gosub('ttyplay', tgt_session['ttyrec'], True)
        return True
Пример #12
0
def chat(sessions):
    """
    Prompt for node and page target session for chat.
    Sysop will send session id of -1, indicating the chat is forced.
    """
    from x84.bbs import gosub, getsession
    session = getsession()
    (node, tgt_session) = get_node(sessions)
    if tgt_session and tgt_session != session:
        gosub('chat', dial=tgt_session['handle'],
              other_sid=tgt_session['sid'])
Пример #13
0
def sendmsg(sessions):
    """
    Prompt for node and gosub 'writemsg' with recipient set to target user.
    """
    from x84.bbs import gosub, Msg
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        msg = Msg()
        msg.recipient = tgt_session['handle']
        msg.tags.add('private')
        gosub('writemsg', msg)
        return True
Пример #14
0
def sendmsg(sessions):
    """
    Prompt for node and gosub 'writemsg' with recipient set to target user.
    """
    from x84.bbs import gosub, Msg
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        msg = Msg()
        msg.recipient = tgt_session['handle']
        msg.tags.add('private')
        gosub('writemsg', msg)
        return True
Пример #15
0
def do_login(term):
    sep_ok = getattr(term, color_secondary)(u'::')
    sep_bad = getattr(term, color_primary)(u'::')
    colors = {'highlight': getattr(term, color_primary)}
    for _ in range(login_max_attempts):

        term.goto_y(10)
        echo(u'\r\n\r\n{sep} Login: '******''

        if handle.strip() == u'':
            continue

        # user says goodbye
        if handle.lower() in bye_usernames:
            return

        # user applies for new account
        if new_allowed and handle.lower() in new_usernames:
            gosub(new_script)
            display_banner(term)
            continue

        # user wants to reset password
        if reset_allowed and handle.lower() == 'reset':
            gosub(reset_script)
            display_banner(term)
            continue

        # user wants to login anonymously
        if anonymous_allowed and handle.lower() in anonymous_names:
            user = User('anonymous')
        else:
            # authenticate password
            echo(u'\r\n\r\n{sep} Password: '******''

            user = authenticate_user(handle, password)
            if not user:
                echo(u'\r\n\r\n{sep} Login failed.'.format(sep=sep_bad))
                continue

        goto(top_script, handle=user.handle)

    echo(u'\r\n\r\n{sep} Too many authentication attempts.\r\n'.format(
        sep=sep_bad))
Пример #16
0
Файл: top.py Проект: gofore/x84
def do_intro_art(term, session):
    """
    Display random art file, prompt for quick login.

    Bonus: allow chosing other artfiles with '<' and '>'.
    """
    from x84.bbs import ini
    show_intro_art = False
    if ini.CFG.has_option('system', 'show_intro_art'):
        show_intro_art = ini.CFG.getboolean('system', 'show_intro_art')
    # set syncterm font, if any
    if syncterm_font and term.kind.startswith('ansi'):
        echo(syncterm_setfont(syncterm_font))

    index = int(time.time()) % len(art_files)
    dirty = True
    echo(u'\r\n')
    while True:
        session.activity = 'top'
        if session.poll_event('refresh') or dirty:
            if show_intro_art:
                display_intro(term, index)
            else:
                return True
            display_prompt(term)
            dirty = False
        dirty = True
        inp = LineEditor(1, colors={'highlight': term.normal}).read()
        if inp is None or inp.lower() == u'y':
            # escape/yes: quick login
            return True
        # issue #242 : set 'N' as default, by adding a check for an empty
        # unicode string.
        elif inp.lower() in (u'n', u'\r', u'\n', u''):
            break

        if len(inp) == 1:
            echo(u'\b')
        if inp == u'!':
            echo(u'\r\n' * 3)
            gosub('charset')
            dirty = True
        elif inp == u'<':
            index -= 1
        elif inp == u'>':
            index += 1
        else:
            dirty = False
Пример #17
0
def do_login(term):
    sep_ok = getattr(term, color_secondary)(u'::')
    sep_bad = getattr(term, color_primary)(u'::')
    colors = {'highlight': getattr(term, color_primary)}
    for _ in range(login_max_attempts):
        echo(u'\r\n\r\n{sep} Login: '******''

        if handle.strip() == u'':
            continue

        # user says goodbye
        if handle.lower() in bye_usernames:
            return

        # user applies for new account
        if new_allowed and handle.lower() in new_usernames:
            gosub(new_script)
            display_banner(term)
            continue

        # user wants to reset password
        if reset_allowed and handle.lower() == 'reset':
            gosub(reset_script)
            display_banner(term)
            continue

        # user wants to login anonymously
        if anonymous_allowed and handle.lower() in anonymous_names:
            user = User('anonymous')
        else:
            # authenticate password
            echo(u'\r\n\r\n{sep} Password: '******''

            user = authenticate_user(handle, password)
            if not user:
                echo(u'\r\n\r\n{sep} Login failed.'.format(sep=sep_bad))
                continue

        goto(top_script, handle=user.handle)

    echo(u'\r\n\r\n{sep} Too many authentication attempts.\r\n'
         .format(sep=sep_bad))
Пример #18
0
def prompt_body(msg):
    """ Prompt for 'body' of message, executing 'editor' script. """
    from x84.bbs import echo, Selector, getterminal, getsession, gosub
    term = getterminal()
    session = getsession()
    inp = Selector(yloc=term.height - 1,
                   xloc=term.width - 22,
                   width=20,
                   left=u'CONtiNUE', right=u'CANCEl')

    # check for previously existing draft
    if 0 != len(session.user.get('draft', u'')):
        # XXX display age of message
        inp = Selector(yloc=term.height - 1,
                       xloc=term.width - 22,
                       width=20,
                       left=u'REStORE', right=u'ERASE')
        blurb = u'CONtiNUE PREViOUSlY SAVEd dRAft ?'
        echo(u'\r\n\r\n')
        echo(term.move(inp.yloc, inp.xloc - len(blurb)))
        echo(term.bold_yellow(blurb))
        selection = inp.read()
        echo(term.move(inp.yloc, 0) + term.clear_eol)
        if selection == u'REStORE':
            msg.body = session.user['draft']

    echo(u'\r\n\r\n')
    session.user['draft'] = msg.body
    if gosub('editor', 'draft'):
        echo(u'\r\n\r\n' + term.normal)
        msg.body = session.user.get('draft', u'')
        del session.user['draft']
        return 0 != len(msg.body.strip())
    return False
Пример #19
0
def chat(sessions):
    """
    Prompt for node and page target session for chat.
    Sysop will send session id of -1, indicating the chat is forced.
    """
    from x84.bbs import gosub, getsession
    session = getsession()
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        # page other user,
        channel = tgt_session['sid']
        sender = (session.user.handle
                  if not 'sysop' in session.user.groups else -1)
        session.send_event('route',
                           (tgt_session['sid'], 'page', channel, sender))
        gosub('chat', channel)
        return True
Пример #20
0
def chat(sessions):
    """
    Prompt for node and page target session for chat.
    Sysop will send session id of -1, indicating the chat is forced.
    """
    from x84.bbs import gosub, getsession
    session = getsession()
    (node, tgt_session) = get_node(sessions)
    if node is not None:
        # page other user,
        channel = tgt_session['sid']
        sender = (session.user.handle
                  if not 'sysop' in session.user.groups else -1)
        session.send_event('route', (
            tgt_session['sid'], 'page', channel, sender))
        gosub('chat', channel)
        return True
Пример #21
0
Файл: debug.py Проект: hick/x84
def main():
    """ Main procedure. """
    # by default, nothing is done.
    from x84.bbs import getsession, gosub
    assert 'sysop' in getsession().user.groups

    #return migrate_105lc()
    #return nothing()
    return gosub('test_keyboard_keys')
Пример #22
0
Файл: top.py Проект: ztaylor/x84
def do_intro_art(term, session):
    """
    Display random art file, prompt for quick login.

    Bonus: allow chosing other artfiles with '<' and '>'.
    """
    editor_colors = {'highlight': term.black_on_red}

    # set syncterm font, if any
    if syncterm_font and term._kind.startswith('ansi'):
        echo(syncterm_setfont(syncterm_font))

    index = int(time.time()) % len(art_files)
    dirty = True
    echo(u'\r\n')
    while True:
        session.activity = 'top'
        if session.poll_event('refresh') or dirty:
            display_intro(term, index)
            display_prompt(term)
            dirty = False
        dirty = True
        inp = LineEditor(1, colors=editor_colors).read()
        if inp is None or inp.lower() == u'y':
            # escape/yes: quick login
            return True
        elif inp.lower() == u'n':
            break

        if len(inp) == 1:
            echo(u'\b')
        if inp == u'!':
            echo(u'\r\n' * 3)
            gosub('charset')
            dirty = True
        elif inp == u'<':
            index -= 1
        elif inp == u'>':
            index += 1
        else:
            dirty = False
Пример #23
0
def main():
    """ Main procedure. """
    from x84.bbs import getsession, getterminal, echo, getch, gosub
    session, term = getsession(), getterminal()
    lcallers, lcalls_txt = lc_retrieve()
    lbr = None
    dirty = True
    handle = None

    if (0 == term.number_of_colors
            or session.user.get('expert', False)):
        echo(redraw(None))
        return dummy_pager(lcalls_txt.split('\n'))

    while lbr is None or not lbr.quit:
        if dirty or lbr is None or session.poll_event('refresh'):
            session.activity = u'Viewing last callers'
            lcallers, lcalls_txt = lc_retrieve()
            pos = lbr.position if lbr is not None else (0, 0)
            lbr = get_lightbar(lcallers, lcalls_txt)
            if pos:
                lbr.position = pos
            echo(redraw(lbr))
            echo(refresh_opts(lbr, handle))
        sel = lbr.selection[0]
        if sel != handle or dirty:
            handle = sel
            echo(refresh_opts(lbr, handle))
            echo(lbr.pos(lbr.yloc + (lbr.height - 1)))
            dirty = False
            continue
        inp = getch(1)
        if inp is not None:
            if inp in (u'v', u'V'):
                view_plan(handle)
                dirty = True
            elif inp in (u'e', u'E') and 'sysop' in session.user.groups:
                gosub('profile', handle)
                dirty = True
            else:
                echo(lbr.process_keystroke(inp))
Пример #24
0
Файл: lc.py Проект: quastdog/x84
def main():
    """ Main procedure. """
    from x84.bbs import getsession, getterminal, echo, getch, gosub
    session, term = getsession(), getterminal()
    lcallers, lcalls_txt = lc_retrieve()
    lbr = None
    dirty = True
    handle = None

    if (0 == term.number_of_colors
            or session.user.get('expert', False)):
        echo(redraw(None))
        return dummy_pager(lcalls_txt.split('\n'))

    while lbr is None or not lbr.quit:
        if dirty or lbr is None or session.poll_event('refresh'):
            session.activity = u'Viewing last callers'
            lcallers, lcalls_txt = lc_retrieve()
            pos = lbr.position if lbr is not None else (0, 0)
            lbr = get_lightbar(lcallers, lcalls_txt)
            if pos:
                lbr.position = pos
            echo(redraw(lbr))
            echo(refresh_opts(lbr, handle))
        sel = lbr.selection[0]
        if sel != handle or dirty:
            handle = sel
            echo(refresh_opts(lbr, handle))
            echo(lbr.pos(lbr.yloc + (lbr.height - 1)))
            dirty = False
            continue
        inp = getch(1)
        if inp is not None:
            if inp in (u'v', u'V'):
                view_plan(handle)
                dirty = True
            elif inp in (u'e', u'E') and 'sysop' in session.user.groups:
                gosub('profile', handle)
                dirty = True
            else:
                echo(lbr.process_keystroke(inp))
Пример #25
0
def do_intro_art(term, session):
    """
    Display random art file, prompt for quick login.

    Bonus: allow chosing other artfiles with '<' and '>'.
    """
    # set syncterm font, if any
    if syncterm_font and term.kind.startswith('ansi'):
        echo(syncterm_setfont(syncterm_font))

    index = int(time.time()) % len(art_files)
    dirty = True
    echo(u'\r\n')
    while True:
        session.activity = 'top'
        if session.poll_event('refresh') or dirty:
            display_intro(term, index)
            display_prompt(term)
            dirty = False
        dirty = True
        inp = LineEditor(1, colors={'highlight': term.normal}).read()
        if inp is None or inp.lower() == u'y':
            # escape/yes: quick login
            return True
        # issue #242 : set 'N' as default, by adding a check for an empty
        # unicode string.
        elif inp.lower() in (u'n', u'\r', u'\n', u''):
            break

        if len(inp) == 1:
            echo(u'\b')
        if inp == u'!':
            echo(u'\r\n' * 3)
            gosub('charset')
            dirty = True
        elif inp == u'<':
            index -= 1
        elif inp == u'>':
            index += 1
        else:
            dirty = False
Пример #26
0
def edit_description(filepath, db_desc):
    """ Edit file description. """
    from x84.bbs import gosub
    new_desc = None
    if filepath in db_desc:
        new_desc = u'\r\n'.join(
            [line.decode('cp437_art') for line in db_desc[filepath]])
    new_desc = gosub('editor', continue_draft=new_desc)
    if not new_desc:
        return
    with db_desc:
        db_desc[filepath] = new_desc.splitlines()
Пример #27
0
def try_reset(user):
    """ Prompt for password reset. """
    from x84.bbs import echo, getch, gosub
    prompt_reset = u'RESEt PASSWORD (bY E-MAil)? [yn]'
    echo(prompt_reset)
    while True:
        inp = getch()
        if inp in (u'y', u'Y'):
            return gosub('pwreset', user.handle)
        elif inp in (u'n', u'N'):
            echo(u'\r\n\r\n')
            return False
Пример #28
0
def edit_description(filepath, db_desc):
    """ Edit file description. """
    from x84.bbs import gosub
    new_desc = None
    if filepath in db_desc:
        new_desc = u'\r\n'.join([line.decode('cp437_art')
                                 for line in db_desc[filepath]])
    new_desc = gosub('editor', continue_draft=new_desc)
    if not new_desc:
        return
    with db_desc:
        db_desc[filepath] = new_desc.splitlines()
Пример #29
0
def try_reset(user):
    """ Prompt for password reset. """
    from x84.bbs import echo, getch, gosub
    prompt_reset = u'RESEt PASSWORD (bY E-MAil)? [yn]'
    echo(prompt_reset)
    while True:
        inp = getch()
        if inp in (u'y', u'Y'):
            return gosub('pwreset', user.handle)
        elif inp in (u'n', u'N'):
            echo(u'\r\n\r\n')
            return False
Пример #30
0
Файл: top.py Проект: hick/x84
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    session, term = getsession(), getterminal()
    session.activity = 'top'

    # attempt to coerce encoding of terminal to match session.
    coerce_terminal_encoding(term, session.encoding)

    # fetch user record
    user = get_user_record(handle)

    # register call
    login(session, user)

    # display art and prompt for quick login
    quick = do_intro_art(term, session)

    echo(term.move_down() * 3)

    # only display news if the account has not
    # yet read the news since last update.
    gosub('news', quick=True)

    if not quick:
        # display last 10 callers, if any
        gosub('lc')

        # one-liners
        gosub('ol')

    goto('main')
Пример #31
0
Файл: top.py Проект: hick/x84
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    session, term = getsession(), getterminal()
    session.activity = 'top'

    # attempt to coerce encoding of terminal to match session.
    coerce_terminal_encoding(term, session.encoding)

    # fetch user record
    user = get_user_record(handle)

    # register call
    login(session, user)

    # display art and prompt for quick login
    quick = do_intro_art(term, session)

    echo(term.move_down() * 3)

    # only display news if the account has not
    # yet read the news since last update.
    gosub('news', quick=True)

    if not quick:
        # display last 10 callers, if any
        gosub('lc')

        # one-liners
        gosub('ol')

    goto('main')
Пример #32
0
def main():
    session, term = getsession(), getterminal()
    session.activity = u'bulletins menu'
    dirty = True

    while True:
        if dirty or session.poll_event('refresh'):
            echo(term.clear())
            showansi('bulletinsmenu.ans')
        echo(u'\r\n' + term.normal + term.white +
             u'  [' + term.blue + u'Select bulletin' + term.white + u']: ')
        inp = getch()

        dirty = True
        if inp == u'1':
            toplist('calls')
        elif inp == u'2':
            toplist('msgs')
        elif inp == u'3':
            gosub('textbrowse')
        else:                      # any other key will return to main menu
            return
Пример #33
0
def main():
    session, term = getsession(), getterminal()
    session.activity = u'bulletins menu'
    dirty = True


    while True:
        if dirty or session.poll_event('refresh'):
            echo(term.clear())
            showansi('bulletinsmenu.ans')
        echo (u'\r\n'+term.normal+term.white+u'  ['+term.blue+u'Select bulletin'+term.white+u']: ')
        inp = getch()

        dirty = True
        if inp == u'1':
            toplist('calls')
        elif inp == u'2':
            toplist('msgs')
        elif inp == u'3':
            gosub('textbrowse')
        else:                      # any other key will return to main menu
            return
Пример #34
0
def main():
    """ Main procedure. """
    from x84.bbs import getsession, echo, getch, gosub
    import codecs
    import time
    import os
    # pylint: disable=W0603
    #         Using the global statement
    global NEWS, NEWSAGE  # in-memory cache
    session = getsession()
    session.activity = 'Reading news'
    newsfile = os.path.join(os.path.dirname(__file__), 'art', 'news.txt')
    if not os.path.exists(newsfile):
        echo(u'\r\n\r\nNo news.')
        return

    pager = None
    dirty = True
    while True:
        if session.poll_event('refresh'):
            dirty = True
        if dirty:
            if NEWS is None or os.stat(newsfile).st_mtime > NEWSAGE:
                # open a utf-8 file for international encodings/art/language
                NEWSAGE = time.time()
                NEWS = [
                    line.rstrip()
                    for line in codecs.open(newsfile, 'rb', 'utf8')
                ]
            if (session.user.get('expert', False)):
                return dummy_pager(NEWS)
            pos = pager.position if pager is not None else None
            pager = get_pager(NEWS, pos)
            echo(redraw(pager))
            dirty = False
        inp = getch(1)
        if inp is not None:
            if inp in (
                    u'e',
                    u'E',
            ) and 'sysop' in session.user.groups:
                session.user['news'] = u'\r\n'.join(NEWS)
                if gosub('editor', 'news'):
                    NEWS = session.user['news'].splitlines()
                    codecs.open(newsfile, 'wb',
                                'utf8').write(u'\r\n'.join(NEWS))
                dirty = True
            else:
                echo(pager.process_keystroke(inp))
                if pager.quit:
                    return
Пример #35
0
def prompt_body(term, msg, colors):
    """ Prompt for and set 'body' of message by executing 'editor' script. """
    with term.fullscreen():
        content = gosub("editor", save_key=None, continue_draft=msg.body)
    # set syncterm font, if any
    if term.kind.startswith("ansi"):
        echo(syncterm_setfont(syncterm_font))
    echo(term.move(term.height, 0) + term.normal + u"\r\n")
    if content and content.strip():
        msg.body = content
        return True
    xpos = max(0, (term.width // 2) - (80 // 2))
    echo(u"".join((term.move_x(xpos), colors["highlight"]("Message canceled."), term.clear_eol)))
    term.inkey(1)
    return False
Пример #36
0
def prompt_body(term, msg, colors):
    """ Prompt for and set 'body' of message by executing 'editor' script. """
    with term.fullscreen():
        content = gosub('editor', save_key=None, continue_draft=msg.body)
    # set syncterm font, if any
    if term.kind.startswith('ansi'):
        echo(syncterm_setfont(syncterm_font))
    echo(term.move(term.height, 0) + term.normal + u'\r\n')
    if content and content.strip():
        msg.body = content
        return True
    xpos = max(0, (term.width // 2) - (80 // 2))
    echo(u''.join((term.move_x(xpos), colors['highlight']('Message canceled.'),
                   term.clear_eol)))
    term.inkey(1)
    return False
Пример #37
0
def main():
    """ Main procedure. """
    from x84.bbs import getsession, echo, getch, gosub
    import codecs
    import time
    import os
    # pylint: disable=W0603
    #         Using the global statement
    global NEWS, NEWSAGE  # in-memory cache
    session = getsession()
    session.activity = 'Reading news'
    newsfile = os.path.join(os.path.dirname(__file__), 'art', 'news.txt')
    if not os.path.exists(newsfile):
        echo(u'\r\n\r\nNo news.')
        return

    pager = None
    dirty = True
    while True:
        if session.poll_event('refresh'):
            dirty = True
        if dirty:
            if NEWS is None or os.stat(newsfile).st_mtime > NEWSAGE:
                # open a utf-8 file for international encodings/art/language
                NEWSAGE = time.time()
                NEWS = [line.rstrip() for line in
                        codecs.open(newsfile, 'rb', 'utf8')]
            if (session.user.get('expert', False)):
                return dummy_pager(NEWS)
            pos = pager.position if pager is not None else None
            pager = get_pager(NEWS, pos)
            echo(redraw(pager))
            dirty = False
        inp = getch(1)
        if inp is not None:
            if inp in (u'e', u'E',) and 'sysop' in session.user.groups:
                session.user['news'] = u'\r\n'.join(NEWS)
                if gosub('editor', 'news'):
                    NEWS = session.user['news'].splitlines()
                    codecs.open(newsfile, 'wb', 'utf8').write(
                        u'\r\n'.join(NEWS))
                dirty = True
            else:
                echo(pager.process_keystroke(inp))
                if pager.quit:
                    return
Пример #38
0
def prompt_body(msg):
    """ Prompt for 'body' of message, executing 'editor' script. """
    from x84.bbs import echo, Selector, getterminal, getsession, gosub
    term = getterminal()
    session = getsession()
    inp = Selector(yloc=term.height - 1,
                   xloc=term.width - 22,
                   width=20,
                   left=u'CONtiNUE',
                   right=u'CANCEl')
    blurb = u'CONtiNUE tO Edit MESSAGE bOdY'
    echo(u'\r\n\r\n')
    echo(term.move(inp.yloc, inp.xloc - len(blurb)))
    echo(term.bold_yellow(blurb))
    selection = inp.read()
    echo(term.move(inp.yloc, 0) + term.clear_eol)
    if selection != u'CONtiNUE':
        return False
    if 0 != len(session.user.get('draft', u'')):
        inp = Selector(yloc=term.height - 1,
                       xloc=term.width - 22,
                       width=20,
                       left=u'REStORE',
                       right=u'ERASE')
        blurb = u'CONtiNUE PREViOUSlY SAVEd dRAft ?'
        echo(u'\r\n\r\n')
        echo(term.move(inp.yloc, inp.xloc - len(blurb)))
        echo(term.bold_yellow(blurb))
        selection = inp.read()
        echo(term.move(inp.yloc, 0) + term.clear_eol)
        if selection == u'REStORE':
            msg.body = session.user['draft']
    echo(u'\r\n\r\n')
    session.user['draft'] = msg.body
    if gosub('editor', 'draft'):
        echo(u'\r\n\r\n' + term.normal)
        msg.body = session.user.get('draft', u'')
        del session.user['draft']
        return 0 != len(msg.body.strip())
    return False
Пример #39
0
Файл: top.py Проект: ztaylor/x84
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    session, term = getsession(), getterminal()
    session.activity = 'top'

    # attempt to coerce encoding of terminal to match session.
    echo ({
        # ESC %G activates UTF-8 with an unspecified implementation
        # level from ISO 2022 in a way that allows to go back to
        # ISO 2022 again.
        'utf8': unichr(27) + u'%G',
        # ESC %@ returns to ISO 2022 in case UTF-8 had been entered.
        # ESC ) U Sets character set G1 to codepage 437, such as on
        # Linux vga console.
        'cp437': unichr(27) + u'%@' + unichr(27) + u')U',
    }.get(session.encoding, u''))

    # fetch user record
    user = get_user_record(handle)

    # register call
    login(session, user)

    # display art and prompt for quick login
    quick = do_intro_art(term, session)

    echo(term.move_down() * 3)

    # only display news if the account has not
    # yet read the news since last update.
    gosub('news', quick=True)

    if not quick:
        # display last 10 callers, if any
        gosub('lc')

        # one-liners
        gosub('ol')

    goto('main')
Пример #40
0
def prompt_body(msg):
    """ Prompt for 'body' of message, executing 'editor' script. """
    from x84.bbs import echo, Selector, getterminal, getsession, gosub
    term = getterminal()
    session = getsession()
    inp = Selector(yloc=term.height - 1,
                   xloc=term.width - 22,
                   width=20,
                   left=u'CONtiNUE', right=u'CANCEl')

    # check for previously existing draft
    if 0 != len(session.user.get('draft', u'')):
        # XXX display age of message
        inp = Selector(yloc=term.height - 1,
                       xloc=term.width - 22,
                       width=20,
                       left=u'REStORE', right=u'ERASE')
        blurb = u'CONtiNUE PREViOUSlY SAVEd dRAft ?'
        echo(u'\r\n\r\n')
        echo(term.move(inp.yloc, inp.xloc - len(blurb)))
        echo(term.bold_yellow(blurb))
        selection = inp.read()
        echo(term.move(inp.yloc, 0) + term.clear_eol)
        if selection == u'REStORE':
            msg.body = session.user['draft']
        else:
            # delete the draft
            del session.user['draft']

    echo(u'\r\n\r\n')
    content = gosub('editor', save_key=None, continue_draft=msg.body)
    if content and content.strip():
        echo(u'\r\n\r\n' + term.normal)
        msg.body = content
        return True
    return False
Пример #41
0
def dummy_pager(last_callers):
    """ Dummy pager for displaying last callers """
    # pylint: disable=R0914
    #         Too many local variables
    from x84.bbs import getterminal, getsession, echo, getch, ini, find_user
    from x84.bbs import LineEditor, Ansi, list_users, get_user, gosub
    session, term = getsession(), getterminal()
    msg_prompt = (
        u'\r\n%sONtiNUE, %stOP, %sON-StOP %siEW .PlAN%s ?\b\b' % (
        term.bold(u'[c]'),
        term.bold(u'[s]'),
        term.bold(u'n'),
        term.bold(u'[v]'),
        u' [e]dit USR' if (
        'sysop' in session.user.groups) else u'',))
    msg_partial = u'PARtiAl MAtChES'
    msg_prompt_handle = u'ViEW .PlAN ::- ENtER hANdlE: '

    redraw()
    echo(u'\r\n\r\n')
    nonstop = False
    row = 10  # after-art,
    for txt in last_callers:
        echo(Ansi(txt).ljust(term.width / 2).center(term.width))
        echo(u'\r\n')
        row += 1
        if ((not nonstop and row > 0 and 0 == (row % (term.height - 3)))
                or (row == len(last_callers) - 1)):
            echo(msg_prompt)
            inp = getch()
            row = 2
            if inp in (u's', u'S', u'q', u'Q', term.KEY_EXIT):
                return
            if inp in (u'v', u'V') or 'sysop' in session.user.groups and (
                    inp in (u'e', u'E')):
                echo(u'\r\n\r\n')
                echo(msg_prompt_handle)
                handle = LineEditor(ini.CFG.getint('nua', 'max_user')).read()
                usrlist = list_users()
                if handle is None or 0 == len(handle.strip()):
                    continue
                handle = handle.strip()
                if handle.lower() in [nick.lower() for nick in list_users()]:
                    nick = ((_nick for _nick in usrlist
                        if _nick.lower() == handle.lower()).next())
                    if find_user(nick):
                        user = get_user(nick)
                        if 'sysop' in session.user.groups and (
                                inp in (u'e', u'E')):
                            gosub('profile', user.handle)
                        else:
                            view_plan(user.handle)
                else:
                    misses = [nick for nick in usrlist.keys()
                              if nick.lower().startswith(handle[:1].lower())]
                    if len(misses) > 0:
                        echo(u'%s:\r\n\r\n%s\r\n' % (msg_partial,
                            Ansi(', '.join(misses)).wrap(term.width)))
                    continue
            if inp in ('n', u'N'):
                nonstop = True
            echo(u'\r\n\r\n')
    pak()
Пример #42
0
def main():
    """ Main procedure. """
    from x84.bbs import getterminal, getsession, getch, goto, gosub
    from x84.bbs import ini, echo
    from ConfigParser import Error as ConfigError
    import os
    import logging

    key_map = {
        '$': 'bulletins',
        'n': 'news',
        'p': 'writemsg',
        'r': 'readmsgs',
        'c': 'chat',
        'i': 'ircchat',
        'l': 'lc',
        'o': 'ol',
        'b': 'bbslist',
        'f': 'weather',
        't': 'tetris',
        'w': 'online',
        '!': 'charset',
        's': 'si',
        'u': 'userlist',
        'e': 'profile',
        'x': 'main',
        'g': 'logoff',
        '#': 'lord'
    }

    # add LORD to menu only if enabled,
    logger = logging.getLogger()
    session, term = getsession(), getterminal()
    session.activity = u'Lightbar Main menu'

    echo(term.clear)
    show_banner()
    lb = lb_init()

    term_width = term.width
    term_height = term.height

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            lb_refresh(lb)

        inp = getch(1)
        dirty = True

        # terminal dimensions may change, so we adapt to that
        if (term_width != term.width or term_height != term.height):
            echo(term.clear)
            show_banner()
            lb = lb_init()
            lb_refresh(lb)
            term_width = term.width
            term_height = term.height

        if inp is not None:
            echo(lb.process_keystroke(inp))

            if lb.selected and lb.selection[0] is not None:
                script = key_map.get(lb.selection[0])

                if script:
                    if script == u'x':
                        goto('main')
                    elif script == u'v' and 'sysop' in session.user.groups:
                        gosub('ttyplay')
                    else:
                        echo(term.clear)
                        gosub(script)

                    echo(term.clear)
                    show_banner()

            else:
                handled = False
                try:
                    for option in ini.CFG.options('sesame'):
                        if option.endswith('_key'):
                            door = option.replace('_key', '')
                            key = ini.CFG.get('sesame', option)
                            if inp == key:
                                gosub('sesame', door)
                                handled = True
                                break
                except ConfigError:
                    pass

                if not handled:
                    dirty = False
Пример #43
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #         Too many branches
    from x84.bbs import getsession, getch, goto, gosub, ini
    from ConfigParser import Error as ConfigError
    session = getsession()

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            goto('main')  # reload main menu using hidden option '*'
        elif inp == u'$':
            gosub('bulletins')
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'u':
            gosub('userlist')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        elif inp == u't':
            gosub('tetris')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'i':
            gosub('ircchat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        else:
            handled = False
            try:
                for option in ini.CFG.options('sesame'):
                    if option.endswith('_key'):
                        door = option.replace('_key', '')
                        key = ini.CFG.get('sesame', option)
                        if inp == key:
                            gosub('sesame', door)
                            handled = True
                            break
            except ConfigError:
                pass

            if not handled:
                dirty = False
Пример #44
0
def read_messages(msgs, title, currentpage, totalpages, threadid, cachetime):
    """
    Provide message reader UI given message list ``msgs``,
    with new messages in list ``new``.
    """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    from x84.bbs import timeago, get_msg, getterminal, echo, gosub
    from x84.bbs import ini, Pager, getsession, getch, Ansi, Msg
    import x84.default.writemsg
    session, term = getsession(), getterminal()

    session.activity = 'reading msgs'
    # build header
    #len_idx = max([len('%d' % (_idx,)) for _idx in msgs])
    len_idx = 40
    len_author = ini.CFG.getint('nua', 'max_user')
    len_ago = 9
    len_subject = ini.CFG.getint('msg', 'max_subject')
    len_preview = min(len_idx + len_author + len_ago + len_subject + -1, term.width - 2)
    reply_depth = ini.CFG.getint('msg', 'max_depth')
    indent_start, indent, indent_end = u'\\', u'-', u'> '

    def get_header(msgs_idx):
        """
        Return list of tuples, (idx, unicodestring), suitable for Lightbar.
        """
        import datetime
        msg_list = list()

        def head(msg, depth=0, maxdepth=reply_depth):
            """ This recursive routine finds the 'head' message
                of any relationship, up to maxdepth.
            """
            if (depth <= maxdepth
                    and hasattr(msg, 'parent')
                    and msg.parent is not None):
                return head(get_msg(msg.parent), depth + 1, maxdepth)
            return msg.idx, depth

        for idx, txt in enumerate(msgs_idx):
            author, subj = txt[0], txt[1]
            msg_list.append([idx, author, subj])
            
        return msg_list

    def get_selector(mailbox, prev_sel=None):
        """
        Provide Lightbar UI element given message mailbox returned from
        function get_header, and prev_sel as previously instantiated Lightbar.
        """
        from x84.bbs import Lightbar
        pos = prev_sel.position if prev_sel is not None else (0, 0)
        sel = Lightbar(
            height=(term.height / 3
                    if term.width < 140 else term.height - 3),
            width=len_preview, yloc=2, xloc=0)
        sel.glyphs['top-horiz'] = u''
        sel.glyphs['left-vert'] = u''
        sel.colors['highlight'] = term.yellow_reverse
        sel.update(mailbox)
        sel.position = pos
        return sel

    def get_reader():
        """
        Provide Pager UI element for message reading.
        """
        reader_height = (term.height - (term.height / 3) - 2)
        reader_indent = 2
        reader_width = min(term.width - 1, min(term.width - reader_indent, 80))
        reader_ypos = ((term.height - 1 ) - reader_height if
                      (term.width - reader_width) < len_preview else 2)
        reader_height = term.height - reader_ypos - 1
        msg_reader = Pager(
            height=reader_height,
            width=reader_width,
            yloc=reader_ypos,
            xloc=min(len_preview + 2, term.width - reader_width))
        msg_reader.glyphs['top-horiz'] = u''
        msg_reader.glyphs['right-vert'] = u''
        return msg_reader

#   def format_msg(reader, idx):
#       """ Format message of index ``idx`` into Pager instance ``reader``. """
#       msg = msgs[idx]
#       author = msg[1][0]
#       body = msg[1][1]
#       ucs = u'\r\n'.join((
#           (u''.join((
#               term.yellow('fROM: '),
#               (u'%s' % term.bold(author,)).rjust(len(author)),
#               u' ' * (reader.visible_width - (len(author) )),
#               ))),
#           u''.join((
#               term.yellow('tO: '),
#           (Ansi(
#               term.yellow('tAGS: ')
#               + (u'%s ' % (term.bold(','),)).join((
#                   [term.bold_red(_tag)
#                       if _tag in SEARCH_TAGS
#                       else term.yellow(_tag)
#                       for _tag in msg.tags]))).wrap(
#                           reader.visible_width,
#                           indent=u'      ')),
#           (term.yellow_underline(
#               (u'SUbj: %s' % (msg.subject,)).ljust(reader.visible_width)
#           )),
#           u'', (msg.body),))
#       return ucs

    def get_selector_title(mbox):
        return cachetime

    def get_selector_footer(currentpage, totalpages):
        return 'Page '+currentpage+'/'+totalpages 

    def get_reader_footer(idx):
        """
        Returns unicode string suitable for displaying
        as footer of reader when window is active
        """

        return u''.join((
            idx,
            term.yellow(u'- '),
            u' '.join((
                term.yellow_underline(u'<') + u':back ',
                term.yellow_underline(u'r') + u':eply ',
                term.yellow_underline(u'q') + u':uit',)),
            term.yellow(u' -'),))

    def refresh(reader, selector, mbox, title):
        """
        Returns unicode string suitable for refreshing the screen.
        """
        if READING:
            reader.colors['border'] = term.bold_yellow
            selector.colors['border'] = term.bold_black
        else:
            reader.colors['border'] = term.bold_black
            selector.colors['border'] = term.bold_yellow
        padd_attr = (term.bold_yellow if not READING
                     else term.bold_black)
        sel_padd_right = padd_attr(
            u'-'
            + selector.glyphs['bot-horiz'] * (
            selector.visible_width - len(Ansi(str(title))) - 7)
            + u'-\u25a0-' if READING else u'- -')
        sel_padd_left = padd_attr(
            selector.glyphs['bot-horiz'] * 3)
        idx = selector.selection[0]
        return u''.join((term.move(0, 0), term.clear, u'\r\n',cachetime,
                         u'// REAdiNG MSGS ..'.center(term.width).rstrip(),
                         selector.refresh(),
                         selector.border() if READING else reader.border(),
                         reader.border() if READING else selector.border(),
                         selector.title(
                             sel_padd_left + title + sel_padd_right),
                         selector.footer(get_selector_footer(currentpage, totalpages)
                                         ) if not READING else u'',
                         #reader.footer(get_reader_footer(u'Post '+str(idx))
                         reader.footer(get_reader_footer(cachetime)
                                       ) if READING else u'',
                         reader.refresh(),
                         ))

    echo((u'\r\n' + term.clear_eol) * (term.height - 1))
    dirty = 2
    msg_selector = None
    msg_reader = None
    idx = None
    # pylint: disable=W0603
    #         Using the global statement
    global READING
    while (msg_selector is None and msg_reader is None
           ) or not (msg_selector.quit or msg_reader.quit):
        if session.poll_event('refresh'):
            dirty = 2
        if dirty:
            if dirty == 2:
                mailbox = get_header(msgs)
            msg_selector = get_selector(mailbox, msg_selector)
            idx = msg_selector.selection[0]
            msg_reader = get_reader()
            msg_reader.update(msgs[idx][1])
            echo(refresh(msg_reader, msg_selector, msgs, title))
            dirty = 0
        inp = getch(1)
        if inp in (u'r', u'R'):
            reply_msgbody = quote_body(msgs[idx][1],
                                        max(30, min(79, term.width - 4)), msgs[idx][0])
            echo(term.move(term.height, 0) + u'\r\n')
            session.user['draft'] = reply_msgbody
            if gosub('editor', 'draft'):
                makepost(threadid, session.user['draft'])
                dirty = 2
                READING = False
            else:
                dirty = 1
            #mark_read(idx)  # also mark as read

        # 't' uses writemsg.prompt_tags() routine, how confusing ..
        elif inp in (u't',) and allow_tag(idx):
            echo(term.move(term.height, 0))
            msg = get_msg(idx)
            if x84.default.writemsg.prompt_tags(msg):
                msg.save()
            dirty = 2

        # spacebar marks as read, goes to next message
        elif inp in (u' ',):
            dirty = 1#2 if mark_read(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        # D marks as deleted, goes to next message
        elif inp in (u'D',):
            dirty = 2 if mark_delete(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        # U undeletes, does not move.
        elif inp in (u'U',):
            dirty = 2 if mark_undelete(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        if READING:
            echo(msg_reader.process_keystroke(inp))
            # left, <, or backspace moves UI
            if inp in (term.KEY_LEFT, u'<', u'h',
                       '\b', term.KEY_BACKSPACE):
                READING = False
                dirty = 1
        else:
            echo(msg_selector.process_keystroke(inp))
            idx = msg_selector.selection[0]
            # right, >, or enter marks message read, moves UI
            if inp in (u'\r', term.KEY_ENTER, u'>',
                       u'l', 'L', term.KEY_RIGHT):
                dirty = 1#2 if mark_read(idx) else 1
                READING = True
            elif msg_selector.moved:
                dirty = 1
    echo(term.move(term.height, 0) + u'\r\n')
    return
Пример #45
0
def read_messages(msgs, new):
    """
    Provide message reader UI given message list ``msgs``,
    with new messages in list ``new``.
    """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    from x84.bbs import timeago, get_msg, getterminal, echo, gosub
    from x84.bbs import ini, Pager, getsession, getch, Ansi, Msg
    import x84.default.writemsg
    session, term = getsession(), getterminal()

    session.activity = 'reading msgs'
    # build header
    len_idx = max([len('%d' % (_idx,)) for _idx in msgs])
    len_author = ini.CFG.getint('nua', 'max_user')
    len_ago = 9
    len_subject = ini.CFG.getint('msg', 'max_subject')
    len_preview = min(len_idx + len_author + len_ago + len_subject + -1, term.width - 2)
    reply_depth = ini.CFG.getint('msg', 'max_depth')
    indent_start, indent, indent_end = u'\\', u'-', u'> '

    def get_header(msgs_idx):
        """
        Return list of tuples, (idx, unicodestring), suitable for Lightbar.
        """
        import datetime
        msg_list = list()
        thread_indent = lambda depth: (term.red(
            (indent_start + (indent * depth) + indent_end))
            if depth else u'')

        def head(msg, depth=0, maxdepth=reply_depth):
            """ This recursive routine finds the 'head' message
                of any relationship, up to maxdepth.
            """
            if (depth <= maxdepth
                    and hasattr(msg, 'parent')
                    and msg.parent is not None):
                return head(get_msg(msg.parent), depth + 1, maxdepth)
            return msg.idx, depth

        for idx in msgs_idx:
            msg = get_msg(idx)
            author, subj = msg.author, msg.subject
            tm_ago = (datetime.datetime.now() - msg.stime).total_seconds()
            # pylint: disable=W0631
            #         Using possibly undefined loop variable 'idx'
            attr = lambda arg: (
                term.bold_green(arg) if (
                    not idx in ALREADY_READ
                    and msg.recipient == session.user.handle) else
                term.red(arg) if not idx in ALREADY_READ
                else term.yellow(arg))
            status = [u'U' if not idx in ALREADY_READ else u' ',
                      u'D' if idx in DELETED else u' ', ]
            row_txt = u'%s %s %s %s %s%s ' % (
                u''.join(status),
                attr(str(idx).rjust(len_idx)),
                attr(author.ljust(len_author)),
                (timeago(tm_ago)).rjust(len_ago),
                attr(u'ago'),
                term.bold_black(':'),)
            msg_list.append((head(msg), idx, row_txt, subj))
        msg_list.sort()
        return [(idx, row_txt + thread_indent(depth) + subj)
                for (_threadid, depth), idx, row_txt, subj in msg_list]

    def get_selector(mailbox, prev_sel=None):
        """
        Provide Lightbar UI element given message mailbox returned from
        function get_header, and prev_sel as previously instantiated Lightbar.
        """
        from x84.bbs import Lightbar
        pos = prev_sel.position if prev_sel is not None else (0, 0)
        sel = Lightbar(
            height=(term.height / 3
                    if term.width < 140 else term.height - 3),
            width=len_preview,
            yloc=2, xloc=0)
        sel.glyphs['top-horiz'] = u''
        sel.glyphs['left-vert'] = u''
        sel.colors['highlight'] = term.yellow_reverse
        sel.update(mailbox)
        sel.position = pos
        return sel

    def get_reader():
        """
        Provide Pager UI element for message reading.
        """
        reader_height = (term.height - (term.height / 3) - 2)
        reader_indent = 2
        reader_width = min(term.width - 1, min(term.width - reader_indent, 80))
        reader_ypos = ((term.height - 1 ) - reader_height if
                      (term.width - reader_width) < len_preview else 2)
        reader_height = term.height - reader_ypos - 1
        msg_reader = Pager(
            height=reader_height,
            width=reader_width,
            yloc=reader_ypos,
            xloc=min(len_preview + 2, term.width - reader_width))
        msg_reader.glyphs['top-horiz'] = u''
        msg_reader.glyphs['right-vert'] = u''
        return msg_reader

    def format_msg(reader, idx):
        """ Format message of index ``idx`` into Pager instance ``reader``. """
        msg = get_msg(idx)
        sent = msg.stime.strftime(TIME_FMT)
        to_attr = term.bold_green if (
            msg.recipient == session.user.handle) else term.underline
        ucs = u'\r\n'.join((
            (u''.join((
                term.yellow('fROM: '),
                (u'%s' % term.bold(msg.author,)).rjust(len_author),
                u' ' * (reader.visible_width - (len_author + len(sent))),
                sent,))),
            u''.join((
                term.yellow('tO: '),
                to_attr((u'%s' % to_attr(msg.recipient,)).rjust(len_author)
                        if msg.recipient is not None else u'All'),)),
            (Ansi(
                term.yellow('tAGS: ')
                + (u'%s ' % (term.bold(','),)).join((
                    [term.bold_red(_tag)
                        if _tag in SEARCH_TAGS
                        else term.yellow(_tag)
                        for _tag in msg.tags]))).wrap(
                            reader.visible_width,
                            indent=u'      ')),
            (term.yellow_underline(
                (u'SUbj: %s' % (msg.subject,)).ljust(reader.visible_width)
            )),
            u'', (msg.body),))
        return ucs

    def get_selector_title(mbox, new):
        """
        Returns unicode string suitable for displaying as title of mailbox.
        """
        newmsg = (term.yellow(u' ]-[ ') +
                  term.yellow_reverse(str(len(new))) +
                  term.bold_underline(u' NEW')) if len(new) else u''
        return u''.join((term.yellow(u'[ '),
                         term.bold_yellow(str(len(mbox))),
                         term.bold(
                         u' MSG%s' % (u's' if 1 != len(mbox) else u'',)),
                         newmsg, term.yellow(u' ]'),))

    dispcmd_mark = lambda idx: (
        (term.yellow_underline(u' ') + u':mark' + u' ')
        if idx not in ALREADY_READ else u'')
    dispcmd_delete = lambda idx: (
        (term.yellow_underline(u'D') + u':elete' + u' ')
        if idx not in DELETED else u'')
    dispcmd_tag = lambda idx: (
        (term.yellow_underline(u't') + u':ag' + u' ')
        if allow_tag(idx) else u'')

    def get_selector_footer(idx):
        """
        Returns unicode string suitable for displaying
        as footer of mailbox when window is active.
        """
        return u''.join((
            term.yellow(u'- '),
            u''.join((
                term.yellow_underline(u'>') + u':read ',
                term.yellow_underline(u'r') + u':eply ',
                dispcmd_mark(idx),
                dispcmd_delete(idx),
                dispcmd_tag(idx),
                term.yellow_underline(u'q') + u':uit',)),
            term.yellow(u' -'),))

    def get_reader_footer(idx):
        """
        Returns unicode string suitable for displaying
        as footer of reader when window is active
        """

        return u''.join((
            term.yellow(u'- '),
            u' '.join((
                term.yellow_underline(u'<') + u':back ',
                term.yellow_underline(u'r') + u':eply ',
                dispcmd_delete(idx),
                dispcmd_tag(idx),
                term.yellow_underline(u'q') + u':uit',)),
            term.yellow(u' -'),))

    def refresh(reader, selector, mbox, new):
        """
        Returns unicode string suitable for refreshing the screen.
        """
        if READING:
            reader.colors['border'] = term.bold_yellow
            selector.colors['border'] = term.bold_black
        else:
            reader.colors['border'] = term.bold_black
            selector.colors['border'] = term.bold_yellow
        title = get_selector_title(mbox, new)
        padd_attr = (term.bold_yellow if not READING
                     else term.bold_black)
        sel_padd_right = padd_attr(
            u'-'
            + selector.glyphs['bot-horiz'] * (
            selector.visible_width - len(Ansi(title)) - 7)
            + u'-\u25a0-' if READING else u'- -')
        sel_padd_left = padd_attr(
            selector.glyphs['bot-horiz'] * 3)
        idx = selector.selection[0]
        return u''.join((term.move(0, 0), term.clear, u'\r\n',
                         u'// REAdiNG MSGS ..'.center(term.width).rstrip(),
                         selector.refresh(),
                         selector.border() if READING else reader.border(),
                         reader.border() if READING else selector.border(),
                         selector.title(
                             sel_padd_left + title + sel_padd_right),
                         selector.footer(get_selector_footer(idx)
                                         ) if not READING else u'',
                         reader.footer(get_reader_footer(idx)
                                       ) if READING else u'',
                         reader.refresh(),
                         ))

    echo((u'\r\n' + term.clear_eol) * (term.height - 1))
    dirty = 2
    msg_selector = None
    msg_reader = None
    idx = None
    # pylint: disable=W0603
    #         Using the global statement
    global READING
    while (msg_selector is None and msg_reader is None
           ) or not (msg_selector.quit or msg_reader.quit):
        if session.poll_event('refresh'):
            dirty = 2
        if dirty:
            if dirty == 2:
                mailbox = get_header(msgs)
            msg_selector = get_selector(mailbox, msg_selector)
            idx = msg_selector.selection[0]
            msg_reader = get_reader()
            msg_reader.update(format_msg(msg_reader, idx))
            echo(refresh(msg_reader, msg_selector, msgs, new))
            dirty = 0
        inp = getch(1)
        if inp in (u'r', u'R'):
            reply_to = get_msg(idx)
            reply_msg = Msg()
            reply_msg.recipient = reply_to.author
            reply_msg.tags = reply_to.tags
            reply_msg.subject = reply_to.subject
            reply_msg.parent = reply_to.idx
            # quote between 30 and 79, 'screen width - 4' as variable dist.
            reply_msg.body = quote_body(reply_to,
                                        max(30, min(79, term.width - 4)))
            echo(term.move(term.height, 0) + u'\r\n')
            if gosub('writemsg', reply_msg):
                reply_msg.save()
                dirty = 2
                READING = False
            else:
                dirty = 1
            mark_read(idx)  # also mark as read

        # 't' uses writemsg.prompt_tags() routine, how confusing ..
        elif inp in (u't',) and allow_tag(idx):
            echo(term.move(term.height, 0))
            msg = get_msg(idx)
            if x84.default.writemsg.prompt_tags(msg):
                msg.save()
            dirty = 2

        # spacebar marks as read, goes to next message
        elif inp in (u' ',):
            dirty = 2 if mark_read(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        # D marks as deleted, goes to next message
        elif inp in (u'D',):
            dirty = 2 if mark_delete(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        # U undeletes, does not move.
        elif inp in (u'U',):
            dirty = 2 if mark_undelete(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        if READING:
            echo(msg_reader.process_keystroke(inp))
            # left, <, or backspace moves UI
            if inp in (term.KEY_LEFT, u'<', u'h',
                       '\b', term.KEY_BACKSPACE):
                READING = False
                dirty = 1
        else:
            echo(msg_selector.process_keystroke(inp))
            idx = msg_selector.selection[0]
            # right, >, or enter marks message read, moves UI
            if inp in (u'\r', term.KEY_ENTER, u'>',
                       u'l', 'L', term.KEY_RIGHT):
                dirty = 2 if mark_read(idx) else 1
                READING = True
            elif msg_selector.moved:
                dirty = 1
    echo(term.move(term.height, 0) + u'\r\n')
    return
Пример #46
0
def process_keystroke(inp, user):
    """ Process keystroke, ``inp``, for target ``user``. """
    # pylint: disable=R0914,R0912,R0915,R0911,W0603
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    #         Too many return statements
    #         Using the global statement
    # ^ lol, this is one of those things that should be
    #   refactored into smaller subroutines =)
    from x84.bbs import getsession, getterminal, echo, getch, gosub
    from x84.bbs import LineEditor, ScrollingEditor
    from x84.default.nua import set_email, set_location
    from x84.bbs.ini import CFG
    def_timeout = CFG.getint('system', 'timeout')
    global EXIT
    session, term = getsession(), getterminal()
    is_self = bool(user.handle == session.user.handle)
    invalid = u'\r\niNVAlid.'
    assert is_self or 'sysop' in session.user.groups

    if is_self and inp in (u'c', u'C'):
        gosub('charset')

    elif is_self and inp in (u't', u'T'):
        echo(term.move(term.height - 1, 0))
        echo(ABOUT_TERM + u'\r\n')
        echo(u'\r\ntERMiNAl tYPE: ')
        term = LineEditor(30, session.env.get('TERM')).read()
        echo(u"\r\n\r\nset TERM to '%s'? [yn]" % (term,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                session.env['TERM'] = term
                break
            elif inp2 in (u'n', u'N'):
                break

    elif is_self and inp in (u'w', u'W'):
        echo(u'\r\ntERMiNAl Width: ')
        width = LineEditor(3, str(term.width)).read()
        try:
            width = int(width)
        except ValueError:
            echo(invalid)
            return True
        if width < 0 or width > 999:
            echo(invalid)
            return True
        echo(u"\r\n\r\nset COLUMNS=%d? [yn]" % (width,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                term.columns = width
                break
            elif inp2 in (u'n', u'N'):
                break

    elif is_self and inp in (u'h', u'H'):
        echo(u'\r\ntERMiNAl hEiGht: ')
        height = LineEditor(3, str(term.height)).read()
        try:
            height = int(height)
        except ValueError:
            echo(invalid)
            return True
        if height < 0 or height > 999:
            echo(invalid)
            return True
        echo(u"\r\n\r\nset LINES=%d? [yn]" % (height,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                term.rows = height
                break
            elif inp2 in (u'n', u'N'):
                break

    elif 'sysop' in session.user.groups and inp in (u'd', u'D',):
        echo(u"\r\n\r\ndElEtE %s ? [yn]" % (user.handle,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user.delete()
                break
            elif inp2 in (u'n', u'N'):
                break
        EXIT = True

    elif 'sysop' in session.user.groups and inp in (u's', u'S',):
        sysop = not 'sysop' in user.groups
        echo(u"\r\n\r\n%s SYSOP ACCESS? [yn]" % (
            'ENAblE' if sysop else 'diSAblE',))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                if sysop:
                    user.groups.add('sysop')
                else:
                    user.groups.remove('sysop')
                user.save()
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'p', u'P'):
        from x84.default.nua import set_password
        set_password(user)
        echo(u"\r\n\r\nSEt PASSWORd ? [yn]")
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user.save()
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'k', 'K',):
        change = True
        if user.get('pubkey', False):
            echo(u"\r\n\r\nSSh PUbliC kEY AlREAdY SEt, ChANGE ? [yn]")
            while True:
                inp2 = getch()
                if inp2 in (u'y', u'Y'):
                    break
                elif inp2 in (u'n', u'N'):
                    change = False
                    break
        if change:
            echo(u"\r\n\r\njUSt PAStE iN YOUR PUbliC kEY, MAkE SURE itS "
                 u"All iN ONE lINE!\r\n\r\n\r\n")
            editor = ScrollingEditor(width=term.width - 6,
                                     yloc=term.height - 3,
                                     xloc=3)
            echo(term.reverse_yellow)
            pubkey = editor.read()
            echo(term.normal)
            if pubkey is not None:
                if not pubkey.strip():
                    if user.get('pubkey', None):
                        del user['pubkey']
                    echo(u'\r\n\r\nYOUR SECREtS ARE NEVER SAfE!\r\n')
                else:
                    echo(u'\r\n\r\nWElCOME tO thE bROthERhOOd!\r\n')
                    user['pubkey'] = pubkey
                user.save()
                getch(timeout=1.5)
            else:
                echo(u'\r\n\r\nCANCElEd!!\r\n')
                getch(timeout=0.5)

    elif inp in (u'.',):
        echo(term.move(0, 0) + term.normal + term.clear)
        echo(term.move(int(term.height * .8), 0))
        for line in term.wrap(ABOUT_DOT_PLAN, term.width / 3):
            echo(line.center(term.width).rstrip() + u'\r\n')
        echo(u'\r\n\r\nPRESS ANY kEY ...')
        getch()
        if is_self:
            gosub('editor', '.plan')
        else:
            tmpkey = '%s-%s' % (user.handle, user.plan)
            draft = user.get('.plan', u'')
            session.user[tmpkey] = draft
            gosub('editor', tmpkey)
            if session.user.get(tmpkey, u'') != draft:
                echo(u"\r\n\r\nSEt .PlAN ? [yn]")
                while True:
                    inp2 = getch()
                    if inp2 in (u'y', u'Y'):
                        user['.plan'] = session.user[tmpkey]
                        break
                    elif inp2 in (u'n', u'N'):
                        break
    elif inp in (u'l', u'L'):
        echo(term.move(term.height - 1, 0))
        set_location(user)
        echo(u"\r\n\r\nSEt lOCAtiON tO '%s'? [yn]" % (user.location,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user.save()
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'e', u'E'):
        echo(term.move(term.height - 1, 0))
        set_email(user)
        echo(u"\r\n\r\nSEt EMAil tO '%s'? [yn]" % (user.email,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user.save()
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'i', u'I'):
        echo(u'\r\ntiMEOUt (0=NONE): ')
        timeout = LineEditor(6, str(user.get('timeout', def_timeout))).read()
        try:
            timeout = int(timeout)
        except ValueError:
            echo(invalid)
            return True
        if timeout < 0:
            echo(invalid)
            return True
        echo(u"\r\n\r\nSet tiMEOUt=%s? [yn]" % (
            timeout if timeout else 'None',))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user['timeout'] = timeout
                session.send_event('set-timeout', timeout)
                break
            elif inp2 in (u'n', u'N'):
                break

    elif inp in (u'm', u'M'):
        mesg = False if user.get('mesg', True) else True
        echo(u"\r\n\r\n%s iNStANt MESSAGiNG? [yn]" % (
            'ENAblE' if mesg else 'DiSAblE',))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user['mesg'] = mesg
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'x', u'X'):
        expert = not user.get('expert', False)
        echo(u"\r\n\r\n%s EXPERt MOdE? [yn]" % (
            'ENAblE' if expert else 'DiSAblE',))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user['expert'] = expert
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'q', u'Q',):
        EXIT = True
    else:
        return False
    return True
Пример #47
0
def process_keystroke(lightbar, inp, user):
    """ Process keystroke, ``inp``, for target ``user``. """
    # pylint: disable=R0914,R0912,R0915,R0911,W0603
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    #         Too many return statements
    #         Using the global statement
    from x84.bbs import getsession, getterminal, echo, getch, gosub
    from x84.bbs import LineEditor, Ansi
    from x84.default.nua import set_email, set_location
    global EXIT
    session, term = getsession(), getterminal()
    is_self = bool(user.handle == session.user.handle)
    invalid = u'\r\niNVAlid.'
    if lightbar is not None:
        echo(lightbar.process_keystroke(inp))
        if lightbar.moved:
            return False
    assert is_self or 'sysop' in session.user.groups
    # pylint: disable=W0311
    #         Bad indentation. Found 12 spaces, expected 8
    if is_self and (
        inp in (u'c', u'C') or (inp == term.KEY_ENTER and
                                lightbar is not None and
                                lightbar.selection[0] == u'c')):
            gosub('charset')
    elif is_self and (
        inp in (u't', u'T') or (inp == term.KEY_ENTER and
                                lightbar is not None and
                                lightbar.selection[0] == u't')):
            echo(term.move(term.height - 1, 0))
            echo(ABOUT_TERM + u'\r\n')
            echo(u'\r\ntERMiNAl tYPE: ')
            term = LineEditor(30, session.env.get('TERM')).read()
            echo(u"\r\n\r\nset TERM to '%s'? [yn]" % (term,))
            while True:
                inp2 = getch()
                if inp2 in (u'y', u'Y'):
                    session.env['TERM'] = term
                    break
                elif inp2 in (u'n', u'N'):
                    break
    elif is_self and (
        inp in (u'w', u'W') or (inp == term.KEY_ENTER and
                                lightbar is not None and
                                lightbar.selection[0] == u'w')):
            echo(u'\r\ntERMiNAl Width: ')
            width = LineEditor(3, str(term.width)).read()
            try:
                width = int(width)
            except ValueError:
                echo(invalid)
                return True
            if width < 0 or width > 999:
                echo(invalid)
                return True
            echo(u"\r\n\r\nset COLUMNS=%d? [yn]" % (width,))
            while True:
                inp2 = getch()
                if inp2 in (u'y', u'Y'):
                    term.columns = width
                    break
                elif inp2 in (u'n', u'N'):
                    break
    elif is_self and (
            inp in (u'h', u'H') or (inp == term.KEY_ENTER and
                                    lightbar is not None and
                                    lightbar.selection[0] == u'h')):
            echo(u'\r\ntERMiNAl hEiGht: ')
            height = LineEditor(3, str(term.height)).read()
            try:
                height = int(height)
            except ValueError:
                echo(invalid)
                return True
            if height < 0 or height > 999:
                echo(invalid)
                return True
            echo(u"\r\n\r\nset LINES=%d? [yn]" % (height,))
            while True:
                inp2 = getch()
                if inp2 in (u'y', u'Y'):
                    term.rows = height
                    break
                elif inp2 in (u'n', u'N'):
                    break
    elif ('sysop' in session.user.groups and (
        inp in (u'd', u'D',) or (inp == term.KEY_ENTER and
                                 lightbar is not None and
                                 lightbar.selection[0] == u'd'))):
        echo(u"\r\n\r\ndElEtE %s ? [yn]" % (user.handle,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user.delete()
                break
            elif inp2 in (u'n', u'N'):
                break
        EXIT = True
    elif 'sysop' in session.user.groups and (
            inp in (u's', u'S',) or (inp == term.KEY_ENTER and
                                     lightbar is not None and
                                     lightbar.selection[0] == u's')):
        sysop = not 'sysop' in user.groups
        echo(u"\r\n\r\n%s SYSOP ACCESS? [yn]" % (
            'ENAblE' if sysop else 'diSAblE',))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                if sysop:
                    user.groups.add('sysop')
                else:
                    user.groups.remove('sysop')
                user.save()
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'p',) or (inp == term.KEY_ENTER and
                            lightbar is not None and
                            lightbar.selection[0] == u'p'):
        from x84.default.nua import set_password
        set_password(user)
        echo(u"\r\n\r\nSEt PASSWORd ? [yn]")
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user.save()
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'.',) or (inp == term.KEY_ENTER and
                            lightbar is not None and
                            lightbar.selection[0] == u'.'):
        echo(term.move(0, 0) + term.normal + term.clear)
        echo(term.move(int(term.height * .8), 0))
        for line in Ansi(ABOUT_DOT_PLAN).wrap(
                term.width / 3).splitlines():
            echo(line.center(term.width).rstrip() + u'\r\n')
        echo(u'\r\n\r\nPRESS ANY kEY ...')
        getch()
        if is_self:
            gosub('editor', '.plan')
        else:
            tmpkey = '%s-%s' % (user.handle, user.plan)
            draft = user.get('.plan', u'')
            session.user[tmpkey] = draft
            gosub('editor', tmpkey)
            if session.user.get(tmpkey, u'') != draft:
                echo(u"\r\n\r\nSEt .PlAN ? [yn]")
                while True:
                    inp2 = getch()
                    if inp2 in (u'y', u'Y'):
                        user['.plan'] = session.user[tmpkey]
                        break
                    elif inp2 in (u'n', u'N'):
                        break
    elif inp in (u'l', u'L') or (inp == term.KEY_ENTER and
                                 lightbar is not None and
                                 lightbar.selection[0] == u'l'):
        echo(term.move(term.height - 1, 0))
        set_location(user)
        echo(u"\r\n\r\nSEt lOCAtiON tO '%s'? [yn]" % (user.location,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user.save()
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'e', u'E') or (inp == term.KEY_ENTER and
                                 lightbar is not None and
                                 lightbar.selection[0] == u'e'):
        echo(term.move(term.height - 1, 0))
        set_email(user)
        echo(u"\r\n\r\nSEt EMAil tO '%s'? [yn]" % (user.email,))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user.save()
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'm', u'M') or (inp == term.KEY_ENTER and
                                 lightbar is not None and
                                 lightbar.selection[0] == u'm'):
        mesg = False if user.get('mesg', True) else True
        echo(u"\r\n\r\n%s iNStANt MESSAGiNG? [yn]" % (
            'ENAblE' if mesg else 'DiSAblE',))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user['mesg'] = mesg
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'x', u'X') or (inp == term.KEY_ENTER and
                                 lightbar is not None and
                                 lightbar.selection[0] == u'x'):
        expert = not user.get('expert', False)
        echo(u"\r\n\r\n%s EXPERt MOdE? [yn]" % (
            'ENAblE' if expert else 'DiSAblE',))
        while True:
            inp2 = getch()
            if inp2 in (u'y', u'Y'):
                user['expert'] = expert
                break
            elif inp2 in (u'n', u'N'):
                break
    elif inp in (u'q', u'Q',) or (inp == term.KEY_ENTER and
                                  lightbar is not None and
                                  lightbar.selection[0] == u'q'):
        EXIT = True
    else:
        return False
    return True
Пример #48
0
def read_messages(msgs, new):
    """
    Provide message reader UI given message list ``msgs``,
    with new messages in list ``new``.
    """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    from x84.bbs import timeago, get_msg, getterminal, echo, gosub
    from x84.bbs import ini, Pager, getsession, getch, Msg
    import x84.default.writemsg
    session, term = getsession(), getterminal()

    session.activity = 'reading msgs'
    # build header
    len_idx = max([len('%d' % (_idx, )) for _idx in msgs])
    len_author = ini.CFG.getint('nua', 'max_user')
    len_ago = 9
    len_subject = ini.CFG.getint('msg', 'max_subject')
    len_preview = min(len_idx + len_author + len_ago + len_subject + -1,
                      term.width - 2)
    reply_depth = ini.CFG.getint('msg', 'max_depth')
    indent_start, indent, indent_end = u'\\', u'-', u'> '

    def get_header(msgs_idx):
        """
        Return list of tuples, (idx, unicodestring), suitable for Lightbar.
        """
        import datetime
        msg_list = list()
        thread_indent = lambda depth: (term.red(
            (indent_start + (indent * depth) + indent_end)) if depth else u'')

        def head(msg, depth=0, maxdepth=reply_depth):
            """ This recursive routine finds the 'head' message
                of any relationship, up to maxdepth.
            """
            if (depth <= maxdepth and hasattr(msg, 'parent')
                    and msg.parent is not None):
                return head(get_msg(msg.parent), depth + 1, maxdepth)
            return msg.idx, depth

        for idx in msgs_idx:
            msg = get_msg(idx)
            author, subj = msg.author, msg.subject
            tm_ago = (datetime.datetime.now() - msg.stime).total_seconds()
            # pylint: disable=W0631
            #         Using possibly undefined loop variable 'idx'
            attr = lambda arg: (term.bold_green(arg)
                                if (not idx in ALREADY_READ and msg.recipient
                                    == session.user.handle) else term.red(arg)
                                if not idx in ALREADY_READ else term.yellow(arg
                                                                            ))
            status = [
                u'U' if not idx in ALREADY_READ else u' ',
                u'D' if idx in DELETED else u' ',
            ]
            row_txt = u'%s %s %s %s %s%s ' % (
                u''.join(status),
                attr(str(idx).rjust(len_idx)),
                attr(author.ljust(len_author)),
                (timeago(tm_ago)).rjust(len_ago),
                attr(u'ago'),
                term.bold_black(':'),
            )
            msg_list.append((head(msg), idx, row_txt, subj))
        msg_list.sort(reverse=True)
        return [(idx, row_txt + thread_indent(depth) + subj)
                for (_threadid, depth), idx, row_txt, subj in msg_list]

    def get_selector(mailbox, prev_sel=None):
        """
        Provide Lightbar UI element given message mailbox returned from
        function get_header, and prev_sel as previously instantiated Lightbar.
        """
        from x84.bbs import Lightbar
        pos = prev_sel.position if prev_sel is not None else (0, 0)
        sel = Lightbar(height=(term.height /
                               3 if term.width < 140 else term.height - 3),
                       width=len_preview,
                       yloc=2,
                       xloc=0)
        sel.glyphs['top-horiz'] = u''
        sel.glyphs['left-vert'] = u''
        sel.colors['highlight'] = term.yellow_reverse
        sel.update(mailbox)
        sel.position = pos
        return sel

    def get_reader():
        """
        Provide Pager UI element for message reading.
        """
        reader_height = (term.height - (term.height / 3) - 2)
        reader_indent = 2
        reader_width = min(term.width - 1, min(term.width - reader_indent, 80))
        reader_ypos = ((term.height - 1) - reader_height if
                       (term.width - reader_width) < len_preview else 2)
        reader_height = term.height - reader_ypos - 1
        msg_reader = Pager(height=reader_height,
                           width=reader_width,
                           yloc=reader_ypos,
                           xloc=min(len_preview + 2,
                                    term.width - reader_width))
        msg_reader.glyphs['top-horiz'] = u''
        msg_reader.glyphs['right-vert'] = u''
        return msg_reader

    def format_msg(reader, idx):
        """ Format message of index ``idx`` into Pager instance ``reader``. """
        msg = get_msg(idx)
        sent = msg.stime.strftime(TIME_FMT)
        to_attr = term.bold_green if (
            msg.recipient == session.user.handle) else term.underline
        ucs = u'\r\n'.join((
            (u''.join((
                term.yellow('fROM: '),
                (u'%s' % term.bold(msg.author, )).rjust(len_author),
                u' ' * (reader.visible_width - (len_author + len(sent))),
                sent,
            ))),
            u''.join((
                term.yellow('tO: '),
                to_attr((
                    u'%s' % to_attr(msg.recipient, )
                ).rjust(len_author) if msg.recipient is not None else u'All'),
            )),
            (u'\r\n'.join((term.wrap(
                term.yellow('tAGS: ') + (u'%s ' % (term.bold(','), )).join(([
                    term.bold_red(_tag)
                    if _tag in SEARCH_TAGS else term.yellow(_tag)
                    for _tag in msg.tags
                ])),
                reader.visible_width,
                subsequent_indent=u' ' * 6)))),
            (term.yellow_underline(
                (u'SUbj: %s' % (msg.subject, )).ljust(reader.visible_width))),
            u'',
            (msg.body),
        ))
        return ucs

    def get_selector_title(mbox, new):
        """
        Returns unicode string suitable for displaying as title of mailbox.
        """
        newmsg = (term.yellow(u' ]-[ ') + term.yellow_reverse(str(len(new))) +
                  term.bold_underline(u' NEW')) if len(new) else u''
        return u''.join((
            term.yellow(u'[ '),
            term.bold_yellow(str(len(mbox))),
            term.bold(u' MSG%s' % (u's' if 1 != len(mbox) else u'', )),
            newmsg,
            term.yellow(u' ]'),
        ))

    dispcmd_mark = lambda idx: ((term.yellow_underline(u' ') + u':mark' + u' ')
                                if idx not in ALREADY_READ else u'')
    dispcmd_delete = lambda idx: (
        (term.yellow_underline(u'D') + u':elete' + u' ')
        if idx not in DELETED else u'')
    dispcmd_tag = lambda idx: ((term.yellow_underline(u't') + u':ag' + u' ')
                               if allow_tag(idx) else u'')

    def get_selector_footer(idx):
        """
        Returns unicode string suitable for displaying
        as footer of mailbox when window is active.
        """
        return u''.join((
            term.yellow(u'- '),
            u''.join((
                term.yellow_underline(u'>') + u':read ',
                term.yellow_underline(u'r') + u':eply ',
                dispcmd_mark(idx),
                dispcmd_delete(idx),
                dispcmd_tag(idx),
                term.yellow_underline(u'q') + u':uit',
            )),
            term.yellow(u' -'),
        ))

    def get_reader_footer(idx):
        """
        Returns unicode string suitable for displaying
        as footer of reader when window is active
        """

        return u''.join((
            term.yellow(u'- '),
            u' '.join((
                term.yellow_underline(u'<') + u':back ',
                term.yellow_underline(u'r') + u':eply ',
                dispcmd_delete(idx),
                dispcmd_tag(idx),
                term.yellow_underline(u'q') + u':uit',
            )),
            term.yellow(u' -'),
        ))

    def refresh(reader, selector, mbox, new):
        """
        Returns unicode string suitable for refreshing the screen.
        """
        from x84.bbs import getsession
        session = getsession()

        if READING:
            reader.colors['border'] = term.bold_yellow
            selector.colors['border'] = term.bold_black
        else:
            reader.colors['border'] = term.bold_black
            selector.colors['border'] = term.bold_yellow
        title = get_selector_title(mbox, new)
        padd_attr = (term.bold_yellow if not READING else term.bold_black)
        sel_padd_right = padd_attr(
            u'-' + selector.glyphs['bot-horiz'] *
            (selector.visible_width - term.length(title) - 7) +
            u'-\u25a0-' if READING else u'- -')
        sel_padd_left = padd_attr(selector.glyphs['bot-horiz'] * 3)
        idx = selector.selection[0]
        return u''.join((
            term.move(0, 0),
            term.clear,
            u'\r\n',
            u'// REAdiNG MSGS ..'.center(term.width).rstrip(),
            selector.refresh(),
            selector.border() if READING else reader.border(),
            reader.border() if READING else selector.border(),
            selector.title(sel_padd_left + title + sel_padd_right),
            selector.footer(get_selector_footer(idx)) if not READING else u'',
            reader.footer(get_reader_footer(idx)) if READING else u'',
            reader.refresh(),
        ))

    echo((u'\r\n' + term.clear_eol) * (term.height - 1))
    dirty = 2
    msg_selector = None
    msg_reader = None
    idx = None
    # pylint: disable=W0603
    #         Using the global statement
    global READING
    while (msg_selector is None and
           msg_reader is None) or not (msg_selector.quit or msg_reader.quit):
        if session.poll_event('refresh'):
            dirty = 2
        if dirty:
            if dirty == 2:
                mailbox = get_header(msgs)
            msg_selector = get_selector(mailbox, msg_selector)
            idx = msg_selector.selection[0]
            msg_reader = get_reader()
            msg_reader.update(format_msg(msg_reader, idx))
            echo(refresh(msg_reader, msg_selector, msgs, new))
            dirty = 0
        inp = getch(1)
        if inp in (u'r', u'R'):
            reply_to = get_msg(idx)
            reply_msg = Msg()
            reply_msg.recipient = reply_to.author
            reply_msg.tags = reply_to.tags
            reply_msg.subject = reply_to.subject
            reply_msg.parent = reply_to.idx
            # quote between 30 and 79, 'screen width - 4' as variable dist.
            reply_msg.body = quote_body(reply_to,
                                        max(30, min(79, term.width - 4)))
            echo(term.move(term.height, 0) + u'\r\n')
            if gosub('writemsg', reply_msg):
                reply_msg.save()
                dirty = 2
                READING = False
            else:
                dirty = 1
            mark_read(idx)  # also mark as read

        # 't' uses writemsg.prompt_tags() routine, how confusing ..
        elif inp in (u't', ) and allow_tag(idx):
            echo(term.move(term.height, 0))
            msg = get_msg(idx)
            if x84.default.writemsg.prompt_tags(msg):
                msg.save()
                session.user['msgs_sent'] = session.user.get('msgs_sent',
                                                             0) + 1
            dirty = 2

        # spacebar marks as read, goes to next message
        elif inp in (u' ', ):
            dirty = 2 if mark_read(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        # D marks as deleted, goes to next message
        elif inp in (u'D', ):
            dirty = 2 if mark_delete(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        # U undeletes, does not move.
        elif inp in (u'U', ):
            dirty = 2 if mark_undelete(idx) else 1
            msg_selector.move_down()
            idx = msg_selector.selection[0]
            READING = False

        if READING:
            echo(msg_reader.process_keystroke(inp))
            # left, <, or backspace moves UI
            if inp in (term.KEY_LEFT, u'<', u'h', '\b', term.KEY_BACKSPACE):
                READING = False
                dirty = 1
        else:
            echo(msg_selector.process_keystroke(inp))
            idx = msg_selector.selection[0]
            # right, >, or enter marks message read, moves UI
            if inp in (u'\r', term.KEY_ENTER, u'>', u'l', 'L', term.KEY_RIGHT):
                dirty = 2 if mark_read(idx) else 1
                READING = True
            elif msg_selector.moved:
                dirty = 1
    echo(term.move(term.height, 0) + u'\r\n')
    return
Пример #49
0
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    from x84.bbs import getsession, getterminal, echo, getch
    from x84.bbs import goto, gosub, User, get_user, DBProxy
    import logging
    import time
    session, term = getsession(), getterminal()
    session.activity = 'top'
    logger = logging.getLogger()

    # 0. just a gimmicky example,
#    gosub('productive')

    # 1. determine & assign user record,
    if handle in (None, u'', 'anonymous',):
        logger.info('anonymous login by %s.', session.sid)
        session.user = User(u'anonymous')
    else:
        logger.debug('%r logged in.', handle)
        session.user = get_user(handle)
        timeout = session.user.get('timeout', None)
        if timeout is not None:
            echo(u'\r\n\r\nUsing preferred timeout of %ss.\r\n' % (
                timeout,))
            session.send_event('set-timeout', timeout)

    # 2. update call records
    session.user.calls += 1
    session.user.lastcall = time.time()
    if session.user.handle != 'anonymous':
        session.user.save()

    # record into " last caller " record
    key = (session.user.handle)
    lcall = (session.user.lastcall, session.user.calls, session.user.location)
    db = DBProxy('lastcalls')
    db[key] = lcall

    # 3. if no preferred charset run charset.py selector
    if (session.user.get('charset', None) is None
            or session.user.handle == 'anonymous'):
        gosub('charset')
        session.activity = 'top'
    else:
        # load default charset
        session.encoding = session.user.get('charset')
        fun = term.bold_green(' (EXCEllENt!)')
        if session.encoding != 'utf8':
            fun = term.bold_red(u' (bUMMER!)')
        echo(u'\r\n\r\nUsing preferred charset, %s%s.\r\n' % (
            session.encoding, fun))

    echo(term.clear())
    # 4. impress with art, prompt for quick login (goto 'main'),
    if session.user.get('expert', False):
        dirty = True
        while True:
            if session.poll_event('refresh'):
                dirty = True
            if dirty:
                session.activity = 'top'
                display_intro()
                echo(u'\r\n QUiCk lOGiN [yn] ?\b\b')
            dirty = False
            inp = getch(1)
            if inp in (u'y', u'Y'):
                goto('main')
            elif inp in (u'n', u'N'):
                break
            elif inp in (u'!',):
                gosub('charset')
                dirty = True
    else:
        ynbar = get_ynbar()
        dirty = True
        while not ynbar.selected:
            if session.poll_event('refresh'):
                dirty = True
            if dirty:
                # redraw yes/no
                session.activity = 'top'
                swp = ynbar.selection
                ynbar = get_ynbar()
                ynbar.selection = swp
                display_intro()
                echo(redraw_quicklogin(ynbar))
            dirty = False
            inp = getch(1)
            if inp in (u'!',):
                gosub('charset')
                dirty = True
            elif inp is not None:
                echo(ynbar.process_keystroke(inp))
                if ynbar.quit:
                    goto('main')
        if ynbar.selection == ynbar.left:
            goto('main')

    # 5. last callers
    gosub('lc')
    session.activity = 'top'

    # 6. check for new public/private msgs,
#   gosub('readmsgs', set())
#   session.activity = 'top'

    # 7. news
    gosub('news')
    session.activity = 'top'

    # 8. one-liners
    gosub('ol')
    session.activity = 'top'

    # 9. weather
#   if session.user.get('location', None):
#       gosub('weather')

    goto('main')
Пример #50
0
def main(handle=None):
    """ 主体程序"""
    session, term = getsession(), getterminal()
    session.activity = 'hick'

    ### 处理登录
    # attempt to coerce encoding of terminal to match session.
    coerce_terminal_encoding(term, session.encoding)

    # fetch user record
    user = get_user_record(handle)

    # register call
    login(session, user)

    session = getsession()

    ### 处理键盘操作事件
    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            goto('main')  # reload main menu using hidden option '*'
        elif inp == u'$':
            gosub('bulletins')
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'u':
            gosub('userlist')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        ### 修改成
        elif inp == u't':
            gosub('feeds')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'i':
            gosub('ircchat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'v':
            gosub('vote')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        else:
            handled = False
            try:
                for option in ini.CFG.options('sesame'):
                    if option.endswith('_key'):
                        door = option.replace('_key', '')
                        key = ini.CFG.get('sesame', option)
                        if inp == key:
                            gosub('sesame', door)
                            handled = True
                            break
            except ConfigError:
                pass

            if not handled:
                dirty = False
Пример #51
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #         Too many branches
    from x84.bbs import getsession, getch, goto, gosub
    session = getsession()

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            refresh()
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        elif inp == u't':
            gosub('tetris')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == u'y':
            gosub('yosindex')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        elif inp == u'v' and 'sysop' in session.user.groups:
            # video cassette player
            gosub('ttyplay')
        else:
            dirty = False
Пример #52
0
def main():
    """ Main menu entry point. """
    import os, random, time
    from x84.bbs import showart
    session, term = getsession(), getterminal()
    global menutoggle
    global arttoggle
    global bgtoggle

    text, width, height, dirty = u'', -1, -1, 2
    menu_items = get_menu_items(session)
    colors = {}
    if colored_menu_items:
       colors['backlight'] = getattr(term, color_backlight)
       colors['highlight'] = getattr(term, color_highlight)
       colors['lowlight'] = getattr(term, color_lowlight)
    editor = get_line_editor(term, menu_items)
    menumode = False
    tallmode = False
    widemode = False

    if term.width >= 132:
        widemode = True
    if term.height >= 43:
        tallmode = True

    #if session.user['bg'] is None:
    randombgset()
    starttime = time.time()
    while True:
        if dirty  > 1:
            # set syncterm font, if any
            if syncterm_font and term.kind.startswith('ansi'):
                echo(syncterm_setfont(syncterm_font))
        if dirty == 2:
	    menutoggle, arttoggle, bgtoggle = True, True, True
        if dirty:
            session.activity = 'main menu'
	    if width != term.width or height != term.height:
                width, height = term.width, term.height
            renderscreen(menutoggle, arttoggle, bgtoggle)
            echo(term.move(term.height, 2))
            echo(u''.join((text,
	    display_prompt(term, colors),
	    editor.refresh()+term.normal)))
            dirty = 0

        event, data = session.read_events(('input', 'refresh'), 0.1)
        if event == 'refresh':
            dirty = True
            continue

        elif event == 'input':
            session.buffer_input(data, pushback=True)

            # we must loop over inkey(0), we received a 'data'
            # event, though there may be many keystrokes awaiting for our
            # decoding -- or none at all (multibyte sequence not yet complete).
            inp = term.inkey(0)
            while inp:
                if inp == u'*':
                    menutoggle = not menutoggle
                    dirty = True
                    break
                if inp.code == term.KEY_TAB:
                    starttime = time.time()
		    randombgset()
                    dirty = True
                    break
                if inp.code == term.KEY_ENTER:
                    # find matching menu item,
                    for item in menu_items:
                        if item.inp_key == editor.content.strip():
                            echo(term.normal + u'\r\n')
                            gosub(item.script, *item.args, **item.kwargs)
                            editor.content = u''
                            dirty = 3
                            break
                    else:
                        if editor.content:
                            # command not found, clear prompt.
                            echo(u''.join((
                                (u'\b' * len(editor.content)),
                                (u' ' * len(editor.content)),
                                (u'\b' * len(editor.content)),)))
                            editor.content = u''
                            echo(editor.refresh()+term.normal)
                elif inp.is_sequence:
                    echo(editor.process_keystroke(inp.code))
                else:
                    echo(editor.process_keystroke(inp))
                inp = term.inkey(0)
        if time.time() - starttime > 1800:
            dirty = True
            starttime = time.time()
            randombgset()
            continue
Пример #53
0
def main():
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #        Too many local variables
    #        Too many branches
    #        Too many statements
    from x84.bbs import getsession, getterminal, echo, ini, getch, gosub
    from x84.bbs import DBProxy
    session, term = getsession(), getterminal()
    pager, lightbar = get_ui(None)

    echo(u'\r\n\r\n')
    thread = None
    if ini.CFG.has_section('bbs-scene'):
        thread = FetchUpdates()
        thread.start()
        session.activity = u'bbs lister [bbs-scene.org]'
        echo(u'fetching bbs-scene.org updates ...')
    else:
        session.activity = u'bbs lister'

    dirty = True
    # session.buffer_event('refresh', ('init',))
    leftright = 0  # 'left'

    while True:
        # check if screen requires refresh of any kind,
        if session.poll_event('refresh'):
            dirty = True
        if thread is not None:
            t_val = chk_thread(thread)
            if t_val != False:
                thread = None
                if t_val == 'dirty':
                    dirty = True
        if session.poll_event('bbslist_update'):
            while session.read_event('bbslist_update', 0.15):
                # pylint: disable=W0104
                #         Statement seems to have no effect
                None
            dirty = True

        # refresh advanced screen with lightbar and pager
        if dirty:
            if session.user.get('expert', False):
                # provide dumb terminal with hotkey prompt
                if thread is not None:
                    wait_for(thread)
                if chk_thread(thread) != False:
                    thread = None
                return dummy_pager()
            else:
                pager, lightbar = get_ui(lightbar.position)
                echo(banner())
                echo(u'\r\n' * lightbar.height)
                echo(redraw(pager, lightbar, leftright))
                dirty = False

        # detect and process keyboard input for advanced screen
        inp = getch(1)
        if inp == term.KEY_LEFT:
            # full refresh for border chang ;/
            leftright = 0
            echo(redraw_pager(
                pager, lightbar.selection, active=(leftright == 1)))
            echo(redraw_lightbar(
                lightbar, active=(leftright == 0)))
        elif inp == term.KEY_RIGHT:
            # full refresh for border chang ;/
            leftright = 1
            echo(redraw_pager(pager,
                              lightbar.selection, active=(leftright == 1)))
            echo(redraw_lightbar(lightbar,
                                 active=(leftright == 0)))
        elif inp is not None:
            # process as pager or lightbar keystroke,
            echo(lightbar.process_keystroke(inp)
                 if leftright == 0 else
                 pager.process_keystroke(inp))

            # full refresh after rate/comment/elnet/view etc.
            if process_keystroke(inp, lightbar.selection[0]):
                session.buffer_event('refresh', ('redraw',))
                continue

            # quit 'q'
            if (lightbar.quit or pager.quit):
                return

            # pressed return, telnet!
            if lightbar.selected and lightbar.selection[0] is not None:
                bbs = DBProxy('bbslist')[lightbar.selection[0]]
                gosub('telnet', bbs['address'], bbs['port'])
                # buffer full refresh after telnet
                session.buffer_event('refresh', ('redraw',))

            # selected new entry, refresh entire pager, a little bit
            # bandwidth excessive as bbs name is part of border title.
            if lightbar.moved:
                echo(redraw_pager(pager, lightbar.selection,
                                  active=(leftright == 1)))
                lightbar.moved = False
Пример #54
0
def main(handle=None):
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    from x84.bbs import getsession, getterminal, echo, getch
    from x84.bbs import goto, gosub, User, get_user, DBProxy
    import logging
    import time
    session, term = getsession(), getterminal()
    session.activity = 'top'
    logger = logging.getLogger()

    # 0. just a gimmicky example,
    gosub('productive')

    # 1. determine & assign user record,
    if handle in (None, u'', 'anonymous',):
        logger.info('anonymous login by %s.', session.sid)
        session.user = User(u'anonymous')
    else:
        logger.debug('%r logged in.', handle)
        session.user = get_user(handle)
        timeout = session.user.get('timeout', None)
        if timeout is not None:
            echo(u'\r\n\r\nUsing preferred timeout of %ss.\r\n' % (
                timeout,))
            session.send_event('set-timeout', timeout)

    # 2. update call records
    session.user.calls += 1
    session.user.lastcall = time.time()
    if session.user.handle != 'anonymous':
        session.user.save()

    # record into " last caller " record
    key = (session.user.handle)
    lcall = (session.user.lastcall, session.user.calls, session.user.location)
    db = DBProxy('lastcalls')
    db[key] = lcall

    # 3. if no preferred charset run charset.py selector
    if (session.user.get('charset', None) is None
            or session.user.handle == 'anonymous'):
        gosub('charset')
        session.activity = 'top'
    else:
        # load default charset
        session.encoding = session.user.get('charset')
        fun = term.bold_green(' (EXCEllENt!)')
        if session.encoding != 'utf8':
            fun = term.bold_red(u' (bUMMER!)')
        echo(u'\r\n\r\nUsing preferred charset, %s%s.\r\n' % (
            session.encoding, fun))

    # 4. impress with art, prompt for quick login (goto 'main'),
    if session.user.get('expert', False):
        dirty = True
        while True:
            if session.poll_event('refresh'):
                dirty = True
            if dirty:
                session.activity = 'top'
                display_intro()
                echo(u'\r\n QUiCk lOGiN [yn] ?\b\b')
            dirty = False
            inp = getch(1)
            if inp in (u'y', u'Y'):
                goto('main')
            elif inp in (u'n', u'N'):
                break
            elif inp in (u'!',):
                gosub('charset')
                dirty = True
    else:
        ynbar = get_ynbar()
        dirty = True
        while not ynbar.selected:
            if session.poll_event('refresh'):
                dirty = True
            if dirty:
                # redraw yes/no
                session.activity = 'top'
                swp = ynbar.selection
                ynbar = get_ynbar()
                ynbar.selection = swp
                display_intro()
                echo(redraw_quicklogin(ynbar))
            dirty = False
            inp = getch(1)
            if inp in (u'!',):
                gosub('charset')
                dirty = True
            elif inp is not None:
                echo(ynbar.process_keystroke(inp))
                if ynbar.quit:
                    goto('main')
        if ynbar.selection == ynbar.left:
            goto('main')

    # 5. last callers
    gosub('lc')
    session.activity = 'top'

    # 6. check for new public/private msgs,
    gosub('readmsgs', set())
    session.activity = 'top'

    # 7. news
    gosub('news')
    session.activity = 'top'

    # 8. one-liners
    gosub('ol')
    session.activity = 'top'

    # 9. weather
    if session.user.get('location', None):
        gosub('weather')
    session.activity = 'top'

    # 10. automsg
    gosub('automsg')
    
    goto('main')
Пример #55
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #         Too many branches
    from x84.bbs import getsession, getch, goto, gosub
    session = getsession()

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            goto('main')  # reload main menu using hidden option '*'
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u't':
            gosub('tetris')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        elif inp == u'v' and 'sysop' in session.user.groups:
            # video cassette player
            gosub('ttyplay')
        else:
            dirty = False
Пример #56
0
def main():
    """ Main procedure. """
    # pylint: disable=R0914,R0912,R0915
    #        Too many local variables
    #        Too many branches
    #        Too many statements
    from x84.bbs import getsession, getterminal, echo, ini, getch, gosub
    from x84.bbs import DBProxy
    session, term = getsession(), getterminal()
    pager, lightbar = get_ui(None)

    echo(u'\r\n\r\n')
    thread = None
    if ini.CFG.has_section('bbs-scene'):
        thread = FetchUpdates()
        thread.start()
        session.activity = u'bbs lister [bbs-scene.org]'
        echo(u'fetching bbs-scene.org updates ...')
    else:
        session.activity = u'bbs lister'

    dirty = True
    # session.buffer_event('refresh', ('init',))
    leftright = 0  # 'left'

    while True:
        # check if screen requires refresh of any kind,
        if session.poll_event('refresh'):
            dirty = True
        if thread is not None:
            t_val = chk_thread(thread)
            if t_val != False:
                thread = None
                if t_val == 'dirty':
                    dirty = True
        if session.poll_event('bbslist_update'):
            while session.read_event('bbslist_update', 0.15):
                # pylint: disable=W0104
                #         Statement seems to have no effect
                None
            dirty = True

        # refresh advanced screen with lightbar and pager
        if dirty:
            if session.user.get('expert', False):
                # provide dumb terminal with hotkey prompt
                if thread is not None:
                    wait_for(thread)
                if chk_thread(thread) != False:
                    thread = None
                return dummy_pager()
            else:
                pager, lightbar = get_ui(lightbar.position)
                echo(banner())
                echo(u'\r\n' * lightbar.height)
                echo(redraw(pager, lightbar, leftright))
                dirty = False

        # detect and process keyboard input for advanced screen
        inp = getch(1)
        if inp == term.KEY_LEFT:
            # full refresh for border chang ;/
            leftright = 0
            echo(
                redraw_pager(pager,
                             lightbar.selection,
                             active=(leftright == 1)))
            echo(redraw_lightbar(lightbar, active=(leftright == 0)))
        elif inp == term.KEY_RIGHT:
            # full refresh for border chang ;/
            leftright = 1
            echo(
                redraw_pager(pager,
                             lightbar.selection,
                             active=(leftright == 1)))
            echo(redraw_lightbar(lightbar, active=(leftright == 0)))
        elif inp is not None:
            # process as pager or lightbar keystroke,
            echo(
                lightbar.process_keystroke(inp) if leftright ==
                0 else pager.process_keystroke(inp))

            # full refresh after rate/comment/elnet/view etc.
            if process_keystroke(inp, lightbar.selection[0]):
                session.buffer_event('refresh', ('redraw', ))
                continue

            # quit 'q'
            if (lightbar.quit or pager.quit):
                return

            # pressed return, telnet!
            if lightbar.selected and lightbar.selection[0] is not None:
                bbs = DBProxy('bbslist')[lightbar.selection[0]]
                gosub('telnet', bbs['address'], bbs['port'])
                # buffer full refresh after telnet
                session.buffer_event('refresh', ('redraw', ))

            # selected new entry, refresh entire pager, a little bit
            # bandwidth excessive as bbs name is part of border title.
            if lightbar.moved:
                echo(
                    redraw_pager(pager,
                                 lightbar.selection,
                                 active=(leftright == 1)))
                lightbar.moved = False
Пример #57
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #         Too many branches
    from x84.bbs import getsession, getch, goto, gosub, ini
    from ConfigParser import Error as ConfigError
    session = getsession()

    inp = -1
    dirty = True
    while True:
        if dirty or session.poll_event('refresh'):
            refresh()
        inp = getch(1)
        dirty = True
        if inp == u'*':
            goto('main')  # reload main menu using hidden option '*'
        elif inp == u'$':
            gosub('bulletins')
        elif inp == u'b':
            gosub('bbslist')
        elif inp == u'l':
            gosub('lc')
        elif inp == u'o':
            gosub('ol')
        elif inp == u's':
            gosub('si')
        elif inp == u'u':
            gosub('userlist')
        elif inp == u'w':
            gosub('online')
        elif inp == u'n':
            gosub('news')
        elif inp == u'f':
            gosub('weather')
        elif inp == u'e':
            gosub('profile')
        elif inp == u'#':
            gosub('lord')
        elif inp == u't':
            gosub('tetris')
        elif inp == u'c':
            gosub('chat')
        elif inp == u'i':
            gosub('ircchat')
        elif inp == u'p':
            gosub('writemsg')
        elif inp == u'r':
            gosub('readmsgs')
        elif inp == u'v':
            gosub('vote')
        elif inp == u'g':
            goto('logoff')
        elif inp == u'!':
            gosub('charset')
        elif inp == '\x1f' and 'sysop' in session.user.groups:
            # ctrl+_, run a debug script
            gosub('debug')
        else:
            handled = False
            try:
                for option in ini.CFG.options('sesame'):
                    if option.endswith('_key'):
                        door = option.replace('_key', '')
                        key = ini.CFG.get('sesame', option)
                        if inp == key:
                            gosub('sesame', door)
                            handled = True
                            break
            except ConfigError:
                pass

            if not handled:
                dirty = False
Пример #58
0
def main():
    """ Main menu entry point. """
    session, term = getsession(), getterminal()

    text, width, height, dirty = u'', -1, -1, 2
    menu_items = get_menu_items(session)
    editor = get_line_editor(term, menu_items)
    colors = {}
    if colored_menu_items:
        colors['backlight'] = getattr(term, color_backlight)
        colors['highlight'] = getattr(term, color_highlight)
        colors['lowlight'] = getattr(term, color_lowlight)

    while True:
        if dirty == 2:
            # set syncterm font, if any
            if syncterm_font and term.kind.startswith('ansi'):
                echo(syncterm_setfont(syncterm_font))
        if dirty:
            session.activity = 'main menu'
            top_margin = display_banner(art_file, encoding=art_encoding) + 1
            echo(u'\r\n')
            if width != term.width or height != term.height:
                width, height = term.width, term.height
                text = render_menu_entries(
                    term, top_margin, menu_items, colors)
            echo(u''.join((text,
                           display_prompt(term, colors),
                           editor.refresh())))
            dirty = 0

        event, data = session.read_events(('input', 'refresh'))

        if event == 'refresh':
            dirty = True
            continue

        elif event == 'input':
            session.buffer_input(data, pushback=True)

            # we must loop over inkey(0), we received a 'data'
            # event, though there may be many keystrokes awaiting for our
            # decoding -- or none at all (multibyte sequence not yet complete).
            inp = term.inkey(0)
            while inp:
                if inp.code == term.KEY_ENTER:
                    # find matching menu item,
                    for item in menu_items:
                        if item.inp_key == editor.content.strip():
                            echo(term.normal + u'\r\n')
                            gosub(item.script, *item.args, **item.kwargs)
                            editor.content = u''
                            dirty = 2
                            break
                    else:
                        if editor.content:
                            # command not found, clear prompt.
                            echo(u''.join((
                                (u'\b' * len(editor.content)),
                                (u' ' * len(editor.content)),
                                (u'\b' * len(editor.content)),)))
                            editor.content = u''
                            echo(editor.refresh())
                elif inp.is_sequence:
                    echo(editor.process_keystroke(inp.code))
                else:
                    echo(editor.process_keystroke(inp))
                inp = term.inkey(0)