Store actions and deck to database
This commit is contained in:
parent
07aba5fefb
commit
7fdee4bae0
3 changed files with 60 additions and 8 deletions
|
@ -9,6 +9,7 @@ import hanabi.live.hanab_live
|
||||||
import hanabi.hanab_game
|
import hanabi.hanab_game
|
||||||
|
|
||||||
import constants
|
import constants
|
||||||
|
import games_db_interface
|
||||||
import database
|
import database
|
||||||
import utils
|
import utils
|
||||||
from database import conn_manager
|
from database import conn_manager
|
||||||
|
@ -181,7 +182,12 @@ def store_new_games(games: Dict[int, GameInfo]):
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
def detailed_fetch_game(game_id: int):
|
def detailed_fetch_game(game_id: int) -> bool:
|
||||||
|
"""
|
||||||
|
Fetches full game details from the server and stores it in local DB if this game is a league game.
|
||||||
|
@param game_id: Game ID from hanab.live
|
||||||
|
@return: Whether the processed game was accepted as a league game, i.e. inserted into the DB
|
||||||
|
"""
|
||||||
url = "https://hanab.live/export/{}".format(game_id)
|
url = "https://hanab.live/export/{}".format(game_id)
|
||||||
response = session.get(url)
|
response = session.get(url)
|
||||||
if not response.status_code == 200:
|
if not response.status_code == 200:
|
||||||
|
@ -191,8 +197,6 @@ def detailed_fetch_game(game_id: int):
|
||||||
game_json = json.loads(response.text)
|
game_json = json.loads(response.text)
|
||||||
|
|
||||||
instance, actions = hanabi.live.hanab_live.parse_json_game(game_json, False)
|
instance, actions = hanabi.live.hanab_live.parse_json_game(game_json, False)
|
||||||
print(instance, actions, instance.deck)
|
|
||||||
print(game_json)
|
|
||||||
|
|
||||||
game_id = game_json["id"]
|
game_id = game_json["id"]
|
||||||
players = game_json["players"]
|
players = game_json["players"]
|
||||||
|
@ -202,15 +206,15 @@ def detailed_fetch_game(game_id: int):
|
||||||
var_name = game_options.get("variant", "No Variant")
|
var_name = game_options.get("variant", "No Variant")
|
||||||
|
|
||||||
if not utils.are_game_options_allowed(game_id, game_options):
|
if not utils.are_game_options_allowed(game_id, game_options):
|
||||||
return
|
return False
|
||||||
|
|
||||||
if not utils.is_player_count_allowed(game_id, num_players):
|
if not utils.is_player_count_allowed(game_id, num_players):
|
||||||
return
|
return False
|
||||||
|
|
||||||
var_id = database.get_variant_id(var_name)
|
var_id = database.get_variant_id(var_name)
|
||||||
if var_id is None:
|
if var_id is None:
|
||||||
logger.debug("Rejected game {} due to invalid variant id {}".format(game_id, var_id))
|
logger.debug("Rejected game {} due to invalid variant id {}".format(game_id, var_id))
|
||||||
return
|
return False
|
||||||
|
|
||||||
# All game options are ok, now check if the number of players is okay.
|
# All game options are ok, now check if the number of players is okay.
|
||||||
normalized_usernames = [utils.normalize_username(username) for username in players]
|
normalized_usernames = [utils.normalize_username(username) for username in players]
|
||||||
|
@ -218,11 +222,12 @@ def detailed_fetch_game(game_id: int):
|
||||||
# The return value here is a str if there was an unregistered participant
|
# The return value here is a str if there was an unregistered participant
|
||||||
if type(user_ids) is str:
|
if type(user_ids) is str:
|
||||||
logger.debug("Rejected game {} due to unregistered participant {}".format(game_id, user_ids))
|
logger.debug("Rejected game {} due to unregistered participant {}".format(game_id, user_ids))
|
||||||
return
|
return False
|
||||||
|
|
||||||
# Now, we can start to actually process the game details
|
# Now, we can start to actually process the game details
|
||||||
instance, actions = hanabi.live.hanab_live.parse_json_game(game_json, False)
|
instance, actions = hanabi.live.hanab_live.parse_json_game(game_json, False)
|
||||||
game = hanabi.hanab_game.GameState(instance)
|
game = hanabi.hanab_game.GameState(instance)
|
||||||
|
# In order to figure out the score, we will need to play the game once
|
||||||
for action in actions:
|
for action in actions:
|
||||||
game.make_action(action)
|
game.make_action(action)
|
||||||
|
|
||||||
|
@ -256,3 +261,8 @@ def detailed_fetch_game(game_id: int):
|
||||||
)
|
)
|
||||||
# DB is now in a consistent state again: We made sure the game and its participants are added.
|
# DB is now in a consistent state again: We made sure the game and its participants are added.
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
# It remains to store the seed and action data for this game
|
||||||
|
games_db_interface.store_deck_for_seed(seed, instance.deck)
|
||||||
|
games_db_interface.store_actions(game_id, actions)
|
||||||
|
return True
|
||||||
|
|
42
games_db_interface.py
Normal file
42
games_db_interface.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
import psycopg2.extras
|
||||||
|
from database import conn_manager
|
||||||
|
|
||||||
|
import hanabi.hanab_game
|
||||||
|
|
||||||
|
|
||||||
|
def store_actions(game_id: int, actions: List[hanabi.hanab_game.Action]):
|
||||||
|
vals = []
|
||||||
|
for turn, action in enumerate(actions):
|
||||||
|
vals.append((game_id, turn, action.type.value, action.target, action.value or 0))
|
||||||
|
|
||||||
|
conn = conn_manager.get_connection()
|
||||||
|
cur = conn.cursor()
|
||||||
|
psycopg2.extras.execute_values(
|
||||||
|
cur,
|
||||||
|
"INSERT INTO game_actions (game_id, turn, type, target, value) "
|
||||||
|
"VALUES %s "
|
||||||
|
"ON CONFLICT (game_id, turn) "
|
||||||
|
"DO NOTHING",
|
||||||
|
vals
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def store_deck_for_seed(seed: str, deck: List[hanabi.hanab_game.DeckCard]):
|
||||||
|
vals = []
|
||||||
|
for index, card in enumerate(deck):
|
||||||
|
vals.append((seed, index, card.suitIndex, card.rank))
|
||||||
|
|
||||||
|
conn = conn_manager.get_connection()
|
||||||
|
cur = conn.cursor()
|
||||||
|
psycopg2.extras.execute_values(
|
||||||
|
cur,
|
||||||
|
"INSERT INTO seeds (seed, card_index, suit_index, rank) "
|
||||||
|
"VALUES %s "
|
||||||
|
"ON CONFLICT (seed, card_index) "
|
||||||
|
"DO NOTHING",
|
||||||
|
vals
|
||||||
|
)
|
||||||
|
conn.commit()
|
|
@ -225,7 +225,7 @@ CREATE TABLE seeds (
|
||||||
card_index SMALLINT NOT NULL,
|
card_index SMALLINT NOT NULL,
|
||||||
suit_index SMALLINT NOT NULL,
|
suit_index SMALLINT NOT NULL,
|
||||||
rank SMALLINT NOT NULL,
|
rank SMALLINT NOT NULL,
|
||||||
CONSTRAINT cards_unique UNIQUE (seed, card_index)
|
PRIMARY KEY (seed, card_index)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue