Example #1
0
def view_ansi(key):
    """ fetch and view a bbs ansi. They're not often very good ...
    """
    from x84.bbs import getterminal, echo, DBProxy, ini, getch, from_cp437
    term = getterminal()
    ansiurl = DBProxy('bbslist')[key]['ansi']
    logger = logging.getLogger()
    echo(u'\r\n\r\n')
    if ansiurl is not None and 0 != len(ansiurl) and ansiurl != 'NONE':
        usernm = ini.CFG.get('bbs-scene', 'user')
        passwd = ini.CFG.get('bbs-scene', 'pass')
        req = requests.get(ansiurl, auth=(usernm, passwd))
        if req.status_code != 200:
            echo(u'\r\n\r\nrequest failed,\r\n')
            echo(u'%r' % (req.content, ))
            echo(u'\r\n\r\n(code : %s).\r\n' % (req.status_code, ))
            echo(u'\r\nPress any key ..')
            logger.warn('ansiurl request failed: %s' % (ansiurl, ))
            getch()
            return
        ansi_txt = from_cp437(sauce.SAUCE(data=req.content).__str__())
        echo(ansi_txt)
    else:
        echo('no ansi available (%s)' % (ansiurl, ))
    # move to bottom of screen and getch
    echo(u''.join((term.move(term.height,
                             0), term.normal, u'\r\n\r\nPRESS ANY kEY ...'), ))
    getch()
Example #2
0
def view_ansi(key):
    """ fetch and view a bbs ansi. They're not often very good ...
    """
    from x84.bbs import getterminal, echo, DBProxy, ini, getch, from_cp437
    term = getterminal()
    ansiurl = DBProxy('bbslist')[key]['ansi']
    logger = logging.getLogger()
    echo(u'\r\n\r\n')
    if ansiurl is not None and 0 != len(ansiurl) and ansiurl != 'NONE':
        usernm = ini.CFG.get('bbs-scene', 'user')
        passwd = ini.CFG.get('bbs-scene', 'pass')
        req = requests.get(ansiurl, auth=(usernm, passwd))
        if req.status_code != 200:
            echo(u'\r\n\r\nrequest failed,\r\n')
            echo(u'%r' % (req.content,))
            echo(u'\r\n\r\n(code : %s).\r\n' % (req.status_code,))
            echo(u'\r\nPress any key ..')
            logger.warn('ansiurl request failed: %s' % (ansiurl,))
            getch()
            return
        ansi_txt = from_cp437(sauce.SAUCE(data=req.content).__str__())
        echo(ansi_txt)
    else:
        echo('no ansi available (%s)' % (ansiurl,))
    # move to bottom of screen and getch
    echo(u''.join((
        term.move(term.height, 0),
        term.normal,
        u'\r\n\r\nPRESS ANY kEY ...'),))
    getch()
Example #3
0
def banner():
    """ Return banner """
    from x84.bbs import getterminal, Ansi, from_cp437
    import os
    term = getterminal()
    output = u''
    output += u'\r\n\r\n'
    if term.width >= 78:
        output += term.home + term.normal + term.clear
        # xzip's ansi is line-clean, center-align with terminal width,
        artfile = os.path.join(os.path.dirname(__file__), 'ol.ans')
        art = open(artfile).readlines()
        max_ans = max([len(Ansi(from_cp437(line.rstrip()))) for line in art])
        for line in art:
            padded = Ansi(from_cp437(line.rstrip())).center(max_ans)
            output += term.normal + term.blue  # minor fix for this art ;/
            output += Ansi(padded).center(term.width).rstrip() + '\r\n'
    return output + term.normal
Example #4
0
def banner():
    """ Return banner """
    from x84.bbs import getterminal, Ansi, from_cp437
    import os
    term = getterminal()
    output = u''
    output += u'\r\n\r\n'
    if term.width >= 78:
        output += term.home + term.normal + term.clear
        # xzip's ansi is line-clean, center-align with terminal width,
        artfile = os.path.join(os.path.dirname(__file__), 'ol.ans')
        art = open(artfile).readlines()
        max_ans = max([len(Ansi(from_cp437(line.rstrip()))) for line in art])
        for line in art:
            padded = Ansi(from_cp437(line.rstrip())).center(max_ans)
            output += term.normal + term.blue  # minor fix for this art ;/
            output += Ansi(padded).center(term.width).rstrip() + '\r\n'
    return output + term.normal
Example #5
0
def get_icon(weather):
    from x84.bbs import from_cp437

    # attribute 'WeatherIcon' is mapped to one of the {}.ans files
    icon = int(weather['WeatherIcon'])
    artfile = os.path.join(weather_icons, '{}.ans'.format(icon))
    if not os.path.exists(artfile):
        warnings.warn('{} not found'.format(artfile))
        art = u'[ .{:>2}. ]'.format(icon)
    else:
        art = [from_cp437(line.rstrip())
               for line in open(artfile, 'r').readlines()]
    return art
Example #6
0
File: ol.py Project: donfanning/x84
def banner():
    """ Return banner """
    from x84.bbs import getterminal, from_cp437
    import os
    term = getterminal()
    output = u''
    output += u'\r\n\r\n' + term.normal
    if term.width >= 78:
        output += term.home + term.normal + term.clear
        # xzip's ansi is line-clean, center-align with terminal width,
        artfile = os.path.join(os.path.dirname(__file__), 'ol.ans')
        art = [line.rstrip()
               for line in from_cp437(open(artfile).read()).splitlines()]
        max_ans = max([term.length(line) for line in art])
        for line in art:
            output += term.center(term.ljust(line.rstrip(), max_ans)).rstrip() + '\r\n'
    return output + term.normal
Example #7
0
File: weather.py Project: hick/x84
def display_panel(weather, column, centigrade):
    from x84.bbs import getterminal, echo, from_cp437
    term = getterminal()

    # display day of week,
    day_txt = term.bold(weather.get('DayCode', u'').center(panel_width))
    echo(term.move(top_margin, column))
    echo(day_txt)

    # display WeatherIcon ansi art,
    for row_idx, art_row in enumerate(get_icon(weather)):
        echo(term.move(row_idx + top_margin + 1, column))
        echo(art_row)
    echo(term.normal)

    degree = from_cp437(''.join([chr(248)]))
    # display days' high,
    echo(term.move(panel_height + top_margin + 1, column))
    high = weather.get('High_Temperature', None)
    high, conv = temp_conv(high, centigrade)
    echo(u'High: {high:>2}{degree}{conv}'.format(high=high,
                                                 degree=degree,
                                                 conv=conv).rjust(panel_width -
                                                                  3))

    # display days' low,
    echo(term.move(panel_height + top_margin + 2, column))
    low = weather.get('Low_Temperature', None)
    low, conv = temp_conv(low, centigrade)
    echo(u'Low: {low:>2}{degree}{conv}'.format(low=low,
                                               degree=degree,
                                               conv=conv).rjust(panel_width -
                                                                3))

    # display short txt,
    weather_txt = unicode(weather.get('TXT_Short', ''))
    txt_wrapped = textwrap.wrap(weather_txt, (panel_width - 2))

    for row_idx, txt_row in enumerate(txt_wrapped):
        row_loc = panel_height + top_margin + row_idx + 4
        echo(term.move(row_loc, column + 1))
        echo(txt_row.center(panel_width - 2))
    return row_loc
Example #8
0
def display_panel(weather, column, centigrade):
    from x84.bbs import getterminal, echo, from_cp437
    term = getterminal()

    # display day of week,
    day_txt = term.bold(weather.get('DayCode', u'').center(panel_width))
    echo(term.move(top_margin, column))
    echo(day_txt)

    # display WeatherIcon ansi art,
    for row_idx, art_row in enumerate(get_icon(weather)):
        echo(term.move(row_idx + top_margin + 2, column))
        echo(art_row)
    echo(term.normal)

    degree = from_cp437(''.join([chr(248)]))
    # display days' high,
    echo(term.move(panel_height + top_margin + 2, column))
    high = weather.get('High_Temperature', None)
    high, conv = temp_conv(high, centigrade)
    echo(u'High: {high:>2}{degree}{conv}'.format(
        high=high, degree=degree, conv=conv).rjust(panel_width - 3))

    # display days' low,
    echo(term.move(panel_height + top_margin + 3, column))
    low = weather.get('Low_Temperature', None)
    low, conv = temp_conv(low, centigrade)
    echo(u'Low: {low:>2}{degree}{conv}'.format(
        low=low, degree=degree, conv=conv).rjust(panel_width - 3))

    # display short txt,
    weather_txt = unicode(weather.get('TXT_Short', ''))
    txt_wrapped = textwrap.wrap(weather_txt, (panel_width - 2))

    row_loc = panel_height + top_margin + 5
    for row_idx, txt_row in enumerate(txt_wrapped):
        row_loc = panel_height + top_margin + row_idx + 5
        echo(term.move(row_loc, column + 1))
        echo(txt_row.center(panel_width - 2))
    return row_loc
Example #9
0
def redraw(pager):
    """ Returns string suitable for refreshing screen. """
    from x84.bbs import getsession, getterminal, from_cp437
    import os
    # pylint: disable=W0603
    #         Using the global statement
    session, term = getsession(), getterminal()

    output = ''
    output += term.home + term.normal + term.clear
    artfile = os.path.join(os.path.dirname(__file__), 'art', 'news.ans')
    art = [line.rstrip()
        for line in from_cp437(open(artfile).read()).splitlines()]
    max_ans = max([term.length(line) for line in art])
    for line in art:
        output += term.center(term.ljust(line.rstrip(), max_ans)).rstrip() + '\r\n'


    title = u''.join((u']- ', term.bold_blue('PARtY NEWS'), ' [-',))
    footer = u''.join((u'-[ ',
                       term.blue_underline(u'Escape'), '/',
                       term.blue_underline(u'q'), term.bold_blue(u'uit '),
                       ((u'- ' + term.blue_underline(u'e')
                           + term.bold_blue(u'dit ')) if (
                               'sysop' in session.user.groups) else u''),
                           u']-',
    ))

    return u''.join((u'',
                         (output), u'',
                     u''.join((
                              u'' * pager.height,
                              pager.refresh(),
                              pager.border(),
                              pager.title(title),
                              pager.footer(footer))
                              ) if pager is not None else u'',))
