Esempio n. 1
0
def prompt_tags(msg):
    """ Prompt for and return tags wished for message. """
    # pylint: disable=R0914,W0603
    #         Too many local variables
    #         Using the global statement
    from x84.bbs import DBProxy, echo, getterminal, getsession
    from x84.bbs import Ansi, LineEditor
    session, term = getsession(), getterminal()
    tagdb = DBProxy('tags')
    msg_onlymods = (u"\r\nONlY MEMbERS Of thE '%s' OR '%s' "
                    "GROUP MAY CREAtE NEW tAGS." % (
                        term.bold_yellow('sysop'),
                        term.bold_blue('moderator'),))
    msg_invalidtag = u"\r\n'%s' is not a valid tag."
    prompt_tags1 = u"ENtER %s, COMMA-dEliMitEd. " % (
        term.bold_red('TAG(s)'),)
    prompt_tags2 = u"OR '/list', %s:quit\r\n : " % (
        term.bold_yellow_underline('Escape'),)
    while True:
        # Accept user input for multiple 'tag's, or /list command
        echo(u'\r\n\r\n')
        echo(prompt_tags1)
        echo(prompt_tags2)
        width = term.width - 6
        sel_tags = u', '.join(msg.tags)
        inp_tags = LineEditor(width, sel_tags).read()
        if inp_tags is not None and 0 == len(inp_tags.strip()):
            # no tags must be (private ..)
            msg.tags = set()
            return True
        if inp_tags is None or inp_tags.strip().lower() == '/quit':
            return False
        elif inp_tags.strip().lower() == '/list':
            # list all available tags, and number of messages
            echo(u'\r\n\r\nTags: \r\n')
            all_tags = sorted(tagdb.items())
            if 0 == len(all_tags):
                echo(u'None !'.center(term.width / 2))
            else:
                echo(Ansi(u', '.join(([u'%s(%d)' % (_key, len(_value),)
                                       for (_key, _value) in all_tags]))
                          ).wrap(term.width - 2))
            continue
        echo(u'\r\n')

        # search input as valid tag(s)
        tags = set([inp.strip().lower() for inp in inp_tags.split(',')])
        err = False
        for tag in tags.copy():
            if not tag in tagdb and not (
                    'sysop' in session.user.groups or
                    'moderator' in session.user.groups):
                tags.remove(tag)
                echo(msg_invalidtag % (term.bold_red(tag),))
                err = True
        if err:
            echo(msg_onlymods)
            continue
        msg.tags = tags
        return True
