def _create_stats(self, session, player_filter=None, replay_ids=None): average = QueryFilterBuilder().with_stat_query( self.get_player_stat_query()) std_devs = QueryFilterBuilder().with_stat_query( self.get_player_stat_std_query()) if player_filter is not None: average.with_players(player_filter) std_devs.with_players(player_filter) if replay_ids is not None: average.with_replay_ids(replay_ids) std_devs.with_replay_ids(replay_ids) average = average.build_query(session).filter( PlayerGame.time_in_game > 0).first() std_devs = std_devs.build_query(session).filter( PlayerGame.time_in_game > 0).first() average = { n.get_field_name(): round(float(s), 2) for n, s in zip(self.player_stats.stat_list, average) if s is not None } std_devs = { n.get_field_name(): round(float(s), 2) for n, s in zip(self.player_stats.stat_list, std_devs) if s is not None } return {'average': average, 'std_dev': std_devs}
def create_with_filters(page: int, limit: int, session=None, **kwargs) -> 'MatchHistory': tags = JsonTag.get_tags_from_query_params(**kwargs, session=session) builder = QueryFilterBuilder().as_game() if len(tags) > 0: builder.with_tags([tag.id for tag in tags]) QueryFilterBuilder.apply_arguments_to_query(builder, kwargs) query = builder.build_query(session) if 'min_length' in kwargs: query = query.filter(Game.length > kwargs['min_length']) if 'max_length' in kwargs: query = query.filter(Game.length < kwargs['max_length']) if 'map' in kwargs: query = query.filter(Game.map == kwargs['map']) count = query.count() games = query.order_by(desc(Game.match_date))[page * limit:(page + 1) * limit] matches = MatchHistory( count, [Replay.create_from_game(game) for game in games]) return matches
def _get_counts(self, session, player_filter=None, replay_ids=None): stats = QueryFilterBuilder().with_stat_query((PlayerGame,)) if player_filter is not None: stats.with_players(player_filter) if replay_ids is not None: stats.with_replay_ids(replay_ids) return stats.build_query(session).filter(PlayerGame.time_in_game > 0).count()
def _create_group_stats_from_query(self, session, query, player_filter=None, replay_ids=None): stats = QueryFilterBuilder().with_stat_query(query) if player_filter is not None: stats.with_players(player_filter) if replay_ids is not None: stats.with_replay_ids(replay_ids) stats = stats.build_query(session).filter(PlayerGame.time_in_game > 0).first() stats = {n.get_query_key(): round(float(s), 2) for n, s in zip(self.player_stats.stat_list, stats) if s is not None} return stats
def have_permission_to_change_game(game_hash: str, user_id, session=None) -> bool: entry = session.query(GameVisibility).filter(GameVisibility.player == user_id, GameVisibility.game == game_hash).first() if entry is None: # Check if user has right to change visibility: builder = QueryFilterBuilder().as_game().set_replay_id(game_hash).with_players([user_id]) if builder.build_query(session).first() is not None: return True else: # Replay might actually exist, but user should not know. raise ReplayNotFound() else: return True
def api_v1_get_playergames_by_rank(session=None): if 'days' in request.args: days = int(request.args['days']) else: days = 3 * 30 builder = QueryFilterBuilder().with_stat_query([PlayerGame]).with_relative_start_time(days) QueryFilterBuilder.apply_arguments_to_query(builder, request.args) games = builder.build_query(session).order_by(func.random())[:1000] columns = [c.name for c in games[0].__table__.columns] data = { 'data': [[getattr(g, c.name) for c in g.__table__.columns] for g in games], 'columns': columns } return jsonify(data)
def create_with_filters(page: int, limit: int, session=None, **kwargs) -> 'MatchHistory': # TODO: move this somewhere else and make it reusable if limit > 100: limit = 100 builder = QueryFilterBuilder().as_game().with_stat_query([Game]) QueryFilterBuilder.apply_arguments_to_query(builder, kwargs) query = builder.build_query(session) if 'min_length' in kwargs: query = query.filter(Game.length > kwargs['min_length']) if 'max_length' in kwargs: query = query.filter(Game.length < kwargs['max_length']) if 'map' in kwargs: query = query.filter(Game.map == kwargs['map']) count = query.count() games = query.order_by(desc(Game.match_date))[page * limit: (page + 1) * limit] matches = MatchHistory(count, [Replay.create_from_game(game) for game in games]) return matches
class PlayerStatWrapper(GlobalStatWrapper): def __init__(self, player_wrapper: PlayerWrapper): super().__init__() self.player_wrapper = player_wrapper # this Object needs to be pooled per a session so only one is used at a time self.player_stats_filter = QueryFilterBuilder() self.player_stats_filter.with_relative_start_time( days_ago=30 * 6).with_team_size(3).with_safe_checking().sticky() def get_wrapped_stats(self, stats): zipped_stats = dict() for i in range(len(self.field_names)): zipped_stats[self.field_names[i].field_name] = stats[i] return zipped_stats def get_stats(self, session, id_, stats_query, std_query, rank=None, redis=None): global_stats, global_stds = self.get_global_stats_by_rank( session, self.player_stats_filter, stats_query, std_query, player_rank=rank, redis=redis) self.player_stats_filter.clean().with_stat_query( stats_query).with_players([id_]) stats = list(self.player_stats_filter.build_query(session).first()) return self.compare_to_global(stats, global_stats, global_stds) def get_averaged_stats(self, session, id_, rank=None, redis=None): stats_query = self.stats_query std_query = self.std_query total_games = self.player_wrapper.get_total_games(session, id_) if total_games > 0: stats = self.get_stats(session, id_, stats_query, std_query, rank=rank, redis=redis) else: stats = [0.0] * len(stats_query) return self.get_wrapped_stats(stats) @staticmethod def get_stat_spider_charts(): titles = [ # 'Basic', 'Aggressiveness', 'Chemistry', 'Skill', 'Tendencies', 'Luck' ] groups = [ # ['score', 'goals', 'assists', 'saves', 'turnovers'], # basic [ 'shots', 'possession', 'hits', 'shots/hit', 'boost usage', 'speed' ], # agressive ['boost wasted', 'assists', 'passes/hit', 'passes', 'assists/hit'], # chemistry [ 'turnovers', 'useful/hits', 'aerials', 'won turnovers', 'avg hit dist' ], # skill ['att 1/3', 'att 1/2', 'def 1/2', 'def 1/3', '< ball', '> ball'] ] # , # tendencies # ['luck1', 'luck2', 'luck3', 'luck4']] # luck return [{ 'title': title, 'group': group } for title, group in zip(titles, groups)] def _create_stats(self, session, query_filter=None, ids=None): if query_filter is not None and ids is not None: query_filter = and_(query_filter, PlayerGame.game.in_(ids)) elif ids is not None: query_filter = PlayerGame.game.in_(ids) average = session.query(*self.stats_query) std_devs = session.query(*self.std_query) if query_filter is not None: average = average.filter(query_filter) std_devs = std_devs.filter(query_filter) average = average.first() std_devs = std_devs.first() average = { n.field_name: round(float(s), 2) for n, s in zip(self.field_names, average) if s is not None } std_devs = { n.field_name: round(float(s), 2) for n, s in zip(self.field_names, std_devs) if s is not None } return {'average': average, 'std_dev': std_devs} def get_group_stats(self, session, ids): return_obj = {} # Players player_tuples = session.query(PlayerGame.player, func.count(PlayerGame.player)).filter( PlayerGame.game.in_(ids)).group_by( PlayerGame.player).all() return_obj['playerStats'] = {} ensemble = [] for player_tuple in player_tuples: player, count = player_tuple if count > 1: player_stats = self._create_stats(session, PlayerGame.player == player, ids=ids) return_obj['playerStats'][player] = player_stats else: ensemble.append(player) if len(ensemble) > 0: ensemble_stats = self._create_stats( session, PlayerGame.player.in_(ensemble), ids=ids) return_obj['ensembleStats'] = ensemble_stats # STATS # Global global_stats = self._create_stats(session, ids=ids) return_obj['globalStats'] = global_stats return return_obj