Example #1
0
 def __init__(self, row):
     self.fastest_cap = row.fastest_cap
     self.create_dt = row.create_dt
     self.create_dt_epoch = timegm(row.create_dt.timetuple())
     self.create_dt_fuzzy = pretty_date(row.create_dt)
     self.player_id = row.player_id
     self.player_nick = row.player_nick
     self.player_nick_stripped = strip_colors(row.player_nick)
     self.player_nick_html = html_colors(row.player_nick)
     self.game_id = row.game_id
     self.server_id = row.server_id
     self.server_name = row.server_name
Example #2
0
 def __init__(self, row):
     self.fastest_cap = row.fastest_cap
     self.create_dt = row.create_dt
     self.create_dt_epoch = timegm(row.create_dt.timetuple())
     self.create_dt_fuzzy = pretty_date(row.create_dt)
     self.player_id = row.player_id
     self.player_nick = row.player_nick
     self.player_nick_stripped = strip_colors(row.player_nick)
     self.player_nick_html = html_colors(row.player_nick)
     self.game_id = row.game_id
     self.server_id = row.server_id
     self.server_name = row.server_name
Example #3
0
def get_or_create_player(session=None, hashkey=None, nick=None):
    """
    Finds a player by hashkey or creates a new one (along with a
    corresponding hashkey entry. Parameters:

    session - SQLAlchemy database session factory
    hashkey - hashkey of the player to be found or created
    nick - nick of the player (in case of a first time create)
    """
    # if we have a bot
    if re.search('^bot#\d+$', hashkey) or re.search('^bot#\d+#', hashkey):
        player = session.query(Player).filter_by(player_id=1).one()
    # if we have an untracked player
    elif re.search('^player#\d+$', hashkey):
        player = session.query(Player).filter_by(player_id=2).one()
    # else it is a tracked player
    else:
        # see if the player is already in the database
        # if not, create one and the hashkey along with it
        try:
            hk = session.query(Hashkey).filter_by(
                    hashkey=hashkey).one()
            player = session.query(Player).filter_by(
                    player_id=hk.player_id).one()
            log.debug("Found existing player {0} with hashkey {1}".format(
                player.player_id, hashkey))
        except:
            player = Player()
            player.create_dt = datetime.datetime.utcnow()
            session.add(player)
            session.flush()

            # if nick is given to us, use it. If not, use "Anonymous Player"
            # with a suffix added for uniqueness.
            if nick:
                player.nick = nick[:128]
                player.stripped_nick = strip_colors(qfont_decode(nick[:128]))
            else:
                player.nick = "Anonymous Player #{0}".format(player.player_id)
                player.stripped_nick = player.nick

            hk = Hashkey(player_id=player.player_id, hashkey=hashkey)
            session.add(hk)
            log.debug("Created player {0} ({2}) with hashkey {1}".format(
                player.player_id, hashkey, player.nick.encode('utf-8')))

    return player
Example #4
0
def get_or_create_player(session, hashkey, nick, untrackedPlayerDict):
    """
    Finds a player by hashkey or creates a new one (along with a
    corresponding hashkey entry. Parameters:

    session - SQLAlchemy database session factory
    hashkey - hashkey of the player to be found or created
    nick - nick of the player (in case of a first time create)
    untrackedPlayerCount - current counter of untracked/anonymous players in the match.

    returns: (player data record, updated untrackedPlayerCount)
    """

    # the getOrCreatePlayer stored procedure looks at the privacy_match_hist setting and
    # returns null if a player deleted himself and wants to stay untracked.
    # For tracked players it may update the nick and aliases, unless the player is anonymous
    # and it returns the player_id
    stripped_nick = strip_colors(qfont_decode(nick[:128]))
    pid = session.execute(
        expr.func.getOrCreatePlayer(hashkey, nick, stripped_nick)).scalar()
    defaultNick = "Untracked Player {0}"
    if pid is not None:
        player = session.query(Player).filter_by(player_id=pid).one()
        if player.privacy_match_hist != 3:  # allow storing match history
            log.debug("Found existing player {0} with hashkey {1}".format(
                player.player_id, hashkey))
            return player
        defaultNick = "Anonymous Player {0}"

    # map untracked or anonymous player to the next available placeholder Player
    if hashkey in untrackedPlayerDict:
        return untrackedPlayerDict[hashkey]
    player = Player()
    untrackedPlayerCount = len(untrackedPlayerDict) + 1
    player.player_id = -untrackedPlayerCount
    player.nick = defaultNick.format(untrackedPlayerCount)
    player.stripped_nick = player.nick
    untrackedPlayerDict[hashkey] = player
    log.debug(("Found " + defaultNick + " with steam-id {1}").format(
        untrackedPlayerCount, hashkey))
    return player
Example #5
0
def register_new_nick(session, player, new_nick):
    """
    Change the player record's nick to the newly found nick. Store the old
    nick in the player_nicks table for that player.

    session - SQLAlchemy database session factory
    player - player record whose nick is changing
    new_nick - the new nickname
    """
    # see if that nick already exists
    stripped_nick = strip_colors(player.nick)
    try:
    	player_nick = session.query(PlayerNick).filter_by(
        	player_id=player.player_id, stripped_nick=stripped_nick).one()
    except NoResultFound, e:
	    # player_id/stripped_nick not found, create one
        # but we don't store "Anonymous Player #N"
        if not re.search('^Anonymous Player #\d+$', player.nick):
            player_nick = PlayerNick()
            player_nick.player_id = player.player_id
            player_nick.stripped_nick = player.stripped_nick
            player_nick.nick = player.nick
            session.add(player_nick)
Example #6
0
def register_new_nick(session, player, new_nick):
    """
    Change the player record's nick to the newly found nick. Store the old
    nick in the player_nicks table for that player.

    session - SQLAlchemy database session factory
    player - player record whose nick is changing
    new_nick - the new nickname
    """
    # see if that nick already exists
    stripped_nick = strip_colors(qfont_decode(player.nick))
    try:
        player_nick = session.query(PlayerNick).filter_by(
            player_id=player.player_id, stripped_nick=stripped_nick).one()
    except NoResultFound, e:
        # player_id/stripped_nick not found, create one
        # but we don't store "Anonymous Player #N"
        if not re.search('^Anonymous Player #\d+$', player.nick):
            player_nick = PlayerNick()
            player_nick.player_id = player.player_id
            player_nick.stripped_nick = stripped_nick
            player_nick.nick = player.nick
            session.add(player_nick)
Example #7
0
def create_player(session, events):
    """
    Creates a new player from the list of events.
    :param session: SQLAlchemy session
    :param events: Dict of player events from the submission
    :return: Player
    """
    player = Player()
    session.add(player)
    session.flush()

    nick = events.get('n', None)
    if nick:
        player.nick = nick[:128]
        player.stripped_nick = strip_colors(qfont_decode(player.nick))
    else:
        player.nick = "Anonymous Player #{0}".format(player.player_id)
        player.stripped_nick = player.nick

    hk = Hashkey(player_id=player.player_id, hashkey=events.get('P', None))
    session.add(hk)

    return player