Example #10
0
def display_weather(todays, weather, centigrade):
    """
    Display weather as vertical panels.

    Thanks to xzip, we now have a sortof tv-weather channel art :-)
    """
    from x84.bbs import getterminal, echo, from_cp437
    term = getterminal()

    echo(term.height * u'\r\n')
    echo(term.move(1, 1))
    at = term.yellow_bold('At')
    city = term.bold(todays.get('City', u''))
    state = todays.get('State', u'')
    if state:
        state = u', {}'.format(term.bold_yellow_reverse(state))
    dotdot = term.bold_black('...')
    echo(u'{at} {city}{state} {dotdot}'.format(
        at=at, city=city, state=state, dotdot=dotdot))
    bottom = 2
    for column in range(0, (term.width - panel_width), panel_width):
        try:
            day = weather.pop(0)
        except IndexError:
            break
        bottom = max(display_panel(day, column, centigrade), bottom)

    timenow = time.strftime('%I:%M%p', time.strptime(todays['Time'], '%H:%M'))
    temp, deg_conv = temp_conv(todays.get('Temperature', ''), centigrade)
    real_temp, deg_conv = temp_conv(todays.get('RealFeel', ''), centigrade)
    speed, spd_conv = speed_conv(todays.get('WindSpeed', ''), centigrade)
    degree = from_cp437(''.join([chr(248)]))

    current_0 = u'Current conditions at {timenow}'.format(timenow=timenow)
    current_1 = u'{w[WeatherText]}'.format(w=todays)
    current_2 = u'Temperature is {temp}{degree}{deg_conv}'.format(
        temp=temp, degree=degree, deg_conv=deg_conv)
    current_3 = u'' if real_temp == temp else (
        u'(feels like {real_temp}{degree}{deg_conv})'.format(
            real_temp=real_temp, degree=degree, deg_conv=deg_conv))
    current_4 = u'Winds {speed}{spd_conv} {w[WindDirection]}'.format(
        speed=speed, w=todays, spd_conv=spd_conv)
    current_5 = u'Humidity of {w[Humidity]}'.format(w=todays)

    wrapped = textwrap.wrap(
        u'{0}: {1}. {2} {3}, {4}, {5}.'.format(
            current_0, current_1, current_2, current_3,
            current_4, current_5), min(term.width - panel_width - 5, 40))
    row_num = 0

    art = get_icon(todays)
    for row_num, (row_txt, art_txt) in enumerate(
            itertools.izip_longest(wrapped, art)):
        echo(term.move(bottom + next_margin + row_num, 1))
        echo(art_txt)
        if row_txt:
            echo(term.move(bottom + next_margin + row_num, panel_width + 5))
            echo(term.normal)
            echo(row_txt + u'\r\n')
        else:
            echo(u'\r\n')
Example #11
0
def main():
    """ Main procedure. """
    # pylint: disable=R0914,W0141,R0912
    #         Too many local variables
    #         Used builtin function 'map'
    #         Too many branches
    from x84.bbs import getsession, getterminal, Ansi, echo, getch, from_cp437
    from x84.engine import __url__ as url
    import platform
    import random
    import sys
    import os
    session, term = getsession(), getterminal()
    session.activity = 'System Info'
    artfile = os.path.join(
        os.path.dirname(__file__),
        'art',
        'plant.ans',
    )
    system, _node, release, _version, machine, _processor = platform.uname()
    body = [
        u'AUthORS:',
        u'Johannes Lundberg',
        u'Jeffrey Quast',
        u'Wijnand Modderman-Lenstra',
        u'',
        u'ARtWORk:',
        u'spidy!food,',
        u'hellbeard!impure',
        u'\r\n',
        u'SYStEM: %s %s %s' % (system, release, machine),
        u'SOftWARE: X/84',
        url,
        u'\r\n',
        (platform.python_implementation() + u' ' +
         '-'.join(map(str, sys.version_info[3:]))) + u' ' +
        (platform.python_version()
         if hasattr(platform, 'python_implementation') else u'.'.join(
             map(str, sys.version_info[:3]))),
    ]
    melt_colors = ([term.normal] + [term.bold_blue] * 3 + [term.red] * 4 +
                   [term.bold_red] + [term.bold_white] + [term.normal] * 6 +
                   [term.blue] * 2 + [term.bold_blue] + [term.bold_white] +
                   [term.normal])
    art = from_cp437(open(artfile).read()) if os.path.exists(artfile) else u''
    otxt = list(art.splitlines())
    for num, line in enumerate(body):
        while num > len(otxt):
            otxt += [
                u'',
            ]
        otxt[num] = otxt[num][:int(term.width / 2.5)] + u' ' + line
    width = max([len(Ansi(line)) for line in otxt])
    height = len(otxt)
    num_stars = int((term.width * term.height) * .002)
    stars = dict([(n, (random.choice('\\|/-'),
                       float(random.choice(range(term.width))),
                       float(random.choice(range(term.height)))))
                  for n in range(num_stars)])
    melting = {}
    show_star = False
    tm_out, tm_min, tm_max, tm_step = 0.08, 0.01, 2.0, .01
    wind = (0.7, 0.1, 0.01, 0.01)

    def refresh():
        """ Refresh screen and return top-left (x, y) location. """
        echo(u'\r\n\r\n')
        if term.width < width:
            echo(u''.join((
                term.move(term.height, 0),
                u'\r\n\r\n',
                term.bold_red + 'screen too thin! (%s/%s)' % (
                    term.width,
                    width,
                ),
                u'\r\n\r\n',
                u'press any key...',
            )))
            getch()
            return (None, None)
        if term.height < height:
            echo(u''.join((
                term.move(term.height, 0),
                u'\r\n\r\n',
                term.bold_red + 'screen too short! (%s/%s)' %
                (term.height, height),
                u'\r\n\r\n',
                u'press any key...',
            )))
            getch()
            return (None, None)
        xloc = (term.width / 2) - (width / 2)
        yloc = (term.height / 2) - (height / 2)
        echo(u''.join((
            term.normal,
            (u'\r\n' + term.clear_eol) * term.height,
            u''.join([
                term.move(yloc + abs_y, xloc) + line
                for abs_y, line in enumerate(otxt)
            ]),
        )))
        return xloc, yloc

    txt_x, txt_y = refresh()
    if (txt_x, txt_y) == (None, None):
        return

    def char_at_pos(yloc, xloc, txt_y, txt_x):
        """ Return art (y, x) for location """
        return (u' ' if yloc - txt_y < 0 or yloc - txt_y >= height
                or xloc - txt_x < 0 or xloc - txt_x >= len(otxt[yloc - txt_y])
                else otxt[yloc - txt_y][xloc - txt_x])

    def iter_wind(xslope, yslope, xdir, ydir):
        """ An easterly Wind """
        xslope += xdir
        yslope += ydir
        if xslope <= 0.5:
            xdir = random.choice([0.01, 0.015, 0.02])
        elif xslope >= 1:
            xdir = random.choice([-0.01, -0.015, -0.02])
        if yslope <= -0.1:
            ydir = random.choice([0.01, 0.015, 0.02, 0.02])
        elif yslope >= 0.1:
            ydir = random.choice([-0.01, -0.015, -0.02])
        return xslope, yslope, xdir, ydir

    def iter_star(char, xloc, yloc):
        """ Given char and current position, apply wind and return new
        char and new position. """
        if char == '\\':
            char = '|'
        elif char == '|':
            char = '/'
        elif char == '/':
            char = '-'
        elif char == '-':
            char = '\\'
        xloc += wind[0]
        yloc += wind[1]
        if xloc < 1 or xloc > term.width:
            xloc = (1.0 if xloc > term.width else float(term.width))
            yloc = (float(random.choice(range(term.height))))
        if yloc < 1 or yloc > term.height:
            yloc = (1.0 if yloc > term.height else float(term.height))
            xloc = (float(random.choice(range(term.width))))
        return char, xloc, yloc

    def erase(star_idx):
        """ erase old star before moving .. """
        if show_star:
            _char, xloc, yloc = stars[star_idx]
            echo(''.join((
                term.move(int(yloc), int(xloc)),
                term.normal,
                char_at_pos(int(yloc), int(xloc), txt_y, txt_x),
            )))

    def melt():
        """ Iterate through all stars and phase through melt sequence. """
        def melted(yloc, xloc):
            """ shift melt, delete if dissapeared. """
            melting[(yloc, xloc)] -= 1
            if 0 == melting[(yloc, xloc)]:
                del melting[(yloc, xloc)]

        for (yloc, xloc), phase in melting.items():
            echo(''.join((
                term.move(yloc, xloc),
                melt_colors[phase - 1],
                char_at_pos(yloc, xloc, txt_y, txt_x),
            )))
            melted(yloc, xloc)

    def draw_star(star, xloc, yloc):
        """ draw star a (x, y) location """
        char = char_at_pos(int(yloc), int(xloc), txt_y, txt_x)
        if char != ' ':
            melting[(int(yloc), int(xloc))] = len(melt_colors)
        if show_star:
            echo(term.move(int(yloc), int(xloc)) + melt_colors[-1] + star)

    with term.hidden_cursor():
        while txt_x is not None and txt_y is not None:
            if session.poll_event('refresh'):
                num_stars = int(num_stars)
                stars = dict([(n, (random.choice('\\|/-'),
                                   float(random.choice(range(term.width))),
                                   float(random.choice(range(term.height)))))
                              for n in range(num_stars)])
                otxt = list(art.splitlines())
                for num, line in enumerate(body):
                    while num > len(otxt):
                        otxt += [
                            u'',
                        ]
                    otxt[num] = (otxt[num][:int(term.width / 2.5)] + u' ' +
                                 line)
                txt_x, txt_y = refresh()
                continue
            inp = getch(tm_out)
            if inp in (term.KEY_UP, 'k'):
                if tm_out >= tm_min:
                    tm_out -= tm_step
            elif inp in (term.KEY_DOWN, 'j'):
                if tm_out <= tm_max:
                    tm_out += tm_step
            elif inp in (term.KEY_LEFT, 'h'):
                if num_stars > 2:
                    num_stars = int(num_stars * .5)
                    stars = dict([(n,
                                   (random.choice('\\|/-'),
                                    float(random.choice(range(term.width))),
                                    float(random.choice(range(term.height)))))
                                  for n in range(num_stars)])
            elif inp in (term.KEY_RIGHT, 'l'):
                if num_stars < (term.width * term.height) / 4:
                    num_stars = int(num_stars * 1.5)
                    stars = dict([(n,
                                   (random.choice('\\|/-'),
                                    float(random.choice(range(term.width))),
                                    float(random.choice(range(term.height)))))
                                  for n in range(num_stars)])
            elif inp in (u'*', ) and not show_star:
                show_star = True
            elif inp in (u'*', ) and show_star:
                for star in stars:
                    erase(star)
                show_star = False
            elif inp is not None:
                echo(term.move(term.height, 0))
                break
            melt()
            for star_key, star_val in stars.items():
                erase(star_key)
                # pylint: disable=W0142
                #         Used * or ** magic
                stars[star_key] = iter_star(*star_val)
                draw_star(*stars[star_key])
            # pylint: disable=W0142
            #         Used * or ** magic
            wind = iter_wind(*wind)
