import datetime
import logging
+from calendar import timegm
+from collections import namedtuple
+from urllib import unquote
+
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
+import sqlalchemy.sql.functions as func
from webhelpers.paginate import Page
-from xonstat.models import *
-from xonstat.util import page_url, to_json, pretty_date, datetime_seconds
+from xonstat.models import DBSession, Server, Map, Game, PlayerWeaponStat, Player, Hashkey
+from xonstat.models import PlayerElo, PlayerCaptime, PlayerMedal, GameType
+from xonstat.models.player import PlayerCapTime
from xonstat.util import is_cake_day, verify_request
+from xonstat.util import page_url, to_json, pretty_date, datetime_seconds
from xonstat.views.helpers import RecentGame, recent_games_q
-from urllib import unquote
log = logging.getLogger(__name__)
# sort the resulting list by # of games played
games_played = sorted(games_played, key=lambda x:x.games)
games_played.reverse()
+
return games_played
return (avg, dmgs)
+def get_player_medals(player_id):
+ """Retrieves the list of medals the player has received from tournaments or
+ other contests."""
+ try:
+ medals = DBSession.query(PlayerMedal)\
+ .filter(PlayerMedal.player_id==player_id)\
+ .order_by(PlayerMedal.place)\
+ .order_by(PlayerMedal.create_dt)\
+ .all()
+
+ return medals
+
+ except Exception as e:
+ log.debug(e)
+ return []
+
+
def player_info_data(request):
player_id = int(request.matchdict['id'])
if player_id <= 2:
fav_maps = get_fav_maps(player_id)
elos = get_elos(player_id)
ranks = get_ranks(player_id)
+ medals = get_player_medals(player_id)
recent_games = get_recent_games(player_id)
cake_day = is_cake_day(player.create_dt)
'fav_maps':fav_maps,
'elos':elos,
'ranks':ranks,
+ 'medals':medals,
'recent_games':recent_games,
'cake_day':cake_day,
}
for gt,mapinfo in player_info['fav_maps'].items():
fav_maps[gt] = to_json(mapinfo)
- recent_games = []
- for game in player_info['recent_games']:
- recent_games.append(to_json(game))
+ recent_games = [g.to_dict() for g in player_info['recent_games']]
return [{
'player': player,
'ranks': ranks,
'recent_games': recent_games,
}]
- #return [{'status':'not implemented'}]
def player_game_index_data(request):
}
-class PlayerCapTime(object):
- def __init__(self, row):
- self.fastest_cap = row.fastest_cap
- self.create_dt = row.create_dt
- self.create_dt_epoch = timegm(row.create_dt.timetuple())
- self.create_dt_fuzzy = pretty_date(row.create_dt)
- self.player_id = row.player_id
- self.game_id = row.game_id
- self.map_id = row.map_id
- self.map_name = row.map_name
- self.server_id = row.server_id
- self.server_name = row.server_name
-
- def to_dict(self):
- return {
- "fastest_cap" : self.fastest_cap.total_seconds(),
- "create_dt_epoch": self.create_dt_epoch,
- "create_dt_fuzzy": self.create_dt_fuzzy,
- "game_id":self.game_id,
- "map_id": self.map_id,
- "map_name": self.map_name,
- "server_id": self.server_id,
- "server_name": self.server_name,
- }
-
def player_captimes_data(request):
player_id = int(request.matchdict['player_id'])
if player_id <= 2:
player_id = -1;
- current_page = request.params.get("page", 1)
+ page = request.params.get("page", 1)
+
+ sort = request.params.get("sort", "create_dt")
try:
player = DBSession.query(Player).filter_by(player_id=player_id).one()
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))
+ filter(Game.server_id==Server.server_id)
+
+ if sort == "fastest":
+ pct_q = pct_q.order_by(PlayerCaptime.fastest_cap)
+ else:
+ sort = "create_dt"
+ pct_q = pct_q.order_by(expr.desc(PlayerCaptime.create_dt))
except Exception as e:
raise pyramid.httpexceptions.HTTPNotFound
- captimes = Page(pct_q, current_page, items_per_page=20, url=page_url)
+ captimes = Page(pct_q, page, items_per_page=20, url=page_url)
# replace the items in the canned pagination class with more rich ones
captimes.items = [PlayerCapTime(row) for row in captimes.items]
"player_id" : player_id,
"player" : player,
"captimes" : captimes,
+ "page" : page,
+ "sort" : sort,
}
"averages": avgs,
}
+
+def player_versus_data(request):
+ try:
+ p1_id = int(request.params.get("p1", None))
+ p2_id = int(request.params.get("p2", None))
+
+ p1_wins = 0
+ p2_wins = 0
+
+ players = DBSession.query(Player).filter(sa.or_(Player.player_id ==
+ p1_id, Player.player_id == p2_id)).order_by(Player.player_id).all()
+
+
+ if len(players) < 2:
+ raise Exception("Not enough players found.")
+
+ # assign the players from the array retrieved above
+ if players[0].player_id == p1_id:
+ p1 = players[0]
+ p2 = players[1]
+ else:
+ p1 = players[1]
+ p2 = players[0]
+
+ # note that wins and losses are from p1's perspective
+ win_loss_sql = """select win_loss, count(1)
+ from (
+ select case
+ when pgsp1.score >= pgsp2.score then 'win'
+ else 'loss'
+ end win_loss
+ from games g join player_game_stats pgsp1
+ on g.game_id = pgsp1.game_id and pgsp1.player_id = :p1
+ join player_game_stats pgsp2
+ on g.game_id = pgsp2.game_id and pgsp2.player_id = :p2
+ where g.players @> ARRAY[:p1,:p2]
+ and g.game_type_cd = 'duel'
+ and pgsp1.create_dt between g.create_dt - interval '1 hour'
+ and g.create_dt + interval '1 hour'
+ and pgsp2.create_dt between g.create_dt - interval '1 hour'
+ and g.create_dt + interval '1 hour'
+ ) wl
+ group by win_loss
+ """
+
+ wins_losses = DBSession.query("win_loss", "count").\
+ from_statement(win_loss_sql).\
+ params(p1=p1_id, p2=p2_id).all()
+
+ for row in wins_losses:
+ if row.win_loss == "win":
+ p1_wins = row.count
+ elif row.win_loss == "loss":
+ p2_wins = row.count
+
+ # grab the 20 most recent games between the two
+ rgs_raw = recent_games_q(player_id=p1_id, player_id_2=p2_id,
+ game_type_cd="duel").limit(20).all()
+
+ rgs = [RecentGame(row) for row in rgs_raw]
+
+ except Exception as e:
+ log.debug(e)
+
+ p1_id = None
+ p2_id = None
+ p1 = None
+ p2 = None
+ p1_wins = None
+ p2_wins = None
+ rgs = None
+
+ return {
+ "p1_id" : p1_id,
+ "p2_id" : p2_id,
+ "p1" : p1,
+ "p2" : p2,
+ "p1_wins" : p1_wins,
+ "p2_wins" : p2_wins,
+ "recent_games" : rgs,
+ }
+
+
+def player_versus(request):
+ return player_versus_data(request)