]> de.git.xonotic.org Git - xonotic/xonstat.git/blobdiff - xonstat/batch/badges/skin.py
fix missing gametypes in some player badges
[xonotic/xonstat.git] / xonstat / batch / badges / skin.py
index 813594df2567cf560231bee4103556474cd991e7..edcb2eb4acde76cff706f71b9008abac03d05e73 100644 (file)
@@ -67,8 +67,8 @@ class Skin:
             'width':            560,
             'height':           70,
             'nick_fontsize':    20,
-            'nick_pos':         (56,18),
-            'nick_maxwidth':    280,
+            'nick_pos':         (52,18),
+            'nick_maxwidth':    270,
             'gametype_fontsize':10,
             'gametype_pos':     (101,33),
             'gametype_width':   94,
@@ -140,7 +140,7 @@ class Skin:
             'ptime_text':       "Playing Time: %s",
             'ptime_align':      0,
         }
-        
+
         for k,v in params.items():
             if self.params.has_key(k):
                 self.params[k] = v
@@ -191,14 +191,29 @@ class Skin:
 
         # 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']
+        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
@@ -207,7 +222,7 @@ class Skin:
         ctx = C.Context(surf)
         self.ctx = ctx
         ctx.set_antialias(C.ANTIALIAS_GRAY)
-        
+
         # draw background
         if self.bg == None:
             if self.bgcolor != None:
@@ -222,7 +237,7 @@ class Skin:
             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()
@@ -252,17 +267,17 @@ class Skin:
 
 
         ## 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)
+        #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
@@ -275,8 +290,15 @@ class Skin:
             break
 
         # determine width of single whitespace for later use
-        xoff, yoff, tw, th = ctx.text_extents("_")[:4]
+        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
@@ -292,11 +314,11 @@ class Skin:
                 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
@@ -314,20 +336,20 @@ class Skin:
             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)
+            ctx.show_text(txt.encode("utf-8"))
 
             tw += (len(txt)-len(txt.strip())) * space_w  # account for lost whitespaces
-            xoffset += tw + 2
+            xoffset += int(tw + sep_w)
 
         ## 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):
+        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:
@@ -338,10 +360,10 @@ class Skin:
                 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):
+            for gt in game_types[:self.num_gametypes]:
+                if not elos.has_key(gt):  # should not happen
                     continue
 
                 offset = (xoffset, yoffset)
@@ -358,7 +380,10 @@ class Skin:
                     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]
+                    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)
 
@@ -384,19 +409,18 @@ class Skin:
 
         txt = "???"
         try:
-            ratio = float(wins)/games
-            txt = "%.2f%%" % round(ratio * 100, 2)
+            txt = "%.2f%%" % round(win_pct, 2)
         except:
-            ratio = 0
-        
+            win_pct = 0.
+
         if self.winp_pos:
-            if ratio >= 0.5:
-                nr = 2*(ratio-0.5)
+            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*ratio
+                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]
@@ -424,24 +448,23 @@ class Skin:
             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)
+            txt = "%.3f" % round(kd_ratio, 3)
         except:
-            ratio = 0
+            kd_ratio = 0
 
         if self.kdr_pos:
-            if ratio >= 1.0:
-                nr = ratio-1.0
+            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 = ratio
+                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]