From be1a2ba20b470a8688930af0bd1d784a538b7152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Ke=C3=9Fler?= Date: Tue, 6 Feb 2024 15:52:03 +0100 Subject: [PATCH] add CLI argument, fix insertion error --- hanabi-league | 8 +++++--- install/database_schema.sql | 3 ++- src/endgames.py | 20 ++++++++++---------- src/render_site.py | 6 ++++-- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/hanabi-league b/hanabi-league index 8706593..00fb640 100755 --- a/hanabi-league +++ b/hanabi-league @@ -21,8 +21,8 @@ import endgames from log_setup import logger -def subcommand_analyze_endgames(): - endgames.work_thread() +def subcommand_analyze_endgames(version: int): + endgames.work_thread(version) def subcommand_init(force: bool, no_fetch_variants: bool): @@ -102,11 +102,13 @@ def get_parser() -> argparse.ArgumentParser: init_parser.add_argument('--force', '-f', help='Force initialization (Drops existing tables)', action='store_true') init_parser.add_argument('--no-fetch-variants', '-n', help='Do not fetch and initialize variants', action='store_true') + endgame_parser = subparsers.add_parser('analyze-endgames', help="Run endgame analysis on games in DB. Resource intensive!") + endgame_parser.add_argument('--version', '-v', type=int, help='Version of endgame program.') + subparsers.add_parser('generate-config', help='Generate config file at default location') subparsers.add_parser('process-ratings', help="Process ratings of all games.") subparsers.add_parser('process-stats', help="Process statistics for all players.") subparsers.add_parser('generate-site', help="Generate the website from the DB.") - subparsers.add_parser('analyze-endgames', help="Run endgame analysis on games in DB. Resource intensive!") subparsers.add_parser('run', help="Run the automatic suite: Fetch + process games and render site.") fetch_parser = subparsers.add_parser('fetch', help='Fetch new data.') diff --git a/install/database_schema.sql b/install/database_schema.sql index d2b88db..92752c3 100644 --- a/install/database_schema.sql +++ b/install/database_schema.sql @@ -399,5 +399,6 @@ DROP TABLE IF EXISTS endgames_analyzed; CREATE TABLE endgames_analyzed ( game_id INTEGER REFERENCES games (id), termination_reason SMALLINT NOT NULL, - PRIMARY KEY (game_id) + version SMALLINT NOT NULL DEFAULT 0, + PRIMARY KEY (game_id, version) ); \ No newline at end of file diff --git a/src/endgames.py b/src/endgames.py index 3c35faf..06ac3e3 100644 --- a/src/endgames.py +++ b/src/endgames.py @@ -34,9 +34,9 @@ class EndgameAction: return self.enumerator / self.denominator -def analyze_and_store_game(game_id: int) -> int: +def analyze_and_store_game(game_id: int, version: int = 0) -> int: actions, return_code = analyze_game_from_db(game_id) - store_endgame_actions(game_id, actions, return_code) + store_endgame_actions(game_id, actions, return_code, version) return return_code @@ -127,7 +127,7 @@ def set_memory_limit(): resource.setrlimit(resource.RLIMIT_DATA, (constants.ENDGAME_MEMORY_BYTES, constants.ENDGAME_MEMORY_BYTES)) -def store_endgame_actions(game_id: int, endgame_actions: List[EndgameAction], result_code) -> None: +def store_endgame_actions(game_id: int, endgame_actions: List[EndgameAction], result_code, version: int = 0) -> None: values = [] for action in endgame_actions: values.append((game_id, action.turn, action.action_type.value, action.card.suitIndex, action.card.rank, action.enumerator, action.denominator)) @@ -149,11 +149,11 @@ def store_endgame_actions(game_id: int, endgame_actions: List[EndgameAction], re # Mark this game as analyzed. cur.execute( "INSERT INTO endgames_analyzed " - "VALUES (%s, %s) " - "ON CONFLICT (game_id) " + "VALUES (%s, %s, %s) " + "ON CONFLICT (game_id, version) " "DO UPDATE " "SET termination_reason = EXCLUDED.termination_reason", - (game_id, result_code) + (game_id, result_code, version) ) conn.commit() @@ -223,7 +223,7 @@ def print_action_type(action_type: hanabi.hanab_game.ActionType) -> str: return "Unknown Action" -def work_thread(): +def work_thread(version: int = 0): """ Will continuously query database to analyze endgames. @return: @@ -235,11 +235,11 @@ def work_thread(): "SELECT games.id " "FROM games " "LEFT OUTER JOIN endgames_analyzed " - " ON endgames_analyzed.game_id = games.id " + " ON endgames_analyzed.game_id = games.id AND endgames_analyzed.version = %s " "WHERE endgames_analyzed.termination_reason IS NULL " "ORDER BY games.league_id DESC " "LIMIT 1", - (False,) + (version, ) ) res = cur.fetchone() if res is None: @@ -250,5 +250,5 @@ def work_thread(): else: (game_id, ) = res logger.info("Analyzing endgame of game {}".format(game_id)) - return_code = analyze_and_store_game(game_id) + return_code = analyze_and_store_game(game_id, version) print("Finished endgame analysis of {}: Returncode {}".format(game_id, return_code)) diff --git a/src/render_site.py b/src/render_site.py index 973e0d4..11393f1 100644 --- a/src/render_site.py +++ b/src/render_site.py @@ -716,7 +716,7 @@ def build_unique_variants(variant_rows: List[VariantRow]): def render_game_pages(env: jinja2.Environment, out_dir: Path): - endgames = get_endgame_page_data() + endgames = get_endgame_page_data(0) template = env.get_template("game.html") for game_id, data in endgames.items(): @@ -781,13 +781,15 @@ def convert_endgame_action(endgame_action: endgames.EndgameAction, game: hanabi. return EndgameActionRow(description, endgame_action.enumerator, endgame_action.denominator, marked) -def get_endgame_page_data(): +def get_endgame_page_data(version: int): cur = conn_manager.get_new_cursor() cur.execute( "SELECT games.id, termination_reason " "FROM games " "LEFT OUTER JOIN endgames_analyzed " " ON endgames_analyzed.game_id = games.id " + "WHERE endgames_analyzed.version = %s", + (version, ) ) ret = {} for (game_id, termination_reason) in cur.fetchall():