]> git.xonotic.org Git - xonotic/xonstat.git/blob - xonstat/batch/badges/playerdata.py
0990208f2e23af8044e5e050531602f224e203bb
[xonotic/xonstat.git] / xonstat / batch / badges / playerdata.py
1 import sqlalchemy as sa
2 import sqlalchemy.sql.functions as func
3 from xonstat.models import *
4
5
6 class PlayerData:
7
8     # player data, will be filled by get_data()
9     data = {}
10
11     def __init__(self):
12         self.data = {}
13
14     def __getattr__(self, key):
15         if self.data.has_key(key):
16             return self.data[key]
17         return None
18
19     def get_data(self, player_id):
20         """Return player data as dict.
21
22         This function is similar to the function in player.py but more optimized
23         for this purpose.
24         """
25         # total games
26         # wins/losses
27         # kills/deaths
28         # duel/dm/tdm/ctf elo + rank
29
30         player = DBSession.query(Player).filter(Player.player_id == player_id).one()
31
32         games_played = DBSession.query(
33                 Game.game_type_cd, func.count(), func.sum(PlayerGameStat.alivetime)).\
34                 filter(Game.game_id == PlayerGameStat.game_id).\
35                 filter(PlayerGameStat.player_id == player_id).\
36                 group_by(Game.game_type_cd).\
37                 order_by(func.count().desc()).\
38                 all()
39
40         total_stats = {}
41         total_stats['games'] = 0
42         total_stats['games_breakdown'] = {}  # this is a dictionary inside a dictionary .. dictception?
43         total_stats['games_alivetime'] = {}
44         total_stats['gametypes'] = []
45         for (game_type_cd, games, alivetime) in games_played:
46             total_stats['games'] += games
47             total_stats['gametypes'].append(game_type_cd)
48             total_stats['games_breakdown'][game_type_cd] = games
49             total_stats['games_alivetime'][game_type_cd] = alivetime
50
51         (total_stats['kills'], total_stats['deaths'], total_stats['alivetime'],) = DBSession.query(
52                 func.sum(PlayerGameStat.kills),
53                 func.sum(PlayerGameStat.deaths),
54                 func.sum(PlayerGameStat.alivetime)).\
55                 filter(PlayerGameStat.player_id == player_id).\
56                 one()
57
58         (total_stats['wins'], total_stats['losses']) = DBSession.\
59                 query("wins", "losses").\
60                 from_statement(
61                     "SELECT SUM(win) wins, SUM(loss) losses "
62                     "FROM   (SELECT  g.game_id, "
63                     "                CASE "
64                     "                  WHEN g.winner = pgs.team THEN 1 "
65                     "                  WHEN pgs.rank = 1 THEN 1 "
66                     "                  ELSE 0 "
67                     "                END win, "
68                     "                CASE "
69                     "                  WHEN g.winner = pgs.team THEN 0 "
70                     "                  WHEN pgs.rank = 1 THEN 0 "
71                     "                  ELSE 1 "
72                     "                END loss "
73                     "        FROM    games g, "
74                     "                player_game_stats pgs "
75                     "        WHERE   g.game_id = pgs.game_id "
76                     "                AND pgs.player_id = :player_id) win_loss").\
77                 params(player_id=player_id).one()
78
79         ranks = DBSession.query("game_type_cd", "rank", "max_rank").\
80                 from_statement(
81                     "SELECT  pr.game_type_cd, pr.rank, overall.max_rank "
82                     "FROM    player_ranks pr, "
83                     "        (SELECT  game_type_cd, max(rank) max_rank "
84                     "        FROM     player_ranks "
85                     "        GROUP BY game_type_cd) overall "
86                     "WHERE   pr.game_type_cd = overall.game_type_cd  "
87                     "        AND player_id = :player_id "
88                     "ORDER BY rank").\
89                 params(player_id=player_id).all()
90
91         ranks_dict = {}
92         for gtc,rank,max_rank in ranks:
93             ranks_dict[gtc] = (rank, max_rank)
94
95         elos = DBSession.query(PlayerElo).\
96                 filter_by(player_id=player_id).\
97                 order_by(PlayerElo.elo.desc()).\
98                 all()
99
100         elos_dict = {}
101         for elo in elos:
102             if elo.games >= 32:
103                 elos_dict[elo.game_type_cd] = elo.elo
104
105         self.data = {
106                 'player':player,
107                 'total_stats':total_stats,
108                 'ranks':ranks_dict,
109                 'elos':elos_dict,
110             }
111