Py-Hanabi/hanabi/cli.py

167 lines
5.6 KiB
Python
Raw Normal View History

2023-05-14 19:11:51 +02:00
import argparse
from typing import Optional
import verboselogs
2023-05-14 19:11:51 +02:00
from hanabi import logger, logger_manager
2023-07-05 18:48:33 +02:00
from hanabi.live import variants
from hanabi.live import check_game
from hanabi.live import download_data
from hanabi.live import compress
2023-07-05 09:33:55 +02:00
from hanabi.database import init_database
from hanabi.database import global_db_connection_manager
2023-05-14 19:11:51 +02:00
"""
Commands supported:
2023-05-14 19:11:51 +02:00
init db + populate tables
download games of variant
download single game
analyze single game
2023-05-14 19:11:51 +02:00
"""
2023-07-05 09:33:55 +02:00
def subcommand_analyze(game_id: int, download: bool = False):
if download:
download_data.detailed_export_game(game_id)
logger.info('Analyzing game {}'.format(game_id))
turn, sol = check_game.check_game(game_id)
if turn == 0:
logger.info('Instance is unfeasible')
else:
logger.info('Game was first lost after {} turns.'.format(turn))
logger.info(
'A replay achieving perfect score from the previous turn onwards is: {}#{}'
.format(compress.link(sol), turn)
)
def subcommand_init(force: bool, populate: bool):
tables = init_database.get_existing_tables()
if len(tables) > 0 and not force:
logger.info(
'Database tables "{}" exist already, aborting. To force re-initialization, use the --force options'
.format(", ".join(tables))
)
return
if len(tables) > 0:
logger.info(
"WARNING: This will drop all existing tables from the database and re-initialize them."
)
response = input("Do you wish to continue? [y/N] ")
if response not in ["y", "Y", "yes"]:
return
init_database.init_database_tables()
logger.info("Successfully initialized database tables")
if populate:
init_database.populate_static_tables()
logger.info("Successfully populated tables with variants and suits from hanab.live")
2023-07-05 18:48:33 +02:00
def subcommand_download(
game_id: Optional[int]
, variant_id: Optional[int]
, export_all: bool = False
, all_variants: bool = False
):
if game_id is not None:
download_data.detailed_export_game(game_id)
2023-07-05 20:59:20 +02:00
logger.info("Successfully exported game {}".format(game_id))
if variant_id is not None:
2023-07-05 18:48:33 +02:00
download_data.download_games(variant_id, export_all)
logger.info("Successfully exported games for variant id {}".format(variant_id))
if all_variants:
for variant in variants.get_all_variant_ids():
download_data.download_games(variant, export_all)
logger.info("Successfully exported games for all variants")
2023-07-05 09:33:55 +02:00
def subcommand_gen_config():
global_db_connection_manager.create_config_file()
2023-05-14 19:11:51 +02:00
def add_init_subparser(subparsers):
parser = subparsers.add_parser(
'init',
help='Init database tables, retrieve variant and suit information from hanab.live'
)
2023-07-05 09:33:55 +02:00
parser.add_argument('--force', '-f', help='Force initialization (Drops existing tables)', action='store_true')
parser.add_argument(
'--no-populate-tables', '-n',
help='Do not download variant and suit information from hanab.live',
action='store_false',
dest='populate'
)
2023-05-14 19:11:51 +02:00
def add_download_subparser(subparsers):
parser = subparsers.add_parser('download', help='Download games from hanab.live')
group = parser.add_mutually_exclusive_group(required=True)
2023-07-05 18:48:33 +02:00
group.add_argument(
'--var', '--variant', '-v',
type=int,
dest='variant_id',
help='Download information on all games given variant id (but not necessarily export all of them)'
)
group.add_argument('--id', '-i', type=int, dest='game_id', help='Download single game given id')
group.add_argument(
'--all-variants', '-a',
action='store_true',
dest='all_variants',
help='Download information from games on all variants (but not necessarily export all of them)'
)
parser.add_argument(
'--export-all', '-e',
action='store_true',
dest='export_all',
help='Export all games specified in full detail (i.e. also actions and game options)'
)
2023-05-14 19:11:51 +02:00
def add_analyze_subparser(subparsers):
parser = subparsers.add_parser('analyze', help='Analyze a game and find the last winning state')
parser.add_argument('game_id', type=int)
parser.add_argument('--download', '-d', help='Download game if not in database', action='store_true')
def add_config_gen_subparser(subparsers):
parser = subparsers.add_parser('gen-config', help='Generate config file at default location')
2023-05-14 19:11:51 +02:00
def main_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog='hanabi_suite',
description='High-level interface for analysis of hanabi instances.'
)
parser.add_argument('--verbose', '-v', help='Enable verbose logging to console', action='store_true')
2023-05-14 19:11:51 +02:00
subparsers = parser.add_subparsers(dest='command', required=True, help='select subcommand')
add_init_subparser(subparsers)
add_analyze_subparser(subparsers)
add_download_subparser(subparsers)
add_config_gen_subparser(subparsers)
2023-05-14 19:11:51 +02:00
return parser
2023-07-04 22:19:13 +02:00
def hanabi_cli():
2023-05-14 19:11:51 +02:00
args = main_parser().parse_args()
subcommand_func = {
2023-07-05 09:33:55 +02:00
'analyze': subcommand_analyze,
'init': subcommand_init,
'download': subcommand_download,
'gen-config': subcommand_gen_config
}[args.command]
if args.command != 'gen-config':
global_db_connection_manager.read_config()
global_db_connection_manager.connect()
if args.verbose:
logger_manager.set_console_level(verboselogs.VERBOSE)
del args.command
del args.verbose
subcommand_func(**vars(args))