import pyramid.httpexceptions
import sqlalchemy as sa
import sqlalchemy.sql.functions as func
+import sqlalchemy.sql.expression as expr
from calendar import timegm
from collections import namedtuple
from webhelpers.paginate import Page
from xonstat.util import page_url, to_json, pretty_date, datetime_seconds
from xonstat.util import is_cake_day, verify_request
from xonstat.views.helpers import RecentGame, recent_games_q
+from urllib import unquote
log = logging.getLogger(__name__)
"from player_ranks "
"group by game_type_cd) overall "
"where pr.game_type_cd = overall.game_type_cd "
+ "and max_rank > 1 "
"and player_id = :player_id "
"order by rank").\
params(player_id=player_id).all()
cake_day = is_cake_day(player.create_dt)
except Exception as e:
- player = None
- games_played = None
- overall_stats = None
- fav_maps = None
- elos = None
- ranks = None
- recent_games = None
- recent_weapons = []
- cake_day = False
- ## do not raise exceptions here (only for debugging)
+ raise pyramid.httpexceptions.HTTPNotFound
+
+ ## do not raise application exceptions here (only for debugging)
# raise e
return {'player':player,
def player_hashkey_info_data(request):
+ # hashkey = request.matchdict['hashkey']
+
+ # the incoming hashkey is double quoted, and WSGI unquotes once...
+ # hashkey = unquote(hashkey)
+
+ # if using request verification to obtain the hashkey
(idfp, status) = verify_request(request)
+ log.debug("d0_blind_id verification: idfp={0} status={1}\n".format(idfp, status))
+
+ log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body +
+ "----- END REQUEST BODY -----\n\n")
# if config is to *not* verify requests and we get nothing back, this
# query will return nothing and we'll 404.
raise pyramid.httpexceptions.HTTPNotFound
return {'player':player,
- 'hashkey':hashkey,
+ 'hashkey':idfp,
'games_played':games_played,
'overall_stats':overall_stats,
'fav_maps':fav_maps,
"""
Provides elo information on a specific player. Raw data is returned.
"""
+ (idfp, status) = verify_request(request)
+ log.debug("d0_blind_id verification: idfp={0} status={1}\n".format(idfp, status))
+
+ log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body +
+ "----- END REQUEST BODY -----\n\n")
+
hashkey = request.matchdict['hashkey']
- print "player_elo_info_data [hashkey={0}]".format(hashkey)
+
+ # the incoming hashkey is double quoted, and WSGI unquotes once...
+ hashkey = unquote(hashkey)
+
try:
player = DBSession.query(Player).\
filter(Player.player_id == Hashkey.player_id).\
def player_captimes_data(request):
- player_id = int(request.matchdict['id'])
+ player_id = int(request.matchdict['player_id'])
if player_id <= 2:
player_id = -1;
- PlayerCaptimes = namedtuple('PlayerCaptimes', ['fastest_cap', 'create_dt', 'create_dt_epoch', 'create_dt_fuzzy',
- 'player_id', 'game_id', 'map_id', 'map_name', 'server_id', 'server_name'])
+ if request.params.has_key('page'):
+ current_page = request.params['page']
+ else:
+ current_page = 1
- dbquery = DBSession.query('fastest_cap', 'create_dt', 'player_id', 'game_id', 'map_id',
- 'map_name', 'server_id', 'server_name').\
- from_statement(
- "SELECT ct.fastest_cap, "
- "ct.create_dt, "
- "ct.player_id, "
- "ct.game_id, "
- "ct.map_id, "
- "m.name map_name, "
- "g.server_id, "
- "s.name server_name "
- "FROM player_map_captimes ct, "
- "games g, "
- "maps m, "
- "servers s "
- "WHERE ct.player_id = :player_id "
- "AND g.game_id = ct.game_id "
- "AND g.server_id = s.server_id "
- "AND m.map_id = ct.map_id "
- #"ORDER BY ct.fastest_cap "
- "ORDER BY ct.create_dt desc"
- ).params(player_id=player_id).all()
+ PlayerCaptimes = namedtuple('PlayerCaptimes', ['fastest_cap',
+ 'create_dt', 'create_dt_epoch', 'create_dt_fuzzy',
+ 'player_id', 'game_id', 'map_id', 'map_name', 'server_id', 'server_name'])
player = DBSession.query(Player).filter_by(player_id=player_id).one()
- player_captimes = []
- for row in dbquery:
- player_captimes.append(PlayerCaptimes(
+ #pct_q = DBSession.query('fastest_cap', 'create_dt', 'player_id', 'game_id', 'map_id',
+ # 'map_name', 'server_id', 'server_name').\
+ # from_statement(
+ # "SELECT ct.fastest_cap, "
+ # "ct.create_dt, "
+ # "ct.player_id, "
+ # "ct.game_id, "
+ # "ct.map_id, "
+ # "m.name map_name, "
+ # "g.server_id, "
+ # "s.name server_name "
+ # "FROM player_map_captimes ct, "
+ # "games g, "
+ # "maps m, "
+ # "servers s "
+ # "WHERE ct.player_id = :player_id "
+ # "AND g.game_id = ct.game_id "
+ # "AND g.server_id = s.server_id "
+ # "AND m.map_id = ct.map_id "
+ # #"ORDER BY ct.fastest_cap "
+ # "ORDER BY ct.create_dt desc"
+ # ).params(player_id=player_id)
+
+ try:
+ pct_q = DBSession.query(PlayerCaptime.fastest_cap, PlayerCaptime.create_dt,
+ PlayerCaptime.player_id, PlayerCaptime.game_id, PlayerCaptime.map_id,
+ Map.name.label('map_name'), Game.server_id, Server.name.label('server_name')).\
+ filter(PlayerCaptime.player_id==player_id).\
+ filter(PlayerCaptime.game_id==Game.game_id).\
+ filter(PlayerCaptime.map_id==Map.map_id).\
+ filter(Game.server_id==Server.server_id).\
+ order_by(expr.desc(PlayerCaptime.create_dt))
+
+ player_captimes = Page(pct_q, current_page, items_per_page=20, url=page_url)
+
+ # replace the items in the canned pagination class with more rich ones
+ player_captimes.items = [PlayerCaptimes(
fastest_cap=row.fastest_cap,
create_dt=row.create_dt,
create_dt_epoch=timegm(row.create_dt.timetuple()),
map_id=row.map_id,
map_name=row.map_name,
server_id=row.server_id,
- server_name=row.server_name,
- ))
+ server_name=row.server_name
+ ) for row in player_captimes.items]
+
+ except Exception as e:
+ player = None
+ player_captimes = None
return {
- 'captimes':player_captimes,
'player_id':player_id,
- 'player_url':request.route_url('player_info', id=player_id),
'player':player,
+ 'captimes':player_captimes,
+ #'player_url':request.route_url('player_info', id=player_id),
}
+
def player_captimes(request):
return player_captimes_data(request)
+
def player_captimes_json(request):
return player_captimes_data(request)
-def player_nvd3_damage(request):
- player_id = int(request.matchdict['id'])
- if player_id <= 2:
- player_id = -1;
-
- game_type_cd = request.params.get("game_type", None)
- if game_type_cd == "overall":
- game_type_cd = None
-
- limit = 20
- if request.params.has_key("limit"):
- limit = int(request.params["limit"])
-
- if limit < 0:
- limit = 20
- if limit > 50:
- limit = 50
-
- return { "player_id": player_id,
- "game_type_cd": game_type_cd,
- "limit": limit,
- }
-
def player_weaponstats_data_json(request):
player_id = request.matchdict["id"]
if player_id <= 2:
filter(PlayerWeaponStat.player_id == player_id).\
filter(PlayerWeaponStat.game_id.in_(games_raw)).all()
- # NVD3 expects data points for all weapons used across the
- # set of games *for each* point on the x axis. This means populating
- # zero-valued weapon stat entries for games where a weapon was not
- # used in that game, but was used in another game for the set
games_to_weapons = {}
- weapons_used = []
+ weapons_used = {}
+ sum_avgs = {}
for ws in weapon_stats_raw:
if ws.game_id not in games_to_weapons:
games_to_weapons[ws.game_id] = [ws.weapon_cd]
else:
games_to_weapons[ws.game_id].append(ws.weapon_cd)
- if ws.weapon_cd not in weapons_used:
- weapons_used.append(ws.weapon_cd)
+ weapons_used[ws.weapon_cd] = weapons_used.get(ws.weapon_cd, 0) + 1
+ sum_avgs[ws.weapon_cd] = sum_avgs.get(ws.weapon_cd, 0) + float(ws.hit)/float(ws.fired)
+ # Creating zero-valued weapon stat entries for games where a weapon was not
+ # used in that game, but was used in another game for the set. This makes
+ # the charts look smoother
for game_id in games_to_weapons.keys():
- for weapon_cd in set(weapons_used) - set(games_to_weapons[game_id]):
+ for weapon_cd in set(weapons_used.keys()) - set(games_to_weapons[game_id]):
weapon_stats_raw.append(PlayerWeaponStat(player_id=player_id,
game_id=game_id, weapon_cd=weapon_cd))
+ # averages for the weapons used in the range
+ avgs = {}
+ for w in weapons_used.keys():
+ avgs[w] = round(sum_avgs[w]/float(weapons_used[w])*100, 2)
- weapon_stats_raw = sorted(weapon_stats_raw, key = lambda x: x.game_id)
+ weapon_stats_raw = sorted(weapon_stats_raw, key = lambda x: x.game_id)
games = sorted(games_to_weapons.keys())
weapon_stats = [ws.to_dict() for ws in weapon_stats_raw]
return {
"weapon_stats": weapon_stats,
- "weapons_used": weapons_used,
+ "weapons_used": weapons_used.keys(),
"games": games,
+ "averages": avgs,
}