From 7274b5bc34538b0cfed923726b7a8ab3315e4273 Mon Sep 17 00:00:00 2001 From: Ant Zucaro Date: Sun, 1 Jan 2017 08:19:33 -0500 Subject: [PATCH] Refactor more of the Maps views into data, HTML, and JSON pieces. --- xonstat/__init__.py | 6 +++ xonstat/templates/map_top_active.mako | 57 ++++++++++++++++++++++ xonstat/views/__init__.py | 2 +- xonstat/views/map.py | 69 ++++++++++++++++++++++++++- 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 xonstat/templates/map_top_active.mako diff --git a/xonstat/__init__.py b/xonstat/__init__.py index f72e5b9..72e849d 100644 --- a/xonstat/__init__.py +++ b/xonstat/__init__.py @@ -167,6 +167,12 @@ def main(global_config, **settings): 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") diff --git a/xonstat/templates/map_top_active.mako b/xonstat/templates/map_top_active.mako new file mode 100644 index 0000000..291f7e4 --- /dev/null +++ b/xonstat/templates/map_top_active.mako @@ -0,0 +1,57 @@ +<%inherit file="base.mako"/> +<%namespace name="nav" file="nav.mako" /> + +<%block name="navigation"> + ${nav.nav('maps')} + + +<%block name="title"> + Map Active Players Index + + +% if not top_players and last is not None: +

Sorry, no more active players!

+ +% elif not top_players and last is None: +

No active players found. Yikes, get playing!

+ +% else: + ##### ACTIVE PLAYERS ##### +
+
+ + + + + + + + + + + % for tp in top_players: + + + + + + % endfor + +
#NickPlay Time
${tp.rank}${tp.nick|n}${tp.alivetime}
+

Note: these figures are from the past ${lifetime} days +

+
+ + % if len(top_players) == 20: +
+
+ +
+
+ % endif + +% endif diff --git a/xonstat/views/__init__.py b/xonstat/views/__init__.py index e947cb0..13564e0 100644 --- a/xonstat/views/__init__.py +++ b/xonstat/views/__init__.py @@ -13,7 +13,7 @@ from xonstat.views.game import game_info, rank_index from xonstat.views.game import game_info_json, rank_index_json from xonstat.views.game import game_finder, game_finder_json -from xonstat.views.map import MapIndex, MapTopScorers +from xonstat.views.map import MapIndex, MapTopScorers, MapTopPlayers from xonstat.views.map import map_info, map_info_json from xonstat.views.map import map_captimes, map_captimes_json diff --git a/xonstat/views/map.py b/xonstat/views/map.py index 702d280..9c4dc29 100644 --- a/xonstat/views/map.py +++ b/xonstat/views/map.py @@ -96,7 +96,6 @@ class MapTopScorers(MapInfoBase): 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"), @@ -154,6 +153,74 @@ class MapTopScorers(MapInfoBase): } +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']) -- 2.39.2