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