]> de.git.xonotic.org Git - xonotic/xonstat.git/blob - xonstat/views/game.py
Merge branch 'approved' of gitorious.org:xonotic/xonstat into approved
[xonotic/xonstat.git] / xonstat / views / game.py
1 import datetime
2 import logging
3 import re
4 import time
5 from pyramid.response import Response
6 from sqlalchemy import desc, func, over
7 from webhelpers.paginate import Page, PageURL
8 from xonstat.models import *
9 from xonstat.util import page_url
10 from xonstat.views.helpers import RecentGame, recent_games_q
11
12 log = logging.getLogger(__name__)
13
14
15 def _game_index_data(request):
16     if request.params.has_key('page'):
17         current_page = request.params['page']
18     else:
19         current_page = 1
20
21     games_q = DBSession.query(Game, Server, Map).\
22             filter(Game.server_id == Server.server_id).\
23             filter(Game.map_id == Map.map_id).\
24             order_by(Game.game_id.desc())
25
26     games = Page(games_q, current_page, items_per_page=10, url=page_url)
27
28     pgstats = {}
29     for (game, server, map) in games:
30         pgstats[game.game_id] = DBSession.query(PlayerGameStat).\
31                 filter(PlayerGameStat.game_id == game.game_id).\
32                 order_by(PlayerGameStat.scoreboardpos).\
33                 order_by(PlayerGameStat.score).all()
34
35     return {'games':games,
36             'pgstats':pgstats}
37
38
39 def game_index(request):
40     """
41     Provides a list of current games, with the associated game stats.
42     These games are ordered by game_id, with the most current ones first.
43     Paginated.
44     """
45     return _game_index_data(request)
46
47
48 def game_index_json(request):
49     """
50     Provides a list of current games, with the associated game stats.
51     These games are ordered by game_id, with the most current ones first.
52     Paginated. JSON.
53     """
54     return [{'status':'not implemented'}]
55
56
57 def _game_info_data(request):
58     game_id = request.matchdict['id']
59
60     if request.params.has_key('show_elo'):
61         show_elo = True
62     else:
63         show_elo = False
64
65     try:
66         notfound = False
67
68         (game, server, map) = DBSession.query(Game, Server, Map).\
69                 filter(Game.game_id == game_id).\
70                 filter(Game.server_id == Server.server_id).\
71                 filter(Game.map_id == Map.map_id).one()
72
73         pgstats = DBSession.query(PlayerGameStat).\
74                 filter(PlayerGameStat.game_id == game_id).\
75                 order_by(PlayerGameStat.scoreboardpos).\
76                 order_by(PlayerGameStat.score).\
77                 all()
78
79         captimes = []
80         if game.game_type_cd == 'ctf':
81             for pgstat in pgstats:
82                 if pgstat.fastest_cap is not None:
83                     captimes.append(pgstat)
84
85             captimes = sorted(captimes, key=lambda x:x.fastest_cap)
86
87         pwstats = {}
88         for (pwstat, pgstat, weapon) in DBSession.query(PlayerWeaponStat, PlayerGameStat, Weapon).\
89                 filter(PlayerWeaponStat.game_id == game_id).\
90                 filter(PlayerWeaponStat.weapon_cd == Weapon.weapon_cd).\
91                 filter(PlayerWeaponStat.player_game_stat_id == \
92                     PlayerGameStat.player_game_stat_id).\
93                 order_by(PlayerGameStat.scoreboardpos).\
94                 order_by(PlayerGameStat.score).\
95                 order_by(Weapon.descr).\
96                 all():
97                     if pgstat.player_game_stat_id not in pwstats:
98                         pwstats[pgstat.player_game_stat_id] = []
99
100                     # NOTE adding pgstat to position 6 in order to display nick.
101                     # You have to use a slice [0:5] to pass to the accuracy 
102                     # template
103                     pwstats[pgstat.player_game_stat_id].append((weapon.descr, 
104                         weapon.weapon_cd, pwstat.actual, pwstat.max, 
105                         pwstat.hit, pwstat.fired, pgstat))
106
107     except Exception as inst:
108         game = None
109         server = None
110         map = None
111         pgstats = None
112         pwstats = None
113         captimes = None
114         show_elo = False
115         raise inst
116
117     return {'game':game,
118             'server':server,
119             'map':map,
120             'pgstats':pgstats,
121             'pwstats':pwstats,
122             'captimes':captimes,
123             'show_elo':show_elo,
124             }
125
126
127 def game_info(request):
128     """
129     List the game stats (scoreboard) for a particular game. Paginated.
130     """
131     return _game_info_data(request)
132
133
134 def game_info_json(request):
135     """
136     List the game stats (scoreboard) for a particular game. Paginated. JSON.
137     """
138     return [{'status':'not implemented'}]
139
140
141 def _rank_index_data(request):
142     if request.params.has_key('page'):
143         current_page = request.params['page']
144     else:
145         current_page = 1
146
147     game_type_cd = request.matchdict['game_type_cd']
148
149     ranks_q = DBSession.query(PlayerRank).\
150             filter(PlayerRank.game_type_cd==game_type_cd).\
151             order_by(PlayerRank.rank)
152
153     ranks = Page(ranks_q, current_page, url=page_url)
154
155     if len(ranks) == 0:
156         ranks = None
157
158     return {
159             'ranks':ranks,
160             'game_type_cd':game_type_cd,
161            }
162
163
164 def rank_index(request):
165     """
166     Provide a list of gametype ranks, paginated.
167     """
168     return _rank_index_data(request)
169
170
171 def rank_index_json(request):
172     """
173     Provide a list of gametype ranks, paginated. JSON.
174     """
175     return [{'status':'not implemented'}]
176
177
178 def game_finder_data(request):
179     if request.params.has_key('page'):
180         current_page = request.params['page']
181     else:
182         current_page = 1
183
184     query = {}
185
186     server_id, map_id, player_id = None, None, None
187     range_start, range_end = None, None
188     # these become WHERE clauses when present
189     if request.params.has_key('server_id'):
190         server_id = request.params['server_id']
191         query['server_id'] = server_id
192
193     if request.params.has_key('map_id'):
194         map_id = request.params['map_id']
195         query['map_id'] = map_id
196
197     if request.params.has_key('player_id'):
198         player_id = request.params['player_id']
199         query['player_id'] = player_id
200
201     if request.params.has_key('range_start'):
202         range_start = request.params['range_start']
203         query['range_start'] = range_start
204
205     if request.params.has_key('range_end'):
206         range_end = request.params['range_end']
207         query['range_end'] = range_end
208
209     rgs_q = recent_games_q(server_id=server_id, map_id=map_id,
210             player_id=player_id)
211
212     recent_games = Page(rgs_q, current_page, url=page_url)
213
214     recent_games.items = [RecentGame(row) for row in recent_games.items]
215
216     return {
217             'recent_games':recent_games,
218             'query':query,
219            }
220
221 def game_finder(request):
222     """
223     Provide a list of recent games with an advanced filter.
224     """
225     return game_finder_data(request)