]> de.git.xonotic.org Git - xonotic/xonstat.git/commitdiff
Make the "recent games" section more modular.
authorAnt Zucaro <azucaro@gmail.com>
Mon, 19 Nov 2012 00:27:14 +0000 (19:27 -0500)
committerJan Behrens <zykure@web.de>
Sun, 23 Dec 2012 14:18:34 +0000 (15:18 +0100)
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!

xonstat/templates/main_index.mako
xonstat/views/helpers.py [new file with mode: 0644]
xonstat/views/main.py

index ca165e46c6fd3c80243831ad02411b649a27a293..551eea4077287b75e5e642896e2541dc2859e5d6 100644 (file)
@@ -218,31 +218,20 @@ Leaderboard
         </tr>
       </thead>
       <tbody>
-      % for (game, server, map, pgstat) in recent_games:
-        % if game != '-':
+      % for rg in recent_games:
         <tr>
-          <td><a class="btn btn-primary btn-small" href="${request.route_url('game_info', id=game.game_id)}" title="View detailed information about this game">view</a></td>
-          <td class="gt_icon"><img title="${game.game_type_cd}" src="/static/images/icons/24x24/${game.game_type_cd}.png" alt="${game.game_type_cd}" /></td>
-          <td><a href="${request.route_url('server_info', id=server.server_id)}" title="Go to the detail page for this server">${server.name}</a></td>
-          <td><a href="${request.route_url('map_info', id=map.map_id)}" title="Go to the map detail page for this map">${map.name}</a></td>
-          <td><span class="abstime" data-epoch="${game.epoch()}" title="${game.start_dt.strftime('%a, %d %b %Y %H:%M:%S UTC')}">${game.fuzzy_date()}</span></td>
+          <td><a class="btn btn-primary btn-small" href="${request.route_url('game_info', id=rg.game_id)}" title="View detailed information about this game">view</a></td>
+          <td class="gt_icon"><img title="${rg.game_type_cd}" src="/static/images/icons/24x24/${rg.game_type_cd}.png" alt="${rg.game_type_cd}" /></td>
+          <td><a href="${request.route_url('server_info', id=rg.server_id)}" title="Go to the detail page for this server">${rg.server_name}</a></td>
+          <td><a href="${request.route_url('map_info', id=rg.map_id)}" title="Go to the map detail page for this map">${rg.map_name}</a></td>
+          <td><span class="abstime" data-epoch="${rg.epoch}" title="${rg.create_dt.strftime('%a, %d %b %Y %H:%M:%S UTC')}">${rg.fuzzy_date}</span></td>
           <td>
-            % if pgstat.player_id > 2:
-            <a href="${request.route_url('player_info', id=pgstat.player_id)}" title="Go to the player info page for this player">${pgstat.nick_html_colors()|n}</a></td>
+            % if rg.player_id > 2:
+            <a href="${request.route_url('player_info', id=rg.player_id)}" title="Go to the player info page for this player">${rg.nick_html_colors|n}</a></td>
             % else:
-            ${pgstat.nick_html_colors()|n}</td>
+            ${rg.nick_html_colors|n}</td>
             % endif
         </tr>
-        % else:
-        <tr>
-          <td>-</td>
-          <td>-</td>
-          <td>-</td>
-          <td>-</td>
-          <td>-</td>
-          <td>-</td>
-        </tr>
-        % endif
         % endfor
         </tbody>
     </table>
diff --git a/xonstat/views/helpers.py b/xonstat/views/helpers.py
new file mode 100644 (file)
index 0000000..01ef143
--- /dev/null
@@ -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
index 05496e93913e6669fc4f5b4493da576669628dbc..3732b48d252427d405ac0ec139666f02205821d2 100644 (file)
@@ -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,