forked from Hanabi/hanabi-league
Add table of played games to user pages
This commit is contained in:
parent
d238c3b67e
commit
7446bd2916
4 changed files with 58 additions and 12 deletions
|
@ -97,8 +97,11 @@ class GameRow:
|
|||
num_players: int
|
||||
users: List[str]
|
||||
user_ids: List[int]
|
||||
user_rating_changes: List[float]
|
||||
user_ratings_after: List[float]
|
||||
variant_id: int
|
||||
variant_name: str
|
||||
rating_type: int
|
||||
seed: str
|
||||
score: int
|
||||
num_turns: int
|
||||
|
@ -132,7 +135,7 @@ class PlayerRow:
|
|||
stats: PlayerStats
|
||||
|
||||
|
||||
def get_games():
|
||||
def get_games() -> List[GameRow]:
|
||||
cur = conn_manager.get_connection().cursor(cursor_factory=psycopg2.extras.DictCursor)
|
||||
cur.execute(
|
||||
"SELECT"
|
||||
|
@ -140,8 +143,11 @@ def get_games():
|
|||
" game_data.num_players,"
|
||||
" users,"
|
||||
" user_ids,"
|
||||
" user_rating_changes,"
|
||||
" user_ratings_after,"
|
||||
" game_data.variant_id,"
|
||||
" variants.name AS variant_name,"
|
||||
" rating_type,"
|
||||
" seed,"
|
||||
" score,"
|
||||
" num_turns,"
|
||||
|
@ -158,11 +164,13 @@ def get_games():
|
|||
" num_players,"
|
||||
" array_agg(users.player_name ORDER BY users.player_name) AS users,"
|
||||
" array_agg(users.id ORDER BY users.player_name) AS user_ids,"
|
||||
" array_agg(user_ratings.change ORDER BY users.player_name) AS user_rating_changes,"
|
||||
" array_agg(user_ratings.value_after ORDER BY users.player_name) AS user_ratings_after,"
|
||||
" variant_id,"
|
||||
" seed,"
|
||||
" score,"
|
||||
" num_turns,"
|
||||
" league_id,"
|
||||
" games.league_id,"
|
||||
" num_bottom_deck_risks,"
|
||||
" num_crits_lost "
|
||||
" FROM games "
|
||||
|
@ -172,9 +180,11 @@ def get_games():
|
|||
" ON games.id = game_participants.game_id "
|
||||
" LEFT OUTER JOIN users"
|
||||
" ON game_participants.user_id = users.id "
|
||||
" LEFT OUTER JOIN user_ratings"
|
||||
" ON user_ratings.league_id = games.league_id AND user_ratings.user_id = game_participants.user_id"
|
||||
" GROUP BY ("
|
||||
" games.id, num_players, variant_id, seed, score, num_turns,"
|
||||
" league_id, num_bottom_deck_risks, num_crits_lost"
|
||||
" games.league_id, num_bottom_deck_risks, num_crits_lost"
|
||||
" )"
|
||||
" ) AS game_data "
|
||||
"LEFT OUTER JOIN game_outcomes "
|
||||
|
@ -185,7 +195,7 @@ def get_games():
|
|||
" ON variant_ratings.league_id = game_data.league_id AND variant_ratings.primary_change = true "
|
||||
"GROUP BY ("
|
||||
" game_data.game_id, game_data.num_players, users, user_ids, game_data.variant_id, variants.name, seed, score, num_turns,"
|
||||
" game_data.league_id, num_bottom_deck_risks, num_crits_lost, change, value_after"
|
||||
" game_data.league_id, num_bottom_deck_risks, num_crits_lost, change, value_after, rating_type, user_rating_changes, user_ratings_after"
|
||||
" ) "
|
||||
"ORDER BY league_id DESC",
|
||||
(True,)
|
||||
|
@ -210,6 +220,19 @@ def group_games_by_var_id(games: List[GameRow]):
|
|||
return ret
|
||||
|
||||
|
||||
def group_games_by_player(games: List[GameRow]):
|
||||
ret = {}
|
||||
for game in games:
|
||||
for i, user in enumerate(game.users):
|
||||
if user not in ret.keys():
|
||||
ret[user] = []
|
||||
row = dataclasses.asdict(game)
|
||||
row["user_rating_change"] = round(game.user_rating_changes[i], 1)
|
||||
row["user_rating_after"] = round(game.user_ratings_after[i], 1)
|
||||
ret[user].append(row)
|
||||
return ret
|
||||
|
||||
|
||||
def get_rating_lists() -> Dict[int, List[PlayerEntry]]:
|
||||
cur = conn_manager.get_connection().cursor()
|
||||
rating_types = [utils.get_rating_type(x) for x in [False, True]]
|
||||
|
@ -502,6 +525,9 @@ def render_variant_pages(env: jinja2.Environment, out_dir: Path):
|
|||
def render_player_pages(env: jinja2.Environment, out_dir: Path):
|
||||
player_stats = get_player_stats()
|
||||
|
||||
games = get_games()
|
||||
games_grouped_by_player = group_games_by_player(games)
|
||||
|
||||
player_template = env.get_template('player.html')
|
||||
for player_name, player_stat in player_stats.items():
|
||||
rendered_player = player_template.render(
|
||||
|
@ -509,7 +535,8 @@ def render_player_pages(env: jinja2.Environment, out_dir: Path):
|
|||
total_players=get_num_players(),
|
||||
latest_run=datetime.datetime.now().isoformat(),
|
||||
player_name=player_name,
|
||||
player_stat=player_stat
|
||||
player_stat=player_stat,
|
||||
player_games=games_grouped_by_player.get(player_name, [])
|
||||
)
|
||||
|
||||
output_file = out_dir / 'player' / urllib.parse.quote_plus(player_name) / 'index.html'
|
||||
|
|
|
@ -35,9 +35,25 @@
|
|||
{% endif %}
|
||||
</h4>
|
||||
{{ stats_list(player_row.stats, True, True) }}
|
||||
<div id="table-{{rating_type}}"></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript part for the tables -->
|
||||
<script>
|
||||
let tabledata = [
|
||||
{% for game in player_games %}
|
||||
{{- game -}},
|
||||
{% endfor %}
|
||||
];
|
||||
|
||||
{% for rating_type in player_stat.keys() %}
|
||||
{{ games_table_js("tabledata", rating_type, True, False, True) }}
|
||||
// Filter table on corresponding rating type
|
||||
table_{{rating_type}}.setFilter("rating_type", "=", {{rating_type}});
|
||||
{% endfor %}
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -65,13 +65,12 @@
|
|||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro games_table_js(data, div_id, show_player_num, show_var_rating) %}
|
||||
{% macro games_table_js(data, div_id, show_player_num, show_var_rating, show_user_rating) %}
|
||||
var table_{{div_id}} = new Tabulator("#table-{{div_id}}", {
|
||||
height: 400,
|
||||
maxHeight: 400,
|
||||
data: {{data}},
|
||||
layout: "fitDataStretch",
|
||||
columns: [
|
||||
{title: "id", field: "league_id"},
|
||||
{title: "Game", field: "game_id", formatter: "link", formatterParams:{
|
||||
urlPrefix: "https://hanab.live/replay/",
|
||||
target:"_blank"
|
||||
|
@ -80,8 +79,12 @@ var table_{{div_id}} = new Tabulator("#table-{{div_id}}", {
|
|||
{title: "# Players", field: "num_players"},
|
||||
{% endif %}
|
||||
{% if show_var_rating %}
|
||||
{title: "Rating Change", field: "variant_rating_change"},
|
||||
{title: "Rating After", field: "variant_rating_after"},
|
||||
{title: "+/-", field: "variant_rating_change"},
|
||||
{title: "ELO After", field: "variant_rating_after"},
|
||||
{% endif %}
|
||||
{% if show_user_rating %}
|
||||
{title: "+/-", field: "user_rating_change"},
|
||||
{title: "ELO After", field: "user_rating_after"},
|
||||
{% endif %}
|
||||
{title: "Players", field: "users", formatter:function(cell, formatterParams, onRendered) {
|
||||
let links = cell.getValue().map(player => `<a href="/player/${encodeURIComponent(player)}">${player}</a>`);
|
||||
|
|
|
@ -76,10 +76,10 @@
|
|||
];
|
||||
|
||||
// Main table
|
||||
{{ games_table_js("tabledata", "overview", True, False) }}
|
||||
{{ games_table_js("tabledata", "overview", True, False, False) }}
|
||||
|
||||
{% for num_players in variant_stats_by_player.keys() %}
|
||||
{{ games_table_js("tabledata", num_players, False, True) }}
|
||||
{{ games_table_js("tabledata", num_players, False, True, False) }}
|
||||
// Filter table on corresponding page to only display games with corresponding player number
|
||||
table_{{num_players}}.setFilter("num_players", "=", {{num_players}});
|
||||
{% endfor %}
|
||||
|
|
Loading…
Reference in a new issue