config.add_view(view=MapTopScorers, route_name="map_top_scorers", attr="json",
renderer="json", accept="application/json")
+ config.add_route("map_top_active", "/map/{id:\d+}/topactive")
+ config.add_view(view=MapTopPlayers, route_name="map_top_active", attr="html",
+ renderer="map_top_active.mako", accept="text/html")
+ config.add_view(view=MapTopPlayers, route_name="map_top_active", attr="json",
+ renderer="json", accept="application/json")
+
config.add_route("map_info", "/map/{id:\d+}")
config.add_view(map_info, route_name="map_info", renderer="map_info.mako")
--- /dev/null
+<%inherit file="base.mako"/>
+<%namespace name="nav" file="nav.mako" />
+
+<%block name="navigation">
+ ${nav.nav('maps')}
+</%block>
+
+<%block name="title">
+ Map Active Players Index
+</%block>
+
+% if not top_players and last is not None:
+ <h2 class="text-center">Sorry, no more active players!</h2>
+
+% elif not top_players and last is None:
+ <h2 class="text-center">No active players found. Yikes, get playing!</h2>
+
+% else:
+ ##### ACTIVE PLAYERS #####
+ <div class="row">
+ <div class="small-12 large-6 large-offset-3 columns">
+ <table class="table-hover table-condensed">
+ <thead>
+ <tr>
+ <th class="small-2">#</th>
+ <th class="small-7">Nick</th>
+ <th class="small-3">Play Time</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ % for tp in top_players:
+ <tr>
+ <td>${tp.rank}</td>
+ <td class="no-stretch"><a href="${request.route_url('player_info', id=tp.player_id)}" title="Go to the player info page for this player">${tp.nick|n}</a></td>
+ <td>${tp.alivetime}</td>
+ </tr>
+ % endfor
+ </tbody>
+ </table>
+ <p class="text-center"><small>Note: these figures are from the past ${lifetime} days</small>
+ </div>
+ </div>
+
+ % if len(top_players) == 20:
+ <div class="row">
+ <div class="small-12 large-6 large-offset-3 columns">
+ <ul class="pagination">
+ <li>
+ <a href="${request.route_url('map_top_active', id=map_id, _query=query)}" name="Next Page">Next <i class="fa fa-arrow-right"></i></a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ % endif
+
+% endif
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"),
}
+class MapTopPlayers(MapInfoBase):
+ """Returns the top players on a given map, by playing time."""
+
+ def __init__(self, request, limit=INDEX_COUNT, last=None):
+ """Common parameter parsing."""
+ super(MapTopPlayers, self).__init__(request, limit, last)
+ self.top_players = self.get_top_players()
+
+ def get_top_players(self):
+ """Top players by playing time. Shared by all renderers."""
+ cutoff = self.now - timedelta(days=self.lifetime)
+
+ 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.map_id == self.map_id)\
+ .filter(Player.player_id > 2) \
+ .filter(PlayerGameStat.create_dt > cutoff).\
+ 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()
+
+ return top_players
+
+ def html(self):
+ """Returns an HTML-ready representation."""
+ TopPlayer = namedtuple("TopPlayer", ["rank", "player_id", "nick", "alivetime"])
+
+ top_players = [TopPlayer(tp.rank, tp.player_id, html_colors(tp.nick), tp.alivetime)
+ for tp in self.top_players]
+
+ # build the query string
+ query = {}
+ if len(top_players) > 1:
+ query['last'] = top_players[-1].rank
+
+ return {
+ "map_id": self.map_id,
+ "top_players": top_players,
+ "lifetime": self.lifetime,
+ "query": query,
+ }
+
+ def json(self):
+ """For rendering this data using JSON."""
+ top_players = [{
+ "rank": tp.rank,
+ "player_id": tp.player_id,
+ "nick": tp.nick,
+ "alivetime": tp.alivetime.total_seconds(),
+ } for tp in self.top_players]
+
+ return {
+ "map_id": self.map_id,
+ "top_scorers": top_players,
+ }
+
+
def _map_info_data(request):
map_id = int(request.matchdict['id'])