Example #8
0
 def nick_stripped(self):
     if self.nick is None:
         return "Anonymous Player"
     else:
         return strip_colors(self.nick)
Example #9
0
    try:
    	player_nick = session.query(PlayerNick).filter_by(
        	player_id=player.player_id, stripped_nick=stripped_nick).one()
    except NoResultFound, e:
	    # player_id/stripped_nick not found, create one
        # but we don't store "Anonymous Player #N"
        if not re.search('^Anonymous Player #\d+$', player.nick):
            player_nick = PlayerNick()
            player_nick.player_id = player.player_id
            player_nick.stripped_nick = player.stripped_nick
            player_nick.nick = player.nick
            session.add(player_nick)

    # We change to the new nick regardless
    player.nick = new_nick
    player.stripped_nick = strip_colors(new_nick)
    session.add(player)


def get_or_create_server(session=None, name=None, hashkey=None):
    """
    Find a server by name or create one if not found. Parameters:

    session - SQLAlchemy database session factory
    name - server name of the server to be found or created
    hashkey - server hashkey
    """
    try:
        # find one by that name, if it exists
        server = session.query(Server).filter_by(name=name).one()
Example #10
0
def create_game_stat(session, game_meta, game, server, gmap, player, events):
    """Game stats handler for all game types"""

    game_type_cd = game.game_type_cd

    pgstat = create_default_game_stat(session, game_type_cd)

    # these fields should be on every pgstat record
    pgstat.game_id       = game.game_id
    pgstat.player_id     = player.player_id
    pgstat.nick          = events.get('n', 'Anonymous Player')[:128]
    pgstat.stripped_nick = strip_colors(qfont_decode(pgstat.nick))
    pgstat.score         = int(round(float(events.get('scoreboard-score', 0))))
    pgstat.alivetime     = datetime.timedelta(seconds=int(round(float(events.get('alivetime', 0.0)))))
    pgstat.rank          = int(events.get('rank', None))
    pgstat.scoreboardpos = int(events.get('scoreboardpos', pgstat.rank))

    if pgstat.nick != player.nick \
            and player.player_id > 2 \
            and pgstat.nick != 'Anonymous Player':
        register_new_nick(session, player, pgstat.nick)

    wins = False

    # gametype-specific stuff is handled here. if passed to us, we store it
    for (key,value) in events.items():
        if key == 'wins': wins = True
        if key == 't': pgstat.team = int(value)

        if key == 'scoreboard-drops': pgstat.drops = int(value)
        if key == 'scoreboard-returns': pgstat.returns = int(value)
        if key == 'scoreboard-fckills': pgstat.carrier_frags = int(value)
        if key == 'scoreboard-pickups': pgstat.pickups = int(value)
        if key == 'scoreboard-caps': pgstat.captures = int(value)
        if key == 'scoreboard-score': pgstat.score = int(round(float(value)))
        if key == 'scoreboard-deaths': pgstat.deaths = int(value)
        if key == 'scoreboard-kills': pgstat.kills = int(value)
        if key == 'scoreboard-suicides': pgstat.suicides = int(value)
        if key == 'scoreboard-objectives': pgstat.collects = int(value)
        if key == 'scoreboard-captured': pgstat.captures = int(value)
        if key == 'scoreboard-released': pgstat.drops = int(value)
        if key == 'scoreboard-fastest':
            pgstat.fastest = datetime.timedelta(seconds=float(value)/100)
        if key == 'scoreboard-takes': pgstat.pickups = int(value)
        if key == 'scoreboard-ticks': pgstat.drops = int(value)
        if key == 'scoreboard-revivals': pgstat.revivals = int(value)
        if key == 'scoreboard-bctime':
            pgstat.time = datetime.timedelta(seconds=int(value))
        if key == 'scoreboard-bckills': pgstat.carrier_frags = int(value)
        if key == 'scoreboard-losses': pgstat.drops = int(value)
        if key == 'scoreboard-pushes': pgstat.pushes = int(value)
        if key == 'scoreboard-destroyed': pgstat.destroys = int(value)
        if key == 'scoreboard-kckills': pgstat.carrier_frags = int(value)
        if key == 'scoreboard-lives': pgstat.lives = int(value)
        if key == 'scoreboard-goals': pgstat.captures = int(value)
        if key == 'scoreboard-faults': pgstat.drops = int(value)
        if key == 'scoreboard-laps': pgstat.laps = int(value)

        if key == 'avglatency': pgstat.avg_latency = float(value)
        if key == 'scoreboard-captime':
            pgstat.fastest = datetime.timedelta(seconds=float(value)/100)
            if game.game_type_cd == 'ctf':
                update_fastest_cap(session, player.player_id, game.game_id,
                        gmap.map_id, pgstat.fastest, game.mod)

    # there is no "winning team" field, so we have to derive it
    if wins and pgstat.team is not None and game.winner is None:
        game.winner = pgstat.team
        session.add(game)

    session.add(pgstat)

    return pgstat
Example #11
0
    try:
        player_nick = session.query(PlayerNick).filter_by(
            player_id=player.player_id, stripped_nick=stripped_nick).one()
    except NoResultFound, e:
        # player_id/stripped_nick not found, create one
        # but we don't store "Anonymous Player #N"
        if not re.search('^Anonymous Player #\d+$', player.nick):
            player_nick = PlayerNick()
            player_nick.player_id = player.player_id
            player_nick.stripped_nick = stripped_nick
            player_nick.nick = player.nick
            session.add(player_nick)

    # We change to the new nick regardless
    player.nick = new_nick
    player.stripped_nick = strip_colors(qfont_decode(new_nick))
    session.add(player)


def update_fastest_cap(session, player_id, game_id, map_id, captime, mod):
    """
    Check the fastest cap time for the player and map. If there isn't
    one, insert one. If there is, check if the passed time is faster.
    If so, update!
    """
    # we don't record fastest cap times for bots or anonymous players
    if player_id <= 2:
        return

    # see if a cap entry exists already
    # then check to see if the new captime is faster
