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 get_oltxt(): """ Return unicode terminal string of oneliners. """ import time from x84.bbs import getterminal, DBProxy, timeago, decode_pipe term = getterminal() colors = (term.bright_white, term.cyan, term.white) hist = [(int(k), v) for (k, v) in DBProxy('oneliner').items()] hist.sort(_sort_oneliner) output = list() for idx, onel in hist[BUF_HISTORY * -1:]: color = colors[int(idx) % len(colors)] atime = timeago(time.time() - time.mktime( time.strptime(onel['timestamp'], '%Y-%m-%d %H:%M:%S'))).strip() if onel.get('fake', False): alias = term.bold_red(u'x') + color(onel['alias']) else: alias = color(onel['alias']) output.append(u''.join(( term.bold_white('('), color(atime), term.bold_black(u' ago'), term.bold_black(u' '), alias, term.bold_black(u'/'), onel['bbsname'], term.bold_white(u')'), color(u': '), decode_pipe(onel['oneliner']), ))) return output[(BUF_HISTORY * -1):]
def generate_recent_oneliners(term, n_liners, offset): """ return string of all oneliners, its vert. hieght and adj. offset. """ # generate a color palette palette = [getattr(term, _color) for _color in color_palette] # for relative 'time ago' now = time.time() # fetch all liners in database, sorted ascending by time oneliners = sorted(DBProxy('oneliner').values(), key=keysort_by_datetime) # decide the start/end by given offset, to allow paging, bounds check to # ensure that it does not scroll out of range offset = min(offset, len(oneliners)) start, end = len(oneliners) - (n_liners + offset), len(oneliners) - offset if start < 0: offset += start start, end = 0, end - start if offset < 0: start, end = start + offset, end + offset offset = 0 # build up one large text field; refresh is smoother when # all text is received as a single packet final_text_field = u'' count = 0 for count, oneliner in enumerate(oneliners[start:end]): _color = palette[count % len(palette)] ago = get_timeago(now, oneliner.get('timestamp')) alias = oneliner.get('alias', 'anonymous') bbsname = ('' if not shroo_ms_enabled else oneliner.get('bbsname', 'untergrund')) content = (oneliner.get('oneliner', u'')) max_msglen = MAX_MSGLEN if len(alias) > username_max_length: max_msglen -= (len(alias) - username_max_length) for _ in range(10): left_part = u'{0}: {1} '.format( alias.rjust(username_max_length), term.ljust(decode_pipe(content[:max_msglen]), max_msglen) ) right_part = '{0} {1}'.format(_color(bbsname.rjust(4)), ago) txt_field = left_part + right_part if term.length(txt_field) < term.width: break elif term.length(left_part) < term.width: txt_field = left_part break max_msglen -= 2 final_text_field = u''.join(( final_text_field, term.move_x(max(0, (term.width / 2) - 45)), txt_field, term.clear_eol, u'\r\n') ) # return text, vertical height, and adjusted offset return final_text_field, count, offset
def generate_recent_oneliners(term, n_liners, offset): """ return string of all oneliners, its vert. hieght and adj. offset. """ # generate a color palette palette = [getattr(term, _color) for _color in color_palette] # for relative 'time ago' now = time.time() # fetch all liners in database, sorted ascending by time oneliners = sorted(DBProxy('oneliner').values(), key=keysort_by_datetime) # decide the start/end by given offset, to allow paging, bounds check to # ensure that it does not scroll out of range offset = min(offset, len(oneliners)) start, end = len(oneliners) - (n_liners + offset), len(oneliners) - offset if start < 0: offset += start start, end = 0, end - start if offset < 0: start, end = start + offset, end + offset offset = 0 # build up one large text field; refresh is smoother when # all text is received as a single packet final_text_field = u'' count = 0 for count, oneliner in enumerate(oneliners[start:end]): _color = palette[count % len(palette)] ago = get_timeago(now, oneliner.get('timestamp')) alias = oneliner.get('alias', 'anonymous') bbsname = ('' if not shroo_ms_enabled else oneliner.get( 'bbsname', 'untergrund')) content = (oneliner.get('oneliner', u'')) max_msglen = MAX_MSGLEN if len(alias) > username_max_length: max_msglen -= (len(alias) - username_max_length) for _ in range(10): left_part = u'{0}: {1} '.format( alias.rjust(username_max_length), term.ljust(decode_pipe(content[:max_msglen]), max_msglen)) right_part = '{0} {1}'.format(_color(bbsname.rjust(4)), ago) txt_field = left_part + right_part if term.length(txt_field) < term.width: break elif term.length(left_part) < term.width: txt_field = left_part break max_msglen -= 2 final_text_field = u''.join( (final_text_field, term.move_x(max(0, (term.width / 2) - 45)), txt_field, term.clear_eol, u'\r\n')) # return text, vertical height, and adjusted offset return final_text_field, count, offset
def display_message(session, term, msg_index, colors): """ Format message of index ``idx``. """ color_handle = lambda handle: (colors["highlight"](handle) if handle == session.user.handle else handle) msg = get_msg(msg_index) txt_sent = msg.stime.replace(tzinfo=dateutil.tz.tzlocal()).astimezone(dateutil.tz.tzutc()).strftime(TIME_FMT) txt_sentago = colors["highlight"](timeago((datetime.datetime.now() - msg.stime).total_seconds()).strip()) txt_to = color_handle(msg.recipient) txt_private = colors["highlight"](" (private)") if not "public" in msg.tags else u"" txt_from = color_handle(msg.author) txt_tags = u", ".join((quote(tag, colors) for tag in msg.tags)) txt_subject = colors["highlight"](msg.subject) txt_body = decode_pipe(msg.body) txt_breaker = ("-" if session.encoding == "ansi" else u"\u2500") * min(80, term.width) msg_txt = ( u"\r\n{txt_breaker}\r\n" u" from: {txt_from}\r\n" u" to: {txt_to}{txt_private}\r\n" u" sent: {txt_sent} ({txt_sentago} ago)\r\n" u" tags: {txt_tags}\r\n" u"subject: {txt_subject}\r\n" u"\r\n" u"{txt_body}\r\n".format( txt_breaker=txt_breaker, txt_from=txt_from, txt_to=txt_to, txt_sent=txt_sent, txt_sentago=txt_sentago, txt_tags=txt_tags, txt_subject=txt_subject, txt_body=txt_body, txt_private=txt_private, ) ) do_mark_as_read(session, [msg_index]) prompt_pager( content=msg_txt.splitlines(), line_no=0, width=min(80, term.width), colors=colors, breaker=u"- ", end_prompt=False, break_long_words=True, )
def main(quick=False): """ Script entry point. :param quick: When True, returns early if this news has already been read. :type quick: bool """ session, term = getsession(), getterminal() if not os.path.exists(news_file): log.warn('No news file, {0}'.format(news_file)) echo(u'\r\n\r\n' + term.center(u'No news.').rstrip() + u'\r\n') return # return early if 'quick' is True and news is not new news_mtime = os.stat(news_file).st_mtime if quick and news_mtime < session.user.get('news_lastread', 0): return # set syncterm font, if any if syncterm_font and term._kind == 'ansi': echo(syncterm_setfont(syncterm_font)) session.activity = 'Reading news' # display banner line_no = display_banner(filepattern=art_file, encoding=art_encoding) # retrieve news_file contents (decoded as utf8) news = decode_pipe(codecs.open( news_file, 'rb', news_file_encoding).read() ).splitlines() echo(u'\r\n\r\n') # display file contents, decoded, using a command-prompt pager. prompt_pager(content=news, line_no=line_no + 2, colors={'highlight': term.yellow, 'lowlight': term.green, }, width=80) # update user's last-read time of news. session.user['news_lastread'] = time.time()
def main(quick=False): """ Script entry point. :param bool quick: When True, returns early if this news has already been read. """ session, term = getsession(), getterminal() if not os.path.exists(news_file): log.warn('No news file, {0}'.format(news_file)) echo(u'\r\n\r\n' + term.center(u'No news.').rstrip() + u'\r\n') return # return early if 'quick' is True and news is not new news_mtime = os.stat(news_file).st_mtime if quick and news_mtime < session.user.get('news_lastread', 0): return # set syncterm font, if any if syncterm_font and term.kind == 'ansi': echo(syncterm_setfont(syncterm_font)) session.activity = 'Reading news' # display banner line_no = display_banner(filepattern=art_file, encoding=art_encoding) # retrieve news_file contents (decoded as utf8) news = decode_pipe( codecs.open(news_file, 'rb', news_file_encoding).read()).splitlines() echo(u'\r\n\r\n') # display file contents, decoded, using a command-prompt pager. prompt_pager(content=news, line_no=line_no + 2, colors={ 'highlight': term.yellow, 'lowlight': term.green, }, width=min(80, term.width)) # update user's last-read time of news. session.user['news_lastread'] = time.time()
def display_message(session, term, msg_index, colors): """ Format message of index ``idx``. """ color_handle = lambda handle: (colors['highlight'](handle) if handle == session.user.handle else handle) msg = get_msg(msg_index) txt_sent = msg.stime.replace(tzinfo=dateutil.tz.tzlocal()).astimezone( dateutil.tz.tzutc()).strftime(TIME_FMT) txt_sentago = colors['highlight'](timeago( (datetime.datetime.now() - msg.stime).total_seconds()).strip()) txt_to = color_handle(msg.recipient) txt_private = (colors['highlight'](' (private)') if not 'public' in msg.tags else u'') txt_from = color_handle(msg.author) txt_tags = u', '.join((quote(tag, colors) for tag in msg.tags)) txt_subject = colors['highlight'](msg.subject) txt_body = decode_pipe(msg.body) txt_breaker = ('-' if session.encoding == 'ansi' else u'\u2500') * min( 80, term.width) msg_txt = (u'\r\n{txt_breaker}\r\n' u' from: {txt_from}\r\n' u' to: {txt_to}{txt_private}\r\n' u' sent: {txt_sent} ({txt_sentago} ago)\r\n' u' tags: {txt_tags}\r\n' u'subject: {txt_subject}\r\n' u'\r\n' u'{txt_body}\r\n'.format(txt_breaker=txt_breaker, txt_from=txt_from, txt_to=txt_to, txt_sent=txt_sent, txt_sentago=txt_sentago, txt_tags=txt_tags, txt_subject=txt_subject, txt_body=txt_body, txt_private=txt_private)) do_mark_as_read(session, [msg_index]) prompt_pager(content=msg_txt.splitlines(), line_no=0, width=min(80, term.width), colors=colors, breaker=u'- ', end_prompt=False, break_long_words=True)