Example #12
0
def main(host, port=None, encoding='cp437'):
    """
    Call script with argument host and optional argument port to connect to a
    telnet server. ctrl-^ to disconnect.
    """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    import telnetlib
    import struct
    from x84.bbs import getsession, getterminal, echo, getch, from_cp437
    import logging
    log = logging.getLogger()

    assert encoding in ('utf8', 'cp437')
    session, term = getsession(), getterminal()
    session.activity = 'connecting to %s' % (host, )
    port = int(port) if port is not None else 23
    telnet_client = telnetlib.Telnet()

    def callback_cmdopt(socket, cmd, opt):
        """ Callback for telnetlib.Telnet.set_option_negotiation_callback. """
        if cmd == telnetlib.WILL:
            if opt in (telnetlib.ECHO, telnetlib.SGA):
                socket.sendall(telnetlib.IAC + telnetlib.DO + opt)
        elif cmd == telnetlib.DO:
            if opt == telnetlib.SGA:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
            elif opt == telnetlib.TTYPE:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
                socket.sendall(telnetlib.IAC + telnetlib.SB + telnetlib.TTYPE +
                               IS + session.env.get('TERM') + chr(0) +
                               telnetlib.IAC + telnetlib.SE)
            elif opt == telnetlib.NAWS:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
                socket.sendall(telnetlib.IAC + telnetlib.SB + telnetlib.NAWS +
                               struct.pack('!HH', term.width, term.height) +
                               telnetlib.IAC + telnetlib.SE)
            else:
                socket.sendall(telnetlib.IAC + telnetlib.WONT + opt[0])
        elif cmd == telnetlib.SB:
            if opt[0] == telnetlib.TTYPE and opt[1] == SEND:
                socket.sendall(telnetlib.IAC + telnetlib.SB + telnetlib.TTYPE +
                               IS + session.env.get('TERM') + chr(0) +
                               telnetlib.IAC + telnetlib.SE)

    telnet_client.set_option_negotiation_callback(callback_cmdopt)

    echo(u"\r\n\r\nEscape character is 'ctrl-^.'")
    if not session.user.get('expert', False):
        getch(3)
    echo(u'\r\nTrying %s:%s... ' % (
        host,
        port,
    ))
    # pylint: disable=W0703
    #         Catching too general exception Exception
    try:
        telnet_client.open(host, port)
    except Exception as err:
        echo(term.bold_red('\r\n%s\r\n' % (err, )))
        echo(u'\r\n press any key ..')
        getch()
        return

    echo(u'\r\n... ')
    inp = session.read_event('input', timeout=0)
    echo(u'\r\nConnected to %s.' % (host, ))
    session.activity = 'connected to %s' % (host, )
    carriage_returned = False
    with term.fullscreen():
        while True:
            if encoding == 'cp437':
                try:
                    unistring = from_cp437(
                        telnet_client.read_very_eager().decode('iso8859-1'))
                except EOFError:
                    break
            else:
                unistring = telnet_client.read_very_eager().decode('utf8')
            if 0 != len(unistring):
                echo(unistring)
            if inp is not None:
                if inp == chr(30):  # ctrl-^
                    telnet_client.close()
                    echo(u'\r\n' + term.clear_el + term.normal)
                    break
                elif not carriage_returned and inp in (b'\x0d', b'\x0a'):
                    telnet_client.write(b'\x0d')
                    log.debug('send {!r}'.format(b'\x0d'))
                    carriage_returned = True
                elif carriage_returned and inp in (b'\x0a', b'\x00'):
                    carriage_returned = False
                elif inp is not None:
                    telnet_client.write(inp)
                    log.debug('send {!r}'.format(inp))
                    carriage_returned = False
            inp = session.read_event('input', timeout=KEY_POLL)
    echo(u'\r\nConnection closed.\r\n')
    echo(u''.join(('\r\n\r\n', term.clear_el, term.normal, 'press any key')))
    echo(u'\x1b[r')  # unset 'set scrolling region', sometimes set by BBS's
    session.flush_event('input')
    getch()
    return
Example #13
0
File: telnet.py Project: gofore/x84
def main(host, port=None, encoding="cp437"):
    """
    Call script with argument host and optional argument port to connect to a
    telnet server. ctrl-^ to disconnect.
    """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    import telnetlib
    from functools import partial
    from x84.bbs import getsession, getterminal, echo, getch, from_cp437, telnet
    import logging

    log = logging.getLogger()

    assert encoding in ("utf8", "cp437")
    session, term = getsession(), getterminal()
    session.activity = "connecting to %s" % (host,)
    port = int(port) if port is not None else 23
    telnet_client = telnetlib.Telnet()
    telnet_client.set_option_negotiation_callback(
        partial(telnet.callback_cmdopt, env_term=session.env["TERM"], height=term.height, width=term.width)
    )
    echo(u"\r\n\r\nEscape character is 'ctrl-^.'")
    if not session.user.get("expert", False):
        getch(3)
    echo(u"\r\nTrying %s:%s... " % (host, port))
    # pylint: disable=W0703
    #         Catching too general exception Exception
    try:
        telnet_client.open(host, port)
    except Exception as err:
        echo(term.bold_red("\r\n%s\r\n" % (err,)))
        echo(u"\r\n press any key ..")
        getch()
        return

    echo(u"\r\n... ")
    inp = session.read_event("input", timeout=0)
    echo(u"\r\nConnected to %s." % (host,))
    session.activity = "connected to %s" % (host,)
    carriage_returned = False
    with term.fullscreen():
        while True:
            if encoding == "cp437":
                try:
                    unistring = from_cp437(telnet_client.read_very_eager().decode("iso8859-1"))
                except EOFError:
                    break
            else:
                unistring = telnet_client.read_very_eager().decode("utf8")
            if 0 != len(unistring):
                echo(unistring)
            if inp is not None:
                if inp == chr(30):  # ctrl-^
                    telnet_client.close()
                    echo(u"\r\n" + term.clear_el + term.normal)
                    break
                elif not carriage_returned and inp in (b"\x0d", b"\x0a"):
                    telnet_client.write(b"\x0d")
                    log.debug("send {!r}".format(b"\x0d"))
                    carriage_returned = True
                elif carriage_returned and inp in (b"\x0a", b"\x00"):
                    carriage_returned = False
                elif inp is not None:
                    telnet_client.write(inp)
                    log.debug("send {!r}".format(inp))
                    carriage_returned = False
            inp = session.read_event("input", timeout=KEY_POLL)
    echo(u"\r\nConnection closed.\r\n")
    echo(u"".join(("\r\n\r\n", term.clear_el, term.normal, "press any key")))
    echo(u"\x1b[r")  # unset 'set scrolling region', sometimes set by BBS's
    session.flush_event("input")
    getch()
    return