Example #12
0
def create_game_stat(session, game_meta, game, server, gmap, player, events):
    """Game stats handler for all game types"""

    game_type_cd = game.game_type_cd

    pgstat = create_default_game_stat(session, game_type_cd)

    # these fields should be on every pgstat record
    pgstat.game_id = game.game_id
    pgstat.create_dt = datetime.datetime.utcnow()
    pgstat.player_id = player.player_id
    pgstat.nick = events.get(
        'n',
        'Anonymous Player')[:128] if player.player_id >= 0 else player.nick
    pgstat.stripped_nick = strip_colors(qfont_decode(
        pgstat.nick)) if player.player_id >= 0 else player.stripped_nick
    pgstat.score = int(round(float(events.get('scoreboard-score', 0))))
    pgstat.alivetime = datetime.timedelta(
        seconds=int(round(float(events.get('alivetime', 0.0)))))
    pgstat.rank = int(events.get('rank', None))
    pgstat.scoreboardpos = int(events.get('scoreboardpos', pgstat.rank))

    if pgstat.nick != player.nick \
            and player.player_id > 2 \
            and pgstat.nick != 'Anonymous Player':
        register_new_nick(session, player, pgstat.nick)

    wins = False

    # gametype-specific stuff is handled here. if passed to us, we store it
    for (key, value) in events.items():
        if key == 'wins': wins = True
        if key == 't': pgstat.team = int(value)

        if key == 'scoreboard-drops': pgstat.drops = int(value)
        if key == 'scoreboard-returns': pgstat.returns = int(value)
        if key == 'scoreboard-fckills': pgstat.carrier_frags = int(value)
        if key == 'scoreboard-pickups': pgstat.pickups = int(value)
        if key == 'scoreboard-caps': pgstat.captures = int(value)
        if key == 'scoreboard-score': pgstat.score = int(round(float(value)))
        if key == 'scoreboard-deaths': pgstat.deaths = int(value)
        if key == 'scoreboard-kills': pgstat.kills = int(value)
        if key == 'scoreboard-suicides': pgstat.suicides = int(value)
        if key == 'scoreboard-objectives': pgstat.collects = int(value)
        if key == 'scoreboard-captured': pgstat.captures = int(value)
        if key == 'scoreboard-released': pgstat.drops = int(value)
        if key == 'scoreboard-fastest':
            pgstat.fastest = datetime.timedelta(seconds=float(value) / 100)
        if key == 'scoreboard-takes': pgstat.pickups = int(value)
        if key == 'scoreboard-ticks': pgstat.drops = int(value)
        if key == 'scoreboard-revivals': pgstat.revivals = int(value)
        if key == 'scoreboard-bctime':
            pgstat.time = datetime.timedelta(seconds=int(value))
        if key == 'scoreboard-bckills': pgstat.carrier_frags = int(value)
        if key == 'scoreboard-losses': pgstat.drops = int(value)
        if key == 'scoreboard-pushes': pgstat.pushes = int(value)
        if key == 'scoreboard-destroyed': pgstat.destroys = int(value)
        if key == 'scoreboard-kckills': pgstat.carrier_frags = int(value)
        if key == 'scoreboard-lives': pgstat.lives = int(value)
        if key == 'scoreboard-goals': pgstat.captures = int(value)
        if key == 'scoreboard-faults': pgstat.drops = int(value)
        if key == 'scoreboard-laps': pgstat.laps = int(value)

        if key == 'avglatency': pgstat.avg_latency = float(value)
        if key == 'scoreboard-captime':
            pgstat.fastest = datetime.timedelta(seconds=float(value) / 100)
            if game.game_type_cd == 'ctf':
                update_fastest_cap(session, player.player_id, game.game_id,
                                   gmap.map_id, pgstat.fastest)

    # there is no "winning team" field, so we have to derive it
    if wins and pgstat.team is not None and game.winner is None:
        game.winner = pgstat.team
        session.add(game)

    session.add(pgstat)

    return pgstat
Example #13
0
def create_player_game_stat(session=None, player=None, 
        game=None, player_events=None):
    """
    Creates game statistics for a given player in a given game. Parameters:

    session - SQLAlchemy session factory
    player - Player record of the player who owns the stats
    game - Game record for the game to which the stats pertain
    player_events - dictionary for the actual stats that need to be transformed
    """

    # in here setup default values (e.g. if game type is CTF then
    # set kills=0, score=0, captures=0, pickups=0, fckills=0, etc
    # TODO: use game's create date here instead of now()
    seq = Sequence('player_game_stats_player_game_stat_id_seq')
    pgstat_id = session.execute(seq)
    pgstat = PlayerGameStat(player_game_stat_id=pgstat_id, 
            create_dt=datetime.datetime.utcnow())

    # set player id from player record
    pgstat.player_id = player.player_id

    #set game id from game record
    pgstat.game_id = game.game_id

    # all games have a score and every player has an alivetime
    pgstat.score = 0
    pgstat.alivetime = datetime.timedelta(seconds=0)

    if game.game_type_cd == 'dm' or game.game_type_cd == 'tdm' or game.game_type_cd == 'duel':
        pgstat.kills = 0
        pgstat.deaths = 0
        pgstat.suicides = 0
    elif game.game_type_cd == 'ctf':
        pgstat.kills = 0
        pgstat.captures = 0
        pgstat.pickups = 0
        pgstat.drops = 0
        pgstat.returns = 0
        pgstat.carrier_frags = 0

    for (key,value) in player_events.items():
        if key == 'n': 
            pgstat.nick = value[:128]
            pgstat.stripped_nick = strip_colors(qfont_decode(pgstat.nick))
        if key == 't': pgstat.team = int(value)
        if key == 'rank': pgstat.rank = int(value)
        if key == 'alivetime': 
            pgstat.alivetime = datetime.timedelta(seconds=int(round(float(value))))
        if key == 'scoreboard-drops': pgstat.drops = int(value)
        if key == 'scoreboard-returns': pgstat.returns = int(value)
        if key == 'scoreboard-fckills': pgstat.carrier_frags = int(value)
        if key == 'scoreboard-pickups': pgstat.pickups = int(value)
        if key == 'scoreboard-caps': pgstat.captures = int(value)
        if key == 'scoreboard-score': pgstat.score = int(value)
        if key == 'scoreboard-deaths': pgstat.deaths = int(value)
        if key == 'scoreboard-kills': pgstat.kills = int(value)
        if key == 'scoreboard-suicides': pgstat.suicides = int(value)

    # check to see if we had a name, and if
    # not use an anonymous handle
    if pgstat.nick == None:
        pgstat.nick = "Anonymous Player"
        pgstat.stripped_nick = "Anonymous Player"

    # otherwise process a nick change
    elif pgstat.nick != player.nick and player.player_id > 2:
        register_new_nick(session, player, pgstat.nick)

    # if the player is ranked #1 and it is a team game, set the game's winner
    # to be the team of that player
    # FIXME: this is a hack, should be using the 'W' field (not present)
    if pgstat.rank == 1 and pgstat.team:
        game.winner = pgstat.team
        session.add(game)

    session.add(pgstat)

    return pgstat
Example #14
0
    try:
        player_nick = session.query(PlayerNick).filter_by(
            player_id=player.player_id, stripped_nick=stripped_nick).one()
    except NoResultFound, e:
        # player_id/stripped_nick not found, create one
        # but we don't store "Anonymous Player #N"
        if not re.search('^Anonymous Player #\d+$', player.nick):
            player_nick = PlayerNick()
            player_nick.player_id = player.player_id
            player_nick.stripped_nick = stripped_nick
            player_nick.nick = player.nick
            session.add(player_nick)

    # We change to the new nick regardless
    player.nick = new_nick
    player.stripped_nick = strip_colors(qfont_decode(new_nick))
    session.add(player)


def update_fastest_cap(session, player_id, game_id, map_id, captime):
    """
    Check the fastest cap time for the player and map. If there isn't
    one, insert one. If there is, check if the passed time is faster.
    If so, update!
    """
    # we don't record fastest cap times for bots or anonymous players
    if player_id <= 2:
        return

    # see if a cap entry exists already
    # then check to see if the new captime is faster
