-import datetime
import logging
-import re
-import time
from collections import OrderedDict
+
from pyramid import httpexceptions
-from pyramid.response import Response
-from sqlalchemy import desc, func, over
-from webhelpers.paginate import Page, PageURL
-from xonstat.models import *
+from sqlalchemy.orm.exc import *
+from webhelpers.paginate import Page
+from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, PlayerWeaponStat
+from xonstat.models import PlayerGameFragMatrix, TeamGameStat, PlayerRank, GameType, Weapon
from xonstat.util import page_url
from xonstat.views.helpers import RecentGame, recent_games_q
-
log = logging.getLogger(__name__)
def _game_info_data(request):
game_id = int(request.matchdict['id'])
- show_elo = False
- if request.params.has_key('show_elo'):
- show_elo = True
-
- show_latency = False
+ # show an extra column if "show_elo" is a GET parameter
+ show_elo = bool(request.params.get("show_elo", False))
try:
- notfound = False
-
- (game, server, map, gametype) = DBSession.query(Game, Server, Map, GameType).\
- filter(Game.game_id == game_id).\
- filter(Game.server_id == Server.server_id).\
- filter(Game.map_id == Map.map_id).\
- filter(Game.game_type_cd == GameType.game_type_cd).one()
-
- pgstats = DBSession.query(PlayerGameStat).\
- filter(PlayerGameStat.game_id == game_id).\
- order_by(PlayerGameStat.scoreboardpos).\
- order_by(PlayerGameStat.score).\
- all()
-
- # if at least one player has a valid latency, we'll show the column
+ (game, server, map, gametype) = DBSession.query(Game, Server, Map, GameType)\
+ .filter(Game.game_id == game_id)\
+ .filter(Game.server_id == Server.server_id)\
+ .filter(Game.map_id == Map.map_id)\
+ .filter(Game.game_type_cd == GameType.game_type_cd)\
+ .one()
+
+ pgstats = DBSession.query(PlayerGameStat)\
+ .filter(PlayerGameStat.game_id == game_id)\
+ .order_by(PlayerGameStat.scoreboardpos)\
+ .order_by(PlayerGameStat.score)\
+ .all()
+
+ # Really old games don't have latency sent, so we have to check. If at
+ # least one player has a latency value, we'll show the ping column.
+ show_latency = False
for pgstat in pgstats:
if pgstat.avg_latency is not None:
show_latency = True
+ break
+
+ q = DBSession.query(TeamGameStat).filter(TeamGameStat.game_id == game_id)
- q = DBSession.query(TeamGameStat).\
- filter(TeamGameStat.game_id == game_id)
if game.game_type_cd == 'ctf':
q = q.order_by(TeamGameStat.caps.desc())
elif game.game_type_cd == 'ca':
q = q.order_by(TeamGameStat.rounds.desc())
- # dom -> ticks, rc -> laps, nb -> goals, as -> objectives
q = q.order_by(TeamGameStat.score.desc())
captimes = sorted(captimes, key=lambda x:x.fastest)
pwstats = {}
- for (pwstat, weapon) in DBSession.query(PlayerWeaponStat, Weapon).\
- filter(PlayerWeaponStat.game_id == game_id).\
- filter(PlayerWeaponStat.weapon_cd == Weapon.weapon_cd).\
- order_by(PlayerWeaponStat.actual.desc()).\
- all():
+ for (pwstat, weapon) in DBSession.query(PlayerWeaponStat, Weapon)\
+ .filter(PlayerWeaponStat.game_id == game_id)\
+ .filter(PlayerWeaponStat.weapon_cd == Weapon.weapon_cd)\
+ .order_by(PlayerWeaponStat.actual.desc())\
+ .all():
if pwstat.player_game_stat_id not in pwstats:
pwstats[pwstat.player_game_stat_id] = []
weapon.weapon_cd, pwstat.actual, pwstat.max,
pwstat.hit, pwstat.fired, pwstat.frags))
- except Exception as inst:
- game = None
- server = None
- map = None
- gametype = None
- pgstats = None
- tgstats = None
- pwstats = None
- captimes = None
- show_elo = False
- show_latency = False
- stats_by_team = None
- raise inst
-
- return {'game':game,
- 'server':server,
- 'map':map,
- 'gametype':gametype,
- 'pgstats':pgstats,
- 'tgstats':tgstats,
- 'pwstats':pwstats,
- 'captimes':captimes,
- 'show_elo':show_elo,
- 'show_latency':show_latency,
- 'stats_by_team':stats_by_team,
- }
+ frag_matrix = DBSession.query(PlayerGameFragMatrix)\
+ .filter(PlayerGameFragMatrix.game_id == game_id)\
+ .all()
+
+ matrix_by_pgstat_id = {e.player_game_stat_id: e for e in frag_matrix}
+ if len(matrix_by_pgstat_id):
+ show_frag_matrix = True
+ else:
+ show_frag_matrix = False
+
+ except NoResultFound as e:
+ raise httpexceptions.HTTPNotFound("Could not find that game!")
+
+ except Exception as e:
+ raise e
+
+ return {
+ 'game': game,
+ 'server': server,
+ 'map': map,
+ 'gametype': gametype,
+ 'pgstats': pgstats,
+ 'tgstats': tgstats,
+ 'pwstats': pwstats,
+ 'captimes': captimes,
+ 'show_elo': show_elo,
+ 'show_latency': show_latency,
+ 'stats_by_team': stats_by_team,
+ 'show_frag_matrix': show_frag_matrix,
+ 'matrix_by_pgstat_id': matrix_by_pgstat_id,
+ }
def game_info(request):
"""
List the game stats (scoreboard) for a particular game. Paginated. JSON.
"""
- return [{'status':'not implemented'}]
+ data = _game_info_data(request)
+
+ # convert pwstats into a more JSON-friendly format
+ pwstats = {}
+ for pgstat_id, pwstat_list in data["pwstats"].items():
+ l = []
+ for pwstat in pwstat_list:
+ l.append({
+ "player_game_stat_id": pgstat_id,
+ "weapon_cd": pwstat[1],
+ "actual": pwstat[2],
+ "max": pwstat[3],
+ "hit": pwstat[4],
+ "fired": pwstat[5],
+ "frags": pwstat[6],
+ })
+
+ pwstats[int(pgstat_id)] = l
+
+ return {
+ "game": data["game"].to_dict(),
+ "server": data["server"].to_dict(),
+ "map": data["map"].to_dict(),
+ 'pgstats': [pgstat.to_dict() for pgstat in data["pgstats"]],
+ 'pwstats': pwstats,
+ 'tgstats': [tgstat.to_dict() for tgstat in data["tgstats"]],
+ # 'captimes': [captime.to_dict() for captime in data["captimes"]],
+ }
def _rank_index_data(request):
- if request.params.has_key('page'):
- current_page = request.params['page']
- else:
- current_page = 1
+ current_page = request.params.get("page", 1)
+
+ # game type whitelist
+ game_types_allowed = ["ca", "ctf", "dm", "duel", "ft", "ka", "tdm"]
game_type_cd = request.matchdict['game_type_cd']
+ if game_type_cd not in game_types_allowed:
+ raise httpexceptions.HTTPNotFound()
ranks_q = DBSession.query(PlayerRank).\
filter(PlayerRank.game_type_cd==game_type_cd).\
order_by(PlayerRank.rank)
+ game_type = DBSession.query(GameType).\
+ filter(GameType.game_type_cd == game_type_cd).one()
+
ranks = Page(ranks_q, current_page, url=page_url)
if len(ranks) == 0:
return {
'ranks':ranks,
'game_type_cd':game_type_cd,
+ 'game_type': game_type,
}
try:
recent_games = [RecentGame(row) for row in rgs_q.limit(20).all()]
-
+
if len(recent_games) > 0:
query['start_game_id'] = recent_games[-1].game_id + 1