Add player pages (draft)

This commit is contained in:
Maximilian Keßler 2023-12-10 19:47:07 +01:00
parent cd3c4190b2
commit b1d0ae5dfd
Signed by: max
GPG key ID: BCC5A619923C0BA5
3 changed files with 84 additions and 38 deletions

View file

@ -2,6 +2,7 @@ import dataclasses
import shutil import shutil
from pathlib import Path from pathlib import Path
from typing import Dict, List from typing import Dict, List
import urllib.parse
import jinja2 import jinja2
import datetime import datetime
@ -23,6 +24,10 @@ class PlayerEntry:
user_accounts: str user_accounts: str
score: int score: int
@property
def player_name_encoded(self):
return urllib.parse.quote_plus(self.player_name)
@dataclass @dataclass
class PlayerStreakEntry(PlayerEntry): class PlayerStreakEntry(PlayerEntry):
@ -37,8 +42,7 @@ class Leader:
@dataclass @dataclass
class VariantStats: class GeneralStats:
rating: int = 0
games_played: int = 0 games_played: int = 0
games_won: int = 0 games_won: int = 0
total_bdr: int = 0 total_bdr: int = 0
@ -75,6 +79,11 @@ class VariantStats:
return self return self
@dataclass
class VariantStats(GeneralStats):
rating: int = 0
@dataclass @dataclass
class VariantRow: class VariantRow:
variant_id: int variant_id: int
@ -110,38 +119,17 @@ class Player:
@dataclass @dataclass
class PlayerStats: class PlayerStats(GeneralStats):
current_streak: int current_streak: int = 0
max_streak: int max_streak: int = 0
games_played: int
games_won: int
total_bdr: int
total_crits_lost: int
total_moves: int
@property
def winrate(self):
if self.games_played == 0:
return 0
return round(100 * float(self.games_won) / self.games_played, 1)
@property @dataclass
def average_bdr(self): class PlayerRow:
if self.games_played == 0: user_id: int
return 0 name: str
return round(float(self.total_bdr) / self.games_played, 3) user_accounts: List[str]
stats: PlayerStats
@property
def average_crits_lost(self):
if self.games_played == 0:
return 0
return round(float(self.total_crits_lost) / self.games_played, 3)
@property
def average_moves(self):
if self.games_played == 0:
return 0
return round(float(self.total_moves) / self.games_played, 3)
def get_games(): def get_games():
@ -360,11 +348,39 @@ def get_variant_rows() -> List[VariantRow]:
"" ""
) )
return [ return [
VariantRow(variant_id, variant_name, num_players, VariantStats(round(rating), games_played, games_won, total_bdr, total_crits_lost, total_turns)) VariantRow(variant_id, variant_name, num_players, VariantStats(games_played, games_won, total_bdr, total_crits_lost, total_turns, round(rating)))
for (variant_id, variant_name, num_players, rating, games_played, games_won, total_bdr, total_crits_lost, total_turns) in cur.fetchall() for (variant_id, variant_name, num_players, rating, games_played, games_won, total_bdr, total_crits_lost, total_turns) in cur.fetchall()
] ]
def get_player_stats() -> Dict[int, Dict[int, PlayerStats]]:
cur = conn_manager.get_new_cursor()
cur.execute(
"SELECT "
" user_id,"
" player_name,"
" variant_type,"
" games_played,"
" games_won,"
" total_bdr,"
" total_crits_lots,"
" total_game_moves,"
" current_streak,"
" maximum_streak "
"FROM user_statistics "
"INNER JOIN users "
" ON user_statistics.user_id = users.id "
"ORDER BY user_id, variant_type"
)
ret = {}
for (user_id, player_name, variant_type, games_played, games_won, total_bdr, total_crits_lost, total_game_moves, current_streak, maximum_streak) in cur.fetchall():
if player_name not in ret.keys():
ret[player_name] = {}
ret[player_name][variant_type] = PlayerStats(games_played, games_won, total_bdr, total_crits_lost, total_game_moves, current_streak, maximum_streak)
return ret
def get_total_games(): def get_total_games():
cur = conn_manager.get_new_cursor() cur = conn_manager.get_new_cursor()
cur.execute("SELECT COUNT(league_id) FROM games") cur.execute("SELECT COUNT(league_id) FROM games")
@ -444,7 +460,7 @@ def render_leaderboard():
total_players=get_num_players(), total_players=get_num_players(),
latest_run=datetime.datetime.now().isoformat(), latest_run=datetime.datetime.now().isoformat(),
variant_stats_by_player=by_player_stats, variant_stats_by_player=by_player_stats,
variant_stats=variant_stats.get(variant_id, VariantStats), variant_stats=variant_stats.get(variant_id, VariantStats()),
variant_name=variant_names[variant_id], variant_name=variant_names[variant_id],
variant_games=grouped_games_var.get(variant_id, []) variant_games=grouped_games_var.get(variant_id, [])
) )
@ -455,6 +471,24 @@ def render_leaderboard():
with open(output_file, 'w') as f: with open(output_file, 'w') as f:
f.write(rendered_var) f.write(rendered_var)
player_stats = get_player_stats()
player_template = env.get_template('player.html')
for player_name, player_stat in player_stats.items():
rendered_player = player_template.render(
total_games_played=get_total_games(),
total_players=get_num_players(),
latest_run=datetime.datetime.now().isoformat(),
player_name=player_name,
player_stat=player_stat
)
output_file = out_dir / 'player' / str(player_name) / 'index.html'
output_file.parent.mkdir(exist_ok=True, parents=True)
with open(output_file, 'w') as f:
f.write(rendered_player)
# Copy CSS to output directory # Copy CSS to output directory
shutil.copytree('css', 'build/css', dirs_exist_ok=True) shutil.copytree('css', 'build/css', dirs_exist_ok=True)
shutil.copytree('deps/tabulator/dist/css', 'build/css', dirs_exist_ok=True) shutil.copytree('deps/tabulator/dist/css', 'build/css', dirs_exist_ok=True)