Example #15
0
    def render_image(self, data, output_filename):
        """Render an image for the given player id."""

        # setup variables

        player                  = data['player']
        elos                    = data['elos']
        ranks                   = data['ranks']
        games_played            = data['games_played']['overall']
        overall_stats           = data['overall_stats']['overall']

        wins, losses, win_pct   = games_played.wins, games_played.losses, games_played.win_pct
        games                   = games_played.games
        kills, deaths, kd_ratio = overall_stats.total_kills, overall_stats.total_deaths, overall_stats.k_d_ratio
        alivetime               = overall_stats.total_playing_time

        # make sorted list of gametypes
        game_types = []
        for gt in data['games_played'].keys():
            if gt == 'overall':
                continue
            if elos.has_key(gt):
                game_types.append(gt)  # only uses gametypes with elo values (needed later on)

        ## make sure gametypes list if sorted correctly (number of games, descending)
        ##game_types = sorted(game_types, key=lambda x: data['games_played'][x].games, reverse=True)
        # make sure gametypes list if sorted correctly (total playing time per game type, descending)
        game_types = sorted(game_types, key=lambda x: data['overall_stats'][x].total_playing_time, reverse=True)


        # build image

        surf = C.ImageSurface(C.FORMAT_ARGB32, self.width, self.height)
        ctx = C.Context(surf)
        self.ctx = ctx
        ctx.set_antialias(C.ANTIALIAS_GRAY)

        # set font hinting options
        fo = C.FontOptions()
        fo.set_antialias(C.ANTIALIAS_GRAY)
        fo.set_hint_style(C.HINT_STYLE_FULL)
        fo.set_hint_metrics(C.HINT_METRICS_ON)
        ctx.set_font_options(fo)

        # draw background
        if self.bg == None:
            if self.bgcolor != None:
                # plain fillcolor, full transparency possible with (1,1,1,0)
                ctx.save()
                ctx.set_operator(C.OPERATOR_SOURCE)
                ctx.rectangle(0, 0, self.width, self.height)
                ctx.set_source_rgba(self.bgcolor[0], self.bgcolor[1], self.bgcolor[2], self.bgcolor[3])
                ctx.fill()
                ctx.restore()
        else:
            try:
                # background texture
                bg = C.ImageSurface.create_from_png("img/%s.png" % self.bg)

                # tile image
                if bg:
                    bg_w, bg_h = bg.get_width(), bg.get_height()
                    bg_xoff = 0
                    while bg_xoff < self.width:
                        bg_yoff = 0
                        while bg_yoff < self.height:
                            ctx.set_source_surface(bg, bg_xoff, bg_yoff)
                            #ctx.mask_surface(bg)
                            ctx.paint()
                            bg_yoff += bg_h
                        bg_xoff += bg_w
            except:
                #print "Error: Can't load background texture: %s" % self.bg
                pass

        # draw overlay graphic
        if self.overlay != None:
            try:
                overlay = C.ImageSurface.create_from_png("img/%s.png" % self.overlay)
                ctx.set_source_surface(overlay, 0, 0)
                #ctx.mask_surface(overlay)
                ctx.paint()
            except:
                #print "Error: Can't load overlay texture: %s" % self.overlay
                pass


        ## draw player's nickname with fancy colors

        # deocde nick, strip all weird-looking characters
        qstr = qfont_decode(qstr=player.nick, glyph_translation=True).\
                replace('^^', '^').\
                replace(u'\x00', '')
        #chars = []
        #for c in qstr:
        #    # replace weird characters that make problems - TODO
        #    if ord(c) < 128:
        #        chars.append(c)
        #qstr = ''.join(chars)
        stripped_nick = strip_colors(qstr.replace(' ', '_'))

        # fontsize is reduced if width gets too large
        ctx.select_font_face(self.font, C.FONT_SLANT_NORMAL, C.FONT_WEIGHT_NORMAL)
        shrinknick = 0
        while shrinknick < 0.6 * self.nick_fontsize:
            ctx.set_font_size(self.nick_fontsize - shrinknick)
            xoff, yoff, tw, th = ctx.text_extents(stripped_nick)[:4]
            if tw > self.nick_maxwidth:
                shrinknick += 1
                continue
            break

        # determine width of single whitespace for later use
        xoff, yoff, tw, th = ctx.text_extents("_ _")[:4]
        space_w = tw
        xoff, yoff, tw, th = ctx.text_extents("__")[:4]
        space_w -= tw

        # this hilarious code should determine the spacing between characters
        sep_w = 0.2*space_w
        if sep_w <= 0:
            sep_w = 1

        # split nick into colored segments
        xoffset = 0
        _all_colors = re.compile(r'(\^\d|\^x[\dA-Fa-f]{3})')
        parts = _all_colors.split(qstr)
        while len(parts) > 0:
            tag = None
            txt = parts[0]
            if _all_colors.match(txt):
                tag = txt[1:]  # strip leading '^'
                if len(parts) < 2:
                    break
                txt = parts[1]
                del parts[1]
            del parts[0]

            if not txt or len(txt) == 0:
                # only colorcode and no real text, skip this
                continue

            if tag:
                if tag.startswith('x'):
                    r = int(tag[1] * 2, 16) / 255.0
                    g = int(tag[2] * 2, 16) / 255.0
                    b = int(tag[3] * 2, 16) / 255.0
                    hue, light, satur = rgb_to_hls(r, g, b)
                    if light < _contrast_threshold:
                        light = _contrast_threshold
                        r, g, b = hls_to_rgb(hue, light, satur)
                else:
                    r,g,b = _dec_colors[int(tag[0])]
            else:
                r,g,b = _dec_colors[7]

            xoff, yoff, tw, th = ctx.text_extents(txt)[:4]
            ctx.set_source_rgb(r, g, b)
            ctx.move_to(self.nick_pos[0] + xoffset - xoff, self.nick_pos[1])
            ctx.show_text(txt.encode("utf-8"))

            tw += (len(txt)-len(txt.strip())) * space_w  # account for lost whitespaces
            xoffset += int(tw + sep_w)

        ## print elos and ranks

        xoffset, yoffset = 0, 0
        count = 0
        for gt in game_types[:self.num_gametypes]:
            if not elos.has_key(gt):
                continue
            count += 1

        # re-align segments if less than max. gametypes are shown
        if count > 0:
            if count < self.num_gametypes:
                diff = self.num_gametypes - count
                if diff % 2 == 0:
                    xoffset += (diff-1) * self.gametype_width
                    yoffset += (diff-1) * self.gametype_height
                else:
                    xoffset += 0.5 * diff * self.gametype_width
                    yoffset += 0.5 * diff * self.gametype_height

            # show a number gametypes the player has participated in
            for gt in game_types[:self.num_gametypes]:
                if not elos.has_key(gt):  # should not happen
                    continue

                offset = (xoffset, yoffset)
                if self.gametype_pos:
                    if self.gametype_upper:
                        txt = self.gametype_text % gt.upper()
                    else:
                        txt = self.gametype_text % gt.lower()
                    self.set_font(self.gametype_fontsize, self.gametype_color, bold=True)
                    self.show_text(txt, self.gametype_pos, self.gametype_align, offset=offset)

                if self.elo_pos:
                    txt = self.elo_text % round(elos[gt], 0)
                    self.set_font(self.elo_fontsize, self.elo_color)
                    self.show_text(txt, self.elo_pos, self.elo_align, offset=offset)
                if  self.rank_pos:
                    if ranks.has_key(gt):
                        txt = self.rank_text % ranks[gt]
                    else:
                        txt = "(preliminary)"
                    self.set_font(self.rank_fontsize, self.rank_color)
                    self.show_text(txt, self.rank_pos, self.rank_align, offset=offset)

                xoffset += self.gametype_width
                yoffset += self.gametype_height
        else:
            if self.nostats_pos:
                xoffset += (self.num_gametypes-2) * self.gametype_width
                yoffset += (self.num_gametypes-2) * self.gametype_height
                offset = (xoffset, yoffset)

                txt = self.nostats_text
                self.set_font(self.nostats_fontsize, self.nostats_color, bold=True)
                self.show_text(txt, self.nostats_pos, self.nostats_align, angle=self.nostats_angle, offset=offset)


        # print win percentage

        if self.wintext_pos:
            txt = self.wintext_text
            self.set_font(self.wintext_fontsize, self.wintext_color)
            self.show_text(txt, self.wintext_pos, self.wintext_align)

        txt = "???"
        try:
            txt = "%.2f%%" % round(win_pct, 2)
        except:
            win_pct = 0.

        if self.winp_pos:
            if win_pct >= 50.0:
                nr = 2*(win_pct/100-0.5)
                r = nr*self.winp_colortop[0] + (1-nr)*self.winp_colormid[0]
                g = nr*self.winp_colortop[1] + (1-nr)*self.winp_colormid[1]
                b = nr*self.winp_colortop[2] + (1-nr)*self.winp_colormid[2]
            else:
                nr = 2*(win_pct/100)
                r = nr*self.winp_colormid[0] + (1-nr)*self.winp_colorbot[0]
                g = nr*self.winp_colormid[1] + (1-nr)*self.winp_colorbot[1]
                b = nr*self.winp_colormid[2] + (1-nr)*self.winp_colorbot[2]
            self.set_font(self.winp_fontsize, (r,g,b), bold=True)
            self.show_text(txt, self.winp_pos, self.winp_align)

        if self.wins_pos:
            txt = "%d win" % wins
            if wins != 1:
                txt += "s"
            self.set_font(self.wins_fontsize, self.wins_color)
            self.show_text(txt, self.wins_pos, self.wins_align)

        if self.loss_pos:
            txt = "%d loss" % losses
            if losses != 1:
                txt += "es"
            self.set_font(self.loss_fontsize, self.loss_color)
            self.show_text(txt, self.loss_pos, self.loss_align)


        # print kill/death ratio

        if self.kdtext_pos:
            txt = self.kdtext_text
            self.set_font(self.kdtext_fontsize, self.kdtext_color)
            self.show_text(txt, self.kdtext_pos, self.kdtext_align)

        txt = "???"
        try:
            txt = "%.3f" % round(kd_ratio, 3)
        except:
            kd_ratio = 0

        if self.kdr_pos:
            if kd_ratio >= 1.0:
                nr = kd_ratio-1.0
                if nr > 1:
                    nr = 1
                r = nr*self.kdr_colortop[0] + (1-nr)*self.kdr_colormid[0]
                g = nr*self.kdr_colortop[1] + (1-nr)*self.kdr_colormid[1]
                b = nr*self.kdr_colortop[2] + (1-nr)*self.kdr_colormid[2]
            else:
                nr = kd_ratio
                r = nr*self.kdr_colormid[0] + (1-nr)*self.kdr_colorbot[0]
                g = nr*self.kdr_colormid[1] + (1-nr)*self.kdr_colorbot[1]
                b = nr*self.kdr_colormid[2] + (1-nr)*self.kdr_colorbot[2]
            self.set_font(self.kdr_fontsize, (r,g,b), bold=True)
            self.show_text(txt, self.kdr_pos, self.kdr_align)

        if self.kills_pos:
            txt = "%d kill" % kills
            if kills != 1:
                txt += "s"
            self.set_font(self.kills_fontsize, self.kills_color)
            self.show_text(txt, self.kills_pos, self.kills_align)

        if self.deaths_pos:
            txt = ""
            if deaths is not None:
                txt = "%d death" % deaths
                if deaths != 1:
                    txt += "s"
            self.set_font(self.deaths_fontsize, self.deaths_color)
            self.show_text(txt, self.deaths_pos, self.deaths_align)


        # print playing time

        if self.ptime_pos:
            txt = self.ptime_text % str(alivetime)
            self.set_font(self.ptime_fontsize, self.ptime_color)
            self.show_text(txt, self.ptime_pos, self.ptime_align)


        # save to PNG
        #surf.write_to_png(output_filename)
        surf.flush()
        imgdata = surf.get_data()
        write_png(output_filename, imgdata, self.width, self.height)
