add CLI argument, fix insertion error

This commit is contained in:
Maximilian Keßler 2024-02-06 15:52:03 +01:00
parent eb833db3ce
commit be1a2ba20b
Signed by: max
GPG key ID: BCC5A619923C0BA5
4 changed files with 21 additions and 16 deletions

View file

@ -21,8 +21,8 @@ import endgames
from log_setup import logger from log_setup import logger
def subcommand_analyze_endgames(): def subcommand_analyze_endgames(version: int):
endgames.work_thread() endgames.work_thread(version)
def subcommand_init(force: bool, no_fetch_variants: bool): 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('--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') 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('generate-config', help='Generate config file at default location')
subparsers.add_parser('process-ratings', help="Process ratings of all games.") 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('process-stats', help="Process statistics for all players.")
subparsers.add_parser('generate-site', help="Generate the website from the DB.") 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.") 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.') fetch_parser = subparsers.add_parser('fetch', help='Fetch new data.')

View file

@ -399,5 +399,6 @@ DROP TABLE IF EXISTS endgames_analyzed;
CREATE TABLE endgames_analyzed ( CREATE TABLE endgames_analyzed (
game_id INTEGER REFERENCES games (id), game_id INTEGER REFERENCES games (id),
termination_reason SMALLINT NOT NULL, termination_reason SMALLINT NOT NULL,
PRIMARY KEY (game_id) version SMALLINT NOT NULL DEFAULT 0,
PRIMARY KEY (game_id, version)
); );

View file

@ -34,9 +34,9 @@ class EndgameAction:
return self.enumerator / self.denominator 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) 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 return return_code
@ -127,7 +127,7 @@ def set_memory_limit():
resource.setrlimit(resource.RLIMIT_DATA, (constants.ENDGAME_MEMORY_BYTES, constants.ENDGAME_MEMORY_BYTES)) 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 = [] values = []
for action in endgame_actions: 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)) 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. # Mark this game as analyzed.
cur.execute( cur.execute(
"INSERT INTO endgames_analyzed " "INSERT INTO endgames_analyzed "
"VALUES (%s, %s) " "VALUES (%s, %s, %s) "
"ON CONFLICT (game_id) " "ON CONFLICT (game_id, version) "
"DO UPDATE " "DO UPDATE "
"SET termination_reason = EXCLUDED.termination_reason", "SET termination_reason = EXCLUDED.termination_reason",
(game_id, result_code) (game_id, result_code, version)
) )
conn.commit() conn.commit()
@ -223,7 +223,7 @@ def print_action_type(action_type: hanabi.hanab_game.ActionType) -> str:
return "Unknown Action" return "Unknown Action"
def work_thread(): def work_thread(version: int = 0):
""" """
Will continuously query database to analyze endgames. Will continuously query database to analyze endgames.
@return: @return:
@ -235,11 +235,11 @@ def work_thread():
"SELECT games.id " "SELECT games.id "
"FROM games " "FROM games "
"LEFT OUTER JOIN endgames_analyzed " "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 " "WHERE endgames_analyzed.termination_reason IS NULL "
"ORDER BY games.league_id DESC " "ORDER BY games.league_id DESC "
"LIMIT 1", "LIMIT 1",
(False,) (version, )
) )
res = cur.fetchone() res = cur.fetchone()
if res is None: if res is None:
@ -250,5 +250,5 @@ def work_thread():
else: else:
(game_id, ) = res (game_id, ) = res
logger.info("Analyzing endgame of game {}".format(game_id)) 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)) print("Finished endgame analysis of {}: Returncode {}".format(game_id, return_code))

View file

@ -716,7 +716,7 @@ def build_unique_variants(variant_rows: List[VariantRow]):
def render_game_pages(env: jinja2.Environment, out_dir: Path): 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") template = env.get_template("game.html")
for game_id, data in endgames.items(): 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) 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 = conn_manager.get_new_cursor()
cur.execute( cur.execute(
"SELECT games.id, termination_reason " "SELECT games.id, termination_reason "
"FROM games " "FROM games "
"LEFT OUTER JOIN endgames_analyzed " "LEFT OUTER JOIN endgames_analyzed "
" ON endgames_analyzed.game_id = games.id " " ON endgames_analyzed.game_id = games.id "
"WHERE endgames_analyzed.version = %s",
(version, )
) )
ret = {} ret = {}
for (game_id, termination_reason) in cur.fetchall(): for (game_id, termination_reason) in cur.fetchall():