X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=xonstat%2Fviews%2Fplayer.py;h=d625dffbe1761d2fb3738f1ede3c9b5159b4717c;hb=c65e08ba4183c010fc5c413f0678f43e2bf945e7;hp=9cfb0dbff9fb337ef2a57282dacb397d504d3c7b;hpb=df71363d882d8ca9df32e359050bee06b0723d33;p=xonotic%2Fxonstat.git diff --git a/xonstat/views/player.py b/xonstat/views/player.py index 9cfb0db..d625dff 100644 --- a/xonstat/views/player.py +++ b/xonstat/views/player.py @@ -5,13 +5,14 @@ import re import sqlalchemy as sa import sqlalchemy.sql.functions as func import time +from calendar import timegm from collections import namedtuple from pyramid.response import Response from pyramid.url import current_route_url from sqlalchemy import desc, distinct from webhelpers.paginate import Page, PageURL from xonstat.models import * -from xonstat.util import page_url, namedtuple_to_dict, fix_json_types +from xonstat.util import page_url, to_json, pretty_date log = logging.getLogger(__name__) @@ -130,6 +131,8 @@ def get_overall_stats(player_id): - total_deaths - k_d_ratio - last_played (last time the player played the game type) + - last_played_epoch (same as above, but in seconds since epoch) + - last_played_fuzzy (same as above, but in relative date) - total_playing_time (total amount of time played the game type) - total_pickups (ctf only) - total_captures (ctf only) @@ -141,8 +144,9 @@ def get_overall_stats(player_id): "overall" game_type_cd which sums the totals and computes the total ratios. """ OverallStats = namedtuple('OverallStats', ['total_kills', 'total_deaths', - 'k_d_ratio', 'last_played', 'total_playing_time', 'total_pickups', - 'total_captures', 'cap_ratio', 'total_carrier_frags', 'game_type_cd']) + 'k_d_ratio', 'last_played', 'last_played_epoch', 'last_played_fuzzy', + 'total_playing_time', 'total_pickups', 'total_captures', 'cap_ratio', + 'total_carrier_frags', 'game_type_cd']) raw_stats = DBSession.query('game_type_cd', 'total_kills', 'total_deaths', 'last_played', 'total_playing_time', @@ -190,7 +194,7 @@ def get_overall_stats(player_id): k_d_ratio = None try: - cap_ratio = float(row.total_pickups)/row.total_captures + cap_ratio = float(row.total_captures)/row.total_pickups except: cap_ratio = None @@ -201,6 +205,8 @@ def get_overall_stats(player_id): total_deaths=row.total_deaths, k_d_ratio=k_d_ratio, last_played=row.last_played, + last_played_epoch=timegm(row.last_played.timetuple()), + last_played_fuzzy=pretty_date(row.last_played), total_playing_time=row.total_playing_time, total_pickups=row.total_pickups, total_captures=row.total_captures, @@ -220,6 +226,8 @@ def get_overall_stats(player_id): total_deaths=overall_deaths, k_d_ratio=overall_k_d_ratio, last_played=overall_last_played, + last_played_epoch=timegm(overall_last_played.timetuple()), + last_played_fuzzy=pretty_date(overall_last_played), total_playing_time=overall_playing_time, total_pickups=None, total_captures=None, @@ -318,7 +326,7 @@ def get_ranks(player_id): The key to the dictionary is the game type code. There is also an "overall" game_type_cd which is the overall best rank. """ - Rank = namedtuple('Rank', ['rank', 'max_rank', 'game_type_cd']) + Rank = namedtuple('Rank', ['rank', 'max_rank', 'percentile', 'game_type_cd']) raw_ranks = DBSession.query("game_type_cd", "rank", "max_rank").\ from_statement( @@ -337,11 +345,15 @@ def get_ranks(player_id): for row in raw_ranks: rank = Rank(rank=row.rank, max_rank=row.max_rank, + percentile=100 - 100*float(row.rank)/row.max_rank, game_type_cd=row.game_type_cd) - + + if not found_top_rank: ranks['overall'] = rank found_top_rank = True + elif rank.percentile > ranks['overall'].percentile: + ranks['overall'] = rank ranks[row.game_type_cd] = rank @@ -549,41 +561,38 @@ def player_info_json(request): """ Provides detailed information on a specific player. JSON. """ - + # All player_info fields are converted into JSON-formattable dictionaries player_info = player_info_data(request) - + player = player_info['player'].to_dict() games_played = {} for game in player_info['games_played']: - games_played[game.game_type_cd] = namedtuple_to_dict(game) - + games_played[game.game_type_cd] = to_json(game) + overall_stats = {} for gt,stats in player_info['overall_stats'].items(): - overall_stats[gt] = fix_json_types(namedtuple_to_dict(stats)) - + overall_stats[gt] = to_json(stats) + elos = {} for gt,elo in player_info['elos'].items(): - elos[gt] = fix_json_types(elo.to_dict()) - + elos[gt] = to_json(elo.to_dict()) + ranks = {} for gt,rank in player_info['ranks'].items(): - ranks[gt] = namedtuple_to_dict(rank) - + ranks[gt] = to_json(rank) + fav_maps = {} - for gt,stats in player_info['fav_maps'].items(): - fav_maps[gt] = namedtuple_to_dict(stats) - + for gt,mapinfo in player_info['fav_maps'].items(): + fav_maps[gt] = to_json(mapinfo) + recent_games = [] for game in player_info['recent_games']: - entry = {} - for key,value in namedtuple_to_dict(game).items(): - entry[key] = fix_json_types(value.to_dict()) - recent_games.append(entry) - - recent_weapons = player_info['recent_weapons'] - + recent_games.append(to_json(game)) + + #recent_weapons = player_info['recent_weapons'] + return [{ 'player': player, 'games_played': games_played, @@ -592,12 +601,17 @@ def player_info_json(request): 'elos': elos, 'ranks': ranks, 'recent_games': recent_games, - 'recent_weapons': recent_weapons, + # 'recent_weapons': recent_weapons, + 'recent_weapons': ['not implemented'], }] #return [{'status':'not implemented'}] def player_game_index_data(request): + RecentGame = namedtuple('RecentGame', ['game_id', 'game_type_cd', 'winner', + 'game_create_dt', 'game_epoch', 'game_fuzzy', 'server_id', + 'server_name', 'map_id', 'map_name', 'team', 'rank', 'elo_delta']) + player_id = request.matchdict['player_id'] if request.params.has_key('page'): @@ -606,7 +620,14 @@ def player_game_index_data(request): current_page = 1 try: - games_q = DBSession.query(Game, Server, Map).\ + player = DBSession.query(Player).filter_by(player_id=player_id).\ + filter(Player.active_ind == True).one() + + games_q = DBSession.query(Game.game_id, Game.game_type_cd, Game.winner, + Game.create_dt, Server.server_id, + Server.name.label('server_name'), Map.map_id, + Map.name.label('map_name'), PlayerGameStat.team, + PlayerGameStat.rank, PlayerGameStat.elo_delta).\ filter(PlayerGameStat.game_id == Game.game_id).\ filter(PlayerGameStat.player_id == player_id).\ filter(Game.server_id == Server.server_id).\ @@ -615,20 +636,32 @@ def player_game_index_data(request): games = Page(games_q, current_page, items_per_page=10, url=page_url) - pgstats = {} - for (game, server, map) in games: - pgstats[game.game_id] = DBSession.query(PlayerGameStat).\ - filter(PlayerGameStat.game_id == game.game_id).\ - order_by(PlayerGameStat.rank).\ - order_by(PlayerGameStat.score).all() + # replace the items in the canned pagination class with more rich ones + games.items = [RecentGame( + game_id = row.game_id, + game_type_cd = row.game_type_cd, + winner = row.winner, + game_create_dt = row.create_dt, + game_epoch = timegm(row.create_dt.timetuple()), + game_fuzzy = pretty_date(row.create_dt), + server_id = row.server_id, + server_name = row.server_name, + map_id = row.map_id, + map_name = row.map_name, + team = row.team, + rank = row.rank, + elo_delta = row.elo_delta + ) for row in games.items] except Exception as e: player = None games = None - return {'player_id':player_id, + return { + 'player_id':player.player_id, + 'player':player, 'games':games, - 'pgstats':pgstats} + } def player_game_index(request):