Example #16
0
    def render_image(self, data, output_filename):
        """Render an image for the given player id."""

        # setup variables

        player          = data.player
        elos            = data.elos
        ranks           = data.ranks
        #games           = data.total_stats['games']
        wins, losses    = data.total_stats['wins'], data.total_stats['losses']
        games           = wins + losses
        kills, deaths   = data.total_stats['kills'], data.total_stats['deaths']
        alivetime       = data.total_stats['alivetime']


        # build image

        surf = C.ImageSurface(C.FORMAT_ARGB32, self.width, self.height)
        ctx = C.Context(surf)
        self.ctx = ctx
        ctx.set_antialias(C.ANTIALIAS_GRAY)
        
        # draw background
        if self.bg == None:
            if self.bgcolor != None:
                # plain fillcolor, full transparency possible with (1,1,1,0)
                ctx.save()
                ctx.set_operator(C.OPERATOR_SOURCE)
                ctx.rectangle(0, 0, self.width, self.height)
                ctx.set_source_rgba(self.bgcolor[0], self.bgcolor[1], self.bgcolor[2], self.bgcolor[3])
                ctx.fill()
                ctx.restore()
        else:
            try:
                # background texture
                bg = C.ImageSurface.create_from_png("img/%s.png" % self.bg)
                
                # tile image
                if bg:
                    bg_w, bg_h = bg.get_width(), bg.get_height()
                    bg_xoff = 0
                    while bg_xoff < self.width:
                        bg_yoff = 0
                        while bg_yoff < self.height:
                            ctx.set_source_surface(bg, bg_xoff, bg_yoff)
                            #ctx.mask_surface(bg)
                            ctx.paint()
                            bg_yoff += bg_h
                        bg_xoff += bg_w
            except:
                #print "Error: Can't load background texture: %s" % self.bg
                pass

        # draw overlay graphic
        if self.overlay != None:
            try:
                overlay = C.ImageSurface.create_from_png("img/%s.png" % self.overlay)
                ctx.set_source_surface(overlay, 0, 0)
                #ctx.mask_surface(overlay)
                ctx.paint()
            except:
                #print "Error: Can't load overlay texture: %s" % self.overlay
                pass


        ## draw player's nickname with fancy colors
        
        # deocde nick, strip all weird-looking characters
        qstr = qfont_decode(player.nick).replace('^^', '^').replace(u'\x00', '')
        chars = []
        for c in qstr:
            # replace weird characters that make problems - TODO
            if ord(c) < 128:
                chars.append(c)
        qstr = ''.join(chars)
        stripped_nick = strip_colors(qstr.replace(' ', '_'))
        
        # fontsize is reduced if width gets too large
        ctx.select_font_face(self.font, C.FONT_SLANT_NORMAL, C.FONT_WEIGHT_NORMAL)
        shrinknick = 0
        while shrinknick < 0.6 * self.nick_fontsize:
            ctx.set_font_size(self.nick_fontsize - shrinknick)
            xoff, yoff, tw, th = ctx.text_extents(stripped_nick)[:4]
            if tw > self.nick_maxwidth:
                shrinknick += 1
                continue
            break

        # determine width of single whitespace for later use
        xoff, yoff, tw, th = ctx.text_extents("_")[:4]
        space_w = tw

        # split nick into colored segments
        xoffset = 0
        _all_colors = re.compile(r'(\^\d|\^x[\dA-Fa-f]{3})')
        parts = _all_colors.split(qstr)
        while len(parts) > 0:
            tag = None
            txt = parts[0]
            if _all_colors.match(txt):
                tag = txt[1:]  # strip leading '^'
                if len(parts) < 2:
                    break
                txt = parts[1]
                del parts[1]
            del parts[0]
                
            if not txt or len(txt) == 0:
                # only colorcode and no real text, skip this
                continue
            
            if tag:
                if tag.startswith('x'):
                    r = int(tag[1] * 2, 16) / 255.0
                    g = int(tag[2] * 2, 16) / 255.0
                    b = int(tag[3] * 2, 16) / 255.0
                    hue, light, satur = rgb_to_hls(r, g, b)
                    if light < _contrast_threshold:
                        light = _contrast_threshold
                        r, g, b = hls_to_rgb(hue, light, satur)
                else:
                    r,g,b = _dec_colors[int(tag[0])]
            else:
                r,g,b = _dec_colors[7]

            xoff, yoff, tw, th = ctx.text_extents(txt)[:4]
            ctx.set_source_rgb(r, g, b)
            ctx.move_to(self.nick_pos[0] + xoffset - xoff, self.nick_pos[1])
            ctx.show_text(txt)

            tw += (len(txt)-len(txt.strip())) * space_w  # account for lost whitespaces
            xoffset += tw + 2

        ## print elos and ranks
        
        xoffset, yoffset = 0, 0
        count = 0
        for gt in data.total_stats['gametypes'][:self.num_gametypes]:
            if not elos.has_key(gt) or not ranks.has_key(gt):
                continue
            count += 1
        
        # re-align segments if less than max. gametypes are shown
        if count > 0:
            if count < self.num_gametypes:
                diff = self.num_gametypes - count
                if diff % 2 == 0:
                    xoffset += (diff-1) * self.gametype_width
                    yoffset += (diff-1) * self.gametype_height
                else:
                    xoffset += 0.5 * diff * self.gametype_width
                    yoffset += 0.5 * diff * self.gametype_height
        
            # show a number gametypes the player has participated in
            for gt in data.total_stats['gametypes'][:self.num_gametypes]:
                if not elos.has_key(gt) or not ranks.has_key(gt):
                    continue

                offset = (xoffset, yoffset)
                if self.gametype_pos:
                    if self.gametype_upper:
                        txt = self.gametype_text % gt.upper()
                    else:
                        txt = self.gametype_text % gt.lower()
                    self.set_font(self.gametype_fontsize, self.gametype_color, bold=True)
                    self.show_text(txt, self.gametype_pos, self.gametype_align, offset=offset)

                if self.elo_pos:
                    txt = self.elo_text % round(elos[gt], 0)
                    self.set_font(self.elo_fontsize, self.elo_color)
                    self.show_text(txt, self.elo_pos, self.elo_align, offset=offset)
                if  self.rank_pos:
                    txt = self.rank_text % ranks[gt]
                    self.set_font(self.rank_fontsize, self.rank_color)
                    self.show_text(txt, self.rank_pos, self.rank_align, offset=offset)

                xoffset += self.gametype_width
                yoffset += self.gametype_height
        else:
            if self.nostats_pos:
                xoffset += (self.num_gametypes-2) * self.gametype_width
                yoffset += (self.num_gametypes-2) * self.gametype_height
                offset = (xoffset, yoffset)

                txt = self.nostats_text
                self.set_font(self.nostats_fontsize, self.nostats_color, bold=True)
                self.show_text(txt, self.nostats_pos, self.nostats_align, angle=self.nostats_angle, offset=offset)


        # print win percentage

        if self.wintext_pos:
            txt = self.wintext_text
            self.set_font(self.wintext_fontsize, self.wintext_color)
            self.show_text(txt, self.wintext_pos, self.wintext_align)

        txt = "???"
        try:
            ratio = float(wins)/games
            txt = "%.2f%%" % round(ratio * 100, 2)
        except:
            ratio = 0
        
        if self.winp_pos:
            if ratio >= 0.5:
                nr = 2*(ratio-0.5)
                r = nr*self.winp_colortop[0] + (1-nr)*self.winp_colormid[0]
                g = nr*self.winp_colortop[1] + (1-nr)*self.winp_colormid[1]
                b = nr*self.winp_colortop[2] + (1-nr)*self.winp_colormid[2]
            else:
                nr = 2*ratio
                r = nr*self.winp_colormid[0] + (1-nr)*self.winp_colorbot[0]
                g = nr*self.winp_colormid[1] + (1-nr)*self.winp_colorbot[1]
                b = nr*self.winp_colormid[2] + (1-nr)*self.winp_colorbot[2]
            self.set_font(self.winp_fontsize, (r,g,b), bold=True)
            self.show_text(txt, self.winp_pos, self.winp_align)

        if self.wins_pos:
            txt = "%d win" % wins
            if wins != 1:
                txt += "s"
            self.set_font(self.wins_fontsize, self.wins_color)
            self.show_text(txt, self.wins_pos, self.wins_align)

        if self.loss_pos:
            txt = "%d loss" % losses
            if losses != 1:
                txt += "es"
            self.set_font(self.loss_fontsize, self.loss_color)
            self.show_text(txt, self.loss_pos, self.loss_align)


        # print kill/death ratio

        if self.kdtext_pos:
            txt = self.kdtext_text
            self.set_font(self.kdtext_fontsize, self.kdtext_color)
            self.show_text(txt, self.kdtext_pos, self.kdtext_align)
        
        txt = "???"
        try:
            ratio = float(kills)/deaths
            txt = "%.3f" % round(ratio, 3)
        except:
            ratio = 0

        if self.kdr_pos:
            if ratio >= 1.0:
                nr = ratio-1.0
                if nr > 1:
                    nr = 1
                r = nr*self.kdr_colortop[0] + (1-nr)*self.kdr_colormid[0]
                g = nr*self.kdr_colortop[1] + (1-nr)*self.kdr_colormid[1]
                b = nr*self.kdr_colortop[2] + (1-nr)*self.kdr_colormid[2]
            else:
                nr = ratio
                r = nr*self.kdr_colormid[0] + (1-nr)*self.kdr_colorbot[0]
                g = nr*self.kdr_colormid[1] + (1-nr)*self.kdr_colorbot[1]
                b = nr*self.kdr_colormid[2] + (1-nr)*self.kdr_colorbot[2]
            self.set_font(self.kdr_fontsize, (r,g,b), bold=True)
            self.show_text(txt, self.kdr_pos, self.kdr_align)

        if self.kills_pos:
            txt = "%d kill" % kills
            if kills != 1:
                txt += "s"
            self.set_font(self.kills_fontsize, self.kills_color)
            self.show_text(txt, self.kills_pos, self.kills_align)

        if self.deaths_pos:
            txt = ""
            if deaths is not None:
                txt = "%d death" % deaths
                if deaths != 1:
                    txt += "s"
            self.set_font(self.deaths_fontsize, self.deaths_color)
            self.show_text(txt, self.deaths_pos, self.deaths_align)


        # print playing time

        if self.ptime_pos:
            txt = self.ptime_text % str(alivetime)
            self.set_font(self.ptime_fontsize, self.ptime_color)
            self.show_text(txt, self.ptime_pos, self.ptime_align)


        # save to PNG
        #surf.write_to_png(output_filename)
        surf.flush()
        imgdata = surf.get_data()
        write_png(output_filename, imgdata, self.width, self.height)
