From: Ant Zucaro Date: Mon, 19 Nov 2012 00:27:14 +0000 (-0500) Subject: Make the "recent games" section more modular. X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=90499e2a01eebca95b55b22ed12accc112635c48;p=xonotic%2Fxonstat.git Make the "recent games" section more modular. The main page was constructing all of the recent games queries manually before. Now I've moved the query and the associated class (which would have been a namedtuple if not for the various transformations needed) into a new "helpers" view. This view is intended to house query functions and the corresponding classes for them, so no more grabbing from a query, then looping around and creating namedtuples to get stuff like nick_html_colors. Now one can just pass the row returned by the query to a class, which will "know" how to construct stuff like that. Win! --- diff --git a/xonstat/templates/main_index.mako b/xonstat/templates/main_index.mako index ca165e4..551eea4 100644 --- a/xonstat/templates/main_index.mako +++ b/xonstat/templates/main_index.mako @@ -218,31 +218,20 @@ Leaderboard - % for (game, server, map, pgstat) in recent_games: - % if game != '-': + % for rg in recent_games: - view - ${game.game_type_cd} - ${server.name} - ${map.name} - ${game.fuzzy_date()} + view + ${rg.game_type_cd} + ${rg.server_name} + ${rg.map_name} + ${rg.fuzzy_date} - % if pgstat.player_id > 2: - ${pgstat.nick_html_colors()|n} + % if rg.player_id > 2: + ${rg.nick_html_colors|n} % else: - ${pgstat.nick_html_colors()|n} + ${rg.nick_html_colors|n} % endif - % else: - - - - - - - - - - - - - - - % endif % endfor diff --git a/xonstat/views/helpers.py b/xonstat/views/helpers.py new file mode 100644 index 0000000..01ef143 --- /dev/null +++ b/xonstat/views/helpers.py @@ -0,0 +1,94 @@ +import logging +import sqlalchemy.sql.expression as expr +from datetime import datetime +from xonstat.models import * +from xonstat.util import * + +log = logging.getLogger(__name__) + +class RecentGame(object): + ''' + This is a helper class to facilitate showing recent games + data within mako. The idea is to take the results of a query + and transform it into class members easily accessible later. + It is like a namedtuple but a little easier to form. + + The constructor takes a query row that has been fetched, and + it requires the following columns to be present in the row: + + game_id, game_type_cd, winner, create_dt, server_id, server_name, + map_id, map_name, player_id, nick, rank, team + + The following columns are optional: + + elo_delta + + This class is meant to be used in conjunction with recent_games_q, + which will return rows matching this specification. + ''' + def __init__(self, row): + self.game_id = row.game_id + self.game_type_cd = row.game_type_cd + self.winner = row.winner + self.create_dt = row.create_dt + self.fuzzy_date = pretty_date(row.create_dt) + self.epoch = timegm(row.create_dt.timetuple()) + self.server_id = row.server_id + self.server_name = row.server_name + self.map_id = row.map_id + self.map_name = row.map_name + self.player_id = row.player_id + self.nick = row.nick + self.nick_html_colors = html_colors(row.nick) + self.rank = row.rank + self.team = row.team + + try: + self.elo_delta = row.elo_delta + except: + self.elo_delta = None + + +def recent_games_q(server_id=None, map_id=None, player_id=None, cutoff=None): + ''' + Returns a SQLA query of recent game data. Parameters filter + the results returned if they are provided. If not, it is + assumed that results from all servers and maps is desired. + + The cutoff parameter provides a way to limit how far back to + look when querying. Only games that happened on or after the + cutoff (which is a datetime object) will be returned. + ''' + recent_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.player_id, + PlayerGameStat.nick, PlayerGameStat.rank, PlayerGameStat.team, + PlayerGameStat.elo_delta).\ + filter(Game.server_id==Server.server_id).\ + filter(Game.map_id==Map.map_id).\ + filter(Game.game_id==PlayerGameStat.game_id).\ + order_by(expr.desc(Game.create_dt)) + + # the various filters provided get tacked on to the query + if server_id is not None: + recent_games_q = recent_games_q.\ + filter(Server.server_id==server_id) + + if map_id is not None: + recent_games_q = recent_games_q.\ + filter(Map.map_id==map_id) + + if player_id is not None: + recent_games_q = recent_games_q.\ + filter(PlayerGameStat.player_id==player_id) + else: + recent_games_q = recent_games_q.\ + filter(PlayerGameStat.rank==1) + + if cutoff is not None: + right_now = datetime.utcnow() + recent_games_q = recent_games_q.\ + filter(expr.between(Game.create_dt, cutoff, right_now)) + + return recent_games_q diff --git a/xonstat/views/main.py b/xonstat/views/main.py index 05496e9..3732b48 100644 --- a/xonstat/views/main.py +++ b/xonstat/views/main.py @@ -5,11 +5,14 @@ from datetime import datetime, timedelta from pyramid.response import Response from xonstat.models import * from xonstat.util import * +from xonstat.views.helpers import RecentGame, recent_games_q + log = logging.getLogger(__name__) + def _main_index_data(request): - try: + try: leaderboard_lifetime = int( request.registry.settings['xonstat.leaderboard_lifetime']) except: @@ -83,14 +86,9 @@ def _main_index_data(request): group_by(Map.name).limit(leaderboard_count).all() # recent games played in descending order - recent_games = DBSession.query(Game, Server, Map, PlayerGameStat).\ - filter(Game.server_id==Server.server_id).\ - filter(Game.map_id==Map.map_id).\ - filter(PlayerGameStat.game_id==Game.game_id).\ - filter(PlayerGameStat.rank==1).\ - filter(expr.between(Game.create_dt, back_then, right_now)).\ - order_by(expr.desc(Game.start_dt)).limit(recent_games_count).all() - + #rgs = recent_games_q(cutoff=back_then).limit(recent_games_count).all() + #recent_games = [RecentGame(row) for row in rgs] + recent_games = [RecentGame(row) for row in recent_games_q(cutoff=back_then).limit(recent_games_count).all()] return {'top_players':top_players, 'top_servers':top_servers, 'top_maps':top_maps,