]> de.git.xonotic.org Git - xonotic/xonstat.git/blobdiff - xonstat/views/player.py
The player JSON view should use to_dict() instead.
[xonotic/xonstat.git] / xonstat / views / player.py
index 6b0b9459f8abe760bdf0f3e211b6fee0e26c3bdb..26da28f9deb3d29732a40ef063a728aeb6c4314d 100644 (file)
@@ -89,7 +89,8 @@ def get_games_played(player_id):
                         "FROM   games g, "
                                "player_game_stats pgs "
                         "WHERE  g.game_id = pgs.game_id "
-                        "AND pgs.player_id = :player_id) win_loss "
+                        "AND pgs.player_id = :player_id "
+                        "AND g.players @> ARRAY[:player_id]) win_loss "
                 "GROUP  BY game_type_cd "
             ).params(player_id=player_id).all()
 
@@ -167,6 +168,7 @@ def get_overall_stats(player_id):
                        "player_game_stats pgs "
                 "WHERE  g.game_id = pgs.game_id "
                   "AND  g.game_type_cd = gt.game_type_cd "
+                  "AND  g.players @> ARRAY[:player_id] "
                   "AND  pgs.player_id = :player_id "
                 "GROUP  BY g.game_type_cd, game_type_descr "
                 "UNION "
@@ -289,6 +291,7 @@ def get_fav_maps(player_id, game_type_cd=None):
                                "maps m "
                         "WHERE  g.game_id = pgs.game_id "
                                "AND g.map_id = m.map_id "
+                               "AND g.players @> ARRAY[:player_id]"
                                "AND pgs.player_id = :player_id "
                         "GROUP  BY g.game_type_cd, "
                                   "m.map_id, "
@@ -345,6 +348,7 @@ def get_ranks(player_id):
                     "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()
@@ -408,24 +412,6 @@ def get_recent_games(player_id, limit=10):
     return recent_games
 
 
