4 import sqlalchemy as sa
\r
5 import sqlalchemy.sql.functions as func
\r
7 from pyramid.response import Response
\r
8 from pyramid.url import current_route_url
\r
9 from sqlalchemy import desc
\r
10 from webhelpers.paginate import Page, PageURL
\r
11 from xonstat.models import *
\r
12 from xonstat.util import page_url
\r
14 log = logging.getLogger(__name__)
\r
17 def player_index(request):
\r
19 Provides a list of all the current players.
\r
21 if 'page' in request.matchdict:
\r
22 current_page = int(request.matchdict['page'])
\r
27 player_q = DBSession.query(Player).\
\r
28 filter(Player.player_id > 2).\
\r
29 filter(Player.active_ind == True).\
\r
30 filter(sa.not_(Player.nick.like('Anonymous Player%'))).\
\r
31 order_by(Player.player_id.desc())
\r
33 players = Page(player_q, current_page, items_per_page=10, url=page_url)
\r
35 last_linked_page = current_page + 4
\r
36 if last_linked_page > players.last_page:
\r
37 last_linked_page = players.last_page
\r
39 pages_to_link = range(current_page+1, last_linked_page+1)
\r
41 except Exception as e:
\r
45 return {'players':players,
\r
46 'pages_to_link':pages_to_link,
\r
50 def get_games_played(player_id):
\r
52 Provides a breakdown by gametype of the games played by player_id.
\r
54 Returns a tuple containing (total_games, games_breakdown), where
\r
55 total_games is the absolute number of games played by player_id
\r
56 and games_breakdown is an array containing (game_type_cd, # games)
\r
58 games_played = DBSession.query(Game.game_type_cd, func.count()).\
\r
59 filter(Game.game_id == PlayerGameStat.game_id).\
\r
60 filter(PlayerGameStat.player_id == player_id).\
\r
61 group_by(Game.game_type_cd).\
\r
62 order_by(func.count().desc()).all()
\r
65 for (game_type_cd, games) in games_played:
\r
68 return (total, games_played)
\r
71 # TODO: should probably factor the above function into this one such that
\r
72 # total_stats['ctf_games'] is the count of CTF games and so on...
\r
73 def get_total_stats(player_id):
\r
75 Provides aggregated stats by player_id.
\r
77 Returns a dict with the keys 'kills', 'deaths', 'alivetime'.
\r
79 kills = how many kills a player has over all games
\r
80 deaths = how many deaths a player has over all games
\r
81 alivetime = how long a player has played over all games
\r
83 If any of the above are None, they are set to 0.
\r
86 (total_stats['kills'], total_stats['deaths'], total_stats['alivetime']) = DBSession.\
\r
87 query("total_kills", "total_deaths", "total_alivetime").\
\r
89 "select sum(kills) total_kills, "
\r
90 "sum(deaths) total_deaths, "
\r
91 "sum(alivetime) total_alivetime "
\r
92 "from player_game_stats "
\r
93 "where player_id=:player_id"
\r
94 ).params(player_id=player_id).one()
\r
96 (total_stats['wins'],) = DBSession.\
\r
97 query("total_wins").\
\r
99 "select count(*) total_wins "
\r
100 "from games g, player_game_stats pgs "
\r
101 "where g.game_id = pgs.game_id "
\r
102 "and player_id=:player_id "
\r
103 "and (g.winner = pgs.team or pgs.rank = 1)"
\r
104 ).params(player_id=player_id).one()
\r
106 for (key,value) in total_stats.items():
\r
108 total_stats[key] = 0
\r
113 def player_info(request):
\r
115 Provides detailed information on a specific player
\r
117 player_id = int(request.matchdict['id'])
\r
122 player = DBSession.query(Player).filter_by(player_id=player_id).\
\r
123 filter(Player.active_ind == True).one()
\r
125 (total_games, games_breakdown) = get_games_played(player.player_id)
\r
127 total_stats = get_total_stats(player.player_id)
\r
129 elos = DBSession.query(PlayerElo).filter_by(player_id=player_id).\
\r
130 filter(PlayerElo.game_type_cd.in_(['ctf','duel','dm'])).\
\r
131 order_by(PlayerElo.elo.desc()).all()
\r
140 elos_display.append(str.format(round(elo.elo, 3),
\r
143 weapon_stats = DBSession.query("descr", "weapon_cd", "actual_total",
\r
144 "max_total", "hit_total", "fired_total", "frags_total").\
\r
146 "select cw.descr, cw.weapon_cd, sum(actual) actual_total, "
\r
147 "sum(max) max_total, sum(hit) hit_total, "
\r
148 "sum(fired) fired_total, sum(frags) frags_total "
\r
149 "from player_weapon_stats ws, cd_weapon cw "
\r
150 "where ws.weapon_cd = cw.weapon_cd "
\r
151 "and player_id = :player_id "
\r
152 "group by descr, cw.weapon_cd "
\r
154 ).params(player_id=player_id).all()
\r
156 recent_games = DBSession.query(PlayerGameStat, Game, Server, Map).\
\r
157 filter(PlayerGameStat.player_id == player_id).\
\r
158 filter(PlayerGameStat.game_id == Game.game_id).\
\r
159 filter(Game.server_id == Server.server_id).\
\r
160 filter(Game.map_id == Map.map_id).\
\r
161 order_by(Game.game_id.desc())[0:10]
\r
163 except Exception as e:
\r
165 elos_display = None
\r
166 weapon_stats = None
\r
168 recent_games = None
\r
170 games_breakdown = None
\r
172 return {'player':player,
\r
173 'elos_display':elos_display,
\r
174 'recent_games':recent_games,
\r
175 'weapon_stats':weapon_stats,
\r
176 'total_stats':total_stats,
\r
177 'total_games':total_games,
\r
178 'games_breakdown':games_breakdown}
\r
181 def player_game_index(request):
\r
183 Provides an index of the games in which a particular
\r
184 player was involved. This is ordered by game_id, with
\r
185 the most recent game_ids first. Paginated.
\r
187 player_id = request.matchdict['player_id']
\r
189 if 'page' in request.matchdict:
\r
190 current_page = request.matchdict['page']
\r
195 games_q = DBSession.query(Game, Server, Map).\
\r
196 filter(PlayerGameStat.game_id == Game.game_id).\
\r
197 filter(PlayerGameStat.player_id == player_id).\
\r
198 filter(Game.server_id == Server.server_id).\
\r
199 filter(Game.map_id == Map.map_id).\
\r
200 order_by(Game.game_id.desc())
\r
202 games = Page(games_q, current_page, url=page_url)
\r
205 for (game, server, map) in games:
\r
206 pgstats[game.game_id] = DBSession.query(PlayerGameStat).\
\r
207 filter(PlayerGameStat.game_id == game.game_id).\
\r
208 order_by(PlayerGameStat.rank).\
\r
209 order_by(PlayerGameStat.score).all()
\r
211 except Exception as e:
\r
215 return {'player_id':player_id,
\r