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 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 upload_files(term, protocol='xmodem1k'): """ Upload files. """ echo(term.clear) while True: echo(u'Filename (empty to quit):\r\n') led = LineEditor(width=term.width - 1) led.refresh() inp = led.read() led = None if inp: for illegal in (os.path.sep, u'..', u'~',): if illegal in inp: echo(term.bold_red(u'\r\nIllegal filename.\r\n')) term.inkey() return echo(term.bold( u'\r\nBegin your {0} sending program now.\r\n' .format(protocol))) upload_filename = os.path.join(UPLOADS_DIR, inp) try: upload = open(upload_filename, 'wb') except IOError as err: echo(term.bold_red('u\r\nIOError: {err}\r\n'.format(err=err))) else: if not recv_modem(upload, protocol): echo(term.bold_red(u'Upload failed!\r\n')) os.unlink(upload_filename) else: echo(term.bold_green(u'Transfer succeeded.\r\n')) term.inkey() else: return
def do_select_encoding(term, session): editor_colors = {'highlight': term.black_on_green} dirty = True while True: if session.poll_event('refresh') or dirty: # attempt to coerce encoding of terminal to match session. coerce_terminal_encoding(term, session.encoding) # display artwork and prompt vertical_padding = 2 if term.height >= 24 else 0 display_banner(filepattern=art_file, encoding=art_encoding, vertical_padding=vertical_padding) display_prompt(term) dirty = False inp = LineEditor(1, colors=editor_colors).read() if inp is None or inp.lower() == 'd': break elif len(inp): # bad input -- reposition cursor for next LineEditor() echo(u'\b') if inp.lower() == u'u' and session.encoding != 'utf8': # switch to utf8, session.encoding = 'utf8' dirty = True elif inp.lower() == 'c' and session.encoding != 'cp437': # or cp437 session.encoding = 'cp437' dirty = True
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 prompt_tags(msg): """ Prompt for and return tags wished for message. """ # pylint: disable=R0914,W0603 # Too many local variables # Using the global statement from x84.bbs import DBProxy, echo, getterminal, getsession from x84.bbs import Ansi, LineEditor session, term = getsession(), getterminal() tagdb = DBProxy('tags') msg_onlymods = (u"\r\nONlY MEMbERS Of thE '%s' OR '%s' " "GROUP MAY CREAtE NEW tAGS." % ( term.bold_yellow('sysop'), term.bold_blue('moderator'),)) msg_invalidtag = u"\r\n'%s' is not a valid tag." prompt_tags1 = u"ENtER %s, COMMA-dEliMitEd. " % ( term.bold_red('TAG(s)'),) prompt_tags2 = u"OR '/list', %s:quit\r\n : " % ( term.bold_yellow_underline('Escape'),) while True: # Accept user input for multiple 'tag's, or /list command echo(u'\r\n\r\n') echo(prompt_tags1) echo(prompt_tags2) width = term.width - 6 sel_tags = u', '.join(msg.tags) inp_tags = LineEditor(width, sel_tags).read() if inp_tags is not None and 0 == len(inp_tags.strip()): # no tags must be (private ..) msg.tags = set() return True if inp_tags is None or inp_tags.strip().lower() == '/quit': return False elif inp_tags.strip().lower() == '/list': # list all available tags, and number of messages echo(u'\r\n\r\nTags: \r\n') all_tags = sorted(tagdb.items()) if 0 == len(all_tags): echo(u'None !'.center(term.width / 2)) else: echo(Ansi(u', '.join(([u'%s(%d)' % (_key, len(_value),) for (_key, _value) in all_tags])) ).wrap(term.width - 2)) continue echo(u'\r\n') # search input as valid tag(s) tags = set([inp.strip().lower() for inp in inp_tags.split(',')]) err = False for tag in tags.copy(): if not tag in tagdb and not ( 'sysop' in session.user.groups or 'moderator' in session.user.groups): tags.remove(tag) echo(msg_invalidtag % (term.bold_red(tag),)) err = True if err: echo(msg_onlymods) continue msg.tags = tags return True
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 prompt_tags(session, term, msg, colors, public=True): xpos = max(0, (term.width // 2) - (80 // 2)) # conditionally enforce tag moderation moderated = get_ini("msg", "moderated_tags", getter="getboolean") tag_moderators = set(get_ini("msg", "tag_moderators", split=True)) # enforce 'public' tag if public and "public" not in msg.tags: msg.tags.add("public") elif not public and "public" in msg.tags: msg.tags.remove("public") # describe all available tags, as we oft want to do. do_describe_available_tags(term, colors) # and remind ourselves of the available network tags, description = get_network_tag_description(term, colors) if description: show_description(term=term, color=None, description=description) echo( u"".join( (term.move_x(xpos), term.clear_eos, u"Enter tags, separated by commas.\r\n", term.move_x(xpos), u":: ") ) ) all_tags = list_tags() while True: inp = LineEditor( subject_max_length, u", ".join(sorted(msg.tags)), colors={"highlight": colors["backlight"]} ).read() if inp is None: echo(u"".join((term.move_x(xpos), colors["highlight"]("Message canceled."), term.clear_eol))) term.inkey(1) return False msg.tags = set(filter(None, set(map(unicode.strip, inp.split(","))))) if moderated and not (tag_moderators | session.user.groups): cannot_tag = [_tag for _tag in msg.tags if _tag not in all_tags] if cannot_tag: echo( u"".join( ( u"\r\n", term.move_x(xpos), u", ".join((quote(tag, colors) for tag in cannot_tag)), u": not allowed; this system is moderated.", ) ) ) term.inkey(2) echo(term.move_up) map(msg.tags.remove, cannot_tag) continue return True
def main(): session = getsession() session.activity = u'hanging out in voting script' term = getterminal() echo(term.clear()) db = DBProxy(databasename) if not 'questions' in db: generate_database() while True: echo(term.clear()) # clears the screen and displays the vote art header for line in showart(os.path.join(os.path.dirname(__file__),'art','vote.ans'),'topaz'): echo(term.cyan+term.move_x((term.width/2)-40)+line) if 'sysop' in session.user.groups: spacing = 1 else: spacing = 7 echo(' ') echo(term.magenta+'\n ('+term.cyan+'r'+term.magenta+')'+term.white+'esults'+' '*spacing) echo(term.magenta+'('+term.cyan+'v'+term.magenta+')'+term.white+'ote on a question'+' '*spacing) echo(term.magenta+'('+term.cyan+'a'+term.magenta+')'+term.white+'dd a new question'+' '*spacing) if 'sysop' in session.user.groups: echo(term.magenta+'('+term.cyan+'d'+term.magenta+')'+term.white+'elete a question'+' '*spacing) echo(term.magenta+'('+term.cyan+'q'+term.magenta+')'+term.white+'uit') echo(term.magenta+'\r\n\r\n\r\nx/84 voting booth command: ') le = LineEditor(30) le.colors['highlight'] = term.cyan inp = le.read() inp = inp.lower() # makes the input indifferent to wheter you used lower case when typing in a command or not.. if 'sysop' in session.user.groups and inp == 'd': while 1: questionnumber = query_question() if questionnumber == 999: break delete_question(questionnumber) elif inp == 'r': while 1: questionnumber = query_question() if questionnumber == 999: break list_results(questionnumber) elif inp == 'v': while 1: questionnumber = query_question() if questionnumber == 999: break vote(questionnumber) elif inp == 'a': add_question() elif inp == 'q': return else: echo(term.red+'\r\nNo such command. Try again.\r\n') # if no valid key is pressed then do some ami/x esthetics. waitprompt()
def locate_user(term, point): """ Prompt for search pattern and return discovered User. """ _color1, _color2, _color3 = [ getattr(term, _color) for _color in (color_lowlight, color_highlight, color_field_edit) ] # show help width = term.width - (point.x * 2) help_txt = (u'Enter username or glob pattern. Press escape to cancel.') y_offset = 0 for y_offset, txt in enumerate(term.wrap(help_txt, width=width)): echo(term.move(point.y + y_offset, point.x)) echo(_color1(txt) + term.clear_eol) point_prompt = Point(y=point.y + y_offset + 2, x=point.x) editor = LineEditor(nua.username_max_length, colors={'highlight': _color3}) while True: # prompt for handle echo(term.move(*point_prompt)) echo(u'handle: ' + term.clear_eol) inp = editor.read() point = Point(y=point_prompt.y + 2, x=point.x) if inp is None: # canceled (escape) return elif u'*' in inp or u'?' in inp: # a glob pattern, fetch all usernames handles = fnmatch.filter(list_users(), inp) if len(handles) == 0: echo(u''.join((term.move(*point), u'No matches for {0}.'.format(_color2(inp)), term.clear_eos))) elif len(handles) == 1: return get_user(handles[0]) else: matches_text = ( u'{0} accounts matched, chose one: {1}.'.format( _color2(str(len(handles))), u', '.join(_color2(handle) for handle in handles))) echo(term.move(*point)) for y_offset, txt in enumerate( term.wrap(matches_text, width=width)): echo(term.move(point.y + y_offset, point.x)) echo(txt + term.clear_eol) if point.y + y_offset > term.height - 3: # we simply cannot display anymore break echo(term.clear_eos) else: handle = find_user(inp) if handle is not None: return get_user(handle) echo(u''.join( (term.move(*point), u'No matches for {0}.'.format(_color2(inp)), term.clear_eos)))
def prompt_recipient(msg): """ Prompt for recipient of message. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getterminal, LineEditor, echo, ini, list_users from x84.bbs import Selector import difflib term = getterminal() echo(u"ENtER %s, OR '%s' tO AddRESS All. %s to exit" % ( term.bold_yellow(u'hANdlE'), term.bold_yellow(u'None'), term.bold_yellow_underline('Escape'),)) echo(u'\r\n\r\n') max_user = ini.CFG.getint('nua', 'max_user') lne = LineEditor(max_user, msg.recipient or u'None') lne.highlight = term.yellow_reverse echo(term.clear_eol + u' RECiPiENt: ') recipient = lne.read() if recipient is None or lne.quit: return False userlist = list_users() if recipient in userlist: msg.recipient = recipient return True elif len(recipient) != 0 and recipient != 'None': for match in difflib.get_close_matches(recipient, userlist): blurb = u'did YOU MEAN: %s ?' % (match,) inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') echo(u''.join(( u'\r\n', term.move(inp.yloc, inp.xloc - len(blurb)), term.clear_eol, term.bold_yellow(blurb)))) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'YES': msg.recipient = match return True if selection is None or inp.quit: return False else: blurb = u' NO RECiPiENT; POSt tO PUbliC? ' inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') echo(u''.join(( u'\r\n', term.move(inp.yloc, inp.xloc - len(blurb)), term.clear_eol, term.bold_yellow(blurb)))) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'YES': msg.recipient = None return True
def prompt_recipient(msg): """ Prompt for recipient of message. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getterminal, LineEditor, echo, ini, list_users from x84.bbs import Selector import difflib term = getterminal() echo(u"ENtER %s, OR '%s' tO AddRESS All. %s to exit" % ( term.bold_yellow(u'hANdlE'), term.bold_yellow(u'None'), term.bold_yellow_underline('Escape'), )) echo(u'\r\n\r\n') max_user = ini.CFG.getint('nua', 'max_user') lne = LineEditor(max_user, msg.recipient or u'None') lne.highlight = term.yellow_reverse echo(term.clear_eol + u' RECiPiENt: ') recipient = lne.read() if recipient is None or lne.quit: return False userlist = list_users() if recipient in userlist: msg.recipient = recipient return True elif len(recipient) != 0 and recipient != 'None': for match in difflib.get_close_matches(recipient, userlist): blurb = u'did YOU MEAN: %s ?' % (match, ) inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') echo(u''.join((u'\r\n', term.move(inp.yloc, inp.xloc - len(blurb)), term.clear_eol, term.bold_yellow(blurb)))) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'YES': msg.recipient = match return True if selection is None or inp.quit: return False else: blurb = u' NO RECiPiENT; POSt tO PUbliC? ' inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') echo(u''.join((u'\r\n', term.move(inp.yloc, inp.xloc - len(blurb)), term.clear_eol, term.bold_yellow(blurb)))) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'YES': msg.recipient = None return True
def locate_user(term, point): """ Prompt for search pattern and return discovered User. """ _color1, _color2, _color3 = [ getattr(term, _color) for _color in ( color_lowlight, color_highlight, color_field_edit)] # show help width = term.width - (point.x * 2) help_txt = (u'Enter username or glob pattern. Press escape to cancel.') y_offset = 0 for y_offset, txt in enumerate(term.wrap(help_txt, width=width)): echo(term.move(point.y + y_offset, point.x)) echo(_color1(txt) + term.clear_eol) point_prompt = Point(y=point.y + y_offset + 2, x=point.x) editor = LineEditor(nua.username_max_length, colors={'highlight': _color3}) while True: # prompt for handle echo(term.move(*point_prompt)) echo(u'handle: ' + term.clear_eol) inp = editor.read() point = Point(y=point_prompt.y + 2, x=point.x) if inp is None: # canceled (escape) return elif u'*' in inp or u'?' in inp: # a glob pattern, fetch all usernames handles = fnmatch.filter(list_users(), inp) if len(handles) == 0: echo(u''.join((term.move(*point), u'No matches for {0}.'.format(_color2(inp)), term.clear_eos))) elif len(handles) == 1: return get_user(handles[0]) else: matches_text = ( u'{0} accounts matched, chose one: {1}.'.format( _color2(str(len(handles))), u', '.join( _color2(handle) for handle in handles))) echo(term.move(*point)) for y_offset, txt in enumerate( term.wrap(matches_text, width=width)): echo(term.move(point.y + y_offset, point.x)) echo(txt + term.clear_eol) if point.y + y_offset > term.height - 3: # we simply cannot display anymore break echo(term.clear_eos) else: handle = find_user(inp) if handle is not None: return get_user(handle) echo(u''.join((term.move(*point), u'No matches for {0}.'.format(_color2(inp)), term.clear_eos)))
def add_question(): term = getterminal() db = DBProxy(databasename) questions = [] amount_of_alternatives = [] index = {} alternatives = {} results = {} index = db['index'] questions = db['questions'] alternatives = db['alternatives'] results = db['results'] amount_of_alternatives = db['amount_of_alternatives'] amount_of_questions = len(questions) echo(term.clear + term.white + '\r\nQuestion: ') le = LineEditor(65) new_question = le.read() if new_question == '': return echo( term.bold_black + '\r\n\r\nLeave a blank line when you are finished..') new_amount = 0 while True: echo(term.normal + term.white + '\r\nchoice ' + term.red + str(new_amount) + term.white + ': ') le = LineEditor(48) alternatives[(amount_of_questions, new_amount)] = le.read() if alternatives[(amount_of_questions, new_amount)] == '': break else: results[(amount_of_questions, new_amount)] = 0 new_amount = new_amount + 1 if new_amount > 0: echo(term.normal + term.white + '\r\n\r\nSave this voting question?') answer = ynprompt() if answer == 1: questions.append(new_question) amount_of_alternatives.append(new_amount) indexcounter = db['indexcounter'] indexcounter = indexcounter + 1 index.append(str(indexcounter)) db['indexcounter'] = indexcounter db['index'] = index db['questions'] = questions db['amount_of_alternatives'] = amount_of_alternatives db['results'] = results db['amount_of_questions'] = amount_of_questions db['alternatives'] = alternatives waitprompt()
def more(cont=False): """ Returns True if user 'q'uit; otherwise False when prompting is complete (moar/next/whatever) """ from x84.bbs import echo, getch, getterminal, LineEditor, DBProxy prompt_key = u'\r\n\r\nENtER BBS iD: ' msg_badkey = u'\r\n\r\nbbS id iNVAliD!' term = getterminal() prompt = u', '.join( fancy_blue(char, blurb) for char, blurb in (( 'i', 'NfO', ), ( 'a', 'dd', ), ( 'c', 'OMMENt', ), ( 'r', 'AtE', ), ( 't', 'ElNEt', ), ('v', 'ANSi'), ( 'q', 'Uit', ))) if cont: prompt += u', ' + fancy_blue(' ', 'more') prompt += u': ' while True: echo(u'\r\n') echo(u'\r\n'.join( term.wrap(text=prompt, width=(term.width - (term.width / 3))))) inp = getch() if inp in (u'q', 'Q'): return True elif inp is not None and type(inp) is not int: if cont and inp == u' ': echo(u'\r\n\r\n') return False if inp.lower() in u'acrtviACRTVI': # these keystrokes require a bbs key argument, # prompt the user for one echo(prompt_key) key = LineEditor(5).read() if (key is None or 0 == len(key.strip()) or not key in DBProxy('bbslist')): echo(msg_badkey) continue process_keystroke(inp, key)
def prompt_tags(session, term, msg, colors, public=True): xpos = max(0, (term.width // 2) - (80 // 2)) # conditionally enforce tag moderation moderated = get_ini('msg', 'moderated_tags', getter='getboolean') tag_moderators = set(get_ini('msg', 'tag_moderators', split=True)) # enforce 'public' tag if public and 'public' not in msg.tags: msg.tags.add('public') elif not public and 'public' in msg.tags: msg.tags.remove('public') # describe all available tags, as we oft want to do. do_describe_available_tags(term, colors) # and remind ourselves of the available network tags, description = get_network_tag_description(term, colors) if description: show_description(term=term, color=None, description=description) echo(u''.join( (term.move_x(xpos), term.clear_eos, u'Enter tags, separated by commas.\r\n', term.move_x(xpos), u':: '))) all_tags = list_tags() while True: inp = LineEditor(subject_max_length, u', '.join(sorted(msg.tags)), colors={ 'highlight': colors['backlight'] }).read() if inp is None: echo(u''.join( (term.move_x(xpos), colors['highlight']('Message canceled.'), term.clear_eol))) term.inkey(1) return False msg.tags = set(filter(None, set(map(unicode.strip, inp.split(','))))) if moderated and not (tag_moderators | session.user.groups): cannot_tag = [_tag for _tag in msg.tags if _tag not in all_tags] if cannot_tag: echo(u''.join((u'\r\n', term.move_x(xpos), u', '.join( (quote(tag, colors) for tag in cannot_tag)), u': not allowed; this system is moderated.'))) term.inkey(2) echo(term.move_up) map(msg.tags.remove, cannot_tag) continue return True
def query_question(): term = getterminal() session = getsession() db = DBProxy(databasename) questions = [] index = [] uservotingdata = [] questions = db['questions'] index = db['index'] # create a new database file if none exists if not session.user.handle in db: db[session.user.handle] = {} uservotingdata = db[session.user.handle] echo(term.clear() + term.blue(u'>>') + term.white(u'questions availible\r\n') + term.blue(u'-' * 21 + '\r\n\r\n')) text = '' for i in range(0, len(questions)): if (index[i], 0) in uservotingdata: text = text + term.green(u'*') text = text + u''.join(term.magenta + u'(' + term.cyan + str(i) + term.magenta + u') ' + term.white + questions[i] + u'\r\n') text = text.splitlines() prompt_pager(content=text, line_no=0, colors={ 'highlight': term.cyan, 'lowlight': term.green, }, width=term.width, breaker=None, end_prompt=False) echo(term.move_x(0) + term.bold_black(u'* = already voted\r\n\r\n')) while True: echo( term.move_x(0) + term.magenta( u'select one of the questions above or press enter to return: ' )) le = LineEditor(10) le.colors['highlight'] = term.cyan inp = le.read() if inp is not None and inp.isnumeric() and int(inp) < len(questions): return int(inp) else: # -1 in this case means that no valid option was chosen.. break # loop. return -1
def prompt_yesno(question): """ yes/no user prompt. """ term = getterminal() sep = getattr(term, color_secondary)(u'**') colors = {'highlight': getattr(term, color_secondary)} echo(fixate_next(term, newlines=1)) while True: echo(u'{sep} {question} [yn] ?\b\b'.format(sep=sep, question=question)) yn = LineEditor(colors=colors, width=1).read() or u'' if yn.lower() in (u'y', u'n'): return yn.lower() == u'y' echo(term.move_x(0) + term.clear_eol) echo(fixate_next(term, newlines=0))
def prompt_subject(term, msg, colors): """ Prompt for subject of message. """ xpos = max(0, (term.width // 2) - (80 // 2)) echo(u"".join((term.move_x(xpos), term.clear_eos, u"Enter Subject.\r\n", term.move_x(xpos), u":: "))) inp = LineEditor(subject_max_length, msg.subject, colors={"highlight": colors["backlight"]}).read() if inp is None or not inp.strip(): echo(u"".join((term.move_x(xpos), colors["highlight"]("Canceled."), term.clear_eol))) term.inkey(1) return False msg.subject = inp.strip() return True
def prompt_subject(msg): """ Prompt for subject of message. """ from x84.bbs import getterminal, LineEditor, echo, ini term = getterminal() max_subject = int(ini.CFG.getint('msg', 'max_subject')) lne = LineEditor(max_subject, msg.subject) lne.highlight = term.yellow_reverse echo(u'\r\n\r\n SUBjECt: ') subject = lne.read() if subject is None or 0 == len(subject): return False msg.subject = subject return True
def set_password(user): """ Prompt for user.password, minimum length. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getterminal, echo, ini, LineEditor term = getterminal() hidden_ch = u'x' prompt_password = u'password: '******' again: ' msg_empty = u'ENtER A PASSWORd!' msg_tooshort = u'TOO ShORt, MUSt bE At lEASt %s.' msg_unmatched = u'VERifY MUSt MAtCH!' width = ini.CFG.getint('nua', 'max_pass') min_pass = ini.CFG.getint('nua', 'min_pass') while True: echo(u'\r\n\r\n' + term.clear_eol + term.normal + prompt_password) led = LineEditor(width) led.hidden = hidden_ch password = led.read() if password == u'' or password is None: warning(msg_empty) elif len(password) < min_pass: warning(msg_tooshort % min_pass) else: echo(u'\r\n\r\n' + term.clear_eol + term.normal + prompt_verify) led = LineEditor(width) led.hidden = hidden_ch verify = led.read() if password != verify: warning(msg_unmatched) continue user.password = password return
def on_nicknameinuse(self, connection, event): """ Nick is being used; pick another one. """ # pylint:disable=W0613 self.session.send_event('route', (self.session.sid, 'irc-connected')) self.connected = True echo(u''.join([self.term.normal, self.term.clear, u'Your nickname is in use or illegal. Pick a new one ' u'(blank to quit):\r\n'])) led = LineEditor(width=MAX_NICK) newnick = led.read() echo(u'\r\n') if not newnick: self.session.send_event('route', (self.session.sid, 'irc-quit')) return connection.nick(newnick)
def on_nicknameinuse(self, connection, event): """ Nick is being used; pick another one. """ # pylint: disable=W0613 self.session.buffer_event('irc-connected') self.connected = True echo(u''.join([self.term.normal, u'\r\n', u'Your nickname is in use or illegal. Pick a new one ' u'(blank to quit):\r\n'])) led = LineEditor(width=MAX_NICK) newnick = led.read() echo(u'\r\n') if not newnick: self.session.buffer_event('irc-quit', 'canceled') return connection.nick(newnick)
def query_question(): term = getterminal() session = getsession() db = DBProxy(databasename) questions = [] index = [] uservotingdata = [] questions = db['questions'] index = db['index'] counter = 0 # create database for user if the user hasn't made any votes if not session.user.handle in db: db[session.user.handle] = {} uservotingdata = db[session.user.handle] echo(term.clear() + term.blue + '>>' + term.white + 'questions availible\r\n' + term.blue + '---------------------\r\n\r\n' + term.white) for i in range(0, len(questions)): if (index[i], 0) in uservotingdata: # prints out a star to show that the user already voted on this # question echo(term.green + '*') echo(term.magenta + '(' + term.cyan + str(i) + term.magenta + ') ' + term.white + questions[i] + '\r\n') # if the list of questions is longer than the screen height, display a # press enter prompt counter = counter + 1 if counter > term.height - 7: counter = 0 waitprompt() echo(term.move_x(0) + term.clear_eol + term.move_up) echo(term.bold_black + '* = already voted\r\n\r\n' + term.normal) while True: echo( term.magenta + '\rselect one of the questions above or press enter to return: ') le = LineEditor(30) le.colors['highlight'] = term.cyan inp = le.read() if inp.isnumeric() and int(inp) < len(questions): return int(inp) else: # 999 in this case means that no valid option was chosen.. break # loop. return 999
def do_intro_art(term, session): """ Display random art file, prompt for quick login. Bonus: allow chosing other artfiles with '<' and '>'. """ from x84.bbs import ini show_intro_art = False if ini.CFG.has_option('system', 'show_intro_art'): show_intro_art = ini.CFG.getboolean('system', 'show_intro_art') # set syncterm font, if any if syncterm_font and term.kind.startswith('ansi'): echo(syncterm_setfont(syncterm_font)) index = int(time.time()) % len(art_files) dirty = True echo(u'\r\n') while True: session.activity = 'top' if session.poll_event('refresh') or dirty: if show_intro_art: display_intro(term, index) else: return True display_prompt(term) dirty = False dirty = True inp = LineEditor(1, colors={'highlight': term.normal}).read() if inp is None or inp.lower() == u'y': # escape/yes: quick login return True # issue #242 : set 'N' as default, by adding a check for an empty # unicode string. elif inp.lower() in (u'n', u'\r', u'\n', u''): break if len(inp) == 1: echo(u'\b') if inp == u'!': echo(u'\r\n' * 3) gosub('charset') dirty = True elif inp == u'<': index -= 1 elif inp == u'>': index += 1 else: dirty = False
def add_leaf_msgnet(): import cryptography.fernet server_tags = get_ini(section='msg', key='server_tags', split=True) if not server_tags: raise ValueError(MSG_NO_SERVER_TAGS) if len(server_tags) == 1: server_tag = server_tags[0] else: while True: echo('chose a server tag: ') idx = 0 for idx, tag in server_tags: echo(u'\r\n{0}. {1}'.format(idx, tag)) echo(u'\r\n: ') inp = LineEditor(width=len(str(idx)).read()) if inp is None: return try: server_tag = server_tags[int(inp)] break except ValueError: pass with DBProxy('{0}keys'.format(server_tag)) as key_db: board_id = max(map(int, key_db.keys()) or [-1]) + 1 client_key = cryptography.fernet.Fernet.generate_key() key_db[board_id] = client_key echo(u'\r\n') echo(u'-' * 40) view_leaf_msgnet(server_tag, board_id)
def prompt_input(term, key, **kwargs): """ Prompt for user input. """ sep_ok = getattr(term, color_secondary)(u'::') sep_bad = getattr(term, color_primary)(u'::') colors = {'highlight': getattr(term, color_primary)} echo(fixate_next(term)) echo(u'{sep} {key:>18}: '.format(sep=sep_ok, key=key)) entry = LineEditor(colors=colors, **kwargs).read() or u'' if not entry.strip(): echo(fixate_next(term)) echo(u'{sep} Canceled !\r\n'.format(sep=sep_bad)) log.debug('Password reset canceled at prompt key={0}.'.format(key)) return u'' return entry
def get_node(sessions): """ Prompt user for session node, Returns node & session attributes. """ from x84.bbs import ini, LineEditor, echo max_user = ini.CFG.getint('nua', 'max_user') invalid = u'\r\ninvalid.' echo(u'\r\n\r\nNOdE: ') node = LineEditor(max_user).read() if node is None or 0 == len(node): # cancel return (None, None) try: node = int(node) except ValueError: # not an int echo(invalid) return (None, None) for tgt_node, (_, attrs) in get_nodes(sessions): if tgt_node == node: return (tgt_node, attrs) # not found echo(invalid) return (None, None)
def prompt_input(term, key, sep_ok=u'::', width=None, colors=None): """ Prompt for and return input, up to given width and colorscheme. """ colors = colors or {'highlight': term.yellow} sep_ok = colors['highlight'](sep_ok) echo(u'{sep} {key:<8}: '.format(sep=sep_ok, key=key)) return LineEditor(colors=colors, width=width).read() or u''
def chose_location_dummy(locations): """ dummy pager to chose location """ from x84.bbs import getterminal, echo, getch, LineEditor term = getterminal() msg_enteridx = ( term.bold_yellow(u'('), term.underline_yellow(u'0'), term.yellow(u'-'), term.underline_yellow(u'%d' % (len(locations) - 1, )), term.yellow(u','), term.underline_yellow('Escape'), term.bold_white(u':'), term.yellow('exit'), term.bold_yellow(u')'), u' ', term.reverse_yellow(':'), ) max_nwidth = len('%d' % (len(locations) - 1, )) def disp_entry(num, loc): """ Display City, State. """ return u''.join(( term.bold_yellow(u'['), u'%*d' % (max_nwidth, num), term.bold_yellow(u']'), u' ', term.yellow(loc['city']), u', ', term.yellow(loc['state']), u'\r\n', )) echo(u'\r\n\r\n') lno = 3 for num, loc in enumerate(locations): echo(disp_entry(num, loc)) lno += 1 if lno != 0 and (0 == lno % (term.height)): echo(term.yellow_reverse('--MORE--')) if getch() is None: break echo(u'\r\n') lno += 1 idx = u'' while True: echo(u'\r\n' + u''.join(msg_enteridx)) idx = LineEditor(width=max_nwidth, content=idx).read() if idx is None or len(idx) == 0: return None try: int_idx = int(idx) except ValueError as err: echo(term.bold_red(u'\r\n%s' % (err, ))) continue if int_idx < 0 or int_idx > len(locations) - 1: echo(term.bold_red(u'\r\nValue out of range')) continue return locations[int_idx]
def set_sacookies(user): """ set SA cookies """ from x84.bbs import getterminal, echo, ini, LineEditor term = getterminal() prompt_sausercookie = u'SA \'user\' cookie data: ' echo(u'\r\n' + term.clear_eol + term.normal + prompt_sausercookie) user['sausercookie'] = LineEditor(50, u'').read() if user['sausercookie'] is None: user['sausercookie'] = u'' prompt_sapasscookie = u'SA \'password\' cookie data: ' echo(u'\r\n' + term.clear_eol + term.normal + prompt_sapasscookie) user['sapasscookie'] = LineEditor(50, u'').read() if user['sapasscookie'] is None: user['sapasscookie'] = u''
def get_article(term, articles): """ Prompt for an article number, return matching article. """ moveto_lastline = term.move(term.height, 0) width = term.width if term.kind.startswith('ansi'): # bah syncterm moveto_lastline = term.move(term.height - 1, 0) width -= 1 echo(u''.join(( moveto_lastline + getattr(term, COLOR_MAIN), term.center('', width), moveto_lastline, ))) echo(u':: enter article #: ') article_idx = LineEditor(width=len(str(ARTICLE_LIMIT)), colors={ 'highlight': getattr(term, COLOR_MAIN) }).read() if article_idx is None: # pressed escape return None try: return articles[int(article_idx) - 1] except (ValueError, IndexError): # not an integer, or out of range return None
def get_line_editor(term, menu): """ Return a line editor suitable for menu entry prompts. """ # if inp_key's were CJK characters, you should use term.length to measure # printable length of double-wide characters ... this is too costly to # enable by default. Just a note for you east-asian folks. max_inp_length = max([len(item.inp_key) for item in menu]) return LineEditor(width=max_inp_length, colors={'highlight': getattr(term, color_backlight)})
def query_question(): term = getterminal() session = getsession() db = DBProxy(databasename) questions = [] index = [] uservotingdata = [] questions = db['questions'] index = db['index'] # create a new database file if none exists if not session.user.handle in db: db[session.user.handle] = {} uservotingdata = db[session.user.handle] echo(term.clear() + term.blue(u'>>') + term.white(u'questions availible\r\n') + term.blue(u'-' * 21 + '\r\n\r\n')) text = '' for i in range(0, len(questions)): if (index[i], 0) in uservotingdata: text = text + term.green(u'*') text = text + u''.join(term.magenta + u'(' + term.cyan + str(i) + term.magenta + u') ' + term.white + questions[i] + u'\r\n') text = text.splitlines() prompt_pager(content=text, line_no=0, colors={'highlight': term.cyan, 'lowlight': term.green, }, width=term.width, breaker=None, end_prompt=False) echo(term.move_x(0) + term.bold_black(u'* = already voted\r\n\r\n')) while True: echo(term.move_x( 0) + term.magenta(u'select one of the questions above or press enter to return: ')) le = LineEditor(10) le.colors['highlight'] = term.cyan inp = le.read() if inp is not None and inp.isnumeric() and int(inp) < len(questions): return int(inp) else: # -1 in this case means that no valid option was chosen.. break # loop. return -1
def prompt_input(term, key, **kwargs): """ Prompt for user input. """ sep_ok = getattr(term, color_primary)(u'::') colors = {'highlight': getattr(term, color_primary)} echo(u'{sep} {key:>18}: '.format(sep=sep_ok, key=key)) entry = LineEditor(colors=colors, **kwargs).read() if entry is None: log.debug('New User Account canceled at prompt key={0}.'.format(key)) return entry
def get_zipsearch(zipcode=u''): """ Prompt user for zipcode or international city. """ from x84.bbs import getterminal, LineEditor, echo term = getterminal() echo(u''.join((u'\r\n\r\n', term.bold_yellow(u' -'), term.reverse_yellow(u':'), u' '))) return LineEditor(width=min(30, term.width - 5), content=zipcode).read()
def query_question(): term = getterminal() session = getsession() db = DBProxy(databasename) questions = [] index = [] uservotingdata = [] questions = db['questions'] index = db['index'] counter = 0 if not session.user.handle in db: # create database for user if the user hasn't made any votes db[session.user.handle] = {} uservotingdata = db[session.user.handle] echo(term.clear() + term.blue + '>>' + term.white + 'questions availible\r\n' + term.blue + '---------------------\r\n\r\n' + term.white) for i in range(0, len(questions)): if (index[i], 0) in uservotingdata: echo( term.green + '*' ) # prints out a star to show that the user already voted on this question echo(term.magenta + '(' + term.cyan + str(i) + term.magenta + ') ' + term.white + questions[i] + '\r\n') counter = counter + 1 # if the list of questions is longer than the screen height, display a press enter prompt if counter > term.height - 7: counter = 0 waitprompt() echo(term.move_x(0) + term.clear_eol + term.move_up) echo(term.bold_black + '* = already voted\r\n\r\n' + term.normal) while 1: echo(term.magenta + '\rselect one of the questions above or press enter to return: ') le = LineEditor(30) le.colors['highlight'] = term.cyan inp = le.read() if inp.isnumeric() and int(inp) < len(questions): return int(inp) else: return 999 # 999 in this case means that no valid option was chosen.. break loop.
def prompt_recipient(term, msg, colors, public=True): """ Prompt for recipient of message. """ xpos = max(0, (term.width // 2) - (80 // 2)) echo(term.move_x(xpos) + term.clear_eos) echo(u'Enter handle{0}.\r\n'.format( u', empty to address to all' if public else u'')) echo(term.move_x(xpos) + ':: ') inp = LineEditor(username_max_length, msg.recipient, colors={ 'highlight': colors['backlight'] }).read() if inp is None: echo(u''.join((term.move_x(xpos), colors['highlight']('Canceled.'), term.clear_eol))) term.inkey(1) return False elif not inp.strip(): # empty, recipient is None msg.recipient = None if public: return True return False inp = inp.strip() # validate/find user userlist = list_users() if inp in userlist: # exact match, msg.recipient = inp echo(u'\r\n') return True # nearest match for match in difflib.get_close_matches(inp.strip(), userlist): echo(u''.join( (term.move_x(xpos), u'{0} [yn]'.format(colors['highlight'](match)), term.clear_eol, u' ?\b\b'))) while True: inp = term.inkey() if inp.code == term.KEY_ESCAPE: # escape/cancel return False elif inp.lower() == u'y': # accept match msg.recipient = match echo(u'\r\n') return True elif inp.lower() == u'n': # next match break echo(u''.join( (term.move_x(xpos), colors['highlight']('No match.'), term.clear_eol))) term.inkey(1) return False
def do_cmd(term): session = getsession() sep_ok = getattr(term, color_secondary)(u'::') sep_bad = getattr(term, color_primary)(u'::') colors = {'highlight': getattr(term, color_primary)} echo(u'\r\n\r\n i hope you know glftpd cmds :)' ) # feel free to change these echoes to personalize your installation echo(u'\r\n\r\n if you dont, type quit') echo( u'\r\n\r\n basically all this is good for at the moment is for msg and request' ) echo(u'\r\n\r\n e.g \'msg kniffy hi\' or \'request coolthing -for:<you>\'') for _ in range(max_attempts): echo(u'\r\n\r\n{sep} tYPE cMD -> '.format(sep=sep_ok)) handle = LineEditor(max_length, colors=colors).read() or u'' if handle.strip() == u'': continue # user says goodbye if handle.lower() in bye_u: return else: # do cmd person = session.user.handle # session.user.handle = person ftps = FTP_TLS() #ftps.set_debuglevel(2) # if you broke something, uncomment this (run it directly, not from eggdrop) ftps.connect( '127.0.0.1', '1234') # enter your server and port within the quotes ftps.login( 'cmd', '<make this a non-sysop user please>' ) # enter your user and pass within the quotes (remember, not a user with privs) # ftps.login(person, auth) ftps.prot_p() ftps.sendcmd('site ' + handle) echo(u'\r\n\r\n cmd sent') ftps.quit()
def prompt_subject(term, msg, colors): """ Prompt for subject of message. """ xpos = max(0, (term.width // 2) - (80 // 2)) echo(u''.join((term.move_x(xpos), term.clear_eos, u'Enter Subject.\r\n', term.move_x(xpos), u':: '))) inp = LineEditor(subject_max_length, msg.subject, colors={ 'highlight': colors['backlight'] }).read() if inp is None or not inp.strip(): echo(u''.join((term.move_x(xpos), colors['highlight']('Canceled.'), term.clear_eol))) term.inkey(1) return False msg.subject = inp.strip() return True
def more(cont=False): """ Returns True if user 'q'uit; otherwise False when prompting is complete (moar/next/whatever) """ from x84.bbs import echo, getch, getterminal, LineEditor, DBProxy prompt_key = u'\r\n\r\nENtER BBS iD: ' msg_badkey = u'\r\n\r\nbbS id iNVAliD!' term = getterminal() prompt = u', '.join(fancy_blue(char, blurb) for char, blurb in (('i', 'NfO',), ('a', 'dd',), ('c', 'OMMENt',), ('r', 'AtE',), ('t', 'ElNEt',), ('v', 'ANSi'), ('q', 'Uit',))) if cont: prompt += u', ' + fancy_blue(' ', 'more') prompt += u': ' while True: echo(u'\r\n') echo(u'\r\n'.join(term.wrap(text=prompt, width=(term.width - (term.width / 3))))) inp = getch() if inp in (u'q', 'Q'): return True elif inp is not None and type(inp) is not int: if cont and inp == u' ': echo(u'\r\n\r\n') return False if inp.lower() in u'acrtviACRTVI': # these keystrokes require a bbs key argument, # prompt the user for one echo(prompt_key) key = LineEditor(5).read() if (key is None or 0 == len(key.strip()) or not key in DBProxy('bbslist')): echo(msg_badkey) continue process_keystroke(inp, key)
def main(): term = getterminal() session = getsession() banner() while True: session.activity = 'Viewing automsg' inp = term.inkey() if inp.lower() in (u'n', 'q') or inp.code == term.KEY_ENTER: return if inp.lower() == u'y': session.activity = 'Writing automsg' echo(term.move(12, 31)) echo(term.bold_white(session.user.handle)) echo((u' ' * 7)) echo(term.move(21, 0) + term.clear_eol) for row in range(1, 4): echo(term.move(15 + row, 5)) echo(u' ' * 57) msg = [] for row in range(1, 4): echo(term.move(15 + row, 5)) le = LineEditor(70) le.colors['highlight'] = term.white msg.append(le.read()) ask(u'submit your text as a public message? ') while True: inp = term.inkey() if inp.lower() == u'n': return if inp == 'y' or inp == 'Y': echo(term.move(21, 0) + term.clear_eol) with codecs.open(get_datafile_path(), 'w', 'utf-8') as fo: fo.write('\n'.join([session.user.handle] + msg)) fo.close() return
def do_intro_art(term, session): """ Display random art file, prompt for quick login. Bonus: allow chosing other artfiles with '<' and '>'. """ editor_colors = {'highlight': term.black_on_red} # set syncterm font, if any if syncterm_font and term._kind.startswith('ansi'): echo(syncterm_setfont(syncterm_font)) index = int(time.time()) % len(art_files) dirty = True echo(u'\r\n') while True: session.activity = 'top' if session.poll_event('refresh') or dirty: display_intro(term, index) display_prompt(term) dirty = False dirty = True inp = LineEditor(1, colors=editor_colors).read() if inp is None or inp.lower() == u'y': # escape/yes: quick login return True elif inp.lower() == u'n': break if len(inp) == 1: echo(u'\b') if inp == u'!': echo(u'\r\n' * 3) gosub('charset') dirty = True elif inp == u'<': index -= 1 elif inp == u'>': index += 1 else: dirty = False
def do_intro_art(term, session): """ Display random art file, prompt for quick login. Bonus: allow chosing other artfiles with '<' and '>'. """ # set syncterm font, if any if syncterm_font and term.kind.startswith('ansi'): echo(syncterm_setfont(syncterm_font)) index = int(time.time()) % len(art_files) dirty = True echo(u'\r\n') while True: session.activity = 'top' if session.poll_event('refresh') or dirty: display_intro(term, index) display_prompt(term) dirty = False dirty = True inp = LineEditor(1, colors={'highlight': term.normal}).read() if inp is None or inp.lower() == u'y': # escape/yes: quick login return True # issue #242 : set 'N' as default, by adding a check for an empty # unicode string. elif inp.lower() in (u'n', u'\r', u'\n', u''): break if len(inp) == 1: echo(u'\b') if inp == u'!': echo(u'\r\n' * 3) gosub('charset') dirty = True elif inp == u'<': index -= 1 elif inp == u'>': index += 1 else: dirty = False
def main(): term = getterminal() session = getsession() banner() while True: session.activity = 'Viewing automsg' inp = term.inkey() if inp.lower() in (u'n', 'q') or inp.code == term.KEY_ENTER: return if inp.lower() == u'y': session.activity = 'Writing automsg' echo(term.move(12, 31)) echo(term.bold_white(session.user.handle)) echo((u' ' * 7)) echo(term.move(21, 0) + term.clear_eol) for row in range (1, 4): echo(term.move(15 + row, 5)) echo(u' ' * 57) msg = [] for row in range (1, 4): echo(term.move(15 + row, 5)) le = LineEditor(70) le.colors['highlight'] = term.white msg.append(le.read()) ask(u'submit your text as a public message? ') while 1: inp = term.inkey() if inp.lower() == u'n': return if inp == 'y' or inp == 'Y': echo(term.move(21, 0) + term.clear_eol) with codecs.open(get_datafile_path(), 'w', 'utf-8') as fo: fo.write('\n'.join([session.user.handle] + msg)) fo.close() return
def prompt_subject(term, msg, colors): """ Prompt for subject of message. """ xpos = max(0, (term.width // 2) - (80 // 2)) echo(u''.join((term.move_x(xpos), term.clear_eos, u'Enter Subject.\r\n', term.move_x(xpos), u':: '))) inp = LineEditor(subject_max_length, msg.subject, colors={'highlight': colors['backlight']} ).read() if inp is None or not inp.strip(): echo(u''.join((term.move_x(xpos), colors['highlight']('Canceled.'), term.clear_eol))) term.inkey(1) return False msg.subject = inp.strip() return True
def rate_bbs(key): """ Prompt user to rate a bbs. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getsession, getterminal, echo, LineEditor, DBProxy from x84.bbs import getch session, term = getsession(), getterminal() prompt_rating = u'\r\n\r\nRAtE 0.0 - 4.0: ' prompt_chg = u'\r\n\r\nChANGE EXiStiNG ? [yn] ' msg_invalid = u'\r\n\r\niNVAlid ENtRY.\r\n' echo(term.move(term.height, 0) + '\r\n') echo(prompt_rating) s_rating = LineEditor(3).read() if s_rating is None or 0 == len(s_rating.strip()): return try: f_rating = float(s_rating) except ValueError: echo(msg_invalid) return if f_rating < 0 or f_rating > 4: echo(msg_invalid) return entry = (session.handle, f_rating) ratings = DBProxy('bbslist', 'ratings') ratings.acquire() if session.handle in (_handle for (_handle, _rating) in ratings[key]): echo(prompt_chg) if getch() not in (u'y', u'Y'): ratings.release() return # re-define list without existing entry, + new entry ratings[key] = [(__handle, __rating) for (__handle, __rating) in ratings[key] if session.handle != __handle] + [entry] ratings.release() return # re-define as existing list + new entry ratings[key] = ratings[key] + [entry] ratings.release()
def say_something(term, session): """ Prompt user to post a 'oneliner' entry. """ # use same line as previous prompt, clearing it first, echo(term.move_x(0) + term.clear_eol) colors = {'highlight': term.red_reverse} xpos = max((term.width / 2) - ((MAX_MSGLEN / 2) + 3), 0) echo(term.move_x(xpos)) if MIN_ELAPSED: lastliner = session.user.get('lastliner', 0) if lastliner and time.time() - lastliner > MIN_ELAPSED: echo(term.red_bold("You've said enough already!")) term.inkey(timeout=1) echo(term.move_x(0)) # only re-draw prompt (user canceled) return False echo(term.move_x(xpos)) echo(term.red('say ') + term.bold_red('>') + u' ') inp = LineEditor(MAX_MSGLEN, colors=colors).read() if not inp or not len(inp.strip()): # canceled echo(term.move_x(0) + term.clear_eol) return False echo(term.move_x(xpos) + term.clear_eol) session.user['lastliner'] = time.time() # optionally post to shroo.ms 'global oneliners' if shroo_ms_enabled: echo(term.red_reverse('Burning, please wait ...')) return post_shroo_ms(message=inp, username=session.user.handle) # or, post locally add_oneline(session=session, message=inp.strip()) return True
def do_select_encoding(term, session): editor_colors = {'highlight': term.black_on_green} dirty = True while True: if session.poll_event('refresh') or dirty: vertical_padding = 2 if term.height >= 24 else 0 display_banner(filepattern=art_file, encoding=art_encoding, vertical_padding=vertical_padding) display_prompt(term) 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'')) dirty = False inp = LineEditor(1, colors=editor_colors).read() if inp is None or inp.lower() == 'd': break elif len(inp) == 1: # position cursor for next call to LineEditor() echo(u'\b') if inp.lower() == u'u' and session.encoding != 'utf8': session.encoding = 'utf8' dirty = True elif inp.lower() == 'c' and session.encoding != 'cp437': session.encoding = 'cp437' dirty = True
def prompt_recipient(term, msg, colors, public=True): """ Prompt for recipient of message. """ xpos = max(0, (term.width // 2) - (80 // 2)) echo(term.move_x(xpos) + term.clear_eos) echo(u"Enter handle{0}.\r\n".format(u", empty to address to all" if public else u"")) echo(term.move_x(xpos) + ":: ") inp = LineEditor(username_max_length, msg.recipient, colors={"highlight": colors["backlight"]}).read() if inp is None: echo(u"".join((term.move_x(xpos), colors["highlight"]("Canceled."), term.clear_eol))) term.inkey(1) return False elif not inp.strip(): # empty, recipient is None msg.recipient = None if public: return True return False inp = inp.strip() # validate/find user userlist = list_users() if inp in userlist: # exact match, msg.recipient = inp echo(u"\r\n") return True # nearest match for match in difflib.get_close_matches(inp.strip(), userlist): echo(u"".join((term.move_x(xpos), u"{0} [yn]".format(colors["highlight"](match)), term.clear_eol, u" ?\b\b"))) while True: inp = term.inkey() if inp.code == term.KEY_ESCAPE: # escape/cancel return False elif inp.lower() == u"y": # accept match msg.recipient = match echo(u"\r\n") return True elif inp.lower() == u"n": # next match break echo(u"".join((term.move_x(xpos), colors["highlight"]("No match."), term.clear_eol))) term.inkey(1) return False
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 prompt_tags(tags): """ Prompt for and return valid tags from TAGDB. """ # pylint: disable=R0914,W0603 # Too many local variables # Using the global statement from x84.bbs import DBProxy, echo, getterminal, getsession from x84.bbs import Ansi, LineEditor, getch session, term = getsession(), getterminal() tagdb = DBProxy('tags') global FILTER_PRIVATE while True: # Accept user input for a 'search tag', or /list command # echo(u"\r\n\r\nENtER SEARCh %s, COMMA-dEliMitEd. " % ( term.red('TAG(s)'),)) echo(u"OR '/list', %s%s\r\n : " % ( (term.yellow_underline('^x') + u':autoscan ' if session.user.get('autoscan', False) else u''), term.yellow_underline('^a') + u':ll msgs ' + term.yellow_underline('Esc') + u':quit',)) width = term.width - 6 sel_tags = u', '.join(tags) while len(Ansi(sel_tags)) >= (width - 8): tags = tags[:-1] sel_tags = u', '.join(tags) lne = LineEditor(width, sel_tags) echo(lne.refresh()) while not lne.carriage_returned: inp = getch() if inp in (unichr(27), term.KEY_EXIT): return None if inp in (unichr(24),): # ^A:all return set() if inp in (unichr(1),): # ^X:autoscan return session.user.get('autoscan', set()) else: echo(lne.process_keystroke(inp)) if lne.carriage_returned: inp_tags = lne.content if (inp_tags is None or 0 == len(inp_tags) or inp_tags.strip().lower() == '/quit'): return set() elif inp_tags.strip().lower() == '/list': # list all available tags, and number of messages echo(term.normal) echo(u'\r\n\r\nTags: \r\n') all_tags = sorted(tagdb.items()) if 0 == len(all_tags): echo(u'None !'.center(term.width / 2)) else: echo(Ansi(u', '.join(([u'%s(%s)' % ( term.red(tag), term.yellow(str(len(msgs))),) for (tag, msgs) in all_tags]))).wrap(term.width - 2)) continue elif (inp_tags.strip().lower() == '/nofilter' and 'sysop' in session.user.groups): # disable filtering private messages FILTER_PRIVATE = False continue echo(u'\r\n') # search input as valid tag(s) tags = set([_tag.strip().lower() for _tag in inp_tags.split(',')]) for tag in tags.copy(): if not tag in tagdb: tags.remove(tag) echo(u"\r\nNO MESSAGES With tAG '%s' fOUNd." % ( term.red(tag),)) return tags