From c129c3d1bf3f32809257df49376a1f5be8b548c9 Mon Sep 17 00:00:00 2001 From: norohind <60548839+norohind@users.noreply.github.com> Date: Mon, 31 Jan 2022 20:04:23 +0300 Subject: [PATCH] Add get_latest_leaderboard --- model/abstract_model.py | 3 + model/postgres_model.py | 26 +++++++ model/postgres_sql_requests.py | 19 ++++- static/index.html | 135 +++++++++++++++++++++++---------- web.py | 26 ++++++- 5 files changed, 164 insertions(+), 45 deletions(-) diff --git a/model/abstract_model.py b/model/abstract_model.py index 90cf1c9..e7a692f 100644 --- a/model/abstract_model.py +++ b/model/abstract_model.py @@ -31,3 +31,6 @@ class AbstractModel(abc.ABC): @abc.abstractmethod def get_leaderboard_by_action_id(self, action_id: int) -> list[dict]: raise NotImplemented + + def get_latest_leaderboard(self, platform: str, leaderboard_type: str) -> list[dict]: + raise NotImplemented diff --git a/model/postgres_model.py b/model/postgres_model.py index 9eb2ef5..07e6bae 100644 --- a/model/postgres_model.py +++ b/model/postgres_model.py @@ -212,3 +212,29 @@ class PostgresModel(AbstractModel): cache.set(cache_key, json.dumps(result)) return result + + @errors_catcher + def get_latest_leaderboard(self, platform: str, leaderboard_type: str) -> list[dict]: + cache_key = f'latest_leaderboard_{platform}_{leaderboard_type}' + cached_result: typing.Union[str, None] = cache.get(cache_key) + + if cached_result is not None: + logger.debug(f'Cached result for {cache_key}') + return json.loads(cached_result) + + logger.debug(f'Not cached result for {cache_key}') + + with self.db.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cursor: + cursor.execute( + postgres_sql_requests.select_latest_leaderboard, + { + 'platform': platform.upper(), + 'LB_type': leaderboard_type.lower() + } + ) + result: list[dict] = cursor.fetchall() + + if not cache.disabled: + cache.set(cache_key, json.dumps(result)) + + return result diff --git a/model/postgres_sql_requests.py b/model/postgres_sql_requests.py index eb7da05..fecf869 100644 --- a/model/postgres_sql_requests.py +++ b/model/postgres_sql_requests.py @@ -98,7 +98,7 @@ limit 1000; """ select_leaderboard_by_action_id = """select - name, + name as squadron_name, tag, rank, score, @@ -110,3 +110,20 @@ from squads_stats_states where action_id = %(action_id)s order by score desc; """ + +select_latest_leaderboard = """select + name as squadron_name, + tag, + rank, + score, + to_char(timestamp, 'YYYY-MM-DD HH24:MI:SS') as timestamp, + leaderboard_type, + platform, + squadron_id +from squads_stats_states +where action_id = ( + select max(action_id) as action_id + from squads_stats_states + where leaderboard_type = %(LB_type)s and platform = %(platform)s) +order by score desc; +""" diff --git a/static/index.html b/static/index.html index f8ba22a..40bbd39 100644 --- a/static/index.html +++ b/static/index.html @@ -3,50 +3,101 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PCPS4XBOX
AXAXAX
BGSBGSBGS
COMBATCOMBATCOMBAT
CQCCQCCQC
EXPLORATIONEXPLORATIONEXPLORATION
POWERPLAYPOWERPLAYPOWERPLAY
TRADETRADETRADE
+
+

Squadrons activity

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PCPS4XBOX
AXAXAX
BGSBGSBGS
COMBATCOMBATCOMBAT
CQCCQCCQC
EXPLORATIONEXPLORATIONEXPLORATION
POWERPLAYPOWERPLAYPOWERPLAY
TRADETRADETRADE
+
+
+

Latest leaderboards

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PCPS4XBOX
AXAXAX
BGSBGSBGS
COMBATCOMBATCOMBAT
CQCCQCCQC
EXPLORATIONEXPLORATIONEXPLORATION
POWERPLAYPOWERPLAYPOWERPLAY
TRADETRADETRADE
+
In order to access to api, add /api/ prefix to any endpoint url
Author contact: a31#6403 (discord), a31@demb.design (email)
Source code diff --git a/web.py b/web.py index 0ac27dd..9e23c03 100644 --- a/web.py +++ b/web.py @@ -125,7 +125,7 @@ class ActivityDiffHtml: resp.text = render( 'table_diff_template.html', { - 'target_column_name': 'Tag', + 'target_column_name': keys_mapping['tag'], 'target_new_url': '/squads/now/by-tag/short/', 'action_id': action_id } @@ -160,6 +160,26 @@ class SumLeaderboardHistoryHtml: ) +class LatestLeaderboard: + def on_get(self, req: falcon.request.Request, resp: falcon.response.Response, leaderboard: str, platform: str)\ + -> None: + resp.content_type = falcon.MEDIA_JSON + resp.text = json.dumps(model.get_latest_leaderboard(platform, leaderboard)) + + +class LatestLeaderboardHtml: + def on_get(self, req: falcon.request.Request, resp: falcon.response.Response, leaderboard: str, platform: str)\ + -> None: + resp.content_type = falcon.MEDIA_HTML + resp.text = render( + 'table_template.html', + { + 'target_column_name': 'tag', + 'target_new_url': '/squads/now/by-tag/short/' + } + ) + + class LeaderboardByActionID: def on_get(self, req: falcon.request.Request, resp: falcon.response.Response, action_id: int) -> None: resp.content_type = falcon.MEDIA_JSON @@ -172,7 +192,7 @@ class LeaderboardByActionIDHTML: resp.text = render( 'table_template.html', { - 'target_column_name': keys_mapping['tag'], + 'target_column_name': 'tag', 'target_new_url': '/api/leaderboard-state/by-action-id/' } ) @@ -198,11 +218,13 @@ app.add_route('/api/leaderboard/{leaderboard}/platform/{platform}', Activity()) app.add_route('/api/diff/{action_id}', ActivityDiff()) app.add_route('/api/leaderboard-history/leaderboard/{leaderboard}/platform/{platform}', SumLeaderboardHistory()) app.add_route('/api/leaderboard-state/by-action-id/{action_id}', LeaderboardByActionID()) +app.add_route('/api/leaderboard-state/now/{leaderboard}/platform/{platform}', LatestLeaderboard()) app.add_route('/leaderboard/{leaderboard}/platform/{platform}', ActivityHtml()) app.add_route('/diff/{action_id}', ActivityDiffHtml()) app.add_route('/leaderboard-history/leaderboard/{leaderboard}/platform/{platform}', SumLeaderboardHistoryHtml()) app.add_route('/leaderboard-state/by-action-id/{action_id}', LeaderboardByActionIDHTML()) +app.add_route('/leaderboard-state/now/{leaderboard}/platform/{platform}', LatestLeaderboardHtml()) app.add_route('/api/cache/{action}', Cache())