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