]> de.git.xonotic.org Git - xonotic/xonstat.git/blob - xonstat/batch/badges/gen_badges.py
Added artwork by Archer, in addition to "classic" and "minimal" skins
[xonotic/xonstat.git] / xonstat / batch / badges / gen_badges.py
1 #-*- coding: utf-8 -*-
2
3 import sys
4 from datetime import datetime
5 import sqlalchemy as sa
6 import sqlalchemy.sql.functions as func
7 from sqlalchemy import distinct
8 from pyramid.paster import bootstrap
9 from xonstat.models import *
10 from xonstat.util import datetime_seconds
11
12 from skin import Skin
13 from playerdata import PlayerData
14
15
16 # maximal number of query results (for testing, set to None to get all)
17 NUM_PLAYERS = None
18
19 # we look for players who have activity within the past DELTA hours
20 DELTA = 6
21
22
23 # classic skin WITHOUT NAME - writes PNGs into "output//###.png"
24 skin_classic = Skin( "",
25         bg              = "broken_noise",
26         overlay         = "overlay_classic",
27     )
28
29 # more fancy skin [** WIP **]- writes PNGs into "output/archer/###.png"
30 skin_archer = Skin( "archer",
31         #bg              = "background_archer-v2_full",
32         bg              = "background_archer-v3",
33         overlay         = "",
34         nick_maxwidth   = 265,
35         gametype_pos    = (91,33),
36         nostats_pos     = (91,59),
37         elo_pos         = (91,47),
38         rank_pos        = (91,58),
39         winp_pos        = (509,20),
40         wins_pos        = (508,35),
41         loss_pos        = (508,45),
42         kdr_pos         = (392,20),
43         kills_pos       = (392,35),
44         deaths_pos      = (392,45),
45         ptime_color     = (0.05, 0.05, 0.1),
46     )
47
48 # minimal skin - writes PNGs into "output/minimal/###.png"
49 skin_minimal = Skin( "minimal",
50         bg              = None,
51         bgcolor         = (0.04, 0.04, 0.04, 1.0),
52         overlay         = "overlay_minimal",
53         width           = 560,
54         height          = 40,
55         nick_fontsize   = 16,
56         nick_pos        = (36,16),
57         num_gametypes   = 3,
58         nick_maxwidth   = 300,
59         gametype_pos    = (70,30),
60         gametype_color  = (0.0, 0.0, 0.0),
61         gametype_text   = "%s:",
62         gametype_width  = 100,
63         gametype_fontsize = 10,
64         gametype_align  = -1,
65         gametype_upper  = False,
66         elo_pos         = (75,30),
67         elo_text        = "Elo %.0f",
68         elo_color       = (0.7, 0.7, 0.7),
69         elo_align       = 1,
70         rank_pos        = None,
71         nostats_pos     = None,
72         #nostats_pos     = (75,30),
73         #nostats_fontsize = 10,
74         #nostats_angle   = 0,
75         #nostats_text    = "no stats yet!",
76         #nostats_color   = (0.7, 0.4, 0.4),
77         kdr_pos         = (392,15),
78         kdr_fontsize    = 10,
79         kdr_colortop    = (0.6, 0.8, 0.6),
80         kdr_colormid    = (0.6, 0.6, 0.6),
81         kdr_colorbot    = (0.8, 0.6, 0.6),
82         kills_pos       = None,
83         deaths_pos      = None,
84         winp_pos        = (508,15),
85         winp_fontsize   = 10,
86         winp_colortop   = (0.6, 0.8, 0.8),
87         winp_colormid   = (0.6, 0.6, 0.6),
88         winp_colorbot   = (0.8, 0.8, 0.6),
89         wins_pos        = None,
90         loss_pos        = None,
91         ptime_pos       = (451,30),
92         ptime_color     = (0.7, 0.7, 0.7),
93     )
94
95
96 # parse cmdline parameters (for testing)
97
98 skins = []
99 for arg in sys.argv[1:]:
100     if arg.startswith("-"):
101         arg = arg[1:]
102         if arg == "force":
103             DELTA = 2**24   # large enough to enforce update, and doesn't result in errors
104         elif arg == "test":
105             NUM_PLAYERS = 100
106         else:
107             print """Usage:  gen_badges.py [options] [skin list]
108     Options:
109         -force      Force updating all badges (delta = 2^24)
110         -test       Limit number of players to 100 (for testing)
111         -help       Show this help text
112     Skin list:
113         Space-separated list of skins to use when creating badges.
114         Available skins:  classic, minimal, archer
115         If no skins are given, classic and minmal will be used by default.
116         NOTE: Output directories must exists before running the program!
117 """
118             sys.exit(-1)
119     else:
120         if arg == "classic":
121             skins.append(skin_classic)
122         elif arg == "minimal":
123             skins.append(skin_minimal)
124         elif arg == "archer":
125             skins.append(skin_archer)
126
127 if len(skins) == 0:
128     skins = [ skin_classic, skin_minimal, skin_archer ]
129
130 # environment setup
131 env = bootstrap('../../../development.ini')
132 req = env['request']
133 req.matchdict = {'id':3}
134
135 print "Requesting player data from db ..."
136 cutoff_dt = datetime.utcnow() - timedelta(hours=DELTA)
137 start = datetime.now()
138 players = []
139 if NUM_PLAYERS:
140     players = DBSession.query(distinct(Player.player_id)).\
141             filter(Player.player_id == PlayerElo.player_id).\
142             filter(Player.player_id == PlayerGameStat.player_id).\
143             filter(PlayerGameStat.create_dt > cutoff_dt).\
144             filter(Player.nick != None).\
145             filter(Player.player_id > 2).\
146             filter(Player.active_ind == True).\
147             limit(NUM_PLAYERS).all()
148 else:
149     players = DBSession.query(distinct(Player.player_id)).\
150             filter(Player.player_id == PlayerElo.player_id).\
151             filter(Player.player_id == PlayerGameStat.player_id).\
152             filter(PlayerGameStat.create_dt > cutoff_dt).\
153             filter(Player.nick != None).\
154             filter(Player.player_id > 2).\
155             filter(Player.active_ind == True).\
156             all()
157
158 playerdata = PlayerData()
159
160 if len(players) > 0:
161     stop = datetime.now()
162     td = stop-start
163     print "Query took %.2f seconds" % (datetime_seconds(td))
164
165     print "Creating badges for %d players ..." % len(players)
166     start = datetime.now()
167     data_time, render_time = 0,0
168     for player_id in players:
169         req.matchdict['id'] = player_id
170
171         sstart = datetime.now()
172         playerdata.get_data(player_id)
173         sstop = datetime.now()
174         td = sstop-sstart
175         data_time += datetime_seconds(td)
176
177         sstart = datetime.now()
178         for sk in skins:
179             sk.render_image(playerdata, "output/%s/%d.png" % (str(sk), player_id[0]))
180         sstop = datetime.now()
181         td = sstop-sstart
182         render_time += datetime_seconds(td)
183
184     stop = datetime.now()
185     td = stop-start
186     total_seconds = datetime_seconds(td)
187     print "Creating the badges took %.1f seconds (%.3f s per player)" % (total_seconds, total_seconds/float(len(players)))
188     print "Total time for rendering images: %.3f s" % render_time
189     print "Total time for getting data: %.3f s" % data_time
190
191 else:
192     print "No active players found!"
193