Example #14
0
def main(host, port=None, encoding='cp437'):
    """
    Call script with argument host and optional argument port to connect to a
    telnet server. ctrl-^ to disconnect.
    """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    import telnetlib
    from functools import partial
    from x84.bbs import getsession, getterminal, echo, from_cp437, telnet
    import logging
    log = logging.getLogger()

    assert encoding in ('utf8', 'cp437')
    session, term = getsession(), getterminal()
    session.activity = 'connecting to %s' % (host, )
    port = int(port) if port is not None else 23
    telnet_client = telnetlib.Telnet()
    telnet_client.set_option_negotiation_callback(
        partial(telnet.callback_cmdopt,
                env_term=session.env['TERM'],
                height=term.height,
                width=term.width))
    echo(u"\r\n\r\nEscape character is 'ctrl-^.'")
    if not session.user.get('expert', False):
        term.inkey(3)
    echo(u'\r\nTrying %s:%s... ' % (
        host,
        port,
    ))
    # pylint: disable=W0703
    #         Catching too general exception Exception
    try:
        telnet_client.open(host, port)
    except Exception as err:
        echo(term.bold_red('\r\n%s\r\n' % (err, )))
        echo(u'\r\n press any key ..')
        term.inkey()
        return

    echo(u'\r\n... ')
    inp = session.read_event('input', timeout=0)
    echo(u'\r\nConnected to %s.' % (host, ))
    session.activity = 'connected to %s' % (host, )
    carriage_returned = False
    with term.fullscreen():
        while True:
            if encoding == 'cp437':
                try:
                    unistring = from_cp437(
                        telnet_client.read_very_eager().decode('iso8859-1'))
                except EOFError:
                    break
            else:
                unistring = telnet_client.read_very_eager().decode('utf8')
            if 0 != len(unistring):
                echo(unistring)
            if inp is not None:
                if inp == chr(30):  # ctrl-^
                    telnet_client.close()
                    echo(u'\r\n' + term.clear_el + term.normal)
                    break
                elif not carriage_returned and inp in (b'\x0d', b'\x0a'):
                    telnet_client.write(b'\x0d')
                    log.debug('send {!r}'.format(b'\x0d'))
                    carriage_returned = True
                elif carriage_returned and inp in (b'\x0a', b'\x00'):
                    carriage_returned = False
                elif inp:
                    telnet_client.write(inp)
                    log.debug('send {!r}'.format(inp))
                    carriage_returned = False
            inp = session.read_event('input', timeout=KEY_POLL)
    echo(u'\r\nConnection closed.\r\n')
    echo(u''.join(('\r\n\r\n', term.clear_el, term.normal, 'press any key')))
    echo(u'\x1b[r')  # unset 'set scrolling region', sometimes set by BBS's
    session.flush_event('input')
    term.inkey()
    return
Example #15
0
File: si.py Project: hick/x84
def main():
    """ Main procedure. """
    # pylint: disable=R0914,W0141,R0912
    #         Too many local variables
    #         Used builtin function 'map'
    #         Too many branches
    from x84.bbs import getsession, getterminal, echo, getch, from_cp437
    from x84.engine import __url__ as url
    import platform
    import random
    import sys
    import os
    session, term = getsession(), getterminal()
    session.activity = 'System Info'
    artfile = os.path.join(os.path.dirname(__file__), 'art', 'plant.ans',)
    system, _node, release, _version, machine, _processor = platform.uname()
    body = [u'AUthORS:',
            u'Johannes Lundberg',
            u'Jeffrey Quast',
            u'Wijnand Modderman-Lenstra',
            u'',
            u'ARtWORk:',
            u'spidy!food,',
            u'hellbeard!impure',
            u'\r\n',
            u'SYStEM: %s %s %s' % (system, release, machine),
            u'SOftWARE: X/84',
            url,
            u'\r\n',
            (platform.python_implementation() + u' '
                + '-'.join(map(str, sys.version_info[3:])))
            + u' ' + (platform.python_version()
                      if hasattr(platform, 'python_implementation')
                      else u'.'.join(map(str, sys.version_info[:3]))),
            ]
    melt_colors = (
        [term.normal]
        + [term.bold_blue] * 3
        + [term.red] * 4
        + [term.bold_red]
        + [term.bold_white]
        + [term.normal] * 6
        + [term.blue] * 2
        + [term.bold_blue]
        + [term.bold_white]
        + [term.normal])
    art = from_cp437(open(artfile).read()) if os.path.exists(artfile) else u''
    otxt = list(art.splitlines())
    for num, line in enumerate(body):
        while num > len(otxt):
            otxt += [u'', ]
        otxt[num] = otxt[num][:int(term.width / 2.5)] + u' ' + line
    width = max([term.length(line) for line in otxt])
    height = len(otxt)
    num_stars = int((term.width * term.height) * .002)
    stars = dict([(n, (random.choice('\\|/-'),
                       float(random.choice(range(term.width))),
                       float(random.choice(range(term.height)))))
                       for n in range(num_stars)])
    melting = {}
    show_star = False
    tm_out, tm_min, tm_max, tm_step = 0.08, 0.01, 2.0, .01
    wind = (0.7, 0.1, 0.01, 0.01)

    def refresh():
        """ Refresh screen and return top-left (x, y) location. """
        echo(u'\r\n\r\n')
        if term.width < width:
            echo(u''.join((
                term.move(term.height, 0),
                u'\r\n\r\n',
                term.bold_red + 'screen too thin! (%s/%s)' % (
                    term.width, width,),
                u'\r\n\r\n',
                u'press any key...',)))
            getch()
            return (None, None)
        if term.height < height:
            echo(u''.join((
                term.move(term.height, 0),
                u'\r\n\r\n',
                term.bold_red + 'screen too short! (%s/%s)' % (
                    term.height, height),
                u'\r\n\r\n',
                u'press any key...',)))
            getch()
            return (None, None)
        xloc = (term.width / 2) - (width / 2)
        yloc = (term.height / 2) - (height / 2)
        echo(u''.join((
            term.normal,
            (u'\r\n' + term.clear_eol) * term.height,
            u''.join([term.move(yloc + abs_y, xloc) + line
            for abs_y, line in enumerate(otxt)]),)))
        return xloc, yloc

    txt_x, txt_y = refresh()
    if (txt_x, txt_y) == (None, None):
        return

    def char_at_pos(yloc, xloc, txt_y, txt_x):
        """ Return art (y, x) for location """
        return (u' ' if yloc - txt_y < 0 or yloc - txt_y >= height
                or xloc - txt_x < 0 or xloc - txt_x >= len(otxt[yloc - txt_y])
                else otxt[yloc - txt_y][xloc - txt_x])

    def iter_wind(xslope, yslope, xdir, ydir):
        """ An easterly Wind """
        xslope += xdir
        yslope += ydir
        if xslope <= 0.5:
            xdir = random.choice([0.01, 0.015, 0.02])
        elif xslope >= 1:
            xdir = random.choice([-0.01, -0.015, -0.02])
        if yslope <= -0.1:
            ydir = random.choice([0.01, 0.015, 0.02, 0.02])
        elif yslope >= 0.1:
            ydir = random.choice([-0.01, -0.015, -0.02])
        return xslope, yslope, xdir, ydir

    def iter_star(char, xloc, yloc):
        """ Given char and current position, apply wind and return new
        char and new position. """
        if char == '\\':
            char = '|'
        elif char == '|':
            char = '/'
        elif char == '/':
            char = '-'
        elif char == '-':
            char = '\\'
        xloc += wind[0]
        yloc += wind[1]
        if xloc < 1 or xloc > term.width:
            xloc = (1.0 if xloc > term.width
                    else float(term.width))
            yloc = (float(random.choice
                   (range(term.height))))
        if yloc < 1 or yloc > term.height:
            yloc = (1.0 if yloc > term.height
                    else float(term.height))
            xloc = (float(random.choice
                   (range(term.width))))
        return char, xloc, yloc

    def erase(star_idx):
        """ erase old star before moving .. """
        if show_star:
            _char, xloc, yloc = stars[star_idx]
            echo(u''.join((term.move(int(yloc), int(xloc)), term.normal,
                          char_at_pos(int(yloc), int(xloc), txt_y, txt_x),)))

    def melt():
        """ Iterate through all stars and phase through melt sequence. """
        def melted(yloc, xloc):
            """ shift melt, delete if dissapeared. """
            melting[(yloc, xloc)] -= 1
            if 0 == melting[(yloc, xloc)]:
                del melting[(yloc, xloc)]
        for (yloc, xloc), phase in melting.items():
            echo(u''.join((term.move(yloc, xloc), melt_colors[phase - 1],
                          char_at_pos(yloc, xloc, txt_y, txt_x),)))
            melted(yloc, xloc)

    def draw_star(star, xloc, yloc):
        """ draw star a (x, y) location """
        char = char_at_pos(int(yloc), int(xloc), txt_y, txt_x)
        if char != ' ':
            melting[(int(yloc), int(xloc))] = len(melt_colors)
        if show_star:
            echo(term.move(int(yloc), int(xloc)) + melt_colors[-1] + star)

    with term.hidden_cursor():
        while txt_x is not None and txt_y is not None:
            if session.poll_event('refresh'):
                num_stars = int(num_stars)
                stars = dict([(n, (random.choice('\\|/-'),
                                   float(random.choice(range(term.width))),
                                   float(random.choice(range(term.height)))))
                              for n in range(num_stars)])
                otxt = list(art.splitlines())
                for num, line in enumerate(body):
                    while num > len(otxt):
                        otxt += [u'', ]
                    otxt[num] = (otxt[num][:int(term.width / 2.5)]
                            + u' ' + line)
                txt_x, txt_y = refresh()
                continue
            inp = getch(tm_out)
            if inp in (term.KEY_UP, 'k'):
                if tm_out >= tm_min:
                    tm_out -= tm_step
            elif inp in (term.KEY_DOWN, 'j'):
                if tm_out <= tm_max:
                    tm_out += tm_step
            elif inp in (term.KEY_LEFT, 'h'):
                if num_stars > 2:
                    num_stars = int(num_stars * .5)
                    stars = dict([(n, (random.choice('\\|/-'),
                        float(random.choice(range(term.width))),
                        float(random.choice(range(term.height)))))
                        for n in range(num_stars)])
            elif inp in (term.KEY_RIGHT, 'l'):
                if num_stars < (term.width * term.height) / 4:
                    num_stars = int(num_stars * 1.5)
                    stars = dict([(n, (random.choice('\\|/-'),
                        float(random.choice(range(term.width))),
                        float(random.choice(range(term.height)))))
                        for n in range(num_stars)])
            elif inp in (u'*',) and not show_star:
                show_star = True
            elif inp in (u'*',) and show_star:
                for star in stars:
                    erase(star)
                show_star = False
            elif inp is not None:
                echo(term.move(term.height, 0))
                break
            melt()
            for star_key, star_val in stars.items():
                erase(star_key)
                # pylint: disable=W0142
                #         Used * or ** magic
                stars[star_key] = iter_star(*star_val)
                draw_star(*stars[star_key])
            # pylint: disable=W0142
            #         Used * or ** magic
            wind = iter_wind(*wind)
