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