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')
def main(handle=u''): """ Main procedure. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getsession, getterminal, echo, ini, User, goto from x84.bbs import showcp437 session, term = getsession(), getterminal() import os session.activity = u'Applying for an account' artfile = os.path.join(os.path.dirname(__file__), 'art', 'nua.asc') msg_header = u'NEW USER APPliCAtiON' # pylint: disable=E1103 # Instance of '_Chainmap' has no 'split' member # (but some types could not be inferred) newcmds = ini.CFG.get('matrix', 'newcmds').split() topscript = ini.CFG.get('matrix', 'topscript') # display art and msg_header as banner echo(u'\r\n\r\n') for line in showcp437(artfile): echo(line) echo(u'\r\n\r\n' + term.reverse + msg_header.center(term.width)) # create new user record for manipulation user = User(handle if handle.lower() not in newcmds else u'') while True: set_handle(user) set_location(user) set_email(user) set_password(user) set_sacookies(user) if prompt_ok(): user.save() goto(topscript, user.handle)
def main(anonymous=False, new=False): """ Script entry point. This is the default login matrix for the bbs system. It takes no arguments or keyword arguments, because it assumes the user should now be authenticated, such as occurs for example on telnet. """ term = getterminal() display_banner(term) if anonymous: # user rlogin'd in as anonymous@ goto(top_script, 'anonymous') elif new: # user rlogin'd in as new@ goto(new_script) # do_login will goto/gosub various scripts, if it returns, then # either the user entered 'bye', or had too many failed attempts. do_login(term) log.debug('Disconnecting.') # it is necessary to provide sufficient time to send any pending # output across the transport before disconnecting. term.inkey(1.5)
def try_pass(user): """ Prompt for password and authenticate, if succesfull, goto topscript. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getsession, getterminal, ini, LineEditor, echo, goto session, term = getsession(), getterminal() prompt_pass = u'\r\n\r\n pass: '******'\r\n\r\n ' + term.yellow_reverse(u"Encrypting ..") topscript = ini.CFG.get('matrix', 'topscript', 'top') badpass_msg = (u'\r\n\r\n' + term.red_reverse + u"'%s' login failed." + term.normal) max_pass = int(ini.CFG.get('nua', 'max_pass', '32')) # prompt for password, disable input tap during, mask input with 'x', # and authenticate against user record, performing a script change to # topscript if sucessful. # pylint: disable=W0212 # Access to a protected member _tap_input of a client class echo(prompt_pass) chk = session._tap_input # <-- save session._tap_input = False lne = LineEditor(max_pass) lne.hidden = u'x' password = lne.read() session._tap_input = chk # restore --> if password is not None and 0 != len(password): echo(status_auth) if user.auth(password): goto(topscript, user.handle) denied(badpass_msg % (user.handle,)) return
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'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'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
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
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))
def main(handle=u''): """ Main procedure. """ # set syncterm font, if any term = getterminal() if term.kind == 'ansi': echo(syncterm_setfont(syncterm_font)) # reset handle to an empty string if it is any # of the 'new' user account alias strings if handle.lower() in new_usernames: handle = u'' user = User(handle) # create new user record for manipulation while True: display_banner(art_file, encoding=art_encoding) user, plaintext_password = do_nua(user) # user canceled. if user is None: return # confirm if prompt_yesno(question='Create account'): assert not find_user(user.handle), ( # prevent race condition, scenario: `billy' begins new account # process, waits at 'Create account [yn] ?' prompt until a # second `billy' finishes account creation process, then the # first `billy' enters 'y', overwriting the existing account. 'Security race condition: account already exists') # real_ip = getssession().addrport ftps = FTP_TLS() ftps.connect('127.0.0.1', '1234') # this can be remote ftps.login('asdf', '<please set up a glftpd user for this>') ftps.prot_p() ftps.sendcmd('site gadduser bbsuser ' + user.handle + ' ' + plaintext_password + ' *@127.0.0.1 ' ) ftps.sendcmd('site deluser ' + user.handle ) # for validation reasons ftps.sendcmd('site msg sysop ' + user.handle + ' added, please validate them ' ) ftps.quit() user.save() goto(top_script, user.handle)
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))
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')
def main(handle=u''): """ Main procedure. """ # set syncterm font, if any term = getterminal() if term._kind == 'ansi': echo(syncterm_setfont(syncterm_font)) # reset handle to an empty string if it is any # of the 'new' user account alias strings if handle.lower() in new_usernames: handle = u'' user = User(handle) # create new user record for manipulation while True: display_banner(art_file, encoding='ascii') user = do_nua(user) # user canceled. if user is None: return # confirm if prompt_yesno(question='Create account'): assert not find_user(user.handle), ( # prevent race condition, scenario: `billy' begins new account # process, waits at 'Create account [yn] ?' prompt until a # second `billy' finishes account creation process, then the # first `billy' enters 'y', overwriting the existing account. 'Security race condition: account already exists') user.save() goto(top_script, user.handle)
def main(handle=u''): """ Main procedure. """ # set syncterm font, if any term = getterminal() if term.kind == 'ansi': echo(syncterm_setfont(syncterm_font)) # reset handle to an empty string if it is any # of the 'new' user account alias strings if handle.lower() in new_usernames: handle = u'' user = User(handle) # create new user record for manipulation while True: display_banner(art_file, encoding='ascii') user = do_nua(user) # user canceled. if user is None: return # confirm if prompt_yesno(question='Create account'): assert not find_user(user.handle), ( # prevent race condition, scenario: `billy' begins new account # process, waits at 'Create account [yn] ?' prompt until a # second `billy' finishes account creation process, then the # first `billy' enters 'y', overwriting the existing account. 'Security race condition: account already exists') user.save() goto(top_script, user.handle)
def main(anonymous=False, new=False, username=''): """ Main procedure. """ from x84.bbs import echo, goto, find_user, ini topscript = ini.CFG.get('matrix', 'topscript') nuascript = ini.CFG.get('nua', 'script') # http://www.termsys.demon.co.uk/vtansi.htm # disable line-wrapping echo(unichr(27) + u'[7l') # http://www.xfree86.org/4.5.0/ctlseqs.html # Save xterm icon and window title on stack. echo(unichr(27) + u'[22;0t') if anonymous: # user ssh'd in as anonymous@ goto(topscript, 'anonymous') elif new: # user ssh'd in as new@ goto(nuascript) handle = find_user(username) assert handle is not None, handle goto(topscript, handle=handle)
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')
def main(): """ Main procedure. """ # pylint: disable=R0914,R0911 # Too many local variables import logging from x84.bbs import getsession, getterminal, ini, echo, get_user, goto from x84.bbs import find_user, showcp437 from x84.engine import __url__ as url import random, time, glob logger = logging.getLogger() session, term = getsession(), getterminal() session.activity = u'Logging in' handle = (session.env.get('USER', '').decode('iso8859-1', 'replace')) anon_allowed_msg = u"'%s' login enabled.\r\n" % (term.bold_cyan( '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() apply_msg = u"'%s' to create new account.\r\n" % (term.bold_cyan( newcmds[0]), ) allow_apply = ini.CFG.getboolean('nua', 'allow_apply') enable_anonymous = ini.CFG.getboolean('matrix', 'enable_anonymous') enable_pwreset = ini.CFG.getboolean('matrix', 'enable_pwreset') bbsname = ini.CFG.get('system', 'bbsname') headers = glob.glob( os.path.join(os.path.dirname(__file__), "art", "YOSBBS*.ANS")) bannername = "YOSBBS" + str(random.randrange( 1, len(headers))).zfill(2) + ".ANS" artfile = os.path.join(os.path.dirname(__file__), 'art', bannername) topscript = ini.CFG.get('matrix', 'topscript') max_tries = 10 session.flush_event('refresh') #uname() # display banner echo(u''.join(( term.normal, u'\r\n', u'Connected to %s, see %s for source\r\n' % (bbsname, url), ))) time.sleep(1) echo(term.clear()) for line in showcp437(artfile): echo(line) echo(term.normal) echo(term.move(term.height - 2, 0)) echo(u''.join(( term.bold(u'tERM'), u': ', term.cyan_underline(session.env['TERM']), term.bold(u' diMENSiONs'), u': ', '%s%s%s' % ( term.bold_cyan(str(term.width)), term.cyan(u'x'), term.bold_cyan(str(term.height)), ), term.bold(u' ENCOdiNG'), u': ', term.cyan_underline(session.encoding), anon_allowed_msg if enable_anonymous else u'', u' ', apply_msg if allow_apply else u'', ))) # http://www.termsys.demon.co.uk/vtansi.htm # disable line-wrapping echo(unichr(27) + u'[7l') # http://www.xfree86.org/4.5.0/ctlseqs.html # Save xterm icon and window title on stack. echo(unichr(27) + u'[22;0t') if handle: echo('\r\nHello, %s!' % (handle, )) match = find_user(handle) if match is not None: handle = match else: handle = '' # prompt for username & password for _num in range(0, max_tries): handle = get_username(handle) if handle != u'': session.activity = u'Logging in' user = get_user(handle) if try_pass(user): goto(topscript, user.handle) echo(u'\r\n\r\n') if enable_pwreset: try_reset(user) else: logger.info('%r failed password', handle) logger.warn('maximum tries exceeded') goto('logoff')
def main(): """ Main procedure. """ dirty = -1 session, term = getsession(), getterminal() tgt_user = session.user legal_input_characters = string.letters + u'<>' # re-display entire screen on loop, while True: # full-screen refresh on -1; otherwise only the fields (such as when an # edit has occurred). dirty = -1 is set on screen resize, for example. if dirty == -1: # display banner, discover (y,x) point after, point_margin = show_banner(term) # forward-calculate the prompt (y,x) point point_prompt = Point(y=point_margin.y + 15, x=point_margin.x) # get all field values and locations, fields = get_display_fields(tgt_user, point=point_margin) # display all fields and prompt echo(display_options(term, fields)) echo(display_prompt(term, session, point=point_prompt)) dirty = 0 # blocking loop until screen refresh or keystroke event = None while event is None: # This dual input/refresh trick only works here, receiving # raw (undecoded) keyboard data as 'inp' because we don't # require the use of any application keys or multi-byte # sequences, only alphabetic characters. event, data = session.read_events(('input', 'refresh')) if event == 'refresh': dirty = -1 break inp = data if inp in legal_input_characters: # display command input echo(inp.decode('ascii')) if inp == u'q': # [q]uit echo(u'\r\n') return elif inp == u'\x0c': # [^L] refresh dirty = -1 break elif inp == u'f' and session.user.is_sysop: tgt_user = locate_user(term, point_prompt) or tgt_user break elif inp == u'd': # yes, you can delete yourself !! if delete_user(term, tgt_user, point_prompt): if tgt_user == session.user: # but if you delete yourself, # you must logoff. goto('logoff') # otherwise, move to next user tgt_user = get_next_user(tgt_user) break elif inp == u'<' and session.user.is_sysop: tgt_user = get_prev_user(tgt_user) break elif inp == u'>' and session.user.is_sysop: tgt_user = get_next_user(tgt_user) break elif inp in string.letters: if do_command( term, session, inp, fields, tgt_user, point_prompt): # when returning True, perform full-screen refresh, break else: # otherwise, clean prompt field time.sleep(0.2) echo(u'\b \b') elif inp in legal_input_characters: # though legal, not authorized: clean prompt field time.sleep(0.2) echo(u'\b \b') event = None dirty = dirty or 1
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
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 key_map = { '$': 'bulletins', 'n': 'news', 'p': 'writemsg', 'r': 'msgarea', 'fb': 'fbrowse', 'hn': 'hackernews', 'c': 'chat', 'i': 'ircchat', 'l': 'lc', 'o': 'ol', 'b': 'bbslist', 'f': 'weather', 't': 'tetris', 'w': 'online', '!': 'charset', 'kb': 'extras.test_keyboard_keys', 's': 'si', 'u': 'userlist', 'v': 'vote', 'e': 'profile', 'x': 'main', 'g': 'logoff', '#': 'lord'} # add LORD to menu only if enabled, 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
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')
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
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
def main(): """ Main procedure. """ # pylint: disable=R0914,R0911 # Too many local variables import logging from x84.bbs import getsession, getterminal, ini, echo, get_user, goto from x84.bbs import find_user, showcp437 from x84.engine import __url__ as url logger = logging.getLogger() session, term = getsession(), getterminal() session.activity = u'Logging in' handle = (session.env.get('USER', '').decode('iso8859-1', 'replace')) anon_allowed_msg = u"'%s' login enabled.\r\n" % ( term.bold_cyan('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() apply_msg = u"'%s' to create new account.\r\n" % ( term.bold_cyan(newcmds[0]),) allow_apply = ini.CFG.getboolean('nua', 'allow_apply') enable_anonymous = ini.CFG.getboolean('matrix', 'enable_anonymous') enable_pwreset = ini.CFG.getboolean('matrix', 'enable_pwreset') bbsname = ini.CFG.get('system', 'bbsname') artfile = os.path.join(os.path.dirname(__file__), 'art', 'xz-1984.ans') topscript = ini.CFG.get('matrix', 'topscript') max_tries = 10 session.flush_event('refresh') #uname() # display banner echo(u''.join(( term.normal, u'\r\n', u'Connected to %s, see %s for source\r\n' % (bbsname, url),))) for line in showcp437(artfile): echo(line) echo(term.normal) echo (u''.join(( u'\r\n\r\n', term.bold(u'tERM'), u': ', term.cyan_underline(session.env['TERM']), u'\r\n', term.bold(u'diMENSiONs'), u': ', '%s%s%s' % ( term.bold_cyan(str(term.width)), term.cyan(u'x'), term.bold_cyan(str(term.height)),), u'\r\n', term.bold(u'ENCOdiNG'), u': ', term.cyan_underline(session.encoding), u'\r\n\r\n', anon_allowed_msg if enable_anonymous else u'', apply_msg if allow_apply else u'', ))) # http://www.termsys.demon.co.uk/vtansi.htm # disable line-wrapping echo(unichr(27) + u'[7l') # http://www.xfree86.org/4.5.0/ctlseqs.html # Save xterm icon and window title on stack. echo(unichr(27) + u'[22;0t') if handle: echo('\r\nHello, %s!' % (handle,)) match = find_user(handle) if match is not None: handle = match else: handle = '' # prompt for username & password for _num in range(0, max_tries): handle = get_username(handle) if handle != u'': session.activity = u'Logging in' user = get_user(handle) if try_pass(user): goto(topscript, user.handle) echo(u'\r\n\r\n') if enable_pwreset: try_reset(user) else: logger.info('%r failed password', handle) logger.warn('maximum tries exceeded') goto('logoff')
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''
def main(handle=None): """ Main procedure. """ dirty = -1 session, term = getsession(), getterminal() tgt_user = get_user(handle) if handle else session.user legal_input_characters = string.letters + u'<>' # re-display entire screen on loop, while True: # full-screen refresh on -1; otherwise only the fields (such as when an # edit has occurred). dirty = -1 is set on screen resize, for example. if dirty == -1: # display banner, discover (y,x) point after, point_margin = show_banner(term) # forward-calculate the prompt (y,x) point point_prompt = Point(y=point_margin.y + 15, x=point_margin.x) # get all field values and locations, fields = get_display_fields(tgt_user, point=point_margin) # display all fields and prompt echo(display_options(term, fields)) echo(display_prompt(term, session, point=point_prompt)) dirty = 0 # blocking loop until screen refresh or keystroke event = None while event is None: # This dual input/refresh trick only works here, receiving # raw (undecoded) keyboard data as 'inp' because we don't # require the use of any application keys or multi-byte # sequences, only alphabetic characters. event, data = session.read_events(('input', 'refresh')) if event == 'refresh': dirty = -1 break inp = data if inp in legal_input_characters: # display command input echo(inp.decode('ascii')) if inp == u'q': # [q]uit echo(u'\r\n') return elif inp == u'\x0c': # [^L] refresh dirty = -1 break elif inp == u'f' and session.user.is_sysop: tgt_user = locate_user(term, point_prompt) or tgt_user break elif inp == u'd': # yes, you can delete yourself !! if delete_user(term, tgt_user, point_prompt): if tgt_user == session.user: # but if you delete yourself, # you must logoff. goto('logoff') # otherwise, move to next user tgt_user = get_next_user(tgt_user) break elif inp == u'<' and session.user.is_sysop: tgt_user = get_prev_user(tgt_user) break elif inp == u'>' and session.user.is_sysop: tgt_user = get_next_user(tgt_user) break elif inp in string.letters: if do_command(term, session, inp, fields, tgt_user, point_prompt): # when returning True, perform full-screen refresh, break else: # otherwise, clean prompt field time.sleep(0.2) echo(u'\b \b') elif inp in legal_input_characters: # though legal, not authorized: clean prompt field time.sleep(0.2) echo(u'\b \b') event = None dirty = dirty or 1
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
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''