def prompt_network(msg, network_tags): """ Prompt for network message """ from x84.bbs import getterminal, echo, Lightbar, Selector from x84.bbs.ini import CFG term = getterminal() inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') blurb = u'iS thiS A NEtWORk MESSAGE?' 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'NO': return False lb = Lightbar(20, 20, term.height / 2 - 10, term.width / 2 - 10) lb.update([(tag, tag,) for tag in network_tags]) echo(u''.join(( term.clear , term.move(term.height / 2 - 11, term.width / 2 - 9) , term.bold_white(u'ChOOSE YOUR NEtWORk') ))) network = lb.read() if network is not None: msg.tags = (u'public', network,) return True return False
def get_ui(position=None): """ Returns user interface (lightbar, pager). Optional argument position is tuple position of prior lightbar instance. """ from x84.bbs import getterminal, Lightbar, Pager term = getterminal() assert term.height > 10 and term.width >= 40 # +-+ +----+ # |lb |pager # +-+ +----+ height = term.height - 7 lb_width = int(term.width * .3) pg_width = term.width - (lb_width) lb_xloc = (term.width / 2) - (term.width / 2) pg_xloc = lb_xloc + lb_width lightbar = Lightbar(height, lb_width, (term.height - height - 1), lb_xloc) pager = Pager(height, pg_width, (term.height - height - 1), pg_xloc) pager.ypadding = 2 pager.xpadding = 2 lightbar.update(get_bbslist(max_len=lightbar.visible_width)) ## pressing Return is same as 't'elnet lightbar.keyset['enter'].extend((u't', u'T')) ## re-select previous selection if position is not None: lightbar.position = position return (pager, lightbar)
def get_lightbar(ucs): """ Returns lightbar with content of given Unicode string, ``ucs``. """ term = getterminal() width = min(80, max(term.width, 40)) yloc = 0 height = term.height - yloc - 1 xloc = max(0, (term.width / 2) - (width / 2)) lightbar = Lightbar(height, width, yloc, xloc) lightbar.glyphs['left-vert'] = lightbar.glyphs['right-vert'] = u'' lightbar.colors['highlight'] = term.yellow_reverse set_lbcontent(lightbar, ucs) return lightbar
def get_sign(force=False): """ Return the user's sign or let them choose one using a Lightbar. :param bool force: If True, does not retrive the user's sign from the db :rtype: :class:`str` """ database = DBProxy('astrology', table='users') if not force and session.user.handle in database: return database[session.user.handle] lbar = Lightbar(width=15, height=14, xloc=max(term.width / 2 - 7, 0), yloc=max(term.height / 2 - 7, 0), colors={'border': lightbar_border, 'highlight': lightbar_highlight, 'lowlight': lightbar_lowlight}, glyphs={'top-left': u'+', 'top-right': u'+', 'top-horiz': u'-', 'bot-horiz': u'-', 'bot-left': u'+', 'bot-right': u'+', 'left-vert': u'|', 'right-vert': u'|'}) def refresh(): """ Refresh the lightbar. """ echo(u''.join((term.normal, term.clear))) contents = ((key, key) for key in SIGNS) lbar.update(contents) echo(u''.join([lbar.border(), lbar.refresh()])) refresh() while not lbar.selected and not lbar.quit: event, data = session.read_events(['refresh', 'input']) if event == 'refresh': refresh() elif event == 'input': session.buffer_input(data, pushback=True) echo(lbar.process_keystroke(term.inkey())) if lbar.quit: return sign, _ = lbar.selection database[session.user.handle] = sign return sign
def main(ttyfile=u'', peek=False): """ Main procedure. """ from x84.bbs import Lightbar, getch, getsession, getterminal, ini, echo # pylint: disable=R0914,R0915 # Too many local variables # Too many statements ttyplay_exe = ini.CFG.get('ttyplay', 'exe') if not os.path.exists(ttyplay_exe): echo(u'\r\n%s NOt iNStAllEd.\r\n' % (ttyplay_exe, )) getch() return session, term = getsession(), getterminal() # pylint: disable=W0212 # Access to a protected member _record_tty of a client class resume_rec = session._record_tty and session.is_recording if resume_rec: session.stop_recording() session._record_tty = False if 'sysop' in session.user.groups and ttyfile == u'': # pylint: disable=W0212 # Access to a protected member _ttyrec_folder of a client class folder = os.path.dirname(ttyfile) or session._ttyrec_folder pos = None while True: files = sorted([ fn for fn in os.listdir(session._ttyrec_folder) if fn.endswith('.ttyrec') ]) echo(u'\r\n' * term.height) sel = Lightbar(term.height - 1, term.width - 1, 0, 0) sel.colors['border'] = term.bold_green echo(sel.border() + sel.title('- SElECt A RECORdiNG -')) sel.update([(fname, fname) for fname in files]) if pos is not None: sel.position = pos x_ttyfile = sel.read() if x_ttyfile is None or sel.quit: break pos = sel.position ttyfile = os.path.join(folder, x_ttyfile) playfile(ttyplay_exe, ttyfile, peek) else: playfile(ttyplay_exe, ttyfile, peek) if not session.is_recording and resume_rec: session._record_tty = True session.start_recording() echo(term.move(term.height, 0)) echo(u'\r\n')
def main(): """ File browser launch point. """ import subprocess import functools session, term = getsession(), getterminal() session.activity = u'Browsing files' db_desc = DBProxy(DIZ_DB) # set syncterm font, if any if SYNCTERM_FONT and term.kind.startswith('ansi'): echo(syncterm_setfont(SYNCTERM_FONT)) # assign extractors to file types browser.diz_extractors['.zip'] = diz_from_zip # detect LHA and DMS support output, _ = subprocess.Popen(('which', 'lha'), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() if output: browser.diz_extractors['.lha'] = functools.partial( diz_from_lha, output.rstrip()) output, _ = subprocess.Popen(('which', 'xdms'), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() if output: browser.diz_extractors['.dms'] = functools.partial( diz_from_dms, output.rstrip()) # load flagged files browser.flagged_files = session.user.get('flaggedfiles', set()) # remove missing files/dirs from flagged files, just in case if len(browser.flagged_files): for filepath in list(browser.flagged_files)[:]: if not os.path.exists(filepath): browser.flagged_files.remove(filepath) session.user['flaggedfiles'] = browser.flagged_files # fire it up! lightbar = Lightbar(height=term.height, width=min(10, int(term.width * 0.25)), xloc=0, yloc=0, colors={ 'border': getattr(term, COLOR_BORDER), 'highlight': getattr(term, COLOR_HIGHLIGHT) }) draw_interface(term, lightbar) with term.hidden_cursor(): browse_dir(session, db_desc, term, lightbar, ROOT) echo(term.move(term.height, term.width)) echo(u'\r\n\r\n' + term.normal)
def main(ttyfile=u'', peek=False): """ Main procedure. """ from x84.bbs import Lightbar, getch, getsession, getterminal, ini, echo # pylint: disable=R0914,R0915 # Too many local variables # Too many statements ttyplay_exe = ini.CFG.get('ttyplay', 'exe') if not os.path.exists(ttyplay_exe): echo(u'\r\n%s NOt iNStAllEd.\r\n' % (ttyplay_exe,)) getch() return session, term = getsession(), getterminal() # pylint: disable=W0212 # Access to a protected member _record_tty of a client class resume_rec = session._record_tty and session.is_recording if resume_rec: session.stop_recording() session._record_tty = False if 'sysop' in session.user.groups and ttyfile == u'': # pylint: disable=W0212 # Access to a protected member _ttyrec_folder of a client class folder = os.path.dirname(ttyfile) or session._ttyrec_folder pos = None while True: files = sorted([fn for fn in os.listdir(session._ttyrec_folder) if fn.endswith('.ttyrec')]) echo(u'\r\n' * term.height) sel = Lightbar(term.height - 1, term.width - 1, 0, 0) sel.colors['border'] = term.bold_green echo(sel.border() + sel.title('- SElECt A RECORdiNG -')) sel.update([(fname, fname) for fname in files]) if pos is not None: sel.position = pos x_ttyfile = sel.read() if x_ttyfile is None or sel.quit: break pos = sel.position ttyfile = os.path.join(folder, x_ttyfile) playfile(ttyplay_exe, ttyfile, peek) else: playfile(ttyplay_exe, ttyfile, peek) if not session.is_recording and resume_rec: session._record_tty = True session.start_recording() echo(term.move(term.height, 0)) echo(u'\r\n')
def chose_location_lightbar(locations): """ Lightbar pager for chosing a location. """ from x84.bbs import getterminal, echo, Lightbar term = getterminal() fmt = u'%(city)s, %(state)s' lookup = dict([(loc['postal'], loc) for loc in locations]) fullheight = min(term.height - 8, len(locations) + 2) fullwidth = min(75, int(term.width * .8)) # shrink window to minimum width maxwidth = max([len(fmt % val) for val in lookup.values()]) + 2 if maxwidth < fullwidth: fullwidth = maxwidth echo(u'\r\n' * fullheight) lightbar = Lightbar(height=fullheight, width=fullwidth, yloc=term.height - fullheight, xloc=int((term.width / 2) - (fullwidth / 2))) lightbar.update([(key, fmt % val) for key, val in lookup.items()]) lightbar.update([(key, fmt % val) for key, val in lookup.items()]) lightbar.colors['border'] = term.yellow echo(lightbar.border()) echo(lightbar.title(u''.join(( term.yellow(u'-'), term.bold_white(u'[ '), term.bold_yellow('CitY'), term.bold_white(u', '), term.bold_yellow('StAtE'), term.bold_white(u' ]'), term.yellow(u'-'),)))) echo(lightbar.footer(u''.join(( term.yellow(u'-'), term.bold_black(u'( '), term.yellow_underline('Escape'), u':', term.yellow('EXit'), term.bold_black(u' )'), term.yellow(u'-'),)))) lightbar.colors['highlight'] = term.yellow_reverse choice = lightbar.read() echo(lightbar.erase()) return ((loc for loc in locations if choice == loc['postal'] ).next() if choice is not None else choice)
def get_selector(mailbox, prev_sel=None): """ Provide Lightbar UI element given message mailbox returned from function get_header, and prev_sel as previously instantiated Lightbar. """ from x84.bbs import Lightbar pos = prev_sel.position if prev_sel is not None else (0, 0) sel = Lightbar( height=(term.height / 3 if term.width < 140 else term.height - 3), width=len_preview, yloc=2, xloc=0) sel.glyphs['top-horiz'] = u'' sel.glyphs['left-vert'] = u'' sel.colors['highlight'] = term.yellow_reverse sel.update(mailbox) sel.position = pos return sel
def get_lightbar(lcallers, lcalls): """ Return UI element for browsing last callers, given ``lcallers`` as a list of handles, and parallel array ``lcalls`` as unicode string to display for last call of each handle. """ from x84.bbs import getterminal, Lightbar term = getterminal() width = min(50, max(10, term.width - 5)) height = max(4, min(term.height - 8, 35)) xloc = (term.width / 2) - (width / 2) yloc = term.height - height pager = Lightbar(height, width, yloc, xloc) pager.glyphs['left-vert'] = pager.glyphs['right-vert'] = u'' pager.colors['highlight'] = term.red_reverse pager.colors['border'] = term.yellow pager.xpadding, pager.ypadding = 2, 1 pager.alignment = 'center' pager.update([(lcallers[n], txt,) for (n, txt) in enumerate(lcalls.split('\n'))]) return pager
def chose_location_lightbar(locations): """ Lightbar pager for chosing a location. """ from x84.bbs import getterminal, echo, Lightbar term = getterminal() fmt = u'%(city)s, %(state)s' lookup = dict([(loc['postal'], loc) for loc in locations]) fullheight = min(term.height - 8, len(locations) + 2) fullwidth = min(75, int(term.width * .8)) # shrink window to minimum width maxwidth = max([len(fmt % val) for val in lookup.values()]) + 2 if maxwidth < fullwidth: fullwidth = maxwidth echo(u'\r\n' * fullheight) lightbar = Lightbar(height=fullheight, width=fullwidth, yloc=term.height - fullheight, xloc=int((term.width / 2) - (fullwidth / 2))) lightbar.update([(key, fmt % val) for key, val in lookup.items()]) lightbar.update([(key, fmt % val) for key, val in lookup.items()]) lightbar.colors['border'] = term.yellow echo(lightbar.border()) echo( lightbar.title(u''.join(( term.yellow(u'-'), term.bold_white(u'[ '), term.bold_yellow('CitY'), term.bold_white(u', '), term.bold_yellow('StAtE'), term.bold_white(u' ]'), term.yellow(u'-'), )))) echo( lightbar.footer(u''.join(( term.yellow(u'-'), term.bold_black(u'( '), term.yellow_underline('Escape'), u':', term.yellow('EXit'), term.bold_black(u' )'), term.yellow(u'-'), )))) lightbar.colors['highlight'] = term.yellow_reverse choice = lightbar.read() echo(lightbar.erase()) return ((loc for loc in locations if choice == loc['postal']).next() if choice is not None else choice)
def lb_init(position=None, menu_index=None): """ Initialize Lightbar Main Menu """ from x84.bbs import getsession, getterminal, ini, Lightbar import os import logging logger = logging.getLogger() session, term = getsession(), getterminal() session.activity = u'Lightbar main menu' # set up lightbar pager, determine terminal dimensions term = getterminal() height = term.height - 11 lb_width = int(term.width * .4) lb_xloc = int(term.width * .3) lightbar = Lightbar(height, lb_width, (term.height - height - 1), lb_xloc) # Lightbar main menu entries entries = [ ('', '-----[COmMs]-----'), ('$', 'rEAD bUllETiNS'), ('n', 'latest nEWS'), ('hn', 'hACkEr nEWS'), # ('p', 'pOSt A MSG'), ('r', 'MEsSAgE ArEAs'), ('c', 'chAt'), ('i', 'iRC chAt'), ('', ' '), ('', '----[FIleS]----'), ('fb', 'FIle BrOWsEr'), ('', ' '), ('', '----[SeRVIcES]----'), ('l', 'lASt CAllS'), ('o', 'oNE liNERS'), ('b', 'bbS NEXUS'), ('f', 'WeAThER fORECASt'), ('t', 'tEtRiS'), ('v', "vOtINg BoOth"), ('w', "whO'S ONliNE"), ('', ' '), ('', '-----[SySTeM]-----'), ('!', 'ENCOdiNG'), ('kb', 'kEYbOaRd tESt'), ('s', 'sYS. iNfO'), ('u', 'uSER LiST'), ('e', 'edit PROfilE'), ] if ini.CFG.getboolean('dosemu', 'enabled') and ( ini.CFG.get('dosemu', 'lord_path') != 'no'): entries.insert(0, ('#', 'PlAY lORd!')) # add sesame doors to menu if enabled if ini.CFG.has_section('sesame'): from ConfigParser import NoOptionError for door in ini.CFG.options('sesame'): if '_' in door: continue # .. but only if we have the binary if not os.path.exists(ini.CFG.get('sesame', door)): continue # .. and a key is configured try: key = ini.CFG.get('sesame', '{}_key'.format(door)) except NoOptionError: logger.error("no key configured for sesame door '{}'".format( door, )) else: logger.debug("added sesame door '{}' with key '{}'".format( door, key )) entries.insert(0, (key, 'PlAY {}'.format(door))) if 'sysop' in session.user.groups: entries += (('v', 'VidEO CASSEttE'),) entries += (('g', 'gOOdbYE /lOGOff'),) lightbar.update(entries) if menu_index is not None: lightbar.goto(menu_index) # set up some nice colors lightbar.colors['highlight'] = term.bold_cyan_reverse lightbar.colors['border'] = term.bold_blue lightbar.xpadding, lightbar.ypadding = 2, 1 lightbar.alignment = 'center' # set lightbar theme # lightbar.init_theme() # re-select previous selection if position is not None: lightbar.position = position return (lightbar)
def main(file=None, invert=False, Showart=True): """ Main procedure. """ if file != None: displayfile(file) return session = getsession() term = getterminal() session.activity = 'Reading text files' currentfolder = [] stored_lbar_pos = [] filelist = getfilelist(STARTFOLDER) dirty = True inp = None lbar = Lightbar(height = 0, width = 0, xloc = 0, yloc = 0, colors={'highlight': term.bold_white_on_red}) # sets up a lightbar. update_lightbar will give it it's actual values. echo(term.clear+banner()+term.hide_cursor) while 1: if dirty: update_lightbar(lbar,term,filelist) dirty = False while not inp: inp = getch(0.2) if session.poll_event('refresh'): echo(term.clear) if term.width > 79: echo(banner()) update_lightbar(lbar,term,filelist) dirty = True lbar.process_keystroke(inp) if lbar.quit: echo(term.normal_cursor) return echo(lbar.refresh_quick()) if inp == term.KEY_ENTER: if lbar.selection[1] == '( .. ) GO BACK' or os.path.isdir(STARTFOLDER+u''.join(currentfolder)+lbar.selection[0]): if lbar.selection[1] == '( .. ) GO BACK': del currentfolder[-1] filelist = getfilelist(STARTFOLDER+u''.join(currentfolder)) lbar.update(filelist) lbar.goto(stored_lbar_pos[-1]) del stored_lbar_pos[-1] else: currentfolder.append(lbar.selection[0]+u'/') stored_lbar_pos.append(lbar.index) filelist = getfilelist(STARTFOLDER+u''.join(currentfolder)) lbar.goto(0) if len(currentfolder) > 0: filelist.insert(0,['( .. ) GO BACK','( .. ) GO BACK']) lbar.update(filelist) else: displayfile(STARTFOLDER+u''.join(currentfolder)+lbar.selection[0]) echo(term.clear+banner()) dirty = True inp = None
def lb_init(position=None, menu_index=None): """ Initialize Lightbar Main Menu """ from x84.bbs import getsession, getterminal, echo, showart, ini, Lightbar import os import logging logger = logging.getLogger() session, term = getsession(), getterminal() session.activity = u'Lightbar main menu' # set up lightbar pager, determine terminal dimensions term = getterminal() height = term.height - 11 lb_width = int(term.width * .4) lb_xloc = int(term.width * .3) lightbar = Lightbar(height, lb_width, (term.height - height - 1), lb_xloc) # Lightbar main menu entries entries = [ #('', '-----[COmMs]-----'), ('$', 'rEAD bUllETiNS'), ('n', 'latest nEWS'), ('p', 'pOSt A MSG'), ('r', 'rEAd All MSGS'), ('c', 'chAt'), ('i', 'iRC chAt'), #('', ' '), #('', '----[SeRVIcES]----'), ('l', 'lASt CAllS'), ('o', 'oNE liNERS'), ('b', 'bbS NEXUS'), ('f', 'WeAThER fORECASt'), ('t', 'tEtRiS'), ('w', "whO'S ONliNE"), #('', ' '), #('', '-----[SySTeM]-----'), ('!', 'ENCOdiNG'), ('s', 'sYS. iNfO'), ('u', 'uSER LiST'), ('e', 'edit PROfilE'), ] if ini.CFG.getboolean( 'dosemu', 'enabled') and (ini.CFG.get('dosemu', 'lord_path') != 'no'): entries.insert(0, ('#', 'PlAY lORd!')) # add sesame doors to menu if enabled if ini.CFG.has_section('sesame'): from ConfigParser import NoOptionError for door in ini.CFG.options('sesame'): if '_' in door: continue # .. but only if we have the binary if not os.path.exists(ini.CFG.get('sesame', door)): continue # .. and a key is configured try: key = ini.CFG.get('sesame', '{}_key'.format(door)) except NoOptionError: logger.error("no key configured for sesame door '{}'".format( door, )) else: logger.debug("added sesame door '{}' with key '{}'".format( door, key)) entries.insert(0, (key, 'PlAY {}'.format(door))) if 'sysop' in session.user.groups: entries += (('v', 'VidEO CASSEttE'), ) entries += (('g', 'gOOdbYE /lOGOff'), ) lightbar.update(entries) if menu_index is not None: lightbar.goto(menu_index) # set up some nice colors lightbar.colors['highlight'] = term.bold_cyan_reverse lightbar.colors['border'] = term.bold_blue lightbar.xpadding, lightbar.ypadding = 2, 1 lightbar.alignment = 'center' # set lightbar theme #lightbar.init_theme() ## re-select previous selection if position is not None: lightbar.position = position return (lightbar)
def main(ttyfile=u'', peek=False): """ Main procedure. """ # pylint: disable=R0914,R0915 # Too many local variables # Too many statements from x84.bbs import getsession, getterminal, echo, getch from x84.bbs import Door, ini, Lightbar import os import re ttyplay_exe = ini.CFG.get('ttyplay', 'exe') if not os.path.exists(ttyplay_exe): echo(u'\r\n%s NOt iNStAllEd.\r\n' % (ttyplay_exe,)) getch() return session, term = getsession(), getterminal() if 'sysop' in session.user.groups and ttyfile == u'': # pylint: disable=W0212 # Access to a protected member _ttyrec_folder of a client class folder = os.path.dirname(ttyfile) or session._ttyrec_folder files = sorted([fn for fn in os.listdir(session._ttyrec_folder) if fn.endswith('.ttyrec')]) echo(u'\r\n' * term.height) sel = Lightbar(term.height - 1, term.width - 1, 0, 0) sel.colors['border'] = term.bold_green echo(sel.border() + sel.title('- SElECt A RECORdiNG -')) sel.update([(fname, fname) for fname in files]) x_ttyfile = sel.read() if x_ttyfile is None or sel.quit: return ttyfile = os.path.join(folder, x_ttyfile) if not (os.path.exists(ttyfile) and os.path.isfile(ttyfile)): echo(term.bold_red('\r\n\r\nPAth NOt fOUNd: %s\r\n' % (ttyfile,))) getch() return # .. we could look for and write various information headers.. # .. esp. at EOF, about session.user.handle & connect_time & etc. data = open(ttyfile, 'rb').read(64) size_pattern = re.compile(r'\[8;(\d+);(\d+)t') match = size_pattern.match(data) if match: echo(u'\r\n\r\nheight, width: %s, %s' % match.groups()) args = tuple() if peek: args += ('-p',) elif 'sysop' in session.user.groups: echo("\r\nPRESS '%s' tO PEEk (2)\b\b" % ( (term.green_underline(u'p'),))) if getch(2) in (u'p', u'P'): peek = True args += (ttyfile,) door = Door(ttyplay_exe, args=args) session.activity = u'playing tty recording' # pylint: disable=W0212 # Access to a protected member _record_tty of a client class resume_rec = session._record_tty and session.is_recording if resume_rec: session.stop_recording() session._record_tty = False # press any key prompt, instructions for quitting (^c) .. echo(u'\r\n\r\n lOAd CASSEttE ANd PRESS %s. PRESS %s tO %s.\r\n' % ( term.green_reverse(u'PlAY'), term.green_underline('bREAk'), term.red_reverse(u'StOP'),)) getch() with term.fullscreen(): door.run() echo(u'\r\n\r\n') echo(u'PRESS ' + term.green_underline('q') + u'.') while not getch() in (u'q', u'Q'): pass if not session.is_recording and resume_rec: session._record_tty = True session.start_recording() echo(term.move(term.height, 0)) echo(u'\r\n')