Example #16
0
def main(host, port=None, encoding='cp437'):
    """
    Call script with argument host and optional argument port to connect to a
    telnet server. ctrl-^ to disconnect.
    """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    import telnetlib
    import struct
    from x84.bbs import getsession, getterminal, echo, getch, from_cp437
    import logging
    log = logging.getLogger()

    assert encoding in ('utf8', 'cp437')
    session, term = getsession(), getterminal()
    session.activity = 'connecting to %s' % (host,)
    port = int(port) if port is not None else 23
    telnet_client = telnetlib.Telnet()

    def callback_cmdopt(socket, cmd, opt):
        """ Callback for telnetlib.Telnet.set_option_negotiation_callback. """
        if cmd == telnetlib.WILL:
            if opt in (telnetlib.ECHO, telnetlib.SGA):
                socket.sendall(telnetlib.IAC + telnetlib.DO + opt)
        elif cmd == telnetlib.DO:
            if opt == telnetlib.SGA:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
            elif opt == telnetlib.TTYPE:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
                socket.sendall(telnetlib.IAC + telnetlib.SB
                               + telnetlib.TTYPE + IS + session.env.get('TERM')
                               + chr(0) + telnetlib.IAC + telnetlib.SE)
            elif opt == telnetlib.NAWS:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
                socket.sendall(telnetlib.IAC + telnetlib.SB
                               + telnetlib.NAWS
                               + struct.pack('!HH', term.width, term.height)
                               + telnetlib.IAC + telnetlib.SE)
            else:
                socket.sendall(telnetlib.IAC + telnetlib.WONT + opt[0])
        elif cmd == telnetlib.SB:
            if opt[0] == telnetlib.TTYPE and opt[1] == SEND:
                socket.sendall(telnetlib.IAC + telnetlib.SB
                               + telnetlib.TTYPE + IS + session.env.get('TERM')
                               + chr(0) + telnetlib.IAC + telnetlib.SE)
    telnet_client.set_option_negotiation_callback(callback_cmdopt)

    echo(u"\r\n\r\nEscape character is 'ctrl-^.'")
    if not session.user.get('expert', False):
        getch(3)
    echo(u'\r\nTrying %s:%s... ' % (host, port,))
    # pylint: disable=W0703
    #         Catching too general exception Exception
    try:
        telnet_client.open(host, port)
    except Exception as err:
        echo(term.bold_red('\r\n%s\r\n' % (err,)))
        echo(u'\r\n press any key ..')
        getch()
        return

    echo(u'\r\n... ')
    inp = session.read_event('input', timeout=0)
    echo(u'\r\nConnected to %s.' % (host,))
    session.activity = 'connected to %s' % (host,)
    carriage_returned = False
    with term.fullscreen():
        while True:
            if encoding == 'cp437':
                try:
                    unistring = from_cp437(
                            telnet_client.read_very_eager().decode('iso8859-1'))
                except EOFError:
                    break
            else:
                unistring = telnet_client.read_very_eager().decode('utf8')
            if 0 != len(unistring):
                echo(unistring)
            if inp is not None:
                if inp == chr(30):  # ctrl-^
                    telnet_client.close()
                    echo(u'\r\n' + term.clear_el + term.normal)
                    break
                elif not carriage_returned and inp in (b'\x0d', b'\x0a'):
                    telnet_client.write(b'\x0d')
                    log.debug('send {!r}'.format(b'\x0d'))
                    carriage_returned = True
                elif carriage_returned and inp in (b'\x0a', b'\x00'):
                    carriage_returned = False
                elif inp is not None:
                    telnet_client.write(inp)
                    log.debug('send {!r}'.format(inp))
                    carriage_returned = False
            inp = session.read_event('input', timeout=KEY_POLL)
    echo(u'\r\nConnection closed.\r\n')
    echo(u''.join(('\r\n\r\n', term.clear_el, term.normal, 'press any key')))
    echo(u'\x1b[r') # unset 'set scrolling region', sometimes set by BBS's
    session.flush_event('input')
    getch()
    return
Example #17
0
def main(host, port=None, encoding='cp437'):
    """
    Call script with argument host and optional argument port to connect to a
    telnet server. ctrl-^ to disconnect.
    """
    # pylint: disable=R0914,R0912,R0915
    #         Too many local variables
    #         Too many branches
    #         Too many statements
    import telnetlib
    import struct
    from x84.bbs import getsession, getterminal, echo, getch, from_cp437
    assert encoding in ('utf8', 'cp437')
    session, term = getsession(), getterminal()
    session.activity = 'connecting to %s' % (host,)
    port = int(port) if port is not None else 23
    telnet_client = telnetlib.Telnet()

    def callback_cmdopt(socket, cmd, opt):
        """ Callback for telnetlib.Telnet.set_option_negotiation_callback. """
        if cmd == telnetlib.WILL:
            if opt in (telnetlib.ECHO, telnetlib.SGA):
                socket.sendall(telnetlib.IAC + telnetlib.DO + opt)
        elif cmd == telnetlib.DO:
            if opt == telnetlib.SGA:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
            elif opt == telnetlib.TTYPE:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
                socket.sendall(telnetlib.IAC + telnetlib.SB
                               + telnetlib.TTYPE + IS + session.env.get('TERM')
                               + chr(0) + telnetlib.IAC + telnetlib.SE)
            elif opt == telnetlib.NAWS:
                socket.sendall(telnetlib.IAC + telnetlib.WILL + opt)
                socket.sendall(telnetlib.IAC + telnetlib.SB
                               + telnetlib.NAWS
                               + struct.pack('!HH', term.width, term.height)
                               + telnetlib.IAC + telnetlib.SE)
            else:
                socket.sendall(telnetlib.IAC + telnetlib.WONT + opt[0])
        elif cmd == telnetlib.SB:
            if opt[0] == telnetlib.TTYPE and opt[1] == SEND:
                socket.sendall(telnetlib.IAC + telnetlib.SB
                               + telnetlib.TTYPE + IS + session.env.get('TERM')
                               + chr(0) + telnetlib.IAC + telnetlib.SE)
    telnet_client.set_option_negotiation_callback(callback_cmdopt)

    echo(u"\r\n\r\nEscape character is 'ctrl-^.'")
    if not session.user.get('expert', False):
        getch(3)
    echo(u'\r\nTrying %s:%s... ' % (host, port,))
    # pylint: disable=W0703
    #         Catching too general exception Exception
    try:
        telnet_client.open(host, port)
    except Exception as err:
        echo(term.bold_red('\r\n%s\r\n' % (err,)))
        echo(u'\r\n press any key ..')
        getch()
        return

    swp = session.enable_keycodes
    # disable keyboard translation .. so special accomidations are
    # made with carriage_return to handle \r\n to just \r, for one.
    session.enable_keycodes = False
    inp = session.poll_event('input')
    echo(u'\r\nConnected to %s.' % (host,))
    session.activity = 'connected to %s' % (host,)
    carriage_returned = False
    while True:
        try:
            unistring = (from_cp437(telnet_client.read_very_eager())
                         if encoding == 'cp437' else
                         telnet_client.read_very_eager().decode('utf8'))
            if 0 != len(unistring):
                echo(unistring)
            if inp is not None:
                if inp in (unichr(30),):  # ctrl-^
                    telnet_client.close()
                    echo(u'\r\n' + term.clear_el + term.normal)
                    break
                elif not carriage_returned and inp in (u'\r', u'\n'):
                    telnet_client.write('\r')
                    carriage_returned = True
                elif carriage_returned and inp in (u'\n', unichr(0)):
                    carriage_returned = False
                elif inp is not None:
                    telnet_client.write(inp)
                    carriage_returned = False
        except Exception as err:
            echo(term.bold_red('%s\r\n%s\r\n' % (
                term.normal, err,)))
            break
        inp = getch(timeout=KEY_POLL)
    echo(u'\r\nConnection closed.\r\n')
    echo(u''.join(('\r\n\r\n', term.clear_el, term.normal, 'press any key')))
    session.flush_event('input')
    getch()
    session.enable_keycodes = swp
    return
