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
from pathlib import Path
from typing import Dict, List
import urllib.parse
import jinja2
import datetime
@ -23,6 +24,10 @@ class PlayerEntry:
user_accounts: str
score: int
@property
def player_name_encoded(self):
return urllib.parse.quote_plus(self.player_name)
@dataclass
class PlayerStreakEntry(PlayerEntry):
@ -37,8 +42,7 @@ class Leader:
@dataclass
class VariantStats:
rating: int = 0
class GeneralStats:
games_played: int = 0
games_won: int = 0
total_bdr: int = 0
@ -75,6 +79,11 @@ class VariantStats:
return self
@dataclass
class VariantStats(GeneralStats):
rating: int = 0
@dataclass
class VariantRow:
variant_id: int
@ -110,38 +119,17 @@ class Player:
@dataclass
class PlayerStats:
current_streak: int
max_streak: int
games_played: int
games_won: int
total_bdr: int
total_crits_lost: int
total_moves: int
class PlayerStats(GeneralStats):
current_streak: int = 0
max_streak: int = 0
@property
def winrate(self):
if self.games_played == 0:
return 0
return round(100 * float(self.games_won) / self.games_played, 1)
@property
def average_bdr(self):
if self.games_played == 0:
return 0
return round(float(self.total_bdr) / self.games_played, 3)
@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)
@dataclass
class PlayerRow:
user_id: int
name: str
user_accounts: List[str]
stats: PlayerStats
def get_games():
@ -360,11 +348,39 @@ def get_variant_rows() -> List[VariantRow]:
""
)
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()
]
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():
cur = conn_manager.get_new_cursor()
cur.execute("SELECT COUNT(league_id) FROM games")
@ -444,7 +460,7 @@ def render_leaderboard():
total_players=get_num_players(),
latest_run=datetime.datetime.now().isoformat(),
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_games=grouped_games_var.get(variant_id, [])
)
@ -455,6 +471,24 @@ def render_leaderboard():
with open(output_file, 'w') as f:
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
shutil.copytree('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 -->
<div class="history-bullets">
<ul class="stat-list">
@ -10,6 +10,12 @@
-
{% endif %}
</li>
{% if show_streaks %}
<li>
<span class="stat-description">Maximum Streak:</span>
{{stats.max_streak}}
</li>
{% endif %}
<li>
<span class="stat-description">Total Perfect Scores:</span>
{{stats.games_won}}
@ -32,6 +38,12 @@
<span class="stat-description">Total Games Played:</span>
{{stats.games_played}}
</li>
{% if show_streaks %}
<li>
<span class="stat-description">Current Streak:</span>
{{stats.current_streak}}
</li>
{% endif %}
<li>
<span class="stat-description">Winrate:</span>
{{stats.winrate}}%
@ -72,7 +84,7 @@ var table_{{div_id}} = new Tabulator("#table-{{div_id}}", {
{title: "Rating After", field: "variant_rating_after"},
{% endif %}
{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(", ");
}},
{title: "Seed", field: "seed", formatter: "link", formatterParams: {

View File

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