Example #17
0
 def nick_strip_colors(self):
     if self.nick is None:
         return "Anonymous Player"
     else:
         return strip_colors(self.nick)
Example #18
0
    def render_image(self, data, output_filename):
        """Render an image for the given player id."""

        # setup variables

        player = data['player']
        elos = data['elos']
        ranks = data['ranks']
        games_played = data['games_played']['overall']
        overall_stats = data['overall_stats']['overall']

        wins, losses, win_pct = games_played.wins, games_played.losses, games_played.win_pct
        games = games_played.games
        kills, deaths, kd_ratio = overall_stats.total_kills, overall_stats.total_deaths, overall_stats.k_d_ratio
        alivetime = overall_stats.total_playing_time

        # make sorted list of gametypes
        game_types = []
        for gt in data['games_played'].keys():
            if gt == 'overall':
                continue
            if elos.has_key(gt):
                game_types.append(
                    gt
                )  # only uses gametypes with elo values (needed later on)

        ## make sure gametypes list if sorted correctly (number of games, descending)
        ##game_types = sorted(game_types, key=lambda x: data['games_played'][x].games, reverse=True)
        # make sure gametypes list if sorted correctly (total playing time per game type, descending)
        game_types = sorted(
            game_types,
            key=lambda x: data['overall_stats'][x].total_playing_time,
            reverse=True)

        # build image

        surf = C.ImageSurface(C.FORMAT_ARGB32, self.width, self.height)
        ctx = C.Context(surf)
        self.ctx = ctx
        ctx.set_antialias(C.ANTIALIAS_GRAY)

        # draw background
        if self.bg == None:
            if self.bgcolor != None:
                # plain fillcolor, full transparency possible with (1,1,1,0)
                ctx.save()
                ctx.set_operator(C.OPERATOR_SOURCE)
                ctx.rectangle(0, 0, self.width, self.height)
                ctx.set_source_rgba(self.bgcolor[0], self.bgcolor[1],
                                    self.bgcolor[2], self.bgcolor[3])
                ctx.fill()
                ctx.restore()
        else:
            try:
                # background texture
                bg = C.ImageSurface.create_from_png("img/%s.png" % self.bg)

                # tile image
                if bg:
                    bg_w, bg_h = bg.get_width(), bg.get_height()
                    bg_xoff = 0
                    while bg_xoff < self.width:
                        bg_yoff = 0
                        while bg_yoff < self.height:
                            ctx.set_source_surface(bg, bg_xoff, bg_yoff)
                            #ctx.mask_surface(bg)
                            ctx.paint()
                            bg_yoff += bg_h
                        bg_xoff += bg_w
            except:
                #print "Error: Can't load background texture: %s" % self.bg
                pass

        # draw overlay graphic
        if self.overlay != None:
            try:
                overlay = C.ImageSurface.create_from_png("img/%s.png" %
                                                         self.overlay)
                ctx.set_source_surface(overlay, 0, 0)
                #ctx.mask_surface(overlay)
                ctx.paint()
            except:
                #print "Error: Can't load overlay texture: %s" % self.overlay
                pass

        ## draw player's nickname with fancy colors

        # deocde nick, strip all weird-looking characters
        qstr = qfont_decode(qstr=player.nick, glyph_translation=True).\
                replace('^^', '^').\
                replace(u'\x00', '')
        #chars = []
        #for c in qstr:
        #    # replace weird characters that make problems - TODO
        #    if ord(c) < 128:
        #        chars.append(c)
        #qstr = ''.join(chars)
        stripped_nick = strip_colors(qstr.replace(' ', '_'))

        # fontsize is reduced if width gets too large
        ctx.select_font_face(self.font, C.FONT_SLANT_NORMAL,
                             C.FONT_WEIGHT_NORMAL)
        shrinknick = 0
        while shrinknick < 0.6 * self.nick_fontsize:
            ctx.set_font_size(self.nick_fontsize - shrinknick)
            xoff, yoff, tw, th = ctx.text_extents(stripped_nick)[:4]
            if tw > self.nick_maxwidth:
                shrinknick += 1
                continue
            break

        # determine width of single whitespace for later use
        xoff, yoff, tw, th = ctx.text_extents("_ _")[:4]
        space_w = tw
        xoff, yoff, tw, th = ctx.text_extents("__")[:4]
        space_w -= tw

        # this hilarious code should determine the spacing between characters
        sep_w = 0.2 * space_w
        if sep_w <= 0:
            sep_w = 1

        # split nick into colored segments
        xoffset = 0
        _all_colors = re.compile(r'(\^\d|\^x[\dA-Fa-f]{3})')
        parts = _all_colors.split(qstr)
        while len(parts) > 0:
            tag = None
            txt = parts[0]
            if _all_colors.match(txt):
                tag = txt[1:]  # strip leading '^'
                if len(parts) < 2:
                    break
                txt = parts[1]
                del parts[1]
            del parts[0]

            if not txt or len(txt) == 0:
                # only colorcode and no real text, skip this
                continue

            if tag:
                if tag.startswith('x'):
                    r = int(tag[1] * 2, 16) / 255.0
                    g = int(tag[2] * 2, 16) / 255.0
                    b = int(tag[3] * 2, 16) / 255.0
                    hue, light, satur = rgb_to_hls(r, g, b)
                    if light < _contrast_threshold:
                        light = _contrast_threshold
                        r, g, b = hls_to_rgb(hue, light, satur)
                else:
                    r, g, b = _dec_colors[int(tag[0])]
            else:
                r, g, b = _dec_colors[7]

            xoff, yoff, tw, th = ctx.text_extents(txt)[:4]
            ctx.set_source_rgb(r, g, b)
            ctx.move_to(self.nick_pos[0] + xoffset - xoff, self.nick_pos[1])
            ctx.show_text(txt.encode("utf-8"))

            tw += (len(txt) -
                   len(txt.strip())) * space_w  # account for lost whitespaces
            xoffset += int(tw + sep_w)

        ## print elos and ranks

        xoffset, yoffset = 0, 0
        count = 0
        for gt in game_types[:self.num_gametypes]:
            if not elos.has_key(gt):
                continue
            count += 1

        # re-align segments if less than max. gametypes are shown
        if count > 0:
            if count < self.num_gametypes:
                diff = self.num_gametypes - count
                if diff % 2 == 0:
                    xoffset += (diff - 1) * self.gametype_width
                    yoffset += (diff - 1) * self.gametype_height
                else:
                    xoffset += 0.5 * diff * self.gametype_width
                    yoffset += 0.5 * diff * self.gametype_height

            # show a number gametypes the player has participated in
            for gt in game_types[:self.num_gametypes]:
                if not elos.has_key(gt):  # should not happen
                    continue

                offset = (xoffset, yoffset)
                if self.gametype_pos:
                    if self.gametype_upper:
                        txt = self.gametype_text % gt.upper()
                    else:
                        txt = self.gametype_text % gt.lower()
                    self.set_font(self.gametype_fontsize,
                                  self.gametype_color,
                                  bold=True)
                    self.show_text(txt,
                                   self.gametype_pos,
                                   self.gametype_align,
                                   offset=offset)

                if self.elo_pos:
                    txt = self.elo_text % round(elos[gt], 0)
                    self.set_font(self.elo_fontsize, self.elo_color)
                    self.show_text(txt,
                                   self.elo_pos,
                                   self.elo_align,
                                   offset=offset)
                if self.rank_pos:
                    if ranks.has_key(gt):
                        txt = self.rank_text % ranks[gt]
                    else:
                        txt = "(preliminary)"
                    self.set_font(self.rank_fontsize, self.rank_color)
                    self.show_text(txt,
                                   self.rank_pos,
                                   self.rank_align,
                                   offset=offset)

                xoffset += self.gametype_width
                yoffset += self.gametype_height
        else:
            if self.nostats_pos:
                xoffset += (self.num_gametypes - 2) * self.gametype_width
                yoffset += (self.num_gametypes - 2) * self.gametype_height
                offset = (xoffset, yoffset)

                txt = self.nostats_text
                self.set_font(self.nostats_fontsize,
                              self.nostats_color,
                              bold=True)
                self.show_text(txt,
                               self.nostats_pos,
                               self.nostats_align,
                               angle=self.nostats_angle,
                               offset=offset)

        # print win percentage

        if self.wintext_pos:
            txt = self.wintext_text
            self.set_font(self.wintext_fontsize, self.wintext_color)
            self.show_text(txt, self.wintext_pos, self.wintext_align)

        txt = "???"
        try:
            txt = "%.2f%%" % round(win_pct, 2)
        except:
            win_pct = 0.

        if self.winp_pos:
            if win_pct >= 50.0:
                nr = 2 * (win_pct / 100 - 0.5)
                r = nr * self.winp_colortop[0] + (1 -
                                                  nr) * self.winp_colormid[0]
                g = nr * self.winp_colortop[1] + (1 -
                                                  nr) * self.winp_colormid[1]
                b = nr * self.winp_colortop[2] + (1 -
                                                  nr) * self.winp_colormid[2]
            else:
                nr = 2 * (win_pct / 100)
                r = nr * self.winp_colormid[0] + (1 -
                                                  nr) * self.winp_colorbot[0]
                g = nr * self.winp_colormid[1] + (1 -
                                                  nr) * self.winp_colorbot[1]
                b = nr * self.winp_colormid[2] + (1 -
                                                  nr) * self.winp_colorbot[2]
            self.set_font(self.winp_fontsize, (r, g, b), bold=True)
            self.show_text(txt, self.winp_pos, self.winp_align)

        if self.wins_pos:
            txt = "%d win" % wins
            if wins != 1:
                txt += "s"
            self.set_font(self.wins_fontsize, self.wins_color)
            self.show_text(txt, self.wins_pos, self.wins_align)

        if self.loss_pos:
            txt = "%d loss" % losses
            if losses != 1:
                txt += "es"
            self.set_font(self.loss_fontsize, self.loss_color)
            self.show_text(txt, self.loss_pos, self.loss_align)

        # print kill/death ratio

        if self.kdtext_pos:
            txt = self.kdtext_text
            self.set_font(self.kdtext_fontsize, self.kdtext_color)
            self.show_text(txt, self.kdtext_pos, self.kdtext_align)

        txt = "???"
        try:
            txt = "%.3f" % round(kd_ratio, 3)
        except:
            kd_ratio = 0

        if self.kdr_pos:
            if kd_ratio >= 1.0:
                nr = kd_ratio - 1.0
                if nr > 1:
                    nr = 1
                r = nr * self.kdr_colortop[0] + (1 - nr) * self.kdr_colormid[0]
                g = nr * self.kdr_colortop[1] + (1 - nr) * self.kdr_colormid[1]
                b = nr * self.kdr_colortop[2] + (1 - nr) * self.kdr_colormid[2]
            else:
                nr = kd_ratio
                r = nr * self.kdr_colormid[0] + (1 - nr) * self.kdr_colorbot[0]
                g = nr * self.kdr_colormid[1] + (1 - nr) * self.kdr_colorbot[1]
                b = nr * self.kdr_colormid[2] + (1 - nr) * self.kdr_colorbot[2]
            self.set_font(self.kdr_fontsize, (r, g, b), bold=True)
            self.show_text(txt, self.kdr_pos, self.kdr_align)

        if self.kills_pos:
            txt = "%d kill" % kills
            if kills != 1:
                txt += "s"
            self.set_font(self.kills_fontsize, self.kills_color)
            self.show_text(txt, self.kills_pos, self.kills_align)

        if self.deaths_pos:
            txt = ""
            if deaths is not None:
                txt = "%d death" % deaths
                if deaths != 1:
                    txt += "s"
            self.set_font(self.deaths_fontsize, self.deaths_color)
            self.show_text(txt, self.deaths_pos, self.deaths_align)

        # print playing time

        if self.ptime_pos:
            txt = self.ptime_text % str(alivetime)
            self.set_font(self.ptime_fontsize, self.ptime_color)
            self.show_text(txt, self.ptime_pos, self.ptime_align)

        # save to PNG
        #surf.write_to_png(output_filename)
        surf.flush()
        imgdata = surf.get_data()
        write_png(output_filename, imgdata, self.width, self.height)
Example #19
0
File: models.py Project: z/XonStat
 def nick_stripped(self):
     return strip_colors(self.nick)