forked from Hanabi/hanabi-league
include base ratings for players without games
This commit is contained in:
parent
65f174c95f
commit
e8ba8ecee3
3 changed files with 55 additions and 49 deletions
|
@ -1,7 +1,8 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict
|
from typing import Dict, List
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
import datetime
|
||||||
import psycopg2.extras
|
import psycopg2.extras
|
||||||
|
|
||||||
import constants
|
import constants
|
||||||
|
@ -12,14 +13,6 @@ from dataclasses import dataclass
|
||||||
from database import conn_manager
|
from database import conn_manager
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Leader:
|
|
||||||
title: str
|
|
||||||
player_name: str
|
|
||||||
user_accounts: str
|
|
||||||
score: int
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PlayerEntry:
|
class PlayerEntry:
|
||||||
player_name: str
|
player_name: str
|
||||||
|
@ -27,44 +20,52 @@ class PlayerEntry:
|
||||||
score: int
|
score: int
|
||||||
|
|
||||||
|
|
||||||
def get_rating_lists():
|
@dataclass
|
||||||
cur = conn_manager.get_connection().cursor(cursor_factory=psycopg2.extras.DictCursor)
|
class Leader:
|
||||||
cur.execute(
|
title: str
|
||||||
"SELECT * FROM ("
|
entry: PlayerEntry
|
||||||
" SELECT DISTINCT ON (type, user_accounts.user_id)"
|
|
||||||
" type,"
|
|
||||||
" player_name,"
|
def get_rating_lists() -> Dict[int, List[PlayerEntry]]:
|
||||||
" string_agg(user_accounts.username, %s ORDER BY user_accounts.username) AS user_accounts,"
|
cur = conn_manager.get_connection().cursor()
|
||||||
" value_after AS current_rating"
|
rating_types = [utils.get_rating_type(x) for x in [False, True]]
|
||||||
" FROM user_ratings "
|
|
||||||
" INNER JOIN users "
|
|
||||||
" ON user_ratings.user_id = users.id "
|
|
||||||
" LEFT OUTER JOIN user_accounts "
|
|
||||||
" ON users.id = user_accounts.user_id "
|
|
||||||
" GROUP BY (user_accounts.user_id, player_name, value_after, league_id, type) "
|
|
||||||
" ORDER BY type, user_accounts.user_id, league_id DESC"
|
|
||||||
" ) AS ratings "
|
|
||||||
"ORDER BY type ASC, current_rating DESC",
|
|
||||||
(", ",)
|
|
||||||
)
|
|
||||||
leaderboard = {
|
leaderboard = {
|
||||||
utils.get_rating_type(x): []
|
utils.get_rating_type(x): []
|
||||||
for x in [True, False]
|
for x in [True, False]
|
||||||
}
|
}
|
||||||
for row in cur.fetchall():
|
for rating_type in rating_types:
|
||||||
rating_type = row['type']
|
cur.execute(
|
||||||
leaderboard[rating_type].append(row)
|
"SELECT * FROM ("
|
||||||
|
" SELECT DISTINCT ON (user_accounts.user_id)"
|
||||||
|
" player_name,"
|
||||||
|
" string_agg(user_accounts.username, %s ORDER BY user_accounts.username) AS user_accounts,"
|
||||||
|
" COALESCE(value_after, rating) AS current_rating"
|
||||||
|
" FROM users "
|
||||||
|
" LEFT OUTER JOIN user_ratings "
|
||||||
|
" ON user_ratings.user_id = users.id AND user_ratings.type = %s "
|
||||||
|
" LEFT OUTER JOIN user_accounts "
|
||||||
|
" ON users.id = user_accounts.user_id "
|
||||||
|
" INNER JOIN user_base_ratings "
|
||||||
|
" ON users.id = user_base_ratings.user_id AND user_base_ratings.type = %s"
|
||||||
|
" GROUP BY (user_accounts.user_id, player_name, value_after, league_id, rating) "
|
||||||
|
" ORDER BY user_accounts.user_id, league_id DESC"
|
||||||
|
" ) AS ratings "
|
||||||
|
"ORDER BY current_rating DESC",
|
||||||
|
(", ", rating_type, rating_type)
|
||||||
|
)
|
||||||
|
for (player_name, user_accounts, current_rating) in cur.fetchall():
|
||||||
|
leaderboard[rating_type].append(PlayerEntry(player_name, user_accounts, round(current_rating)))
|
||||||
|
|
||||||
return leaderboard
|
return leaderboard
|
||||||
|
|
||||||
|
|
||||||
def get_leaders(rating_lists: Dict):
|
def get_leaders(rating_lists: Dict) -> Dict[int, Dict[str, Leader]]:
|
||||||
leaders = {}
|
leaders = {}
|
||||||
for rating_type, rating_list in rating_lists.items():
|
for rating_type, rating_list in rating_lists.items():
|
||||||
if len(rating_list) != 0:
|
if len(rating_list) != 0:
|
||||||
leader = rating_list[0]
|
leader = rating_list[0]
|
||||||
leaders[rating_type] = {
|
leaders[rating_type] = {
|
||||||
'Player Rating': Leader('Highest Rating', leader['player_name'], leader['user_accounts'], round(leader['current_rating']))
|
'Player Rating': Leader('Highest Rating', leader)
|
||||||
}
|
}
|
||||||
return leaders
|
return leaders
|
||||||
|
|
||||||
|
@ -87,11 +88,18 @@ def get_streak_leaderboards():
|
||||||
|
|
||||||
def get_total_games():
|
def get_total_games():
|
||||||
cur = conn_manager.get_new_cursor()
|
cur = conn_manager.get_new_cursor()
|
||||||
cur.execute("SELECT MAX(league_id) FROM games")
|
cur.execute("SELECT COUNT(league_id) FROM games")
|
||||||
(num_games,) = cur.fetchone()
|
(num_games,) = cur.fetchone()
|
||||||
return num_games
|
return num_games
|
||||||
|
|
||||||
|
|
||||||
|
def get_num_players():
|
||||||
|
cur = conn_manager.get_new_cursor()
|
||||||
|
cur.execute("SELECT COUNT(id) FROM users")
|
||||||
|
(num_users,) = cur.fetchone()
|
||||||
|
return num_users
|
||||||
|
|
||||||
|
|
||||||
def render_leaderboard():
|
def render_leaderboard():
|
||||||
rating_lists = get_rating_lists()
|
rating_lists = get_rating_lists()
|
||||||
leaders = get_leaders(rating_lists)
|
leaders = get_leaders(rating_lists)
|
||||||
|
@ -105,13 +113,11 @@ def render_leaderboard():
|
||||||
# rendered_html = template.render(leaders=leaders, leaderboards=leaderboards, variants=variants)
|
# rendered_html = template.render(leaders=leaders, leaderboards=leaderboards, variants=variants)
|
||||||
rendered_html = template.render(
|
rendered_html = template.render(
|
||||||
leaders=leaders,
|
leaders=leaders,
|
||||||
leaderboards=leaderboards
|
leaderboards=leaderboards,
|
||||||
# leaders=leaders,
|
total_games_played=get_total_games(),
|
||||||
# leaderboards=leaderboards,
|
total_players=get_num_players(),
|
||||||
|
latest_run=datetime.datetime.now().isoformat()
|
||||||
# variants=variants,
|
# variants=variants,
|
||||||
# total_games_played=constants['total_games_played'],
|
|
||||||
# latest_run=latest_run_utc_formatted,
|
|
||||||
# total_players=total_players
|
|
||||||
)
|
)
|
||||||
output_file = Path(constants.WEBSITE_OUTPUT_DIRECTORY) / 'index.html'
|
output_file = Path(constants.WEBSITE_OUTPUT_DIRECTORY) / 'index.html'
|
||||||
output_file.parent.mkdir(exist_ok=True, parents=True)
|
output_file.parent.mkdir(exist_ok=True, parents=True)
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
<div class="card text-center">
|
<div class="card text-center">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title mb-4">{{ data.title }}</h5>
|
<h5 class="card-title mb-4">{{ data.title }}</h5>
|
||||||
<p class="mb-0 player-name">{{ data.player_name }}</p>
|
<p class="mb-0 player-name">{{ data.entry.player_name }}</p>
|
||||||
<p class="mt-1 alt-name">{{ data.user_accounts }}</p>
|
<p class="mt-1 alt-name">{{ data.entry.user_accounts }}</p>
|
||||||
<p class="score-large">{{ data.score }}</p>
|
<p class="score-large">{{ data.entry.score }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -30,13 +30,13 @@
|
||||||
<div id="{{ category|lower|replace(' ', '-') }}" class="collapse" data-parent="#leaderboards-{{rating_type}}-data">
|
<div id="{{ category|lower|replace(' ', '-') }}" class="collapse" data-parent="#leaderboards-{{rating_type}}-data">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
{% for row in leaderboard[rating_type] %}
|
{% for entry in leaderboard[rating_type] %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="player-name">{{ row['player_name'] }}</div>
|
<div class="player-name">{{ entry.player_name }}</div>
|
||||||
<div class="alt-name">{{ row['user_accounts'] }}</div>
|
<div class="alt-name">{{ entry.user_accounts }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="score">{{ row['current_rating'] }}</td>
|
<td class="score">{{ entry.score }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a class="navbar-brand" href="#">The Hanabi Pro Hunting League<small class="text-muted"> - Test Season Zero</small></a>
|
<a class="navbar-brand" href="#">The Hanabi Pro Hunting League<small class="text-muted"> - Season One</small></a>
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
Loading…
Reference in a new issue