From 22f514deac8d843df3e3a8989b3ff4f9d7236259 Mon Sep 17 00:00:00 2001 From: Ant Zucaro Date: Mon, 17 Oct 2016 21:47:45 -0400 Subject: [PATCH] More server refactoring...still not sure if this is the right way to go. --- xonstat/__init__.py | 29 +++++++++- xonstat/views/__init__.py | 3 +- xonstat/views/server.py | 118 +++++++++++++++++++++++++++++--------- 3 files changed, 122 insertions(+), 28 deletions(-) diff --git a/xonstat/__init__.py b/xonstat/__init__.py index b925989..86024a0 100644 --- a/xonstat/__init__.py +++ b/xonstat/__init__.py @@ -150,6 +150,33 @@ def main(global_config, **settings): accept="text/json" ) + config.add_route("server_top_maps", "/server/{id:\d+}/topmaps") + config.add_view( + view=ServerTopMaps, + route_name="server_top_maps", + attr="json", + renderer="json", + accept="text/json" + ) + + config.add_route("server_top_players", "/server/{id:\d+}/topplayers") + config.add_view( + view=ServerTopPlayers, + route_name="server_top_players", + attr="json", + renderer="json", + accept="text/json" + ) + + config.add_route("server_top_scorers", "/server/{id:\d+}/topscorers") + config.add_view( + view=ServerTopScorers, + route_name="server_top_scorers", + attr="json", + renderer="json", + accept="text/json" + ) + config.add_route("server_info", "/server/{id:\d+}") config.add_view( view=ServerInfo, @@ -162,7 +189,7 @@ def main(global_config, **settings): view=ServerInfo, route_name="server_info", attr="json", - renderer="server_info.mako", + renderer="json", accept="text/json" ) diff --git a/xonstat/views/__init__.py b/xonstat/views/__init__.py index 8720cb1..5b34b87 100644 --- a/xonstat/views/__init__.py +++ b/xonstat/views/__init__.py @@ -17,7 +17,8 @@ from xonstat.views.map import map_info, map_index from xonstat.views.map import map_info_json, map_index_json from xonstat.views.map import map_captimes, map_captimes_json -from xonstat.views.server import ServerIndex, ServerInfo +from xonstat.views.server import ServerIndex, ServerTopMaps, ServerTopScorers, ServerTopPlayers +from xonstat.views.server import ServerInfo from xonstat.views.search import search_q, search from xonstat.views.search import search_json diff --git a/xonstat/views/server.py b/xonstat/views/server.py index b914d5d..83d642e 100644 --- a/xonstat/views/server.py +++ b/xonstat/views/server.py @@ -24,10 +24,10 @@ class ServerIndex(object): """Common parameter parsing.""" self.request = request self.page = request.params.get("page", 1) - self.servers = self._data() + self.servers = self.raw() - def _data(self): - """Returns the data shared by all renderers.""" + def raw(self): + """Returns the raw data shared by all renderers.""" try: server_q = DBSession.query(Server).order_by(Server.server_id.desc()) servers = Page(server_q, self.page, items_per_page=25, url=page_url) @@ -50,8 +50,8 @@ class ServerIndex(object): } -class ServerInfo(object): - """Returns detailed information about a particular server.""" +class ServerInfoBase(object): + """Baseline parameter parsing for Server URLs with a server_id in them.""" def __init__(self, request): """Common parameter parsing.""" @@ -63,10 +63,18 @@ class ServerInfo(object): self.lifetime = int(raw_lifetime) self.now = datetime.utcnow() - self.server_info = self._data() - def _top_maps(self): - """Top maps on this server by total times played.""" + +class ServerTopMaps(ServerInfoBase): + """Returns the top maps played on a given server.""" + + def __init__(self, request): + """Common parameter parsing.""" + super(ServerTopMaps, self).__init__(request) + self.top_maps = self.raw() + + def raw(self): + """Returns the raw data shared by all renderers.""" try: top_maps = DBSession.query(Game.map_id, Map.name, func.count())\ .filter(Map.map_id==Game.map_id)\ @@ -75,13 +83,34 @@ class ServerInfo(object): .group_by(Game.map_id)\ .group_by(Map.name) \ .order_by(expr.desc(func.count()))\ - .limit(LEADERBOARD_COUNT) + .limit(LEADERBOARD_COUNT)\ + .all() except: top_maps = None return top_maps - def _top_scorers(self): + def json(self): + """For rendering this data using JSON.""" + top_maps = [{ + "map_id": tm.map_id, + "map_name": tm.name, + "times_played": tm[2], + } for tm in self.top_maps] + + return top_maps + + +class ServerTopScorers(ServerInfoBase): + """Returns the top scorers on a given server.""" + + def __init__(self, request): + """Common parameter parsing.""" + + super(ServerTopScorers, self).__init__(request) + self.top_scorers = self.raw() + + def raw(self): """Top scorers on this server by total score.""" try: top_scorers = DBSession.query(Player.player_id, Player.nick, @@ -97,16 +126,32 @@ class ServerInfo(object): .group_by(Player.player_id)\ .limit(LEADERBOARD_COUNT) - # We can't call a Python function directly in our query, so we have to convert - # it out-of-band. - top_scorers = [(player_id, html_colors(nick), score) - for (player_id, nick, score) in top_scorers] except: top_scorers = None return top_scorers - def _top_players(self): + def json(self): + """For rendering this data using JSON.""" + top_scorers = [{ + "player_id": ts.player_id, + "nick": ts.nick, + "score": ts[2], + } for ts in self.top_scorers] + + return top_scorers + + +class ServerTopPlayers(ServerInfoBase): + """Returns the top players by playing time on a given server.""" + + def __init__(self, request): + """Common parameter parsing.""" + + super(ServerTopPlayers, self).__init__(request) + self.top_players = self.raw() + + def raw(self): """Top players on this server by total playing time.""" try: top_players = DBSession.query(Player.player_id, Player.nick, @@ -121,24 +166,45 @@ class ServerInfo(object): .group_by(Player.player_id)\ .limit(LEADERBOARD_COUNT) - # We can't call a Python function directly in our query, so we have to convert - # it out-of-band. - top_players = [(player_id, html_colors(nick), score) \ - for (player_id, nick, score) in top_players] - except: top_players = None return top_players - def _data(self): - """Returns the data shared by all renderers.""" + def json(self): + """For rendering this data using JSON.""" + top_players = [{ + "player_id": ts.player_id, + "nick": ts.nick, + "time": ts[2].total_seconds(), + } for ts in self.top_players] + + return top_players + + +class ServerInfo(ServerInfoBase): + """Returns detailed information about a particular server.""" + + def __init__(self, request): + """Common parameter parsing.""" + + super(ServerInfo, self).__init__(request) + self.server_info = self.raw() + + def raw(self): + """Returns the raw data shared by all renderers.""" try: server = DBSession.query(Server).filter_by(server_id=self.server_id).one() - top_maps = self._top_maps() - top_scorers = self._top_scorers() - top_players = self._top_players() + top_maps = ServerTopMaps(self.request).top_maps + + top_scorers_raw = ServerTopScorers(self.request).top_scorers + top_scorers = [(player_id, html_colors(nick), score) + for (player_id, nick, score) in top_scorers_raw] + + top_players_raw = ServerTopPlayers(self.request).top_players + top_players = [(player_id, html_colors(nick), score) + for (player_id, nick, score) in top_players_raw] rgs = recent_games_q(server_id=self.server_id).limit(RECENT_GAMES_COUNT).all() recent_games = [RecentGame(row) for row in rgs] @@ -159,4 +225,4 @@ class ServerInfo(object): def json(self): """For rendering this data using JSON.""" - return {"status":"Not implemented"} + return {"status": "Not implemented"} -- 2.39.2