Example #18
0
def play():
    import time
    from random import randint
    import os
    from x84.bbs import getterminal, from_cp437, AnsiWindow, syncterm_setfont
    from x84.bbs import echo as echo_unbuffered
    term = getterminal()
    field = []
    global charcache
    charcache = u''
    field_width = 10
    field_height = 20
    # Access scheme looks like this:
    #   layout[p][r][ypox][xpos]
    # layoutcolor = [ 7,2,3,4,4,6,7 ]
    layout = [
        #  ##
        #  ##
        [
            [
                [1, 1, ],
                [1, 1, ],
            ],
        ],
        #  #
        #  #
        #  #
        #  #
        [
            [
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
            ],
            [
                [0, 0, 0, 0],
                [1, 1, 1, 1],
                [0, 0, 0, 0],
                [0, 0, 0, 0],
            ]
        ],
        #  ###
        #   #
        [
            [
                [0, 0, 0],
                [1, 1, 1],
                [0, 1, 0],
            ],
            [
                [0, 1, 0],
                [0, 1, 1],
                [0, 1, 0],
            ],
            [
                [0, 1, 0],
                [1, 1, 1],
                [0, 0, 0],
            ],
            [
                [0, 1, 0],
                [1, 1, 0],
                [0, 1, 0],
            ],
        ],
        #  #
        #  #
        #  ##
        [
            [
                [0, 1, 0],
                [0, 1, 0],
                [0, 1, 1],
            ],
            [
                [0, 0, 1],
                [1, 1, 1],
                [0, 0, 0],
            ],
            [
                [1, 1, 0],
                [0, 1, 0],
                [0, 1, 0],
            ],
            [
                [0, 0, 0],
                [1, 1, 1],
                [1, 0, 0],
            ],
        ],
        #   #
        #   #
        #  ##
        [
            [
                [0, 1, 0],
                [0, 1, 0],
                [1, 1, 0],
            ],
            [
                [0, 0, 0],
                [1, 1, 1],
                [0, 0, 1],
            ],
            [
                [0, 1, 1],
                [0, 1, 0],
                [0, 1, 0],
            ],
            [
                [1, 0, 0],
                [1, 1, 1],
                [0, 0, 0],
            ],
        ],
        #  ##
        #   ##
        [
            [
                [0, 1, 0],
                [1, 1, 0],
                [1, 0, 0],
            ],
            [
                [0, 0, 0],
                [1, 1, 0],
                [0, 1, 1],
            ],
        ],
        #   ##
        #  ##
        [
            [
                [0, 1, 0],
                [0, 1, 1],
                [0, 0, 1],
            ],
            [
                [0, 0, 0],
                [0, 1, 1],
                [1, 1, 0],
            ],
        ],
    ]

    fieldx1 = 32
    fieldy1 = 10
    scorex1 = 11
    scorey1 = 11

    class RectRedraw:
        x1 = None
        y1 = None
        x2 = None
        y2 = None

        def max(r, val, valmax):
            if val > valmax:
                return valmax
            return val

        def min(r, val, valmin):
            if val < valmin:
                return valmin
            return val

        def merge(r, x1, y1, x2, y2):
            if r.x1 is None or r.x1 > x1:
                r.x1 = r.min(x1, 0)
            if r.y1 is None or r.y1 > y1:
                r.y1 = r.min(y1, 0)
            if r.x2 is None or r.x2 < x2:
                r.x2 = r.max(x2, field_width)
            if r.y2 is None or r.y2 < y2:
                r.y2 = r.max(y2, field_height)
            # print r.x1,r.y1,r.x2,r.y2

        def clean(r):
            r.x1 = None
            r.y1 = None
            r.x2 = None
            r.y2 = None
    rr = RectRedraw()
    for _ in range(field_height):
        field.append([0] * field_width)

    def echo(s):
        global charcache
        charcache += s
    assert term.height > (field_height + 1)
    echo_unbuffered(u''.join((
        u'\r\n\r\n',
        u'REAdY YOUR tERMiNAl %s ' % (term.bold_blue('(!)'),),
        u'\r\n\r\n',
        u'%s PRESS ANY kEY' % (term.bold_black('...'),),
    )))

    term.inkey()

    # set syncterm font to cp437
    if term.kind.startswith('ansi'):
        echo_unbuffered(syncterm_setfont('cp437'))
    artfile = os.path.join(os.path.dirname(__file__), 'art', 'tetris.ans')
    echo_unbuffered(u'\r\n' * term.height)  # cls
    if os.path.exists(artfile):
        echo_unbuffered(from_cp437(open(artfile).read()).rstrip())

    def gotoxy(x, y):
        echo(term.move(y, x))

    def plotblock(color, lastcolor):
        if color:
            c = u'\u2588\u2588'  # '\xDB\xDB'
        else:  # both empty
            c = '  '
            color = 0
        # Output optimization
        if color % 8 == 0:
            color = color / 8
        if color == lastcolor:
            echo(c)
        else:
            if color:
                fg = str(30 + color % 8)
            else:
                fg = '37'
            if color >= 8:
                bg = ';%d' % (40 + color / 8)
            else:
                bg = ''
            echo('\x1b[0;' + fg + bg + 'm')
            echo(c)
            lastcolor = color
        return lastcolor

    def drawfield():
        lastcolor = ''
        for y in range(0, field_height, 2):
            # gotoxy(field_width,2+y/2)
            gotoxy(fieldx1 + 2, fieldy1 + 1 + y / 2)
            # Which block to show, full, half-up, half-down or empty.
            for x in range(field_width):
                color = field[y][x] + field[y + 1][x] * 8
                if field[y][x] and field[y + 1][x]:
                    c = u'\u2588'  # '\xDB'
                    if field[y][x] == field[y + 1][x]:
                        color = color % 8
                    else:
                        c = u'\u2580'  # '\xDF'
                elif field[y][x] and not field[y + 1][x]:
                    c = u'\u2580'  # '\xDF'
                elif not field[y][x] and field[y + 1][x]:
                    c = u'\u2584'  # '\xDC'
                else:  # both empty
                    c = ' '
                # Output optimization
                if color % 8 == 0:
                    color = color / 8
                if color == lastcolor:
                    echo(c)
                else:
                    if color:
                        fg = str(30 + color % 8)
                    else:
                        fg = '37'
                    if color >= 8:
                        bg = ';%d' % (40 + color / 8)
                    else:
                        bg = ''
                    echo('\x1b[0;' + fg + bg + 'm')
                    echo(c)
                    lastcolor = color
        echo(term.normal)

    layoutcolor = [7, 2, 7, 6, 3, 6, 3]
    # p    = -1  # Current piece type
    nextpiece = randint(0, len(layout) - 1)
    p = randint(0, len(layout) - 1)
    p = 1
    r = 0   # Current rotation
    xpos = 4   # X position
    # ypos = -2  # Y position
    ypos = -len(layout[p][0])
    level = 1
    score = 0
    lines = 0

    def flush():
        global charcache
        echo_unbuffered(charcache)
        charcache = u''

    def fillpiece(x, y, p, r, value):
        row = 0
        for line in layout[p][r]:
            col = 0
            for c in line:
                if c and (y + row) >= 0:
                    field[y + row][x + col] = value
                col += 1
            row += 1

    def showpiece(x, y, p, r):
        fillpiece(x, y, p, r, layoutcolor[p])

    def hidepiece():
        fillpiece(xpos, ypos, p, r, 0)

    def testpiece(x, y, newr):
        hidepiece()
        # Space at the new location?
        row = 0
        for line in layout[p][newr]:
            col = 0
            for c in line:
                try:
                    if c:
                        if ((y + row) >= 0 and field[y + row][x + col]
                                or (x + col) < 0 or (x + col) > 9):
                            return 0
                except IndexError:
                    return 0
                col += 1
            row += 1
        # Movement possible
        return 1

    def movepiece(x, y, newr):
        if testpiece(x, y, newr):
            # Build redraw rectangle
            rr.merge(xpos, ypos,
                     xpos + len(layout[p][0][0]), ypos + len(layout[p][0]))
            rr.merge(x, y,
                     x + len(layout[p][0][0]), y + len(layout[p][0]))
            showpiece(x, y, p, newr)
            return (x, y, newr, 1)
        else:
            showpiece(xpos, ypos, p, r)
            return (xpos, ypos, r, 0)

    def shownext(p):
        r = 0
        for y in range(4):
            gotoxy(26, 18 + y)
            echo(u' ' * 4)

        echo(term.color(layoutcolor[p]))

        yoffset = int(len(layout[p][r][0]) < 4)
        xoffset = int(len(layout[p][r]) < 3)
        for y in range(len(layout[p][r])):
            for x in range(len(layout[p][r][y])):
                val = layout[p][r][y][x]
                if val:
                    gotoxy(26 + x + xoffset, 18 + y + yoffset)
                    echo(u'\u2588\u2588')

    def drawstats():
        echo(term.move(scorey1, scorex1) + '%d' % level)
        echo(term.move(scorey1 + 2, scorex1) + '%d' % lines)
        echo(term.move(scorey1 + 3, scorex1) + '%d' % score)

    drawstats()
    ticksize = 0.4
    nexttick = time.time() + ticksize
    showpiece(xpos, ypos, p, r)
    gotoxy(26, 17)
    echo(term.blue_reverse('next'))
    shownext(nextpiece)

    # Full redraw first frame
    rr.merge(0, 0, field_width, field_height)

    buf = ''
    while True:
        drawfield()
        # gotoxy(0,0)
        # echo('\x1b[37mx: %d, y: %d, p: %d         '%(xpos,ypos,p))
        slice = nexttick - time.time()
        if slice < 0:
            slice = 0
        echo(buf)
        buf = ''
        flush()
        key = term.inkey(slice + 0.01)
        now = time.time()
        # hidepiece()
        if key is not None:
            if key in (u'q', u'Q'):
                return (0, 0, 0)
            elif key.code == term.KEY_LEFT or key == u'h':
                xpos, ypos, r, m = movepiece(xpos - 1, ypos, r)
            elif key.code == term.KEY_RIGHT or key == u'l':
                xpos, ypos, r, m = movepiece(xpos + 1, ypos, r)
            elif key.code == term.KEY_UP or key == u'k':
                xpos, ypos, r, m = movepiece(
                    xpos, ypos, (r + 1) % len(layout[p]))
            elif key.code == term.KEY_DOWN or key == u'j':
                xpos, ypos, r, m = movepiece(xpos, ypos + 1, r)
            elif key in (' ',):
                m = True
                c = 0
                while m:
                    xpos, ypos, r, m = movepiece(xpos, ypos + 1, r)
                    if m:
                        c += 1
                if c:
                    nexttick = time.time() + ticksize
        # New tick?
        if now > nexttick:
            nexttick += ticksize
            # Move down piece
            xpos, ypos, r, moved = movepiece(xpos, ypos + 1, r)
            # Piece has touched down?
            if not moved:
                # Is the player dead?
                if ypos <= -len(layout[p][0]):
                    death_win = AnsiWindow(height=6, width=40,
                                           yloc=fieldy1 + 10 / 2, xloc=fieldx1 - 11)
                    death_win.colors['border'] = term.bold_black
                    echo_unbuffered(death_win.clear() + death_win.border())
                    echo_unbuffered(
                        term.move(fieldy1 + 10 / 2 + 1, fieldx1 - 11))
                    echo_unbuffered((
                                    u'!! gAME OVeR!! Score was: %i' % (score,)).center(40))
                    echo_unbuffered(
                        term.move(fieldy1 + 10 / 2 + 3, fieldx1 - 11))
                    echo_unbuffered(u'press RETURN'.center(40))
                    while True:
                        inp = term.inkey()
                        if inp.code == term.KEY_ENTER:
                            break
                    return (score, level, lines)

                # Any complete rows to remove?
                complete = []
                for y in range(field_height):
                    x = 0
                    while x < field_width:
                        if field[y][x] == 0:
                            break
                        x += 1
                    if x == field_width:
                        complete.append(y)
                if len(complete) > 0:
                    # Add score
                    lines += len(complete)
                    score += len(complete) * len(complete) * 100
                    # Shrink field
                    for line in complete:
                        del field[line]
                        field.insert(0, [0] * field_width)

                    if lines >= level * 10:
                        level += 1
                        ticksize = 0.4 - level * 0.02
                    drawstats()

                    # Redraw complete field
                    rr.merge(0, 0, field_width, field_height)

                # Time for a new piece
                p = nextpiece
                nextpiece = randint(0, len(layout) - 1)
                r = 0
                xpos = 4
                ypos = -len(layout[p][0])
                showpiece(xpos, ypos, p, r)
                shownext(nextpiece)
