def kbhit(self, timeout=0, _intr_continue=True): # _intr_continue has no meaning here, sigwinch or events do not # interrupt the event IPC. from x84.bbs import getsession val = getsession().read_event('input', timeout) if val is not None: getsession()._buffer['input'].append(val) return True return False
def notify_update_database(self, content): new_content = {} for key, oneliner in content: if str(key) not in self.existing_content: new_content[key] = oneliner if new_content: self.log.info('[shroo.ms] %d new entries', len(new_content)) self.new_content = new_content getsession().buffer_event('oneliner', True) else: self.log.debug('[shroo.ms] no new entries')
def get_centigrade(): """ Blocking prompt for setting C/F preference """ from x84.bbs import getterminal, getsession, echo, getch term = getterminal() session = getsession() echo(u'\r\n\r\n') echo(term.yellow(u'CElCiUS')) echo(term.bold_yellow(u'(')) echo(term.bold_yellow_reverse(u'C')) echo(term.bold_yellow(u')')) echo(u' or ') echo(term.yellow(u'fAhRENhEit')) echo(term.bold_yellow(u'(')) echo(term.bold_yellow_reverse(u'F')) echo(term.bold_yellow(u')')) echo('? ') while True: inp = getch() if inp in (u'c', u'C'): session.user['centigrade'] = True session.user.save() break elif inp in (u'f', u'F'): session.user['centigrade'] = False session.user.save() break elif inp in (u'q', u'Q', term.KEY_EXIT): break
def main(msg=None): """ Main procedure. """ from x84.bbs import Msg, getsession session = getsession() if msg is None: msg = Msg() msg.tags = ('public', ) banner() while True: session.activity = 'Constructing a %s message' % ( u'public' if u'public' in msg.tags else u'private', ) if not prompt_recipient(msg): break if not prompt_subject(msg): break if not prompt_tags(msg): break if not prompt_public(msg): break if not prompt_body(msg): break display_msg(msg) if not prompt_send(): break msg.save() return True return False
def chk_save_location(location): """ Prompt user to save location for quick re-use """ from x84.bbs import getterminal, getsession, echo session, term = getsession(), getterminal() stored_location = session.user.get('location', dict()).items() if (sorted(location.items()) == sorted(stored_location)): # location already saved return False if session.user.handle == 'anonymous': # anonymous cannot save preferences return False # prompt to store (unsaved/changed) location echo(u'\r\n\r\n') echo(term.yellow(u'Save Location')) echo(term.bold_yellow(u' (')) echo(term.bold_black(u'private')) echo(term.bold_yellow(u') ')) echo(term.yellow(u'? ')) echo(term.bold_yellow(u'[')) echo(term.underline_yellow(u'yn')) echo(term.bold_yellow(u']')) echo(u': ') while True: inp = term.inkey() if inp.code == term.KEY_EXIT or inp.lower() in (u'n', 'q'): break elif inp.code == term.KEY_ENTER or inp.lower() in (u'y', u' '): session.user['location'] = location break
def display_msg(msg): """ Display full message """ from x84.bbs import getterminal, getsession, echo, decode_pipe session, term = getsession(), getterminal() body = msg.body.splitlines() style = getstyle() receipt = (msg.recipient if msg.recipient is not None else u'<(None)=All users>') echo(u' AUthOR: ' + style['highlight'](msg.author) + u'\r\n\r\n') echo(u' RECiPiENt: ') echo(style['lowlight'](receipt)) echo(u'\r\n\r\n') echo(u' SUBjECt: ') echo(style['lowlight'](msg.subject)) echo(u'\r\n\r\n') echo(u' tAGS: ') echo(style['lowlight'](u', '.join(msg.tags))) echo(u'\r\n\r\n') echo(term.underline(u' bOdY: '.ljust(term.width - 1)) + u'\r\n') echo(decode_pipe(u'\r\n'.join(body)) + term.normal) echo(u'\r\n' + term.underline(u''.ljust(term.width - 1))) echo(u'\r\n\r\n') session.activity = 'Constructing a %s message' % ( u'public' if u'public' in msg.tags else u'private',) return
def main(): session, term = getsession(), getterminal() session.activity = 'Viewing Userlist' colors = {'highlight': term.red, 'lowlight': term.green, } line_no = display_banner(filepattern=art_file, encoding=art_encoding) # get and format userlist userlist = ( u'{sp}{handle} {location} {lastcall}' .format(sp=u' ' * 4, handle=ur.handle.ljust(username_max_length), location=colors['lowlight']( ur.location.ljust(location_max_length)), lastcall=timeago(ur.timeago)) for ur in iter_userlist()) echo(u'\r\n') # display users, using a command-prompt pager. prompt_pager(content=userlist, line_no=line_no + 1, colors={'highlight': term.red, 'lowlight': term.green, }, width=80, breaker=None)
def chk_thread(thread): """ for asyncronous lightbar, return False if thread is still running, 'dirty' if thread completed and new entries were found, 'None' if thread completed and no no entries were discovered. """ from x84.bbs import getsession, DBProxy if thread is None or thread.is_alive(): return False # check if bbs-scene.org thread finished, silly hack logger = logging.getLogger() session = getsession() udbkeys = DBProxy('bbslist').keys() nlc = 0 for key, value in thread.content: if key not in udbkeys: DBProxy('bbslist')[key] = value DBProxy('bbslist', 'comments')[key] = list() DBProxy('bbslist', 'ratings')[key] = list() nlc += 1 else: # update anyway (fe. port changed), we don't # detect this as an update. DBProxy('bbslist')[key] = value if nlc > 0: logger.info('%d new entries', nlc) session.send_event('global', ('bbslist_update', None)) session.buffer_event('bbslist_update') return 'dirty' else: logger.info('no new bbs-scene.org entries') return None
def saysomething(dumb=True): """ Prompt user to post oneliner, also prompt user to post to bbs-scene.org if configured, returning background Thread. """ import time from x84.bbs import getsession, getterminal, echo, LineEditor, ini session, term = getsession(), getterminal() prompt_say = u'SAY WhAt ?! ' # heard_msg = u'YOUR MESSAGE hAS bEEN VOiCEd.' yloc = term.height - 3 xloc = max(0, ((term.width / 2) - (MAX_INPUT / 2))) if dumb: echo(u'\r\n\r\n' + term.bold_blue(prompt_say)) else: echo(term.move(yloc, xloc) or u'\r\n\r\n') echo(term.bold_blue(prompt_say)) ole = LineEditor(MAX_INPUT) ole.highlight = term.green_reverse oneliner = ole.read() if oneliner is None or 0 == len(oneliner.strip()): if not dumb: # clear input line, echo(term.normal + term.move(yloc, 0) + term.clear_eol) return None session.user['lastliner'] = time.time() # post local-onlyw hen bbs-scene.org is not configured if not ini.CFG.has_section('bbs-scene'): add_oneline(oneliner.strip()) return None return post_bbs_scene(oneliner, dumb)
def main(): session, term = getsession(), getterminal() session.activity = 'Viewing Userlist' colors = { 'highlight': term.red, 'lowlight': term.green, } line_no = display_banner(filepattern=art_file, encoding=art_encoding) # get and format userlist userlist = (u'{sp}{handle} {location} {lastcall}'.format( sp=u' ' * 4, handle=ur.handle.ljust(username_max_length), location=colors['lowlight'](ur.location.ljust(location_max_length)), lastcall=timeago(ur.timeago)) for ur in iter_userlist()) echo(u'\r\n') # display users, using a command-prompt pager. prompt_pager(content=userlist, line_no=line_no + 1, colors={ 'highlight': term.red, 'lowlight': term.green, }, width=80, breaker=None)
def describe(sessions): """ Returns unicode string suitable for describing the activity of session id's of array ``sessions``. """ from x84.bbs import getsession, getterminal, ini slen = lambda sessions: len(u'%d' % (len(sessions), )) session, term = getsession(), getterminal() max_user = ini.CFG.getint('nua', 'max_user') return u'\r\n'.join(([ u''.join(( u'%*d' % (4 + slen(sessions), node), u'%4is' % (attrs.get('idle', 0), ), u' ', (term.bold_green(u'%-*s' % ( max_user, (u'** diSCONNECtEd' if 'delete' in attrs else attrs.get( 'handle', u'** CONNECtiNG')), )) if attrs.get('handle', u'') != session.user.handle else term.green(u'%-*s' % (max_user, session.user.handle))), term.green(u' - '), term.bold_green((attrs.get('activity', u'')) if attrs.get( 'sid') != session.sid else term.bold_black(session.activity)), )) for node, (_sid, attrs) in get_nodes(sessions) ]))
def send_passkey(user): """ Send passkey token to user by e-mail. """ session = getsession() passkey = base64.encodestring(os.urandom(50))[:password_max_length] email_msg = MIMEText( msg_mailbody.format(bbsname=system_bbsname, session=session, user=user, passkey=passkey)) email_msg['From'] = msg_mailfrom email_msg['To'] = user.email email_msg['Subject'] = msg_mailsubj.format(bbsname=system_bbsname) try: smtp = smtplib.SMTP(mail_smtphost) smtp.sendmail(msg_mailfrom, [user.email], email_msg.as_string()) smtp.quit() except Exception as err: log.exception(err) echo(u'{0}'.format(err)) return False log.info(u'Password reset token delivered ' u'to address {0!r} for user {1!r}.'.format( user.email, user.handle)) return passkey
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 prompt_body(msg): """ Prompt for 'body' of message, executing 'editor' script. """ from x84.bbs import echo, Selector, getterminal, getsession, gosub term = getterminal() session = getsession() inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'CONtiNUE', right=u'CANCEl') # check for previously existing draft if 0 != len(session.user.get('draft', u'')): # XXX display age of message inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'REStORE', right=u'ERASE') blurb = u'CONtiNUE PREViOUSlY SAVEd dRAft ?' echo(u'\r\n\r\n') echo(term.move(inp.yloc, inp.xloc - len(blurb))) echo(term.bold_yellow(blurb)) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'REStORE': msg.body = session.user['draft'] echo(u'\r\n\r\n') session.user['draft'] = msg.body if gosub('editor', 'draft'): echo(u'\r\n\r\n' + term.normal) msg.body = session.user.get('draft', u'') del session.user['draft'] return 0 != len(msg.body.strip()) return False
def refresh_opts(pager, handle): """ Refresh pager border with command keys available. """ from x84.bbs import getsession, getterminal, get_user, find_user, Ansi session, term = getsession(), getterminal() if not handle or not find_user(handle): has_plan = 0 else: has_plan = 0 != len(get_user(handle).get('.plan', u'').strip()) decorate = lambda key, desc: u''.join(( term.red_underline(key,), u':', term.yellow(desc.split()[0]), u' ', u' '.join(desc.split()[1:]), u' ' if len(desc.split()) > 1 else u'',)) statusline = u''.join(( term.bold_yellow(u'- '), decorate(u'Escape/q', 'Uit'), decorate(u'v', 'iEW .PLAN') if has_plan else u'', decorate(u'e', 'dit USR') if 'sysop' in session.user.groups else u'', term.bold_yellow(u'-'), )) if len(Ansi(statusline)) < (pager.visible_width - 4): return pager.border() + pager.footer(statusline) else: return pager.border() + pager.footer(term.bold_red('q') + u':uit')
def redraw(pager, selector): """ Redraw pager and selector """ from x84.bbs import getsession, getterminal, echo session, term = getsession(), getterminal() session.flush_event('oneliner_update') pager.colors['border'] = term.white pager.glyphs['top-horiz'] = u'' pager.glyphs['top-right'] = u'' pager.glyphs['top-left'] = u'' pager.glyphs['bot-horiz'] = u'' pager.glyphs['bot-right'] = u'' pager.glyphs['bot-left'] = u'' pager.glyphs['left-vert'] = u'' pager.glyphs['right-vert'] = u'' prompt_ole = u'write an oneliner?' pager.update(u'\n\n\nFetching ...') echo(u''.join(( pager.refresh(), pager.border(), term.move(selector.yloc - 2, selector.xloc), term.bold_red(prompt_ole.center(selector.width).rstrip()), term.clear_eol, selector.refresh(),))) pager.update(u'\n'.join(get_oltxt())) pager.move_end() echo(pager.refresh())
def redraw(pager, selector): """ Redraw pager and selector """ from x84.bbs import getsession, getterminal, echo session, term = getsession(), getterminal() session.flush_event('oneliner_update') pager.colors['border'] = term.white pager.glyphs['top-horiz'] = u'' pager.glyphs['top-right'] = u'' pager.glyphs['top-left'] = u'' pager.glyphs['bot-horiz'] = u'' pager.glyphs['bot-right'] = u'' pager.glyphs['bot-left'] = u'' pager.glyphs['left-vert'] = u'' pager.glyphs['right-vert'] = u'' prompt_ole = u'write an oneliner?' pager.update(u'\n\n\nFetching ...') echo(u''.join(( pager.refresh(), pager.border(), term.move(selector.yloc - 2, selector.xloc), term.bold_red(prompt_ole.center(selector.width).rstrip()), term.clear_eol, selector.refresh(), ))) pager.update(u'\n'.join(get_oltxt())) pager.move_end() echo(pager.refresh())
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()
def describe(sessions): """ Returns unicode string suitable for describing the activity of session id's of array ``sessions``. """ from x84.bbs import getsession, getterminal, ini slen = lambda sessions: len(u'%d' % (len(sessions),)) session, term = getsession(), getterminal() max_user = ini.CFG.getint('nua', 'max_user') text = u'\r\n'.join(([u''.join(( term.move_x(max(0, (term.width / 2) - 40)), term.green, u'%*d' % (5 + slen(sessions), node), u' ' * 7, term.normal, u'%4is' % (attrs.get('idle', 0),), u' ', u' ' * 8, (term.bold_red(u'%-*s' % (max_user, ( u'** diSCONNECtEd' if 'delete' in attrs else attrs.get('handle', u'** CONNECtiNG')),) ) if attrs.get('handle', u'') != session.user.handle else term.red(u'%-*s' % (max_user, session.user.handle))), term.green(u' '), term.yellow((attrs.get('activity', u'')) if attrs.get('sid') != session.sid else term.yellow(session.activity)), )) for node, (_, attrs) in get_nodes(sessions)])) return text + '\r\n'
def prompt_ok(): """ Prompt user to continue, True if they select yes. """ from x84.bbs import getsession, getterminal, echo, getch, Selector session, term = getsession(), getterminal() prompt_confirm = u'EVERYthiNG lOOk Ok ?' prompt_continue = u'YES (CONtiNUE)' prompt_chg = u'NO! (ChANGE)' def prompt_ok_dumb(): """ Dummy terminal prompt for confirm/cancel. """ echo('\r\n\r\n%s\r\n' % (prompt_confirm,)) echo('1 - %s\r\n' % (prompt_continue,)) echo('2 - %s\r\n\r\n' % (prompt_chg,)) echo('select (1, 2) --> ') while True: inp = getch() if inp == u'1': return True elif inp == u'2': return False if session.env.get('TERM') == 'unknown': return prompt_ok_dumb() sel = Selector(yloc=term.height - 1, xloc=5, width=term.width - 10, left=prompt_continue, right=prompt_chg) echo(term.normal) echo(term.move(term.height - 2, 0) + term.clear_eol) echo(prompt_confirm.center(term.width - 1) + '\r\n') echo(term.clear_eol + sel.refresh()) while True: echo(sel.process_keystroke(getch())) if sel.selected: return True if sel.selection == prompt_continue else False
def main(): """ Main menu entry point. """ from x84.default.common import display_banner session, term = getsession(), getterminal() text, width, height, dirty = u'', -1, -1, 2 menu_items = get_menu_items(session) editor = get_line_editor(term, menu_items) while True: if dirty == 2: # set syncterm font, if any if syncterm_font and term.kind.startswith('ansi'): echo(syncterm_setfont(syncterm_font)) if dirty: session.activity = 'main menu' top_margin = display_banner(art_file, encoding=art_encoding) + 1 echo(u'\r\n') if width != term.width or height != term.height: width, height = term.width, term.height text = render_menu_entries(term, top_margin, menu_items) echo(u''.join((text, display_prompt(term), editor.refresh()))) dirty = 0 event, data = session.read_events(('input', 'refresh')) if event == 'refresh': dirty = True continue elif event == 'input': session.buffer_input(data, pushback=True) # we must loop over inkey(0), we received a 'data' # event, though there may be many keystrokes awaiting for our # decoding -- or none at all (multibyte sequence not yet complete). inp = term.inkey(0) while inp: if inp.code == term.KEY_ENTER: # find matching menu item, for item in menu_items: if item.inp_key == editor.content.strip(): echo(term.normal + u'\r\n') gosub(item.script, *item.args, **item.kwargs) editor.content = u'' dirty = 2 break else: if editor.content: # command not found, clear prompt. echo(u''.join(( (u'\b' * len(editor.content)), (u' ' * len(editor.content)), (u'\b' * len(editor.content)),))) editor.content = u'' echo(editor.refresh()) elif inp.is_sequence: echo(editor.process_keystroke(inp.code)) else: echo(editor.process_keystroke(inp)) inp = term.inkey(0)
def getposts(threadid='3263403', number=40): from x84.bbs import User, getsession import requests import bs4 session = getsession() url = 'http://forums.somethingawful.com/showthread.php?threadid='+threadid+'&goto=lastpost' print url cookies = dict(bbuserid=session.user['sausercookie'], bbpassword=session.user['sapasscookie']) response = requests.get(url, cookies=cookies) soup = bs4.BeautifulSoup(response.text) title = soup.find('a',{"class":"bclast"}).text if hasattr(soup.find('option',{"selected":"selected"}), 'text'): currentpage = soup.find('option',{"selected":"selected"}).text totalpages = soup.find('div',{"class":"pages top"}).find_all('option',)[-1].text else: currentpage = "1" totalpages = "1" posts = soup.findAll("table", {'class':'post'}) authors = [] times = [] bodies = [] seens = [] print len(posts) for post in posts: seenstyle = post.find('tr')['class'][0] if seenstyle == 'seen' or seenstyle == 'seen2': newpost = False else: newpost = True seens.append(newpost) authors.append(post.find('dt', {"class":['author','author platinum']}).text) bodies.append(post.find('td',{"class":"postbody"}).text.rstrip().lstrip()) return [zip(authors, bodies, seens), title, currentpage, totalpages]
def send_passkey(user): """ Send passkey token to user by e-mail. """ session = getsession() passkey = base64.encodestring(os.urandom(50))[:password_max_length] email_msg = MIMEText(msg_mailbody.format(bbsname=system_bbsname, session=session, user=user, passkey=passkey)) email_msg['From'] = msg_mailfrom email_msg['To'] = user.email email_msg['Subject'] = msg_mailsubj.format(bbsname=system_bbsname) try: smtp = smtplib.SMTP(mail_smtphost) smtp.sendmail(msg_mailfrom, [user.email], email_msg.as_string()) smtp.quit() except Exception as err: log.exception(err) echo('{0}'.format(err)) return False log.info(u'Password reset token delivered ' u'to address {0!r} for user {1!r}.' .format(user.email, user.handle)) return passkey
def try_pass(user): """ Prompt for password and authenticate, returns True if succesfull. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getsession, getterminal, ini, LineEditor, echo session, term = getsession(), getterminal() prompt_pass = u'pass: '******'\r\n\r\n ' + term.yellow_reverse(u"Encrypting ..") 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')) # 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(term.move(term.height, max_pass + 10) + 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): return True denied(badpass_msg % (user.handle, )) return False
def get_centigrade(): """ Blocking prompt for setting C/F preference. """ from x84.bbs import getterminal, getsession, echo term = getterminal() session = getsession() if bool(session.user.handle == 'anonymous'): # anonymous cannot set a preference. return echo(u''.join(( u'\r\n\r\n', term.yellow(u'Celcius'), term.bold_yellow(u'('), term.bold_yellow_reverse(u'C'), term.bold_yellow(u')'), u' or ', term.yellow(u'Fahrenheit'), term.bold_yellow(u'('), term.bold_yellow_reverse(u'F'), term.bold_yellow(u')'), u'? '))) while True: inp = term.inkey() if inp in (u'c', u'C'): session.user['centigrade'] = True session.user.save() break elif inp in (u'f', u'F'): session.user['centigrade'] = False session.user.save() break elif inp in (u'q', u'Q', term.KEY_EXIT): break
def try_pass(user): """ Prompt for password and authenticate, returns True if succesfull. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getsession, getterminal, ini, LineEditor, echo session, term = getsession(), getterminal() prompt_pass = u'\r\n\r\n pass: '******'\r\n\r\n ' + term.yellow_reverse(u"Encrypting ..") 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')) # 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): return True denied(badpass_msg % (user.handle,)) return False
def chk_save_location(location): """ Prompt user to save location for quick re-use """ from x84.bbs import getterminal, getsession, echo, getch session, term = getsession(), getterminal() stored_location = session.user.get('location', dict()).items() if (sorted(location.items()) == sorted(stored_location)): return # prompt to store (unsaved/changed) location echo(u'\r\n\r\n') echo(term.yellow(u'SAVE lOCAtION')) echo(term.bold_yellow(' (')) echo(term.bold_black(u'PRiVAtE')) echo(term.bold_yellow(') ')) echo(term.yellow('? ')) echo(term.bold_yellow(u'[')) echo(term.underline_yellow(u'yn')) echo(term.bold_yellow(u']')) echo(u': ') while True: inp = getch() if inp is None or inp in (u'n', u'N', u'q', u'Q', term.KEY_EXIT): break if inp in (u'y', u'Y', u' ', term.KEY_ENTER): session.user['location'] = location break
def __init__(self, cmd='/bin/uname', args=(), env_lang='en_US.UTF-8', env_term=None, env_path=None, env_home=None): # pylint: disable=R0913 # Too many arguments (7/5) """ cmd, args = argv[0], argv[1:] lang, term, and env_path become LANG, TERM, and PATH environment variables. When term is None, the session terminal type is used. When env_path is None, the .ini 'env_path' value of section [door] is used. When env_home is None, $HOME of the main process is used. """ from x84.bbs import getsession, ini # pylint: disable=R0913 # Too many arguments (7/5) self.cmd = cmd self.args = (self.cmd,) + args self.env_lang = env_lang if env_term is None: self.env_term = getsession().env.get('TERM') else: self.env_term = env_term if env_path is None: self.env_path = ini.CFG.get('door', 'path') else: self.env_path = env_path if env_home is None: self.env_home = os.getenv('HOME') else: self.env_home = env_home
def refresh(): """ Refresh main menu. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getsession, getterminal, echo, showcp437, ini import os session, term = getsession(), getterminal() session.activity = u'Main menu' artfile = os.path.join(os.path.dirname(__file__), 'art', 'main.asc') echo(u''.join(( u'\r\n\r\n', term.blue(u'/'.rjust(term.width / 2)), term.bold_black(u'/ '), term.bold('x'), term.bold_blue('/'), term.bold('84'), u' ', 'MAiN MENU', u'\r\n'))) for line in showcp437(artfile): echo(line) echo(u'\r\n\r\n') entries = [ ('b', 'bS NEXUS'), ('l', 'ASt CAllS'), ('o', 'NE liNERS'), ('w', "hO'S ONliNE"), ('n', 'EWS'), ('c', 'hAt'), ('!', 'ENCOdiNG'), ('t', 'EtRiS'), ('s', 'YS. iNfO'), ('u', 'SER LiST'), ('f', 'ORECASt'), ('e', 'dit PROfilE'), ('p', 'OSt A MSG'), ('r', 'EAd All MSGS'), ('g', 'OOdbYE /lOGOff'),] # add LORD to menu only if enabled, if ini.CFG.getboolean('dosemu', 'enabled') and ( ini.CFG.get('dosemu', 'lord_path') != 'no'): entries.insert(0, ('#', 'PlAY lORd!')) if 'sysop' in session.user.groups: entries += (('v', 'idEO CASSEttE'),) buf_str = u'' for key, name in entries: out_str = u''.join(( term.bold(u'('), term.bold_blue_underline(key), term.bold(u')'), term.bold_blue(name.split()[0]), u' ', u' '.join(name.split()[1:]), u' ')) ansilen = term.length(buf_str + out_str) if ansilen >= (term.width * .8): echo(term.center(buf_str) + u'\r\n\r\n') buf_str = out_str else: buf_str += out_str echo(term.center(buf_str) + u'\r\n\r\n') echo(u' [%s]:' % ( term.blue_underline(''.join([key for key, name in entries]))))
def main(msg=None): """ Main procedure. """ from x84.bbs import Msg, getsession session = getsession() if msg is None: msg = Msg() msg.tags = ('public',) banner() while True: session.activity = 'Constructing a %s message' % ( u'public' if u'public' in msg.tags else u'private',) if not prompt_recipient(msg): break if not prompt_subject(msg): break if not prompt_public(msg): break if not prompt_body(msg): break # XXX if not prompt_tags(msg): break display_msg(msg) if not prompt_send(): break msg.save() return True return False
def prompt(): """ Return string suitable for displaying prompt and available commands. """ from x84.bbs import getsession, getterminal, Ansi session, term = getsession(), getterminal() decorate = lambda key, desc: u''.join(( u'(', term.green_underline(key,), u')', term.reverse_green(desc.split()[0]), u' ', u' '.join(desc.split()[1:]), u' ',)) return Ansi(u''.join(( u' ' * 2, term.green_reverse(':keys'), u' ', decorate('c', 'hAt USR'), decorate('s', 'ENd MSG'), (u''.join(( decorate('p', 'lAYbACk REC'), decorate('w', 'AtCh liVE'), decorate('d', 'iSCONNECt SiD'), decorate('e', 'diT USR'), decorate('v', 'iEW SiD AttRS'), u' ',)) if 'sysop' in session.user.groups else u''), decorate('Escape/q', 'Uit'), decorate('Spacebar', 'REfRESh'), ))).wrap(int(term.width * .7), indent=u' ' * 8)
def usernum(self): from x84.bbs import getsession from x84.bbs.userbase import list_users try: return list_users().index(getsession().user.handle) except ValueError: return 999
def process_keystroke(inp, key=None): """ Process general keystroke and call routines. """ from x84.bbs import getsession, DBProxy, gosub, echo session = getsession() if inp is None: return False elif type(inp) is int: return False elif inp in (u't', u'T') and key is not None: bbs = DBProxy('bbslist')[key] gosub( 'telnet', bbs['address'], bbs['port'], ) elif inp in (u'a', u'A'): add_bbs() elif inp in (u'c', u'C') and key is not None: add_comment(key) elif inp in (u'r', u'R') and key is not None: rate_bbs(key) elif inp in (u'i', u'I') and key is not None: echo(get_bbsinfo(key) + '\r\n') elif inp in (u'v', u'V') and key is not None: view_ansi(key) elif inp in (u'd', u'D') and key is not None and ('sysop' in session.user.groups): del DBProxy('bbslist')[key] else: return False # unhandled return True
def process_keystroke(inp, key=None): """ Process general keystroke and call routines. """ from x84.bbs import getsession, DBProxy, gosub, echo session = getsession() if inp is None: return False elif type(inp) is int: return False elif inp in (u't', u'T') and key is not None: bbs = DBProxy('bbslist')[key] gosub('telnet', bbs['address'], bbs['port'],) elif inp in (u'a', u'A'): add_bbs() elif inp in (u'c', u'C') and key is not None: add_comment(key) elif inp in (u'r', u'R') and key is not None: rate_bbs(key) elif inp in (u'i', u'I') and key is not None: echo(get_bbsinfo(key) + '\r\n') elif inp in (u'v', u'V') and key is not None: view_ansi(key) elif inp in (u'd', u'D') and key is not None and ( 'sysop' in session.user.groups): del DBProxy('bbslist')[key] else: return False # unhandled return True
def refresh(reader, selector, mbox, new): """ Returns unicode string suitable for refreshing the screen. """ from x84.bbs import getsession session = getsession() if READING: reader.colors['border'] = term.bold_yellow selector.colors['border'] = term.bold_black else: reader.colors['border'] = term.bold_black selector.colors['border'] = term.bold_yellow title = get_selector_title(mbox, new) padd_attr = (term.bold_yellow if not READING else term.bold_black) sel_padd_right = padd_attr( u'-' + selector.glyphs['bot-horiz'] * (selector.visible_width - term.length(title) - 7) + u'-\u25a0-' if READING else u'- -') sel_padd_left = padd_attr(selector.glyphs['bot-horiz'] * 3) idx = selector.selection[0] return u''.join(( term.move(0, 0), term.clear, u'\r\n', u'// REAdiNG MSGS ..'.center(term.width).rstrip(), selector.refresh(), selector.border() if READING else reader.border(), reader.border() if READING else selector.border(), selector.title(sel_padd_left + title + sel_padd_right), selector.footer(get_selector_footer(idx)) if not READING else u'', reader.footer(get_reader_footer(idx)) if READING else u'', reader.refresh(), ))
def main(): session, term = getsession(), getterminal() session.activity = "Tripping out on colors!" term.color_distance_algorithm = 'rgb-weighted' with term.hidden_cursor(), term.fullscreen(): pause, dirty = False, True t = time.time() while True: if dirty or not pause: if not pause: t = time.time() with elapsed_timer() as elapsed: outp = term.home + screen_plasma(term, rgb_at_xy, t) outp += status(term, elapsed()) echo(outp) #assert False, repr(outp) dirty = False if pause: show_paused(term) inp = term.inkey(timeout=0.01 if not pause else None) if inp.lower() == 'q': break if inp == '?': assert False, "don't panic" if inp == '\x0c': dirty = True if inp in ('[', ']'): term.color_distance_algorithm = next_algo( term.color_distance_algorithm, inp == '[') show_please_wait(term) dirty = True if inp == ' ': pause = not pause
def prompt(): """ Return string suitable for displaying prompt and available commands. """ from x84.bbs import getsession, getterminal session, term = getsession(), getterminal() decorate = lambda key, desc: u"".join( (u"(", term.magenta_underline(key), u")", term.cyan(desc.split()[0]), u" ", u" ".join(desc.split()[1:]), u" ") ) return term.wrap( u"".join( ( u" " * 2, term.green_reverse(":keys"), u" ", decorate("c", "hAt USR"), decorate("s", "ENd MSG"), ( u"".join( (decorate("d", "iSCONNECt SiD"), decorate("e", "diT USR"), decorate("v", "iEW SiD AttRS"), u" ") ) if "sysop" in session.user.groups else u"" ), decorate("Escape/q", "Uit"), decorate("Spacebar", "REfRESh"), ) ), int(term.width * 0.8), subsequent_indent=u" " * 8, )
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 process(mesg): """ Process a command recieved by event system. and return string suitable for displaying in chat window. """ from x84.bbs import getsession session = getsession() sid, tgt_channel, (handle, cmd, args) = mesg ucs = u'' # pylint: disable=W0602 # Using global for 'NICKS' but no assignment is done global NICKS if (CHANNEL != tgt_channel and 'sysop' not in session.user.groups): ucs = u'' elif cmd == 'join': if handle not in NICKS: NICKS[handle] = sid ucs = show_join(handle, sid, tgt_channel) elif handle not in NICKS: NICKS[handle] = sid elif cmd == 'part': if handle in NICKS: del NICKS[handle] ucs = show_part(handle, sid, tgt_channel, args) elif cmd == 'say': ucs = show_say(handle, tgt_channel, args) elif cmd == 'act': ucs = show_act(handle, tgt_channel, args) else: ucs = u'unhandled: %r' % (mesg,) return ucs
def main(anonymous=False, new=False, username=''): """ Main procedure. """ from x84.bbs import ( getsession, getterminal, find_user, get_user, User, ) session, term = getsession(), getterminal() session.activity = 'sftp' if anonymous: user = User(u'anonymous') else: assert not new, ("new@ user not supported by SFTP.") # ProperCase user-specified handle handle = find_user(username) assert handle is not None, handle # fetch user record user = get_user(handle) # assign session user, just as top.py function login() session.user = user while True: inp = term.inkey() # should block indefinately log = logging.getLogger(__name__) log.warn('Got inkey: {0!r}'.format(inp))
def describe(sessions): """ Returns unicode string suitable for describing the activity of session id's of array ``sessions``. """ from x84.bbs import getsession, getterminal, ini slen = lambda sessions: len(u'%d' % (len(sessions), )) session, term = getsession(), getterminal() max_user = ini.CFG.getint('nua', 'max_user') text = u'\r\n'.join(([ u''.join(( term.move_x(max(0, (term.width / 2) - 40)), term.green, u'%*d' % (5 + slen(sessions), node), u' ' * 7, term.normal, u'%4is' % (attrs.get('idle', 0), ), u' ', u' ' * 8, (term.bold_red(u'%-*s' % ( max_user, (u'** diSCONNECtEd' if 'delete' in attrs else attrs.get( 'handle', u'** CONNECtiNG')), )) if attrs.get('handle', u'') != session.user.handle else term.red(u'%-*s' % (max_user, session.user.handle))), term.green(u' '), term.yellow((attrs.get('activity', u'')) if attrs.get('sid') != session.sid else term.yellow(session.activity)), )) for node, (_, attrs) in get_nodes(sessions) ])) return text + '\r\n'
def get_centigrade(): """ Blocking prompt for setting C/F preference. """ from x84.bbs import getterminal, getsession, echo term = getterminal() session = getsession() if bool(session.user.handle == 'anonymous'): # anonymous cannot set a preference. return echo(u''.join( (u'\r\n\r\n', term.yellow(u'Celcius'), term.bold_yellow(u'('), term.bold_yellow_reverse(u'C'), term.bold_yellow(u')'), u' or ', term.yellow(u'Fahrenheit'), term.bold_yellow(u'('), term.bold_yellow_reverse(u'F'), term.bold_yellow(u')'), u'? '))) while True: inp = term.inkey() if inp in (u'c', u'C'): session.user['centigrade'] = True session.user.save() break elif inp in (u'f', u'F'): session.user['centigrade'] = False session.user.save() break elif inp in (u'q', u'Q', term.KEY_EXIT): break
def prompt(): """ Return string suitable for displaying prompt and available commands. """ from x84.bbs import getsession, getterminal session, term = getsession(), getterminal() decorate = lambda key, desc: u''.join(( u'(', term.magenta_underline(key, ), u')', term.cyan(desc.split()[0]), u' ', u' '.join(desc.split()[1:]), u' ', )) return term.wrap(u''.join(( u' ' * 2, term.green_reverse(':keys'), u' ', decorate('c', 'hAt USR'), decorate('s', 'ENd MSG'), (u''.join(( decorate('d', 'iSCONNECt SiD'), decorate('e', 'diT USR'), decorate('v', 'iEW SiD AttRS'), u' ', )) if 'sysop' in session.user.groups else u''), decorate('Escape/q', 'Uit'), decorate('Spacebar', 'REfRESh'), )), int(term.width * .8), subsequent_indent=u' ' * 8)
def chk_save_location(location): """ Prompt user to save location for quick re-use """ from x84.bbs import getterminal, getsession, echo, getch session, term = getsession(), getterminal() stored_location = session.user.get('location', dict()).items() if (sorted(location.items()) == sorted(stored_location)): # location already saved return if session.user.handle == 'anonymous': # anonymous cannot save preferences return # prompt to store (unsaved/changed) location echo(u'\r\n\r\n') echo(term.yellow(u'Save Location')) echo(term.bold_yellow(u' (')) echo(term.bold_black(u'private')) echo(term.bold_yellow(u') ')) echo(term.yellow(u'? ')) echo(term.bold_yellow(u'[')) echo(term.underline_yellow(u'yn')) echo(term.bold_yellow(u']')) echo(u': ') while True: inp = getch() if inp is None or inp in (u'n', u'N', u'q', u'Q', term.KEY_EXIT): break if inp in (u'y', u'Y', u' ', term.KEY_ENTER): session.user['location'] = location break
def save(key, ucs): """ Persist message to user attrs database """ from x84.bbs import getsession getsession().user[key] = HARDWRAP.join( [softwrap_join(_ucs) for _ucs in ucs.split(HARDWRAP)])