Esempio n. 2
0
def prompt_subject(term, msg, colors):
    """ Prompt for subject of message. """
    xpos = max(0, (term.width // 2) - (80 // 2))
    echo(u"".join((term.move_x(xpos), term.clear_eos, u"Enter Subject.\r\n", term.move_x(xpos), u":: ")))
    inp = LineEditor(subject_max_length, msg.subject, colors={"highlight": colors["backlight"]}).read()

    if inp is None or not inp.strip():
        echo(u"".join((term.move_x(xpos), colors["highlight"]("Canceled."), term.clear_eol)))
        term.inkey(1)
        return False

    msg.subject = inp.strip()
    return True
Esempio n. 3
0
def prompt_recipient(term, msg, colors, public=True):
    """ Prompt for recipient of message. """
    xpos = max(0, (term.width // 2) - (80 // 2))
    echo(term.move_x(xpos) + term.clear_eos)
    echo(u"Enter handle{0}.\r\n".format(u", empty to address to all" if public else u""))
    echo(term.move_x(xpos) + ":: ")
    inp = LineEditor(username_max_length, msg.recipient, colors={"highlight": colors["backlight"]}).read()

    if inp is None:
        echo(u"".join((term.move_x(xpos), colors["highlight"]("Canceled."), term.clear_eol)))
        term.inkey(1)
        return False

    elif not inp.strip():
        # empty, recipient is None
        msg.recipient = None
        if public:
            return True
        return False

    inp = inp.strip()

    # validate/find user
    userlist = list_users()
    if inp in userlist:
        # exact match,
        msg.recipient = inp
        echo(u"\r\n")
        return True

    # nearest match
    for match in difflib.get_close_matches(inp.strip(), userlist):
        echo(u"".join((term.move_x(xpos), u"{0} [yn]".format(colors["highlight"](match)), term.clear_eol, u" ?\b\b")))
        while True:
            inp = term.inkey()
            if inp.code == term.KEY_ESCAPE:
                # escape/cancel
                return False
            elif inp.lower() == u"y":
                # accept match
                msg.recipient = match
                echo(u"\r\n")
                return True
            elif inp.lower() == u"n":
                # next match
                break

    echo(u"".join((term.move_x(xpos), colors["highlight"]("No match."), term.clear_eol)))
    term.inkey(1)
    return False
Esempio n. 4
0
def add_comment(key):
    """ Prompt user to add a comment about a bbs. """
    # pylint: disable=R0914
    #        Too many local variables.
    from x84.bbs import getsession, getterminal, echo, DBProxy, LineEditor
    from x84.bbs import getch
    session, term = getsession(), getterminal()
    prompt_comment = u'\r\n\r\nWhAt YOU GOt tO SAY? '
    prompt_chg = u'\r\n\r\nChANGE EXiStiNG ? [yn] '
    echo(term.move(term.height, 0))
    echo(prompt_comment)
    comment = LineEditor(max(10, term.width - len(prompt_comment) - 5)).read()
    if comment is None or 0 == len(comment.strip()):
        return
    new_entry = (session.handle, comment)
    comments = DBProxy('bbslist', 'comments')
    comments.acquire()
    existing = comments[key]
    if session.handle in (_nick for (_nick, _cmt) in comments[key]):
        # change existing comment,
        echo(prompt_chg)
        if getch() not in (u'y', u'Y'):
            comments.release()
            return
        # re-define list without existing entry, + new entry
        comments[key] = [(_enick, _ecmt) for (_enick, _ecmt) in existing
                         if session.handle != _enick] + [new_entry]
        comments.release()
        return
    # re-define as existing list + new entry
    comments[key] = existing + [new_entry]
    comments.release()
Esempio n. 5
0
def prompt_subject(term, msg, colors):
    """ Prompt for subject of message. """
    xpos = max(0, (term.width // 2) - (80 // 2))
    echo(u''.join((term.move_x(xpos),
                   term.clear_eos,
                   u'Enter Subject.\r\n',
                   term.move_x(xpos),
                   u':: ')))
    inp = LineEditor(subject_max_length, msg.subject,
                     colors={'highlight': colors['backlight']}
                     ).read()

    if inp is None or not inp.strip():
        echo(u''.join((term.move_x(xpos),
                       colors['highlight']('Canceled.'),
                       term.clear_eol)))
        term.inkey(1)
        return False

    msg.subject = inp.strip()
    return True
Esempio n. 6
0
File: ol.py Progetto: rostob/x84
def say_something(term, session):
    """ Prompt user to post a 'oneliner' entry. """
    # use same line as previous prompt, clearing it first,
    echo(term.move_x(0) + term.clear_eol)
    colors = {'highlight': term.red_reverse}

    xpos = max((term.width / 2) - ((MAX_MSGLEN / 2) + 3), 0)
    echo(term.move_x(xpos))
    if MIN_ELAPSED:
        lastliner = session.user.get('lastliner', 0)
        if lastliner and time.time() - lastliner > MIN_ELAPSED:
            echo(term.red_bold("You've said enough already!"))
            term.inkey(timeout=1)
            echo(term.move_x(0))
            # only re-draw prompt (user canceled)
            return False

    echo(term.move_x(xpos))
    echo(term.red('say ') + term.bold_red('>') + u' ')
    inp = LineEditor(MAX_MSGLEN, colors=colors).read()
    if not inp or not len(inp.strip()):
        # canceled
        echo(term.move_x(0) + term.clear_eol)
        return False

    echo(term.move_x(xpos) + term.clear_eol)
    session.user['lastliner'] = time.time()

    # optionally post to shroo.ms 'global oneliners'
    if shroo_ms_enabled:
        echo(term.red_reverse('Burning, please wait ...'))
        return post_shroo_ms(message=inp, username=session.user.handle)

    # or, post locally
    add_oneline(session=session, message=inp.strip())
    return True
Esempio n. 7
0
File: matrix.py Progetto: gofore/x84
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))
Esempio n. 8
0
def prompt_input(term, key, **kwargs):
    """ Prompt for user input. """
    sep_ok = getattr(term, color_secondary)(u'::')
    sep_bad = getattr(term, color_primary)(u'::')
    colors = {'highlight': getattr(term, color_primary)}

    echo(fixate_next(term))
    echo(u'{sep} {key:>18}: '.format(sep=sep_ok, key=key))
    entry = LineEditor(colors=colors, **kwargs).read() or u''
    if not entry.strip():
        echo(fixate_next(term))
        echo(u'{sep} Canceled !\r\n'.format(sep=sep_bad))
        log.debug('Password reset canceled at prompt key={0}.'.format(key))
        return u''

    return entry
Esempio n. 9
0
File: bbslist.py Progetto: hick/x84
def more(cont=False):
    """
    Returns True if user 'q'uit; otherwise False
    when prompting is complete (moar/next/whatever)
    """
    from x84.bbs import echo, getch, getterminal, LineEditor, DBProxy
    prompt_key = u'\r\n\r\nENtER BBS iD: '
    msg_badkey = u'\r\n\r\nbbS id iNVAliD!'
    term = getterminal()
    prompt = u', '.join(fancy_blue(char, blurb)
                        for char, blurb in
                        (('i', 'NfO',),
                         ('a', 'dd',),
                         ('c', 'OMMENt',),
                         ('r', 'AtE',),
                         ('t', 'ElNEt',),
                         ('v', 'ANSi'),
                         ('q', 'Uit',)))
    if cont:
        prompt += u', ' + fancy_blue(' ', 'more')
    prompt += u': '
    while True:
        echo(u'\r\n')
        echo(u'\r\n'.join(term.wrap(text=prompt,
                                    width=(term.width - (term.width / 3)))))
        inp = getch()
        if inp in (u'q', 'Q'):
            return True
        elif inp is not None and type(inp) is not int:
            if cont and inp == u' ':
                echo(u'\r\n\r\n')
                return False
            if inp.lower() in u'acrtviACRTVI':
                # these keystrokes require a bbs key argument,
                # prompt the user for one
                echo(prompt_key)
                key = LineEditor(5).read()
                if (key is None or 0 == len(key.strip())
                        or not key in DBProxy('bbslist')):
                    echo(msg_badkey)
                    continue
                process_keystroke(inp, key)
Esempio n. 10
0
def rate_bbs(key):
    """ Prompt user to rate a bbs. """
    # pylint: disable=R0914
    #        Too many local variables
    from x84.bbs import getsession, getterminal, echo, LineEditor, DBProxy
    from x84.bbs import getch
    session, term = getsession(), getterminal()
    prompt_rating = u'\r\n\r\nRAtE 0.0 - 4.0: '
    prompt_chg = u'\r\n\r\nChANGE EXiStiNG ? [yn] '
    msg_invalid = u'\r\n\r\niNVAlid ENtRY.\r\n'
    echo(term.move(term.height, 0) + '\r\n')
    echo(prompt_rating)
    s_rating = LineEditor(3).read()
    if s_rating is None or 0 == len(s_rating.strip()):
        return
    try:
        f_rating = float(s_rating)
    except ValueError:
        echo(msg_invalid)
        return
    if f_rating < 0 or f_rating > 4:
        echo(msg_invalid)
        return
    entry = (session.handle, f_rating)
    ratings = DBProxy('bbslist', 'ratings')
    ratings.acquire()
    if session.handle in (_handle for (_handle, _rating) in ratings[key]):
        echo(prompt_chg)
        if getch() not in (u'y', u'Y'):
            ratings.release()
            return
        # re-define list without existing entry, + new entry
        ratings[key] = [(__handle, __rating)
                        for (__handle, __rating) in ratings[key]
                        if session.handle != __handle] + [entry]
        ratings.release()
        return
    # re-define as existing list + new entry
    ratings[key] = ratings[key] + [entry]
    ratings.release()
Esempio n. 11
0
File: lc.py Progetto: quastdog/x84
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
    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()]:
                    user = get_user((nick for nick in usrlist
                                     if nick.lower() == handle.lower()).next())
                    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()
Esempio n. 12
0
def prompt_tags(msg):
    """ Prompt for and return tags wished for message. """
    # pylint: disable=R0914,W0603
    #         Too many local variables
    #         Using the global statement
    from x84.bbs import DBProxy, echo, getterminal, getsession
    from x84.bbs import LineEditor, ini
    session, term = getsession(), getterminal()
    tagdb = DBProxy('tags')
    # version 1.0.9 introduced new ini option; set defaults for
    # those missing it from 1.0.8 upgrades.
    import ConfigParser
    try:
        moderated_tags = ini.CFG.getboolean('msg', 'moderated_tags')
    except ConfigParser.NoOptionError:
        moderated_tags = False
    try:
        moderated_groups = set(ini.CFG.get('msg', 'tag_moderator_groups'
                                           ).split())
    except ConfigParser.NoOptionError:
        moderated_groups = ('sysop', 'moderator',)
    msg_onlymods = (u"\r\nONlY MEMbERS Of GROUPS %s MAY CREAtE NEW tAGS." % (
        ", ".join(["'%s'".format(term.bold_yellow(grp)
                                 for grp in moderated_groups)])))
    msg_invalidtag = u"\r\n'%s' is not a valid tag."
    prompt_tags1 = u"ENtER %s, COMMA-dEliMitEd. " % (term.bold_red('TAG(s)'),)
    prompt_tags2 = u"OR '/list', %s:quit\r\n : " % (
        term.bold_yellow_underline('Escape'),)
    while True:
        # Accept user input for multiple 'tag's, or /list command
        echo(u'\r\n\r\n')
        echo(prompt_tags1)
        echo(prompt_tags2)
        width = term.width - 6
        sel_tags = u', '.join(msg.tags)
        inp_tags = LineEditor(width, sel_tags).read()
        if inp_tags is not None and 0 == len(inp_tags.strip()):
            # no tags must be (private ..)
            msg.tags = set()
            return True
        if inp_tags is None or inp_tags.strip().lower() == '/quit':
            return False
        elif inp_tags.strip().lower() == '/list':
            # list all available tags, and number of messages
            echo(u'\r\n\r\nTags: \r\n')
            all_tags = sorted(tagdb.items())
            if 0 == len(all_tags):
                echo(u'None !'.center(term.width / 2))
            else:
                echo(u', '.join((term.wrap([u'%s(%d)' % (_key, len(_value),)
                                       for (_key, _value) in all_tags]))
                          ), term.width - 2)
            continue
        echo(u'\r\n')

        # search input as valid tag(s)
        tags = set([inp.strip().lower() for inp in inp_tags.split(',')])

        # if the tag is new, and the user's group is not in
        # tag_moderator_groups, then dissallow such tag if
        # 'moderated_tags = yes' in ini cfg
        if moderated_tags:
            err = False
            for tag in tags.copy():
                if not tag in tagdb and not (
                        session.users.groups & moderated_groups):
                    tags.remove(tag)
                    echo(msg_invalidtag % (term.bold_red(tag),))
                    err = True
            if err:
                echo(msg_onlymods)
                continue
        msg.tags = tags
        return True
Esempio n. 13
0
def main():
    """ Main procedure. """
    # pylint: disable=R0914,R0912
    #         Too many local variables
    #         Too many branches
    from x84.bbs import DBProxy, getsession, getterminal, echo
    from x84.bbs import ini, LineEditor, timeago, showart
    from x84.bbs import disconnect, getch
    import time
    import os
    session, term = getsession(), getterminal()
    session.activity = 'logging off'
    handle = session.user.handle or 'anonymous'
    max_user = ini.CFG.getint('nua', 'max_user')
    prompt_msg = u'[spnG]: ' if session.user.get('expert', False) else (
        u'%s:AY SOMEthiNG %s:REViOUS %s:EXt %s:Et thE f**k Off !\b' % (
            term.bold_blue_underline(u's'),
            term.bold_blue_underline(u'p'),
            term.bold_blue_underline(u'n'),
            term.red_underline(u'Escape/g'),))
    prompt_say = u''.join((term.bold_blue(handle),
                           term.bold_blue(u' SAYS WhAt'), term.bold(': '),))
    boards = (('1984.ws', 'x/84 dEfAUlt bOARd', 'Dingo',),
              ('htc.zapto.org', 'Haunting the Chapel', 'Mercyful fate',),
              ('bbs.pharcyde.org', 'Pharcyde BBS', 'Access Denied',),
              ('bloodisland.ph4.se', 'Blood Island/X', 'Xzippo',),
              ('blackflag.acid.org:2627', 'Piranha: Black Flag', 'Caphood',),
              ('oddnetwork.org', '79 columns', 'Haliphax'),
              ('bbs.beardy.se', 'The Swamp', 'Beardy'),
              ('maze.io', 'rANDOM nOIZE', 'Maze'),)
    board_fmt = u'%25s %-30s %-15s\r\n'
    goodbye_msg = u''.join((
        term.move(term.height, 0),
        u'\r\n' * 10,
        u'tRY ANOthER fiNE bOARd', term.bold(u':'), u'\r\n\r\n',
        board_fmt % (
            term.underline('host'.rjust(25)),
            term.underline('board'.ljust(30)),
            term.underline('sysop'.ljust(15)),),
        u'\r\n'.join([board_fmt % (
            term.bold(host.rjust(25)),
            term.reverse(board.center(30)),
            term.bold_underline(sysop),)
            for (host, board, sysop) in boards]),
        u'\r\n\r\n',
        term.bold(
            u'back to the mundane world...'),
        u'\r\n',))
    commit_msg = term.bold_blue(
        u'-- !  thANk YOU fOR YOUR CONtRibUtiON, bROthER  ! --')
    write_msg = term.red_reverse(
        u'bURNiNG tO ROM, PlEASE WAiT ...')
    db_firstrecord = ((time.time() - 1984,
                       u'B. b.', u'bEhAVE YOURSElVES ...'),)
    automsg_len = 40

    def refresh_prompt(msg):
        """ Refresh automsg prompt using string msg. """
        echo(u''.join((u'\r\n\r\n', term.clear_eol, msg)))

    def refresh_automsg(idx):
        """ Refresh automsg database, display automsg of idx, return idx. """
        session.flush_event('automsg')
        autodb = DBProxy('automsg')
        automsgs = sorted(autodb.values()) if len(autodb) else db_firstrecord
        dblen = len(automsgs)
        # bounds check
        if idx < 0:
            idx = dblen - 1
        elif idx > dblen - 1:
            idx = 0
        tm_ago, handle, msg = automsgs[idx]
        asc_ago = u'%s ago' % (timeago(time.time() - tm_ago))
        disp = u''.join(('\r\n\r\n',
                         term.bold(handle.rjust(max_user)),
                         term.bold_blue(u'/'),
                         term.bold_blue(u'%*d' % (len('%d' % (dblen,)), idx,)),
                         term.bold_blue(u':'),
                         term.bold_green(msg.ljust(automsg_len)),
                         term.bold(u'\\'),
                         term.bold_blue(asc_ago),))
        echo(u'\r\n'.join(term.wrap(disp)))
        return idx

    def refresh_all(idx=None):
        """
        refresh screen, database, and return database index
        """
        echo(u''.join((u'\r\n\r\n', term.clear_eol,)))
        for line in showart(
                os.path.join(os.path.dirname(__file__), 'art', 'logoff.ans'), 'cp437'):
            echo(line)
        idx = refresh_automsg(-1 if idx is None else idx)
        refresh_prompt(prompt_msg)
        return idx

    idx = refresh_all()
    while True:
        if session.poll_event('refresh'):
            idx = refresh_all()
        elif session.poll_event('automsg'):
            refresh_automsg(-1)
            echo(u'\a')  # bel
            refresh_prompt(prompt_msg)
        inp = getch(1)
        if inp in (u'g', u'G', term.KEY_EXIT, unichr(27), unichr(3),):
            # http://www.xfree86.org/4.5.0/ctlseqs.html
            # Restore xterm icon and window title from stack.
            echo(unichr(27) + u'[23;0t')
            echo(goodbye_msg)
            getch(1.5)
            disconnect('logoff.')
        elif inp in (u'n', u'N', term.KEY_DOWN, term.KEY_NPAGE,):
            idx = refresh_automsg(idx + 1)
            refresh_prompt(prompt_msg)
        elif inp in (u'p', u'P', term.KEY_UP, term.KEY_PPAGE,):
            idx = refresh_automsg(idx - 1)
            refresh_prompt(prompt_msg)
        elif inp in (u's', u'S'):
            # new prompt: say something !
            refresh_prompt(prompt_say)
            msg = LineEditor(width=automsg_len).read()
            if msg is not None and msg.strip():
                echo(u''.join((u'\r\n\r\n', write_msg,)))
                autodb = DBProxy('automsg')
                autodb.acquire()
                idx = max([int(ixx) for ixx in autodb.keys()] or [-1]) + 1
                autodb[idx] = (time.time(), handle, msg.strip())
                autodb.release()
                session.send_event('global', ('automsg', True,))
                refresh_automsg(idx)
                echo(u''.join((u'\r\n\r\n', commit_msg,)))
                getch(0.5)  # for effect, LoL
            # display prompt
            refresh_prompt(prompt_msg)
Esempio n. 14
0
def get_username(handle=u''):
    """
    Prompt for a login handle. If unfound, script change to 'nua' when
    allow_apply is enabled (default=yes). Also allow 'anonymous' when enabled
    (default=no). A unicode handle of non-zero length is returned when the
    login handle matches a userbase record.
    """
    # pylint: disable=R0914,R0911
    #         Too many local variables
    #         Too many return statements
    from x84.bbs import getterminal, ini, echo, LineEditor, gosub, goto
    from x84.bbs import find_user, getch
    term = getterminal()
    prompt_user = u'user: '******'\r\n\r\n  --> Create new account? [ynq]   <--' + '\b' * 5
    allow_apply = ini.CFG.getboolean('nua', 'allow_apply')
    enable_anonymous = ini.CFG.getboolean('matrix', 'enable_anonymous')
    # pylint: disable=E1103
    #         Instance of '_Chainmap' has no 'split' member
    #         (but some types could not be inferred)
    newcmds = ini.CFG.get('matrix', 'newcmds').split()
    byecmds = ini.CFG.get('matrix', 'byecmds').split()
    denied_msg = u'\r\n\r\nfiRSt, YOU MUSt AbANdON YOUR libERtIES.'
    badanon_msg = u"\r\n  " + term.bright_red + u"'%s' login denied."
    max_user = ini.CFG.getint('nua', 'max_user')
    nuascript = ini.CFG.get('nua', 'script')
    topscript = ini.CFG.get('matrix', 'topscript')

    echo(prompt_user)
    handle = LineEditor(max_user, handle).read()
    if handle is None or 0 == len(handle.strip()):
        echo(u'\r\n')
        return u''
    elif handle.lower() in newcmds:
        if allow_apply:
            gosub('nua', u'')
            return u''
        denied(denied_msg)
        return u''
    elif handle.lower() in byecmds:
        goto('logoff')
    elif handle.lower() == u'anonymous':
        if enable_anonymous:
            goto(topscript, 'anonymous')
        denied(badanon_msg % (handle, ))
        return u''
    u_handle = find_user(handle)
    if u_handle is not None:
        return u_handle  # matched
    if allow_apply is False:
        denied(denied_msg)
        return u''

    echo(apply_msg)
    ynq = getch()
    if ynq in (u'q', u'Q', term.KEY_EXIT):
        # goodbye
        goto('logoff')
    elif ynq in (u'y', u'Y'):
        # new user application
        goto(nuascript, handle)
    echo(u'\r\n')
    return u''
Esempio n. 15
0
def main(quick=False):
    """ Main procedure. """

    session, term = getsession(), getterminal()
    session.activity = 'checking for new messages'

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

    colors = dict(highlight=lambda txt: txt,
                  lowlight=lambda txt: txt,
                  backlight=lambda txt: txt,
                  text=lambda txt: txt) if not colored_menu_items else dict(
                      highlight=getattr(term, color_highlight),
                      lowlight=getattr(term, color_lowlight),
                      backlight=getattr(term, color_backlight),
                      text=getattr(term, color_text))

    yloc = top_margin = 0
    subscription = session.user.get('msg_subscription', [])
    dirty = 2

    while True:
        if dirty == 2:
            # display header art,
            yloc = display_banner(art_file, encoding=art_encoding, center=True)
            xloc = max(0, (term.width // 2) - 40)
            echo(u'\r\n')
            top_margin = yloc = (yloc + 1)

        elif dirty:
            echo(term.move(top_margin, 0) + term.normal + term.clear_eos)
            echo(term.move(top_margin, xloc))

        if dirty:

            if not subscription:
                # prompt the user for a tag subscription, and loop
                # back again when completed to re-draw and show new messages.
                subscription = session.user['msg_subscription'] = (
                    prompt_subscription(session=session,
                                        term=term,
                                        yloc=top_margin,
                                        subscription=subscription,
                                        colors=colors))
                continue

            messages, messages_bytags = get_messages_by_subscription(
                session, subscription)

            # When quick login ('y') selected in top.py, return immediately
            # when no new messages are matched any longer.
            if quick and not messages['new']:
                echo(term.move_x(xloc) + u'\r\nNo new messages.\r\n')
                return waitprompt(term)

            txt = describe_message_area(term=term,
                                        subscription=subscription,
                                        messages_bytags=messages_bytags,
                                        colors=colors)

            yloc = top_margin + show_description(
                term=term,
                description=txt,
                color=None,
                subsequent_indent=' ' * len('message area: '))

            echo(
                render_menu_entries(term=term,
                                    top_margin=yloc,
                                    menu_items=get_menu(messages),
                                    colors=colors,
                                    max_cols=2))
            echo(display_prompt(term=term, colors=colors))
            echo(colors['backlight'](u' \b'))
            dirty = False

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

        if event == 'refresh':
            # screen resized, redraw.
            dirty = 2
            continue

        elif event == 'newmsg':
            # When a new message is sent, 'newmsg' event is broadcasted.
            session.flush_event('newmsg')
            nxt_msgs, nxt_bytags = get_messages_by_subscription(
                session, subscription)
            if nxt_msgs['new'] - messages['new']:
                # beep and re-display when a new message has arrived.
                echo(u'\b')
                messages, messages_bytags = nxt_msgs, nxt_bytags
                dirty = True
                continue

        elif event == 'input':
            # on input, block until carriage return
            session.buffer_input(data, pushback=True)
            given_inp = LineEditor(1,
                                   colors={
                                       'highlight': colors['backlight']
                                   }).read()

            if given_inp is None:
                # escape/cancel
                continue

            inp = given_inp.strip()
            if inp.lower() in (u'n', 'a', 'v'):
                # read new/all/private messages
                message_indices = sorted(
                    list({
                        'n': messages['new'],
                        'a': messages['all'],
                        'v': messages['private'],
                    }[inp.lower()]))
                if message_indices:
                    dirty = 2
                    read_messages(session=session,
                                  term=term,
                                  message_indices=message_indices,
                                  colors=colors)
            elif inp.lower() == u'm' and messages['new']:
                # mark all messages as read
                dirty = 1
                do_mark_as_read(session, messages['new'])
            elif inp.lower() in (u'p', u'w'):
                # write new public/private message
                dirty = 2
                public = bool(inp.lower() == u'p')
                msg = Msg()
                if (not prompt_recipient(
                        term=term, msg=msg, colors=colors, public=public) or
                        not prompt_subject(term=term, msg=msg, colors=colors)
                        or not prompt_body(term=term, msg=msg, colors=colors)
                        or not prompt_tags(session=session,
                                           term=term,
                                           msg=msg,
                                           colors=colors,
                                           public=public)):
                    continue
                do_send_message(session=session,
                                term=term,
                                msg=msg,
                                colors=colors)
            elif inp.lower() == u'c':
                # prompt for new tag subscription (at next loop)
                subscription = []
                dirty = 1
            elif inp.lower() == u'?':
                # help
                echo(term.move(top_margin, 0) + term.clear_eos)
                do_describe_message_system(term, colors)
                waitprompt(term)
                dirty = 2
            elif inp.lower() == u'q':
                return
            if given_inp:
                # clear out line editor prompt
                echo(colors['backlight'](u'\b \b'))
Esempio n. 16
0
def prompt_tags(msg):
    """ Prompt for and return tags wished for message. """
    # pylint: disable=R0914,W0603
    #         Too many local variables
    #         Using the global statement
    from x84.bbs import DBProxy, echo, getterminal, getsession
    from x84.bbs import Ansi, LineEditor, ini
    session, term = getsession(), getterminal()
    tagdb = DBProxy('tags')
    # version 1.0.9 introduced new ini option; set defaults for
    # those missing it from 1.0.8 upgrades.
    import ConfigParser
    try:
        moderated_tags = ini.CFG.getboolean('msg', 'moderated_tags')
    except ConfigParser.NoOptionError:
        moderated_tags = False
    try:
        moderated_groups = set(
            ini.CFG.get('msg', 'tag_moderator_groups').split())
    except ConfigParser.NoOptionError:
        moderated_groups = (
            'sysop',
            'moderator',
        )
    msg_onlymods = (
        u"\r\nONlY MEMbERS Of GROUPS %s MAY CREAtE NEW tAGS." % (", ".join(
            ["'%s'".format(term.bold_yellow(grp)
                           for grp in moderated_groups)])))
    msg_invalidtag = u"\r\n'%s' is not a valid tag."
    prompt_tags1 = u"ENtER %s, COMMA-dEliMitEd. " % (term.bold_red('TAG(s)'), )
    prompt_tags2 = u"OR '/list', %s:quit\r\n : " % (
        term.bold_yellow_underline('Escape'), )
    while True:
        # Accept user input for multiple 'tag's, or /list command
        echo(u'\r\n\r\n')
        echo(prompt_tags1)
        echo(prompt_tags2)
        width = term.width - 6
        sel_tags = u', '.join(msg.tags)
        inp_tags = LineEditor(width, sel_tags).read()
        if inp_tags is not None and 0 == len(inp_tags.strip()):
            # no tags must be (private ..)
            msg.tags = set()
            return True
        if inp_tags is None or inp_tags.strip().lower() == '/quit':
            return False
        elif inp_tags.strip().lower() == '/list':
            # list all available tags, and number of messages
            echo(u'\r\n\r\nTags: \r\n')
            all_tags = sorted(tagdb.items())
            if 0 == len(all_tags):
                echo(u'None !'.center(term.width / 2))
            else:
                echo(
                    Ansi(u', '.join(([
                        u'%s(%d)' % (
                            _key,
                            len(_value),
                        ) for (_key, _value) in all_tags
                    ]))).wrap(term.width - 2))
            continue
        echo(u'\r\n')

        # search input as valid tag(s)
        tags = set([inp.strip().lower() for inp in inp_tags.split(',')])

        # if the tag is new, and the user's group is not in
        # tag_moderator_groups, then dissallow such tag if
        # 'moderated_tags = yes' in ini cfg
        if moderated_tags:
            err = False
            for tag in tags.copy():
                if not tag in tagdb and not (session.users.groups
                                             & moderated_groups):
                    tags.remove(tag)
                    echo(msg_invalidtag % (term.bold_red(tag), ))
                    err = True
            if err:
                echo(msg_onlymods)
                continue
        msg.tags = tags
        return True
Esempio n. 17
0
def main():
    """ Main procedure. """
    # pylint: disable=R0914,R0912
    #         Too many local variables
    #         Too many branches
    from x84.bbs import DBProxy, getsession, getterminal, echo
    from x84.bbs import ini, LineEditor, timeago, Ansi, showcp437
    from x84.bbs import disconnect, getch
    import time
    import os
    session, term = getsession(), getterminal()
    session.activity = 'logging off'
    handle = session.handle if (
        session.handle is not None
    ) else 'anonymous'
    max_user = ini.CFG.getint('nua', 'max_user')
    prompt_msg = u'[spnG]: ' if session.user.get('expert', False) else (
        u'%s:AY SOMEthiNG %s:REViOUS %s:EXt %s:Et thE f**k Off !\b' % (
        term.bold_blue_underline(u's'), term.blue_underline(u'p'),
        term.blue_underline(u'n'), term.red_underline(u'Escape/g'),))
    prompt_say = u''.join((term.bold_blue(handle),
                           term.blue(u' SAYS WhAt'), term.bold(': '),))
    boards = (('1984.ws', 'x/84 dEfAUlt bOARd', 'dingo',),
              ('htc.zapto.org', 'Haunting the Chapel', 'Mercyful',),
              ('pharcyde.ath.cx', 'Pharcyde BBS', 'Access Denied',),
              ('bloodisland.ph4.se', 'Blood Island', 'xzip',),
              ('ssl.archaicbinary.net', 'Archaic Binary', 'Wayne Smith',),
              ('bbs.godta.com', 'godta', 'sk-5',)
              ,)
    board_fmt = u'%25s %-30s %-15s\r\n'
    goodbye_msg = u''.join((
        term.move(term.height, 0),
        u'\r\n' * 10,
        u'tRY ANOthER fiNE bOARd', term.bold(u':'), u'\r\n\r\n',
        board_fmt % (
            term.underline('host'.rjust(25)),
            term.underline('board'.ljust(30)),
            term.underline('sysop'.ljust(15)),),
        u'\r\n'.join([board_fmt % (
            term.bold(host.rjust(25)),
            term.reverse(board.center(30)),
            term.bold_underline(sysop),)
            for (host, board, sysop) in boards]),
        u'\r\n\r\n',
        term.bold(
            u'back to the mundane world...'),
        u'\r\n',))
    commit_msg = term.bold_blue(
        u'-- !  thANk YOU fOR YOUR CONtRibUtiON, bROthER  ! --')
    write_msg = term.red_reverse(
        u'bURNiNG tO ROM, PlEASE WAiT ...')
    db_firstrecord = ((time.time() - 1984,
                       u'B. b.', u'bEhAVE YOURSElVES ...'),)
    automsg_len = 40
    artfile = os.path.join(os.path.dirname(__file__), 'art', '1984.asc')

    def refresh_prompt(msg):
        """ Refresh automsg prompt using string msg. """
        echo(u''.join((u'\r\n\r\n', term.clear_eol, msg)))

    def refresh_automsg(idx):
        """ Refresh automsg database, display automsg of idx, return idx. """
        session.flush_event('automsg')
        autodb = DBProxy('automsg')
        automsgs = sorted(autodb.values()) if len(autodb) else db_firstrecord
        dblen = len(automsgs)
        # bounds check
        if idx < 0:
            idx = dblen - 1
        elif idx > dblen - 1:
            idx = 0
        tm_ago, handle, msg = automsgs[idx]
        asc_ago = u'%s ago' % (timeago(time.time() - tm_ago))
        disp = (u''.join(('\r\n\r\n',
                          term.bold(handle.rjust(max_user)),
                          term.bold_blue(u'/'),
                          term.blue(u'%*d' % (len('%d' % (dblen,)), idx,)),
                          term.bold_blue(u':'),
                          term.blue_reverse(msg.ljust(automsg_len)),
                          term.bold(u'\\'),
                          term.blue(asc_ago),)))
        echo(u''.join((
            u'\r\n\r\n',
            Ansi(disp).wrap(term.width),
        )))
        return idx

    def refresh_all(idx=None):
        """
        refresh screen, database, and return database index
        """
        echo(u''.join((u'\r\n\r\n', term.clear_eol,)))
        for line in showcp437(artfile):
            echo(line)
        idx = refresh_automsg(-1 if idx is None else idx)
        refresh_prompt(prompt_msg)
        return idx

    idx = refresh_all()
    while True:
        if session.poll_event('refresh'):
            idx = refresh_all()
        elif session.poll_event('automsg'):
            refresh_automsg(-1)
            echo(u'\a')  # bel
            refresh_prompt(prompt_msg)
        inp = getch(1)
        if inp in (u'g', u'G', term.KEY_EXIT, unichr(27), unichr(3),):
            # http://www.xfree86.org/4.5.0/ctlseqs.html
            # Restore xterm icon and window title from stack.
            echo(unichr(27) + u'[23;0t')
            echo(goodbye_msg)
            getch(1.5)
            disconnect('logoff.')
        elif inp in (u'n', u'N', term.KEY_DOWN, term.KEY_NPAGE,):
            idx = refresh_automsg(idx + 1)
            refresh_prompt(prompt_msg)
        elif inp in (u'p', u'P', term.KEY_UP, term.KEY_PPAGE,):
            idx = refresh_automsg(idx - 1)
            refresh_prompt(prompt_msg)
        elif inp in (u's', u'S'):
            # new prompt: say something !
            refresh_prompt(prompt_say)
            msg = LineEditor(width=automsg_len).read()
            if msg is not None and msg.strip():
                echo(u''.join((u'\r\n\r\n', write_msg,)))
                autodb = DBProxy('automsg')
                autodb.acquire()
                idx = max([int(ixx) for ixx in autodb.keys()] or [-1]) + 1
                autodb[idx] = (time.time(), handle, msg.strip())
                autodb.release()
                session.send_event('global', ('automsg', True,))
                refresh_automsg(idx)
                echo(u''.join((u'\r\n\r\n', commit_msg,)))
                getch(0.5)  # for effect, LoL
            # display prompt
            refresh_prompt(prompt_msg)
Esempio n. 18
0
def main(quick=False):
    """ Main procedure. """

    session, term = getsession(), getterminal()
    session.activity = 'checking for new messages'

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

    colors = dict(
        highlight=lambda txt: txt,
        lowlight=lambda txt: txt,
        backlight=lambda txt: txt,
        text=lambda txt: txt
    ) if not colored_menu_items else dict(
        highlight=getattr(term, color_highlight),
        lowlight=getattr(term, color_lowlight),
        backlight=getattr(term, color_backlight),
        text=getattr(term, color_text))

    yloc = top_margin = 0
    subscription = session.user.get('msg_subscription', [])
    dirty = 2

    while True:
        if dirty == 2:
            # display header art,
            yloc = display_banner(art_file, encoding=art_encoding, center=True)
            xloc = max(0, (term.width // 2) - 40)
            echo(u'\r\n')
            top_margin = yloc = (yloc + 1)

        elif dirty:
            echo(term.move(top_margin, 0) + term.normal + term.clear_eos)
            echo(term.move(top_margin, xloc))

        if dirty:

            if not subscription:
                # prompt the user for a tag subscription, and loop
                # back again when completed to re-draw and show new messages.
                subscription = session.user['msg_subscription'] = (
                    prompt_subscription(
                        session=session, term=term, yloc=top_margin,
                        subscription=subscription, colors=colors))
                continue

            messages, messages_bytags = get_messages_by_subscription(
                session, subscription)

            # When quick login ('y') selected in top.py, return immediately
            # when no new messages are matched any longer.
            if quick and not messages['new']:
                echo(term.move_x(xloc) + u'\r\nNo new messages.\r\n')
                return waitprompt(term)

            txt = describe_message_area(
                term=term, subscription=subscription,
                messages_bytags=messages_bytags, colors=colors)

            yloc = top_margin + show_description(
                term=term, description=txt, color=None,
                subsequent_indent=' ' * len('message area: '))

            echo(render_menu_entries(
                term=term, top_margin=yloc,
                menu_items=get_menu(messages),
                colors=colors, max_cols=2))
            echo(display_prompt(term=term, colors=colors))
            echo(colors['backlight'](u' \b'))
            dirty = False

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

        if event == 'refresh':
            # screen resized, redraw.
            dirty = 2
            continue

        elif event == 'newmsg':
            # When a new message is sent, 'newmsg' event is broadcasted.
            session.flush_event('newmsg')
            nxt_msgs, nxt_bytags = get_messages_by_subscription(
                session, subscription)
            if nxt_msgs['new'] - messages['new']:
                # beep and re-display when a new message has arrived.
                echo(u'\b')
                messages, messages_bytags = nxt_msgs, nxt_bytags
                dirty = True
                continue

        elif event == 'input':
            # on input, block until carriage return
            session.buffer_input(data, pushback=True)
            given_inp = LineEditor(
                1, colors={'highlight': colors['backlight']}
            ).read()

            if given_inp is None:
                # escape/cancel
                continue

            inp = given_inp.strip()
            if inp.lower() in (u'n', 'a', 'v'):
                # read new/all/private messages
                message_indices = sorted(list(
                    {'n': messages['new'],
                     'a': messages['all'],
                     'v': messages['private'],
                     }[inp.lower()]))
                if message_indices:
                    dirty = 2
                    read_messages(session=session, term=term,
                                  message_indices=message_indices,
                                  colors=colors)
            elif inp.lower() == u'm' and messages['new']:
                # mark all messages as read
                dirty = 1
                do_mark_as_read(session, messages['new'])
            elif inp.lower() in (u'p', u'w'):
                # write new public/private message
                dirty = 2
                public = bool(inp.lower() == u'p')
                msg = Msg()
                if (
                        not prompt_recipient(
                            term=term, msg=msg,
                            colors=colors, public=public
                        ) or not prompt_subject(
                            term=term, msg=msg, colors=colors
                        ) or not prompt_body(
                            term=term, msg=msg, colors=colors
                        ) or not prompt_tags(
                            session=session, term=term, msg=msg,
                            colors=colors, public=public
                        )):
                    continue
                do_send_message(session=session, term=term,
                                msg=msg, colors=colors)
            elif inp.lower() == u'c':
                # prompt for new tag subscription (at next loop)
                subscription = []
                dirty = 1
            elif inp.lower() == u'?':
                # help
                echo(term.move(top_margin, 0) + term.clear_eos)
                do_describe_message_system(term, colors)
                waitprompt(term)
                dirty = 1
            elif inp.lower() == u'q':
                return
            if given_inp:
                # clear out line editor prompt
                echo(colors['backlight'](u'\b \b'))
Esempio n. 19
0
def get_username(handle=u''):
    """
    Prompt for a login handle. If unfound, script change to 'nua' when
    allow_apply is enabled (default=yes). Also allow 'anonymous' when enabled
    (default=no). A unicode handle of non-zero length is returned when the
    login handle matches a userbase record.
    """
    # pylint: disable=R0914,R0911
    #         Too many local variables
    #         Too many return statements
    from x84.bbs import getterminal, ini, echo, LineEditor, gosub, goto
    from x84.bbs import find_user, getch
    term = getterminal()
    prompt_user = u'\r\n  user: '******'\r\n\r\n  --> Create new account? [ynq]   <--' + '\b' * 5
    allow_apply = ini.CFG.getboolean('nua', 'allow_apply')
    enable_anonymous = ini.CFG.getboolean('matrix', 'enable_anonymous')
    # pylint: disable=E1103
    #         Instance of '_Chainmap' has no 'split' member
    #         (but some types could not be inferred)
    newcmds = ini.CFG.get('matrix', 'newcmds').split()
    byecmds = ini.CFG.get('matrix', 'byecmds').split()
    denied_msg = u'\r\n\r\nfiRSt, YOU MUSt AbANdON YOUR libERtIES.'
    badanon_msg = u"\r\n  " + term.bright_red + u"'%s' login denied."
    max_user = ini.CFG.getint('nua', 'max_user')
    nuascript = ini.CFG.get('nua', 'script')
    topscript = ini.CFG.get('matrix', 'topscript')

    echo(prompt_user)
    handle = LineEditor(max_user, handle).read()
    if handle is None or 0 == len(handle.strip()):
        echo(u'\r\n')
        return u''
    elif handle.lower() in newcmds:
        if allow_apply:
            gosub('nua', u'')
            return u''
        denied(denied_msg)
        return u''
    elif handle.lower() in byecmds:
        goto('logoff')
    elif handle.lower() == u'anonymous':
        if enable_anonymous:
            goto(topscript, 'anonymous')
        denied(badanon_msg % (handle,))
        return u''
    u_handle = find_user(handle)
    if u_handle is not None:
        return u_handle  # matched
    if allow_apply is False:
        denied(denied_msg)
        return u''

    echo(apply_msg)
    ynq = getch()
    if ynq in (u'q', u'Q', term.KEY_EXIT):
        # goodbye
        goto('logoff')
    elif ynq in (u'y', u'Y'):
        # new user application
        goto(nuascript, handle)
    echo(u'\r\n')
    return u''
Esempio n. 20
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()
Esempio n. 21
0
def prompt_recipient(term, msg, colors, public=True):
    """ Prompt for recipient of message. """
    xpos = max(0, (term.width // 2) - (80 // 2))
    echo(term.move_x(xpos) + term.clear_eos)
    echo(u'Enter handle{0}.\r\n'.format(
        u', empty to address to all' if public else u''))
    echo(term.move_x(xpos) + ':: ')
    inp = LineEditor(username_max_length, msg.recipient,
                     colors={'highlight': colors['backlight']}
                     ).read()

    if inp is None:
        echo(u''.join((term.move_x(xpos),
                       colors['highlight']('Canceled.'),
                       term.clear_eol)))
        term.inkey(1)
        return False

    elif not inp.strip():
        # empty, recipient is None
        msg.recipient = None
        if public:
            return True
        return False

    inp = inp.strip()

    # validate/find user
    userlist = list_users()
    if inp in userlist:
        # exact match,
        msg.recipient = inp
        echo(u'\r\n')
        return True

    # nearest match
    for match in difflib.get_close_matches(inp.strip(), userlist):
        echo(u''.join((
            term.move_x(xpos),
            u'{0} [yn]'.format(colors['highlight'](match)),
            term.clear_eol,
            u' ?\b\b')))
        while True:
            inp = term.inkey()
            if inp.code == term.KEY_ESCAPE:
                # escape/cancel
                return False
            elif inp.lower() == u'y':
                # accept match
                msg.recipient = match
                echo(u'\r\n')
                return True
            elif inp.lower() == u'n':
                # next match
                break

    echo(u''.join((term.move_x(xpos),
                   colors['highlight']('No match.'),
                   term.clear_eol)))
    term.inkey(1)
    return False