Example #19
0
def play():
    import time
    from random import randint
    import os
    from x84.bbs import getterminal, getch, from_cp437, AnsiWindow, syncterm_setfont
    from x84.bbs import echo as echo_unbuffered
    term = getterminal()
    field = []
    global charcache
    charcache = u''
    field_width = 10
    field_height = 20
    # Access scheme looks like this:
    #   layout[p][r][ypox][xpos]
    # layoutcolor = [ 7,2,3,4,4,6,7 ]
    layout = [
        #  ##
        #  ##
        [
            [
                [1, 1, ],
                [1, 1, ],
            ],
        ],
        #  #
        #  #
        #  #
        #  #
        [
            [
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
            ],
            [
                [0, 0, 0, 0],
                [1, 1, 1, 1],
                [0, 0, 0, 0],
                [0, 0, 0, 0],
            ]
        ],
        #  ###
        #   #
        [
            [
                [0, 0, 0],
                [1, 1, 1],
                [0, 1, 0],
            ],
            [
                [0, 1, 0],
                [0, 1, 1],
                [0, 1, 0],
            ],
            [
                [0, 1, 0],
                [1, 1, 1],
                [0, 0, 0],
            ],
            [
                [0, 1, 0],
                [1, 1, 0],
                [0, 1, 0],
            ],
        ],
        #  #
        #  #
        #  ##
        [
            [
                [0, 1, 0],
                [0, 1, 0],
                [0, 1, 1],
            ],
            [
                [0, 0, 1],
                [1, 1, 1],
                [0, 0, 0],
            ],
            [
                [1, 1, 0],
                [0, 1, 0],
                [0, 1, 0],
            ],
            [
                [0, 0, 0],
                [1, 1, 1],
                [1, 0, 0],
            ],
        ],
        #   #
        #   #
        #  ##
        [
            [
                [0, 1, 0],
                [0, 1, 0],
                [1, 1, 0],
            ],
            [
                [0, 0, 0],
                [1, 1, 1],
                [0, 0, 1],
            ],
            [
                [0, 1, 1],
                [0, 1, 0],
                [0, 1, 0],
            ],
            [
                [1, 0, 0],
                [1, 1, 1],
                [0, 0, 0],
            ],
        ],
        #  ##
        #   ##
        [
            [
                [0, 1, 0],
                [1, 1, 0],
                [1, 0, 0],
            ],
            [
                [0, 0, 0],
                [1, 1, 0],
                [0, 1, 1],
            ],
        ],
        #   ##
        #  ##
        [
            [
                [0, 1, 0],
                [0, 1, 1],
                [0, 0, 1],
            ],
            [
                [0, 0, 0],
                [0, 1, 1],
                [1, 1, 0],
            ],
        ],
    ]

    fieldx1 = 32
    fieldy1 = 10
    scorex1 = 11
    scorey1 = 11

    class RectRedraw:
        x1 = None
        y1 = None
        x2 = None
        y2 = None

        def max(r, val, valmax):
            if val > valmax:
                return valmax
            return val

        def min(r, val, valmin):
            if val < valmin:
                return valmin
            return val

        def merge(r, x1, y1, x2, y2):
            if r.x1 is None or r.x1 > x1:
                r.x1 = r.min(x1, 0)
            if r.y1 is None or r.y1 > y1:
                r.y1 = r.min(y1, 0)
            if r.x2 is None or r.x2 < x2:
                r.x2 = r.max(x2, field_width)
            if r.y2 is None or r.y2 < y2:
                r.y2 = r.max(y2, field_height)
            # print r.x1,r.y1,r.x2,r.y2

        def clean(r):
            r.x1 = None
            r.y1 = None
            r.x2 = None
            r.y2 = None
    rr = RectRedraw()
    for _ in range(field_height):
        field.append([0] * field_width)

    def echo(s):
        global charcache
        charcache += s
    assert term.height > (field_height + 1)
    echo_unbuffered(u''.join((
        u'\r\n\r\n',
        u'REAdY YOUR tERMiNAl %s ' % (term.bold_blue('(!)'),),
        u'\r\n\r\n',
        u'%s PRESS ANY kEY' % (term.bold_black('...'),),
    )))
    getch()
    # set syncterm font to cp437
    if term.kind.startswith('ansi'):
        echo_unbuffered(syncterm_setfont('cp437'))
    artfile = os.path.join(os.path.dirname(__file__), 'art', 'tetris.ans')
    echo_unbuffered(u'\r\n' * term.height)  # cls
    if os.path.exists(artfile):
        echo_unbuffered(from_cp437(open(artfile).read()).rstrip())

    def gotoxy(x, y):
        echo(term.move(y, x))

    def plotblock(color, lastcolor):
        if color:
            c = u'\u2588\u2588'  # '\xDB\xDB'
        else:  # both empty
            c = '  '
            color = 0
        # Output optimization
        if color % 8 == 0:
            color = color / 8
        if color == lastcolor:
            echo(c)
        else:
            if color:
                fg = str(30 + color % 8)
            else:
                fg = '37'
            if color >= 8:
                bg = ';%d' % (40 + color / 8)
            else:
                bg = ''
            echo('\x1b[0;' + fg + bg + 'm')
            echo(c)
            lastcolor = color
        return lastcolor

    def drawfield():
        lastcolor = ''
        for y in range(0, field_height, 2):
            # gotoxy(field_width,2+y/2)
            gotoxy(fieldx1 + 2, fieldy1 + 1 + y / 2)
            # Which block to show, full, half-up, half-down or empty.
            for x in range(field_width):
                color = field[y][x] + field[y + 1][x] * 8
                if field[y][x] and field[y + 1][x]:
                    c = u'\u2588'  # '\xDB'
                    if field[y][x] == field[y + 1][x]:
                        color = color % 8
                    else:
                        c = u'\u2580'  # '\xDF'
                elif field[y][x] and not field[y + 1][x]:
                    c = u'\u2580'  # '\xDF'
                elif not field[y][x] and field[y + 1][x]:
                    c = u'\u2584'  # '\xDC'
                else:  # both empty
                    c = ' '
                # Output optimization
                if color % 8 == 0:
                    color = color / 8
                if color == lastcolor:
                    echo(c)
                else:
                    if color:
                        fg = str(30 + color % 8)
                    else:
                        fg = '37'
                    if color >= 8:
                        bg = ';%d' % (40 + color / 8)
                    else:
                        bg = ''
                    echo('\x1b[0;' + fg + bg + 'm')
                    echo(c)
                    lastcolor = color
        echo(term.normal)

    layoutcolor = [7, 2, 7, 6, 3, 6, 3]
    # p    = -1  # Current piece type
    nextpiece = randint(0, len(layout) - 1)
    p = randint(0, len(layout) - 1)
    p = 1
    r = 0   # Current rotation
    xpos = 4   # X position
    # ypos = -2  # Y position
    ypos = -len(layout[p][0])
    level = 1
    score = 0
    lines = 0

    def flush():
        global charcache
        echo_unbuffered(charcache)
        charcache = u''

    def fillpiece(x, y, p, r, value):
        row = 0
        for line in layout[p][r]:
            col = 0
            for c in line:
                if c and (y + row) >= 0:
                    field[y + row][x + col] = value
                col += 1
            row += 1

    def showpiece(x, y, p, r):
        fillpiece(x, y, p, r, layoutcolor[p])

    def hidepiece():
        fillpiece(xpos, ypos, p, r, 0)

    def testpiece(x, y, newr):
        hidepiece()
        # Space at the new location?
        row = 0
        for line in layout[p][newr]:
            col = 0
            for c in line:
                try:
                    if c:
                        if ((y + row) >= 0 and field[y + row][x + col]
                                or (x + col) < 0 or (x + col) > 9):
                            return 0
                except IndexError:
                    return 0
                col += 1
            row += 1
        # Movement possible
        return 1

    def movepiece(x, y, newr):
        if testpiece(x, y, newr):
            # Build redraw rectangle
            rr.merge(xpos, ypos,
                     xpos + len(layout[p][0][0]), ypos + len(layout[p][0]))
            rr.merge(x, y,
                     x + len(layout[p][0][0]), y + len(layout[p][0]))
            showpiece(x, y, p, newr)
            return (x, y, newr, 1)
        else:
            showpiece(xpos, ypos, p, r)
            return (xpos, ypos, r, 0)

    def shownext(p):
        r = 0
        for y in range(4):
            gotoxy(26, 18 + y)
            echo(u' ' * 4)

        echo(term.color(layoutcolor[p]))

        yoffset = int(len(layout[p][r][0]) < 4)
        xoffset = int(len(layout[p][r]) < 3)
        for y in range(len(layout[p][r])):
            for x in range(len(layout[p][r][y])):
                val = layout[p][r][y][x]
                if val:
                    gotoxy(26 + x + xoffset, 18 + y + yoffset)
                    echo(u'\u2588\u2588')

    def drawstats():
        echo(term.move(scorey1, scorex1) + '%d' % level)
        echo(term.move(scorey1 + 2, scorex1) + '%d' % lines)
        echo(term.move(scorey1 + 3, scorex1) + '%d' % score)

    drawstats()
    ticksize = 0.4
    nexttick = time.time() + ticksize
    showpiece(xpos, ypos, p, r)
    gotoxy(26, 17)
    echo(term.blue_reverse('next'))
    shownext(nextpiece)

    # Full redraw first frame
    rr.merge(0, 0, field_width, field_height)

    buf = ''
    while True:
        drawfield()
        # gotoxy(0,0)
        # echo('\x1b[37mx: %d, y: %d, p: %d         '%(xpos,ypos,p))
        slice = nexttick - time.time()
        if slice < 0:
            slice = 0
        echo(buf)
        buf = ''
        flush()
        key = getch(slice + 0.01)
        now = time.time()
        # hidepiece()
        if key is not None:
            if key in (u'q', u'Q'):
                return (0, 0, 0)
            elif key in (term.KEY_LEFT, u'h',):
                xpos, ypos, r, m = movepiece(xpos - 1, ypos, r)
            elif key in (term.KEY_RIGHT, u'l',):
                xpos, ypos, r, m = movepiece(xpos + 1, ypos, r)
            elif key in (term.KEY_UP, u'k',):
                xpos, ypos, r, m = movepiece(
                    xpos, ypos, (r + 1) % len(layout[p]))
            elif key in (term.KEY_DOWN, u'j',):
                xpos, ypos, r, m = movepiece(xpos, ypos + 1, r)
            elif key in (' ',):
                m = True
                c = 0
                while m:
                    xpos, ypos, r, m = movepiece(xpos, ypos + 1, r)
                    if m:
                        c += 1
                if c:
                    nexttick = time.time() + ticksize
        # New tick?
        if now > nexttick:
            nexttick += ticksize
            # Move down piece
            xpos, ypos, r, moved = movepiece(xpos, ypos + 1, r)
            # Piece has touched down?
            if not moved:
                # Is the player dead?
                if ypos <= -len(layout[p][0]):
                    death_win = AnsiWindow(height=6, width=40,
                                           yloc=fieldy1 + 10 / 2, xloc=fieldx1 - 11)
                    death_win.colors['border'] = term.bold_black
                    echo_unbuffered(death_win.clear() + death_win.border())
                    echo_unbuffered(
                        term.move(fieldy1 + 10 / 2 + 1, fieldx1 - 11))
                    echo_unbuffered((
                                    u'!! gAME OVeR!! Score was: %i' % (score,)).center(40))
                    echo_unbuffered(
                        term.move(fieldy1 + 10 / 2 + 3, fieldx1 - 11))
                    echo_unbuffered(u'press RETURN'.center(40))
                    while True:
                        inp = getch()
                        if inp in (u'\r', term.KEY_ENTER):
                            break
                    return (score, level, lines)

                # Any complete rows to remove?
                complete = []
                for y in range(field_height):
                    x = 0
                    while x < field_width:
                        if field[y][x] == 0:
                            break
                        x += 1
                    if x == field_width:
                        complete.append(y)
                if len(complete) > 0:
                    # Add score
                    lines += len(complete)
                    score += len(complete) * len(complete) * 100
                    # Shrink field
                    for line in complete:
                        del field[line]
                        field.insert(0, [0] * field_width)

                    if lines >= level * 10:
                        level += 1
                        ticksize = 0.4 - level * 0.02
                    drawstats()

                    # Redraw complete field
                    rr.merge(0, 0, field_width, field_height)

                # Time for a new piece
                p = nextpiece
                nextpiece = randint(0, len(layout) - 1)
                r = 0
                xpos = 4
                ypos = -len(layout[p][0])
                showpiece(xpos, ypos, p, r)
                shownext(nextpiece)