-def get_recent_weapons(player_id):
-    """
-    Returns the weapons that have been used in the past 90 days
-    and also used in 5 games or more.
-    """
-    cutoff = datetime.datetime.utcnow() - datetime.timedelta(days=90)
-    recent_weapons = []
-    for weapon in DBSession.query(PlayerWeaponStat.weapon_cd, func.count()).\
-            filter(PlayerWeaponStat.player_id == player_id).\
-            filter(PlayerWeaponStat.create_dt > cutoff).\
-            group_by(PlayerWeaponStat.weapon_cd).\
-            having(func.count() > 4).\
-            all():
-                recent_weapons.append(weapon[0])
-
-    return recent_weapons
-
-
 def get_accuracy_stats(player_id, weapon_cd, games):
     """
     Provides accuracy for weapon_cd by player_id for the past N games.
@@ -522,7 +508,6 @@ def player_info_data(request):
         elos           = get_elos(player_id)
         ranks          = get_ranks(player_id)
         recent_games   = get_recent_games(player_id)
-        recent_weapons = get_recent_weapons(player_id)
         cake_day       = is_cake_day(player.create_dt)
 
     except Exception as e:
@@ -538,7 +523,6 @@ def player_info_data(request):
             'elos':elos,
             'ranks':ranks,
             'recent_games':recent_games,
-            'recent_weapons':recent_weapons,
             'cake_day':cake_day,
             }
 
@@ -580,11 +564,7 @@ def player_info_json(request):
     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_weapons = player_info['recent_weapons']
+    recent_games = [g.to_dict() for g in player_info['recent_games']]
 
     return [{
         'player':           player,
@@ -594,14 +574,14 @@ def player_info_json(request):
         'elos':             elos,
         'ranks':            ranks,
         'recent_games':     recent_games,
-    #    'recent_weapons':   recent_weapons,
-        'recent_weapons':   ['not implemented'],
     }]
-    #return [{'status':'not implemented'}]
 
 
 def player_game_index_data(request):
-    player_id = request.matchdict['player_id']
+    try:
+        player_id = int(request.matchdict['player_id'])
+    except:
+        player_id = -1
 
     game_type_cd = None
     game_type_descr = None
@@ -641,6 +621,7 @@ def player_game_index_data(request):
         games_played = get_games_played(player_id)
 
     except Exception as e:
+        raise e
         player = None
         games = None
         game_type_cd = None
@@ -994,41 +975,11 @@ def player_captimes_data(request):
     if player_id <= 2:
         player_id = -1;
 
-    if request.params.has_key('page'):
-        current_page = request.params['page']
-    else:
-        current_page = 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'])
-
-    player = DBSession.query(Player).filter_by(player_id=player_id).one()
-
-    #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)
+    current_page = request.params.get("page", 1)
 
     try:
+        player = DBSession.query(Player).filter_by(player_id=player_id).one()
+
         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')).\
@@ -1036,33 +987,20 @@ def player_captimes_data(request):
                 filter(PlayerCaptime.game_id==Game.game_id).\
                 filter(PlayerCaptime.map_id==Map.map_id).\
                 filter(Game.server_id==Server.server_id).\
-                order_by(expr.asc(PlayerCaptime.fastest_cap))  # or PlayerCaptime.create_dt
+                order_by(expr.desc(PlayerCaptime.create_dt))
 
-        player_captimes = Page(pct_q, current_page, items_per_page=20, url=page_url)
+    except Exception as e:
+        raise pyramid.httpexceptions.HTTPNotFound
 
-        # 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()),
-                create_dt_fuzzy=pretty_date(row.create_dt),
-                player_id=row.player_id,
-                game_id=row.game_id,
-                map_id=row.map_id,
-                map_name=row.map_name,
-                server_id=row.server_id,
-                server_name=row.server_name
-                ) for row in player_captimes.items]
+    captimes = Page(pct_q, current_page, items_per_page=20, url=page_url)
 
-    except Exception as e:
-        player = None
-        player_captimes = None
+    # replace the items in the canned pagination class with more rich ones
+    captimes.items = [PlayerCapTime(row) for row in captimes.items]
 
     return {
-            'player_id':player_id,
-            'player':player,
-            'captimes':player_captimes,
-            #'player_url':request.route_url('player_info', id=player_id),
+            "player_id" : player_id,
+            "player"    : player,
+            "captimes"  : captimes,
         }
 
 
@@ -1071,11 +1009,23 @@ def player_captimes(request):
 
 
 def player_captimes_json(request):
-    return player_captimes_data(request)
+    data = player_captimes_data(request)
+    page = request.params.get("page", 1)
+
+    # perform any necessary JSON conversions
+    player_id = data["player_id"]
+    player = data["player"].to_dict()
+    captimes = [ct.to_dict() for ct in data["captimes"].items]
+
+    return {
+            "player"    : player,
+            "captimes"  : captimes,
+            "page"      : page,
+            }
 
 
 def player_weaponstats_data_json(request):
-    player_id = request.matchdict["id"]
+    player_id = int(request.matchdict["id"])
     if player_id <= 2:
         player_id = -1;
 
@@ -1092,23 +1042,22 @@ def player_weaponstats_data_json(request):
         if limit > 50:
             limit = 50
 
-    games_raw = DBSession.query(sa.distinct(Game.game_id)).\
-        filter(Game.game_id == PlayerWeaponStat.game_id).\
-        filter(PlayerWeaponStat.player_id == player_id)
+
+    # the game_ids of the most recently played ones 
+    # of the given game type is used for a subquery
+    games_list = DBSession.query(Game.game_id).\
+            filter(Game.players.contains([player_id]))
 
     if game_type_cd is not None:
-        games_raw = games_raw.filter(Game.game_type_cd == game_type_cd)
+        games_list = games_list.filter(Game.game_type_cd == game_type_cd)
 
-    games_raw = games_raw.order_by(Game.game_id.desc()).limit(limit).all()
+    games_list = games_list.order_by(Game.game_id.desc()).limit(limit)
 
     weapon_stats_raw = DBSession.query(PlayerWeaponStat).\
         filter(PlayerWeaponStat.player_id == player_id).\
-        filter(PlayerWeaponStat.game_id.in_(games_raw)).all()
+        filter(PlayerWeaponStat.game_id.in_(games_list)).\
+        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 = {}
     sum_avgs = {}
@@ -1121,6 +1070,9 @@ def player_weaponstats_data_json(request):
         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.keys()) - set(games_to_weapons[game_id]):
             weapon_stats_raw.append(PlayerWeaponStat(player_id=player_id,