def map_captimes_data(request): map_id = int(request.matchdict['id']) current_page = request.params.get('page', 1) try: mmap = DBSession.query(Map).filter_by(map_id=map_id).one() mct_q = DBSession.query(PlayerCaptime.fastest_cap, PlayerCaptime.create_dt, PlayerCaptime.player_id, PlayerCaptime.game_id, Game.server_id, Server.name.label('server_name'), PlayerGameStat.nick.label('player_nick')).\ filter(PlayerCaptime.map_id==map_id).\ filter(PlayerCaptime.game_id==Game.game_id).\ filter(PlayerCaptime.map_id==Map.map_id).\ filter(Game.server_id==Server.server_id).\ filter(PlayerCaptime.player_id==PlayerGameStat.player_id).\ filter(PlayerCaptime.game_id==PlayerGameStat.game_id).\ order_by(expr.asc(PlayerCaptime.fastest_cap)) except Exception as e: raise HTTPNotFound map_captimes = Page(mct_q, current_page, items_per_page=20, url=page_url) map_captimes.items = [MapCapTime(row) for row in map_captimes.items] return { 'map_id':map_id, 'map':mmap, 'captimes':map_captimes, }
def _rank_index_data(request): current_page = request.params.get("page", 1) # game type whitelist game_types_allowed = ["ca", "ctf", "dm", "duel", "ft", "ka", "tdm"] game_type_cd = request.matchdict['game_type_cd'] if game_type_cd not in game_types_allowed: raise httpexceptions.HTTPNotFound() ranks_q = DBSession.query(PlayerRank).\ filter(PlayerRank.game_type_cd==game_type_cd).\ order_by(PlayerRank.rank) game_type = DBSession.query(GameType).\ filter(GameType.game_type_cd == game_type_cd).one() ranks = Page(ranks_q, current_page, url=page_url) if len(ranks) == 0: ranks = None return { 'ranks': ranks, 'game_type_cd': game_type_cd, 'game_type': game_type, }
def _rank_index_data(request): current_page = request.params.get("page", 1) # game type whitelist game_types_allowed = ["ca", "ctf", "dm", "duel", "ft", "ka", "tdm"] game_type_cd = request.matchdict['game_type_cd'] if game_type_cd not in game_types_allowed: raise httpexceptions.HTTPNotFound() ranks_q = DBSession.query(PlayerRank).\ filter(PlayerRank.game_type_cd==game_type_cd).\ order_by(PlayerRank.rank) game_type = DBSession.query(GameType).\ filter(GameType.game_type_cd == game_type_cd).one() ranks = Page(ranks_q, current_page, url=page_url) if len(ranks) == 0: ranks = None return { 'ranks':ranks, 'game_type_cd':game_type_cd, 'game_type': game_type, }
def player_game_index_data(request): try: player_id = int(request.matchdict['player_id']) except: player_id = -1 game_type_cd = None game_type_descr = None if request.params.has_key('type'): game_type_cd = request.params['type'] try: game_type_descr = DBSession.query(GameType.descr).\ filter(GameType.game_type_cd == game_type_cd).\ one()[0] except Exception as e: pass else: game_type_cd = None game_type_descr = None if request.params.has_key('page'): current_page = request.params['page'] else: current_page = 1 try: player = DBSession.query(Player).\ filter_by(player_id=player_id).\ filter(Player.active_ind == True).\ one() rgs_q = recent_games_q(player_id=player.player_id, force_player_id=True, game_type_cd=game_type_cd) games = Page(rgs_q, current_page, items_per_page=20, url=page_url) # replace the items in the canned pagination class with more rich ones games.items = [RecentGame(row) for row in games.items] games_played = get_games_played(player_id) except Exception as e: raise e player = None games = None game_type_cd = None game_type_descr = None games_played = None return { 'player_id':player.player_id, 'player':player, 'games':games, 'game_type_cd':game_type_cd, 'game_type_descr':game_type_descr, 'games_played':games_played, }
def merge(request): '''A simple merge view. The merge.mako template does the work.''' s = DBSession() # only do a merge if we have all of the required data if request.params.has_key("csrf_token"): # check the token to prevent request forgery st = request.session.get_csrf_token() check_csrf_token(request) if request.params.has_key("w_pid") and request.params.has_key("l_pid"): w_pid = request.params.get("w_pid") l_pid = request.params.get("l_pid") # do the merge, hope for the best! try: s.execute("select merge_players(:w_pid, :l_pid)", { "w_pid": w_pid, "l_pid": l_pid }) s.commit() request.session.flash( "Successfully merged player %s into %s!" % (l_pid, w_pid), "success") except: s.rollback() request.session.flash( "Could not merge player %s into %s." % (l_pid, w_pid), "failure") return {}
def get_elos(player_id): """ Provides a breakdown of the player's elos by game type. Returns a dictionary of namedtuples with the following members: - player_id - game_type_cd - games - elo The key to the dictionary is the game type code. There is also an "overall" game_type_cd which is the overall best rank. """ raw_elos = DBSession.query(PlayerElo).filter_by(player_id=player_id).\ order_by(PlayerElo.elo.desc()).all() elos = {} found_max_elo = False for row in raw_elos: if not found_max_elo: elos['overall'] = row found_max_elo = True elos[row.game_type_cd] = row return elos
def player_info_data(request): player_id = int(request.matchdict['id']) if player_id <= 2: player_id = -1; try: player = DBSession.query(Player).filter_by(player_id=player_id).\ filter(Player.active_ind == True).one() games_played = get_games_played(player_id) overall_stats = get_overall_stats(player_id) 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) except Exception as e: raise pyramid.httpexceptions.HTTPNotFound ## do not raise application exceptions here (only for debugging) # raise e return {'player':player, 'games_played':games_played, 'overall_stats':overall_stats, 'fav_maps':fav_maps, 'elos':elos, 'ranks':ranks, 'medals':medals, 'recent_games':recent_games, 'cake_day':cake_day, }
def get_top_scorers(self): """Top players by score. Shared by all renderers.""" cutoff = self.now - timedelta(days=self.lifetime) cutoff = self.now - timedelta(days=120) top_scorers_q = DBSession.query( fg.row_number().over(order_by=expr.desc(func.sum(PlayerGameStat.score))).label("rank"), Player.player_id, Player.nick, func.sum(PlayerGameStat.score).label("total_score"))\ .filter(Player.player_id == PlayerGameStat.player_id)\ .filter(Game.game_id == PlayerGameStat.game_id)\ .filter(Game.map_id == self.map_id)\ .filter(Player.player_id > 2)\ .filter(PlayerGameStat.create_dt > cutoff)\ .order_by(expr.desc(func.sum(PlayerGameStat.score)))\ .group_by(Player.nick)\ .group_by(Player.player_id) if self.last: top_scorers_q = top_scorers_q.offset(self.last) if self.limit: top_scorers_q = top_scorers_q.limit(self.limit) top_scorers = top_scorers_q.all() return top_scorers
def top_players(self): """Top players on this server by total playing time.""" try: top_players_q = DBSession.query( fg.row_number().over( order_by=expr.desc(func.sum(PlayerGameStat.alivetime))).label("rank"), Player.player_id, Player.nick, func.sum(PlayerGameStat.alivetime).label("alivetime"))\ .filter(Player.player_id == PlayerGameStat.player_id)\ .filter(Game.game_id == PlayerGameStat.game_id)\ .filter(Game.server_id == self.server_id)\ .filter(Player.player_id > 2)\ .filter(PlayerGameStat.create_dt > (self.now - timedelta(days=self.lifetime)))\ .order_by(expr.desc(func.sum(PlayerGameStat.alivetime)))\ .group_by(Player.nick)\ .group_by(Player.player_id) if self.last: top_players_q = top_players_q.offset(self.last) if self.limit: top_players_q = top_players_q.limit(self.limit) top_players = top_players_q.all() except Exception as e: log.debug(e) raise HTTPNotFound return top_players
def get_top_scorers(self): """Top players by score. Shared by all renderers.""" cutoff = self.now - timedelta(days=self.lifetime) try: top_scorers_q = DBSession.query( fg.row_number().over(order_by=expr.desc(func.sum(PlayerGameStat.score))).label("rank"), Player.player_id, Player.nick, func.sum(PlayerGameStat.score).label("total_score"))\ .filter(Player.player_id == PlayerGameStat.player_id)\ .filter(Game.game_id == PlayerGameStat.game_id)\ .filter(Game.map_id == self.map_id)\ .filter(Player.player_id > 2)\ .filter(PlayerGameStat.create_dt > cutoff)\ .order_by(expr.desc(func.sum(PlayerGameStat.score)))\ .group_by(Player.nick)\ .group_by(Player.player_id) if self.last: top_scorers_q = top_scorers_q.offset(self.last) if self.limit: top_scorers_q = top_scorers_q.limit(self.limit) top_scorers = top_scorers_q.all() return top_scorers except Exception as e: log.debug(e) raise HTTPNotFound
def get_top_servers(self): """Top servers by the number of times they have played the map. Shared by all renderers.""" cutoff = self.now - timedelta(days=self.lifetime) try: top_servers_q = DBSession.query( fg.row_number().over(order_by=expr.desc(func.count(Game.game_id))).label("rank"), Server.server_id, Server.name, func.count(Game.game_id).label("games"))\ .filter(Game.server_id == Server.server_id)\ .filter(Game.map_id == self.map_id)\ .filter(Game.create_dt > cutoff)\ .order_by(expr.desc(func.count(Game.game_id)))\ .group_by(Server.name)\ .group_by(Server.server_id) if self.last: top_servers_q = top_servers_q.offset(self.last) if self.limit: top_servers_q = top_servers_q.limit(self.limit) top_servers = top_servers_q.all() return top_servers except Exception as e: log.debug(e) raise HTTPNotFound
def player_info_data(request): player_id = int(request.matchdict['id']) if player_id <= 2: player_id = -1; try: player = DBSession.query(Player).filter_by(player_id=player_id).\ filter(Player.active_ind == True).one() games_played = get_games_played(player_id) overall_stats = get_overall_stats(player_id) fav_maps = get_fav_maps(player_id) elos = get_elos(player_id) ranks = {} medals = get_player_medals(player_id) recent_games = get_recent_games(player_id) cake_day = is_cake_day(player.create_dt) except Exception as e: log.error(e) raise pyramid.httpexceptions.HTTPNotFound ## do not raise application exceptions here (only for debugging) # raise e return {'player':player, 'games_played':games_played, 'overall_stats':overall_stats, 'fav_maps':fav_maps, 'elos':elos, 'ranks':ranks, 'medals':medals, 'recent_games':recent_games, 'cake_day':cake_day, }
def top_maps(self): """Returns the raw data shared by all renderers.""" try: top_maps_q = DBSession.query( fg.row_number().over(order_by=expr.desc(func.count())).label("rank"), Game.map_id, Map.name, func.count().label("times_played"))\ .filter(Map.map_id == Game.map_id)\ .filter(Game.server_id == self.server_id)\ .filter(Game.create_dt > (self.now - timedelta(days=self.lifetime)))\ .group_by(Game.map_id)\ .group_by(Map.name) \ .order_by(expr.desc(func.count())) if self.last: top_maps_q = top_maps_q.offset(self.last) if self.limit: top_maps_q = top_maps_q.limit(self.limit) top_maps = top_maps_q.all() except Exception as e: log.debug(e) raise HTTPNotFound return top_maps
def player_elo_info_data(request): """ Provides elo information on a specific player. Raw data is returned. """ (idfp, status) = verify_request(request) log.debug("d0_blind_id verification: idfp={0} status={1}\n".format(idfp, status)) log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body + "----- END REQUEST BODY -----\n\n") hashkey = request.matchdict['hashkey'] # the incoming hashkey is double quoted, and WSGI unquotes once... hashkey = unquote(hashkey) try: player = DBSession.query(Player).\ filter(Player.player_id == Hashkey.player_id).\ filter(Player.active_ind == True).\ filter(Hashkey.hashkey == hashkey).one() elos = get_elos(player.player_id) except Exception as e: log.debug(e) raise pyramid.httpexceptions.HTTPNotFound return { 'hashkey':hashkey, 'player':player, 'elos':elos, }
def merge(request): '''A simple merge view. The merge.mako template does the work.''' s = DBSession() # only do a merge if we have all of the required data if request.params.has_key("csrf_token"): # check the token to prevent request forgery st = request.session.get_csrf_token() check_csrf_token(request) if request.params.has_key("w_pid") and request.params.has_key("l_pid"): w_pid = request.params.get("w_pid") l_pid = request.params.get("l_pid") # do the merge, hope for the best! try: s.execute("select merge_players(:w_pid, :l_pid)", {"w_pid": w_pid, "l_pid": l_pid}) s.commit() request.session.flash( "Successfully merged player %s into %s!" % (l_pid, w_pid), "success") except: s.rollback() request.session.flash( "Could not merge player %s into %s." % (l_pid, w_pid), "failure") return {}
def groupfinder(userid, request): groups = [] try: groups_q = DBSession.query(PlayerGroups.group_name).filter(Player.email_addr == userid).all() for g in groups_q: groups.append(g.group_name) except: pass return groups
def player_captimes_data(request): player_id = int(request.matchdict['player_id']) if player_id <= 2: player_id = -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() 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')).\ 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) 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, 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] return { "player_id" : player_id, "player" : player, "captimes" : captimes, "page" : page, "sort" : sort, }
def groupfinder(userid, request): groups = [] try: groups_q = DBSession.query(PlayerGroups.group_name).\ filter(Player.email_addr == userid).all() for g in groups_q: groups.append(g.group_name) except: pass return groups
def get_damage_stats(player_id, weapon_cd, games): """ Provides damage info for weapon_cd by player_id for the past N games. """ try: raw_avg = DBSession.query(func.sum(PlayerWeaponStat.actual), func.sum(PlayerWeaponStat.hit)).\ filter(PlayerWeaponStat.player_id == player_id).\ filter(PlayerWeaponStat.weapon_cd == weapon_cd).\ one() avg = round(float(raw_avg[0])/raw_avg[1], 2) # Determine the damage efficiency (hit, fired) numbers for $games games # This is then enumerated to create parameters for a flot graph raw_dmgs = DBSession.query(PlayerWeaponStat.game_id, PlayerWeaponStat.actual, PlayerWeaponStat.hit).\ filter(PlayerWeaponStat.player_id == player_id).\ filter(PlayerWeaponStat.weapon_cd == weapon_cd).\ order_by(PlayerWeaponStat.game_id.desc()).\ limit(games).\ all() # they come out in opposite order, so flip them in the right direction raw_dmgs.reverse() dmgs = [] for i in range(len(raw_dmgs)): # try to derive, unless we've hit nothing then set to 0! try: dmg = round(float(raw_dmgs[i][1])/raw_dmgs[i][2], 2) except: dmg = 0.0 dmgs.append((raw_dmgs[i][0], dmg)) except Exception as e: dmgs = [] avg = 0.0 return (avg, dmgs)
def server_index(self): """Returns the raw data shared by all renderers.""" try: server_q = DBSession.query(Server)\ .filter(Server.active_ind)\ .order_by(Server.server_id.desc()) servers = Page(server_q, self.page, items_per_page=25, url=page_url) except Exception as e: log.debug(e) raise HTTPNotFound return servers
def search_q(nick=None, server_name=None, map_name=None, create_dt=None, gametypes=[]): session = DBSession() result_type = None q = None # player-only searches if nick and not server_name and not map_name and not create_dt \ and len(gametypes) < 1: result_type = "player" q = session.query(Player) if nick: q = q.filter( func.upper(Player.stripped_nick).like('%'+nick.upper()+'%')).\ filter(Player.player_id > 2).\ filter(Player.active_ind == True).\ order_by(Player.player_id) # server-only searches elif server_name and not nick and not map_name and not create_dt and len(gametypes) < 1: result_type = "server" q = session.query(Server) if server_name: q = q.filter(func.upper(Server.name).like('%'+server_name.upper()+'%'))\ .filter(Server.active_ind)\ .order_by(Server.server_id) # map-only searches elif map_name and not nick and not server_name and not create_dt \ and len(gametypes) < 1: result_type = "map" q = session.query(Map) if map_name: q = q.filter(func.upper(Map.name).\ like('%'+map_name.upper()+'%')).\ order_by(Map.map_id) # game searches (all else) else: result_type = "game" q = session.query(Game, Server, Map).\ filter(Game.server_id == Server.server_id).\ filter(Server.active_ind).\ filter(Game.map_id == Map.map_id).\ order_by(Game.game_id.desc()) if len(gametypes) > 0: q = q.filter(Game.game_type_cd.in_(gametypes)) if nick: q = q.filter(func.upper(PlayerGameStat.stripped_nick).\ like('%'+nick.upper()+'%')).\ filter(PlayerGameStat.game_id == Game.game_id) if map_name: q = q.filter(func.upper(Map.name).\ like('%'+map_name.upper()+'%')) if server_name: q = q.filter(func.upper(Server.name).\ like('%'+server_name.upper()+'%')) return (result_type, q)
def get_accuracy_stats(player_id, weapon_cd, games): """ Provides accuracy for weapon_cd by player_id for the past N games. """ # Reaching back 90 days should give us an accurate enough average # We then multiply this out for the number of data points (games) to # create parameters for a flot graph try: raw_avg = DBSession.query(func.sum(PlayerWeaponStat.hit), func.sum(PlayerWeaponStat.fired)).\ filter(PlayerWeaponStat.player_id == player_id).\ filter(PlayerWeaponStat.weapon_cd == weapon_cd).\ one() avg = round(float(raw_avg[0])/raw_avg[1]*100, 2) # Determine the raw accuracy (hit, fired) numbers for $games games # This is then enumerated to create parameters for a flot graph raw_accs = DBSession.query(PlayerWeaponStat.game_id, PlayerWeaponStat.hit, PlayerWeaponStat.fired).\ filter(PlayerWeaponStat.player_id == player_id).\ filter(PlayerWeaponStat.weapon_cd == weapon_cd).\ order_by(PlayerWeaponStat.game_id.desc()).\ limit(games).\ all() # they come out in opposite order, so flip them in the right direction raw_accs.reverse() accs = [] for i in range(len(raw_accs)): accs.append((raw_accs[i][0], round(float(raw_accs[i][1])/raw_accs[i][2]*100, 2))) except: accs = [] avg = 0.0 return (avg, accs)
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 get_top_maps_by_games(limit=None, start=None): """ The top maps by the number of games played during a date range. """ q = DBSession.query(ActiveMap) if start is not None: q = q.filter(ActiveMap.sort_order >= start) q = q.order_by(ActiveMap.sort_order) if limit is not None: q = q.limit(limit) return q.all()
def get_top_servers_by_play_time(limit=None, start=None): """ The top servers by the cumulative amount of time played on them during a given interval. """ q = DBSession.query(ActiveServer) if start is not None: q = q.filter(ActiveServer.sort_order >= start) q = q.order_by(ActiveServer.sort_order) if limit is not None: q = q.limit(limit) return q.all()
def get_top_players_by_time(limit=None, start=None): """ The top players by the amount of time played during a date range. """ q = DBSession.query(ActivePlayer) if start is not None: q = q.filter(ActivePlayer.sort_order >= start) q = q.order_by(ActivePlayer.sort_order) if limit is not None: q = q.limit(limit) return q.all()
def get_or_create_server(session, name, hashkey, ip_addr, revision, port, impure_cvars): """ Find a server by name or create one if not found. Parameters: session - SQLAlchemy database session factory name - server name of the server to be found or created hashkey - server hashkey ip_addr - the IP address of the server revision - the xonotic revision number port - the port number of the server impure_cvars - the number of impure cvar changes """ servers_q = DBSession.query(Server).filter(Server.active_ind) if hashkey: # if the hashkey is provided, we'll use that servers_q = servers_q.filter((Server.name == name) or (Server.hashkey == hashkey)) else: # otherwise, it is just by name servers_q = servers_q.filter(Server.name == name) # order by the hashkey, which means any hashkey match will appear first if there are multiple servers = servers_q.order_by(Server.hashkey, Server.create_dt).all() if len(servers) == 0: server = Server(name=name, hashkey=hashkey) session.add(server) session.flush() log.debug("Created server {} with hashkey {}.".format( server.server_id, server.hashkey)) else: server = servers[0] if len(servers) == 1: log.info("Found existing server {}.".format(server.server_id)) elif len(servers) > 1: server_id_list = ", ".join( ["{}".format(s.server_id) for s in servers]) log.warn("Multiple servers found ({})! Using the first one ({}).". format(server_id_list, server.server_id)) if update_server(server, name, hashkey, ip_addr, port, revision, impure_cvars): session.add(server) return server
def map_index(self): """Returns the raw data shared by all renderers.""" try: map_q = DBSession.query(Map) if self.last: map_q = map_q.filter(Map.map_id < self.last) map_q = map_q.order_by(Map.map_id.desc()).limit(INDEX_COUNT) maps = map_q.all() except Exception as e: log.debug(e) raise HTTPNotFound return maps
def get_ranks(player_id): """ Provides a breakdown of the player's ranks by game type. Returns a dictionary of namedtuples with the following members: - game_type_cd - rank - max_rank 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', 'percentile', 'game_type_cd']) raw_ranks = DBSession.query("game_type_cd", "rank", "max_rank").\ from_statement( "select pr.game_type_cd, pr.rank, overall.max_rank " "from player_ranks pr, " "(select game_type_cd, max(rank) max_rank " "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() ranks = {} found_top_rank = False for row in raw_ranks: rank = Rank(rank=row.rank, max_rank=row.max_rank, percentile=100 - 100*float(row.rank-1)/(row.max_rank-1), 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 return ranks;
def get_ranks(player_id): """ Provides a breakdown of the player's ranks by game type. Returns a dictionary of namedtuples with the following members: - game_type_cd - rank - max_rank 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', 'percentile', 'game_type_cd']) raw_ranks = DBSession.query("game_type_cd", "rank", "max_rank").\ from_statement(text( "select pr.game_type_cd, pr.rank, overall.max_rank " "from player_ranks pr, " "(select game_type_cd, max(rank) max_rank " "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() ranks = {} found_top_rank = False for row in raw_ranks: rank = Rank(rank=row.rank, max_rank=row.max_rank, percentile=100 - 100*float(row.rank-1)/(row.max_rank-1), 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 return ranks;
def get_or_create_server(session, name, hashkey, ip_addr, revision, port, impure_cvars): """ Find a server by name or create one if not found. Parameters: session - SQLAlchemy database session factory name - server name of the server to be found or created hashkey - server hashkey ip_addr - the IP address of the server revision - the xonotic revision number port - the port number of the server impure_cvars - the number of impure cvar changes """ servers_q = DBSession.query(Server).filter(Server.active_ind) if hashkey: # if the hashkey is provided, we'll use that servers_q = servers_q.filter((Server.name == name) or (Server.hashkey == hashkey)) else: # otherwise, it is just by name servers_q = servers_q.filter(Server.name == name) # order by the hashkey, which means any hashkey match will appear first if there are multiple servers = servers_q.order_by(Server.hashkey, Server.create_dt).all() if len(servers) == 0: server = Server(name=name, hashkey=hashkey) session.add(server) session.flush() log.debug("Created server {} with hashkey {}.".format(server.server_id, server.hashkey)) else: server = servers[0] if len(servers) == 1: log.info("Found existing server {}.".format(server.server_id)) elif len(servers) > 1: server_id_list = ", ".join(["{}".format(s.server_id) for s in servers]) log.warn("Multiple servers found ({})! Using the first one ({})." .format(server_id_list, server.server_id)) if update_server(server, name, hashkey, ip_addr, port, revision, impure_cvars): session.add(server) return server
def __init__(self, request): """Common data and parameters.""" super(ServerInfo, self).__init__(request) # this view uses data from other views, so we'll save the data at that level try: self.server = DBSession.query(Server)\ .filter(Server.active_ind)\ .filter(Server.server_id == self.server_id)\ .one() self.top_maps_v = ServerTopMaps(self.request, limit=LEADERBOARD_COUNT) self.top_scorers_v = ServerTopScorers(self.request, limit=LEADERBOARD_COUNT) self.top_players_v = ServerTopPlayers(self.request, limit=LEADERBOARD_COUNT) rgs = recent_games_q(server_id=self.server_id).limit(RECENT_GAMES_COUNT).all() self.recent_games = [RecentGame(row) for row in rgs] except: raise HTTPNotFound
def get_ranks(game_type_cd): """ Gets a set number of the top-ranked people for the specified game_type_cd. The game_type_cd parameter is the type to fetch. Currently limited to duel, dm, ctf, and tdm. """ # how many ranks we want to fetch leaderboard_count = 10 # only a few game modes are actually ranked if game_type_cd not in 'duel' 'dm' 'ctf' 'tdm': return None ranks = DBSession.query(PlayerRank).\ filter(PlayerRank.game_type_cd==game_type_cd).\ order_by(PlayerRank.rank).\ limit(leaderboard_count).all() return ranks
def login(request): # Verify the assertion and get the email of the user persona_email = verify_login(request) # Check that the email exists in the players table player_email = DBSession.query(Player).\ filter(Player.email_addr == persona_email).one() #log.debug("Verified email address: %s" % persona_email) #log.debug("Corresponding player is %s" % player_email) if player_email is not None: # Add the headers required to remember the user to the response request.response.headers.extend(remember(request, persona_email)) else: url = request.route_url("forbidden") return HTTPFound(location=url) # Return a json message containing the address or path to redirect to. return {'redirect': request.POST['came_from'], 'success': True}
def login(request): # Verify the assertion and get the email of the user # Short-circuit this to prevent anyone from logging in right now. persona_email = None # Check that the email exists in the players table player_email = DBSession.query(Player).\ filter(Player.email_addr == persona_email).one() #log.debug("Verified email address: %s" % persona_email) #log.debug("Corresponding player is %s" % player_email) if player_email is not None: # Add the headers required to remember the user to the response request.response.headers.extend(remember(request, persona_email)) else: url = request.route_url("forbidden") return HTTPFound(location=url) # Return a json message containing the address or path to redirect to. return {'redirect': request.POST['came_from'], 'success': True}
def summary_stats_data(scope="all"): """ Gets the summary stats (number of active players, the game type, and the number of games) for a given scope. :param scope: The scope to fetch from the table. May be "all" or "day". :return: list[tuple] """ sql = text("SELECT num_players, game_type_cd, num_games, create_dt refresh_dt " "FROM summary_stats_mv " "WHERE scope = :scope " "ORDER BY sort_order ") try: ss = DBSession.query("num_players", "game_type_cd", "num_games", "refresh_dt").\ from_statement(sql).params(scope=scope).all() return ss except Exception as e: log.error(e) return []
def player_index_data(request): if request.params.has_key('page'): current_page = request.params['page'] else: current_page = 1 try: player_q = DBSession.query(Player).\ filter(Player.player_id > 2).\ filter(Player.active_ind == True).\ filter(sa.not_(Player.nick.like('Anonymous Player%'))).\ order_by(Player.player_id.desc()) players = Page(player_q, current_page, items_per_page=25, url=page_url) except Exception as e: players = None raise e return {'players':players }
def player_hashkey_info_data(request): # hashkey = request.matchdict['hashkey'] # the incoming hashkey is double quoted, and WSGI unquotes once... # hashkey = unquote(hashkey) # if using request verification to obtain the hashkey (idfp, status) = verify_request(request) log.debug("d0_blind_id verification: idfp={0} status={1}\n".format(idfp, status)) log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body + "----- END REQUEST BODY -----\n\n") # if config is to *not* verify requests and we get nothing back, this # query will return nothing and we'll 404. try: player = DBSession.query(Player).\ filter(Player.player_id == Hashkey.player_id).\ filter(Player.active_ind == True).\ filter(Hashkey.hashkey == idfp).one() games_played = get_games_played(player.player_id) overall_stats = get_overall_stats(player.player_id) fav_maps = get_fav_maps(player.player_id) elos = get_elos(player.player_id) ranks = get_ranks(player.player_id) most_recent_game = get_recent_games(player.player_id, 1)[0] except Exception as e: raise pyramid.httpexceptions.HTTPNotFound return {'player':player, 'hashkey':idfp, 'games_played':games_played, 'overall_stats':overall_stats, 'fav_maps':fav_maps, 'elos':elos, 'ranks':ranks, 'most_recent_game':most_recent_game, }
def player_hashkey_info_data(request): # hashkey = request.matchdict['hashkey'] # the incoming hashkey is double quoted, and WSGI unquotes once... # hashkey = unquote(hashkey) # if using request verification to obtain the hashkey (idfp, status) = verify_request(request) log.debug("d0_blind_id verification: idfp={0} status={1}\n".format(idfp, status)) log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body + "----- END REQUEST BODY -----\n\n") # if config is to *not* verify requests and we get nothing back, this # query will return nothing and we'll 404. try: player = DBSession.query(Player).\ filter(Player.player_id == Hashkey.player_id).\ filter(Player.active_ind == True).\ filter(Hashkey.hashkey == idfp).one() games_played = get_games_played(player.player_id) overall_stats = get_overall_stats(player.player_id) fav_maps = get_fav_maps(player.player_id) elos = get_elos(player.player_id) ranks = {} most_recent_game = get_recent_games(player.player_id, 1)[0] except Exception as e: raise pyramid.httpexceptions.HTTPNotFound return {'player':player, 'hashkey':idfp, 'games_played':games_played, 'overall_stats':overall_stats, 'fav_maps':fav_maps, 'elos':elos, 'ranks':ranks, 'most_recent_game':most_recent_game, }
def get_data(self, player_id): """Return player data as dict. This function is similar to the function in player.py but more optimized for this purpose. """ # total games # wins/losses # kills/deaths # duel/dm/tdm/ctf elo + rank player = DBSession.query(Player).filter_by(player_id=player_id).\ filter(Player.active_ind == True).one() games_played = get_games_played(player_id) overall_stats = get_overall_stats(player_id) ranks = get_ranks(player_id) elos = get_elos(player_id) games_played_dict = {} for game in games_played: games_played_dict[game.game_type_cd] = game ranks_dict = {} for gt, rank in ranks.items(): ranks_dict[gt] = (rank.rank, rank.max_rank) elos_dict = {} for gt, elo in elos.items(): if elo.games > 0: elos_dict[gt] = elo.elo self.data = { 'player': player, 'games_played': games_played_dict, 'overall_stats': overall_stats, 'ranks': ranks_dict, 'elos': elos_dict, }
def get_data(self, player_id): """Return player data as dict. This function is similar to the function in player.py but more optimized for this purpose. """ # total games # wins/losses # kills/deaths # duel/dm/tdm/ctf elo + rank player = DBSession.query(Player).filter_by(player_id=player_id).\ filter(Player.active_ind == True).one() games_played = get_games_played(player_id) overall_stats = get_overall_stats(player_id) ranks = get_ranks(player_id) elos = get_elos(player_id) games_played_dict = {} for game in games_played: games_played_dict[game.game_type_cd] = game ranks_dict = {} for gt,rank in ranks.items(): ranks_dict[gt] = (rank.rank, rank.max_rank) elos_dict = {} for gt,elo in elos.items(): if elo.games > 0: elos_dict[gt] = elo.elo self.data = { 'player':player, 'games_played':games_played_dict, 'overall_stats':overall_stats, 'ranks':ranks_dict, 'elos':elos_dict, }