Example #20
0
def display_weather(todays, weather, centigrade):
    """
    Display weather as vertical panels.

    Thanks to xzip, we now have a sortof tv-weather channel art :-)
    """
    from x84.bbs import getterminal, echo, from_cp437, syncterm_setfont
    term = getterminal()
    # set syncterm font to cp437
    if term.kind.startswith('ansi'):
        echo(syncterm_setfont('cp437'))
    echo(term.height * u'\r\n')
    echo(term.move(0, 0))
    at = term.yellow_bold('At')
    city = term.bold(todays.get('City', u''))
    state = todays.get('State', u'')
    if state:
        state = u', {}'.format(term.bold_yellow_reverse(state))
    dotdot = term.bold_black('...')
    echo(u'{at} {city}{state} {dotdot}'.format(
        at=at, city=city, state=state, dotdot=dotdot))
    bottom = 2
    if weather:
        for column in range(0, (term.width - panel_width), panel_width):
            try:
                day = weather.pop(0)
            except IndexError:
                break
            bottom = max(display_panel(day, column, centigrade), bottom)

    timenow = time.strftime('%I:%M%p',
                            time.strptime(todays.get('Time', '00:00'),
                                          '%H:%M'))
    temp, deg_conv = temp_conv(todays.get('Temperature', ''), centigrade)
    real_temp, deg_conv = temp_conv(todays.get('RealFeel', ''), centigrade)
    speed, spd_conv = speed_conv(todays.get('WindSpeed', ''), centigrade)
    degree = from_cp437(''.join([chr(248)]))

    current_0 = u'Current conditions at {timenow}'.format(timenow=timenow)
    current_1 = u'{0}'.format(todays.get('WeatherText', ''))
    current_2 = u'Temperature is {temp}{degree}{deg_conv}'.format(
        temp=temp, degree=degree, deg_conv=deg_conv)
    current_3 = u'' if real_temp == temp else (
        u'(feels like {real_temp}{degree}{deg_conv})'.format(
            real_temp=real_temp, degree=degree, deg_conv=deg_conv))
    current_4 = u'Winds {speed}{spd_conv} {wind}'.format(
        speed=speed, spd_conv=spd_conv,
        wind=todays.get('WindDirection', ''))
    current_5 = u'Humidity of {0}'.format(todays.get('Humidity', ''))

    wrapped = textwrap.wrap(
        u'{0}: {1}. {2} {3}, {4}, {5}.'.format(
            current_0, current_1, current_2, current_3,
            current_4, current_5), min(term.width - panel_width - 2, 40))
    row_num = 0

    art = get_icon(todays)
    joined_art_conditions = list(itertools.izip_longest(wrapped, art))
    last_line = lambda row_num: row_num == len(joined_art_conditions) - 1
    for row_num, (row_txt, art_txt) in enumerate(joined_art_conditions):
        echo(term.move(bottom + next_margin + row_num, 1))
        echo(art_txt)
        if not row_txt and not last_line(row_num):
            echo(u'\r\n')
        elif row_txt:
            echo(term.move(bottom + next_margin + row_num, panel_width + 5))
            echo(term.normal)
            echo(row_txt)
Example #21
0
def main():
    """ Main procedure. """
    # pylint: disable=R0912
    #        Too many branches
    from x84.bbs import getsession, getterminal, echo, getch, Ansi, from_cp437
    session, term = getsession(), getterminal()
    session.activity = u'Selecting chracter set'
    artfile = os.path.join(
        os.path.dirname(__file__), 'art', (
            'plant-256.ans' if term.number_of_colors == 256
            else 'plant.ans'))
    enc_prompt = (
        u'Press left/right until artwork looks best. Clients should'
        ' select utf8 encoding and Andale Mono font. Older clients or'
        ' clients with appropriate 8-bit fontsets can select cp437, though'
        ' some characters may appear as "?".')
    save_msg = u"\r\n\r\n'%s' is now your preferred encoding ..\r\n"
    if session.user.get('expert', False):
        echo(u'\r\n\r\n(U) UTF-8 encoding or (C) CP437 encoding [uc] ?\b\b')
        while True:
            inp = getch()
            if inp in (u'u', u'U'):
                session.encoding = 'utf8'
                break
            elif inp in (u'c', u'C'):
                session.encoding = 'cp437'
                break
        session.user['charset'] = session.encoding
        echo(save_msg % (session.encoding,))
        getch(1.0)
        return

    art = (from_cp437(open(artfile).read()).splitlines()
           if os.path.exists(artfile) else [u''])

    def refresh(sel):
        """ Refresh art and yes/no prompt, ``sel``. """
        session.flush_event('refresh')
        session.encoding = selector.selection
        if sel.selection == 'utf8':
            # 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.
            echo(unichr(27) + u'%G')
        elif sel.selection == 'cp437':
            # ESC %@ returns to ISO 2022 in case UTF-8 had been entered.
            # ESC ) U Sets character set G1 to codepage 437 .. usually.
            echo(unichr(27) + u'%@')
            echo(unichr(27) + u')U')
        else:
            assert False, "Only encodings 'utf8' and 'cp437' supported."
        # display art, banner, paragraph, refresh selector refresh
        buf = [line for line in art]
        return u''.join((
            u'\r\n\r\n',
            u'\r\n'.join(buf),
            u'\r\n\r\n',
            Ansi(enc_prompt).wrap(int(term.width * .95)),
            u'\r\n\r\n',
            sel.refresh(),))

    selector = get_selector(session.encoding)
    echo(refresh(selector))
    while True:
        inp = getch(1)
        if inp == term.KEY_ENTER:
            session.user['charset'] = session.encoding
            echo(save_msg % (session.encoding,))
            getch(1.0)
            return
        elif inp is not None:
            selector.process_keystroke(inp)
            if selector.quit:
                # 'escape' quits without save, though the encoding
                # has been temporarily set for this session.
                return
            if selector.moved:
                # set and refresh art in new encoding
                echo(refresh(selector))
        if session.poll_event('refresh') is not None:
            # instantiate a new selector in case the window size has changed.
            selector = get_selector(session.encoding)
            echo(refresh(selector))