View file

@ -1,4 +1,4 @@
{% macro stats_list(stats, show_rating) %} {% macro stats_list(stats, show_rating, show_streaks) %}
<!-- Table for statistics of a variant --> <!-- Table for statistics of a variant -->
<div class="history-bullets"> <div class="history-bullets">
<ul class="stat-list"> <ul class="stat-list">
@ -10,6 +10,12 @@
- -
{% endif %} {% endif %}
</li> </li>
{% if show_streaks %}
<li>
<span class="stat-description">Maximum Streak:</span>
{{stats.max_streak}}
</li>
{% endif %}
<li> <li>
<span class="stat-description">Total Perfect Scores:</span> <span class="stat-description">Total Perfect Scores:</span>
{{stats.games_won}} {{stats.games_won}}
@ -32,6 +38,12 @@
<span class="stat-description">Total Games Played:</span> <span class="stat-description">Total Games Played:</span>
{{stats.games_played}} {{stats.games_played}}
</li> </li>
{% if show_streaks %}
<li>
<span class="stat-description">Current Streak:</span>
{{stats.current_streak}}
</li>
{% endif %}
<li> <li>
<span class="stat-description">Winrate:</span> <span class="stat-description">Winrate:</span>
{{stats.winrate}}% {{stats.winrate}}%
@ -72,7 +84,7 @@ var table_{{div_id}} = new Tabulator("#table-{{div_id}}", {
{title: "Rating After", field: "variant_rating_after"}, {title: "Rating After", field: "variant_rating_after"},
{% endif %} {% endif %}
{title: "Players", field: "users", formatter:function(cell, formatterParams, onRendered) { {title: "Players", field: "users", formatter:function(cell, formatterParams, onRendered) {
let links = cell.getValue().map(player => `<a href="/player/${player}">${player}</a>`); let links = cell.getValue().map(player => `<a href="/player/${encodeURIComponent(player)}">${player}</a>`);
return links.join(", "); return links.join(", ");
}}, }},
{title: "Seed", field: "seed", formatter: "link", formatterParams: { {title: "Seed", field: "seed", formatter: "link", formatterParams: {

View file

@ -35,7 +35,7 @@
<h3> <h3>
League Statistics for {{variant_name}} League Statistics for {{variant_name}}
</h3> </h3>
{{ stats_list(variant_stats, False) }} {{ stats_list(variant_stats, False, False) }}
<h4> <h4>
List of Played Games List of Played Games
</h4> </h4>
@ -53,7 +53,7 @@
<h3> <h3>
League Statistics for {{variant_name}} - {{num_players}} Players League Statistics for {{variant_name}} - {{num_players}} Players
</h3> </h3>
{{ stats_list(num_player_stats, True) }} {{ stats_list(num_player_stats, True, False) }}
<h4> <h4>
List of Played Games List of Played Games
</h4> </h4>