Update logging to RotatingFileHandler

Add auto game end
Calculate stats and decisions
Support raising instantiated exceptions
This commit is contained in:
Cal Corum 2024-11-09 23:14:54 -06:00
parent c3418c4dfd
commit bfd72ae0f5
28 changed files with 1470 additions and 788 deletions

View File

@ -6,6 +6,8 @@ import logging
import aiohttp import aiohttp
import os import os
from exceptions import DatabaseError
AUTH_TOKEN = {'Authorization': f'Bearer {os.environ.get("API_TOKEN")}'} AUTH_TOKEN = {'Authorization': f'Bearer {os.environ.get("API_TOKEN")}'}
try: try:
ENV_DATABASE = os.environ.get('DATABASE').lower() ENV_DATABASE = os.environ.get('DATABASE').lower()
@ -14,6 +16,7 @@ except Exception as e:
DB_URL = 'https://pd.manticorum.com/api' if 'prod' in ENV_DATABASE else 'https://pddev.manticorum.com/api' DB_URL = 'https://pd.manticorum.com/api' if 'prod' in ENV_DATABASE else 'https://pddev.manticorum.com/api'
master_debug = True master_debug = True
PLAYER_CACHE = {} PLAYER_CACHE = {}
logger = logging.getLogger('discord_app')
def param_char(other_params): def param_char(other_params):
@ -37,16 +40,16 @@ def get_req_url(endpoint: str, api_ver: int = 2, object_id: int = None, params:
def log_return_value(log_string: str): def log_return_value(log_string: str):
if master_debug: if master_debug:
logging.info(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}\n') logger.info(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}\n')
else: else:
logging.debug(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}\n') logger.debug(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}\n')
async def db_get(endpoint: str, api_ver: int = 2, object_id: int = None, params: list = None, none_okay: bool = True, async def db_get(endpoint: str, api_ver: int = 2, object_id: int = None, params: list = None, none_okay: bool = True,
timeout: int = 3): timeout: int = 3):
req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id, params=params) req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id, params=params)
log_string = f'db_get - get: {endpoint} id: {object_id} params: {params}' log_string = f'db_get - get: {endpoint} id: {object_id} params: {params}'
logging.info(log_string) if master_debug else logging.debug(log_string) logger.info(log_string) if master_debug else logger.debug(log_string)
async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session: async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session:
async with session.get(req_url) as r: async with session.get(req_url) as r:
@ -56,18 +59,18 @@ async def db_get(endpoint: str, api_ver: int = 2, object_id: int = None, params:
return js return js
elif none_okay: elif none_okay:
e = await r.text() e = await r.text()
logging.error(e) logger.error(e)
return None return None
else: else:
e = await r.text() e = await r.text()
logging.error(e) logger.error(e)
raise ValueError(f'DB: {e}') raise DatabaseError(e)
async def db_patch(endpoint: str, object_id: int, params: list, api_ver: int = 2, timeout: int = 3): async def db_patch(endpoint: str, object_id: int, params: list, api_ver: int = 2, timeout: int = 3):
req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id, params=params) req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id, params=params)
log_string = f'db_patch - patch: {endpoint} {params}' log_string = f'db_patch - patch: {endpoint} {params}'
logging.info(log_string) if master_debug else logging.debug(log_string) logger.info(log_string) if master_debug else logger.debug(log_string)
async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session: async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session:
async with session.patch(req_url) as r: async with session.patch(req_url) as r:
@ -77,14 +80,14 @@ async def db_patch(endpoint: str, object_id: int, params: list, api_ver: int = 2
return js return js
else: else:
e = await r.text() e = await r.text()
logging.error(e) logger.error(e)
raise ValueError(f'DB: {e}') raise DatabaseError(e)
async def db_post(endpoint: str, api_ver: int = 2, payload: dict = None, timeout: int = 3): async def db_post(endpoint: str, api_ver: int = 2, payload: dict = None, timeout: int = 3):
req_url = get_req_url(endpoint, api_ver=api_ver) req_url = get_req_url(endpoint, api_ver=api_ver)
log_string = f'db_post - post: {endpoint} payload: {payload}\ntype: {type(payload)}' log_string = f'db_post - post: {endpoint} payload: {payload}\ntype: {type(payload)}'
logging.info(log_string) if master_debug else logging.debug(log_string) logger.info(log_string) if master_debug else logger.debug(log_string)
async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session: async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session:
async with session.post(req_url, json=payload) as r: async with session.post(req_url, json=payload) as r:
@ -94,14 +97,14 @@ async def db_post(endpoint: str, api_ver: int = 2, payload: dict = None, timeout
return js return js
else: else:
e = await r.text() e = await r.text()
logging.error(e) logger.error(e)
raise ValueError(f'DB: {e}') raise DatabaseError(e)
async def db_put(endpoint: str, api_ver: int = 2, payload: dict = None, timeout: int = 3): async def db_put(endpoint: str, api_ver: int = 2, payload: dict = None, timeout: int = 3):
req_url = get_req_url(endpoint, api_ver=api_ver) req_url = get_req_url(endpoint, api_ver=api_ver)
log_string = f'post:\n{endpoint} payload: {payload}\ntype: {type(payload)}' log_string = f'post:\n{endpoint} payload: {payload}\ntype: {type(payload)}'
logging.info(log_string) if master_debug else logging.debug(log_string) logger.info(log_string) if master_debug else logger.debug(log_string)
async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session: async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session:
async with session.put(req_url, json=payload) as r: async with session.put(req_url, json=payload) as r:
@ -111,8 +114,8 @@ async def db_put(endpoint: str, api_ver: int = 2, payload: dict = None, timeout:
return js return js
else: else:
e = await r.text() e = await r.text()
logging.error(e) logger.error(e)
raise ValueError(f'DB: {e}') raise DatabaseError(e)
# retries = 0 # retries = 0
# while True: # while True:
@ -120,7 +123,7 @@ async def db_put(endpoint: str, api_ver: int = 2, payload: dict = None, timeout:
# resp = requests.put(req_url, json=payload, headers=AUTH_TOKEN, timeout=timeout) # resp = requests.put(req_url, json=payload, headers=AUTH_TOKEN, timeout=timeout)
# break # break
# except requests.Timeout as e: # except requests.Timeout as e:
# logging.error(f'Post Timeout: {req_url} / retries: {retries} / timeout: {timeout}') # logger.error(f'Post Timeout: {req_url} / retries: {retries} / timeout: {timeout}')
# if retries > 1: # if retries > 1:
# raise ConnectionError(f'DB: The internet was a bit too slow for me to grab the data I needed. Please ' # raise ConnectionError(f'DB: The internet was a bit too slow for me to grab the data I needed. Please '
# f'hang on a few extra seconds and try again.') # f'hang on a few extra seconds and try again.')
@ -131,19 +134,19 @@ async def db_put(endpoint: str, api_ver: int = 2, payload: dict = None, timeout:
# data = resp.json() # data = resp.json()
# log_string = f'{data}' # log_string = f'{data}'
# if master_debug: # if master_debug:
# logging.info(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}') # logger.info(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}')
# else: # else:
# logging.debug(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}') # logger.debug(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}')
# return data # return data
# else: # else:
# logging.warning(resp.text) # logger.warning(resp.text)
# raise ValueError(f'DB: {resp.text}') # raise ValueError(f'DB: {resp.text}')
async def db_delete(endpoint: str, object_id: int, api_ver: int = 2, timeout=3): async def db_delete(endpoint: str, object_id: int, api_ver: int = 2, timeout=3):
req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id) req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id)
log_string = f'db_delete - delete: {endpoint} {object_id}' log_string = f'db_delete - delete: {endpoint} {object_id}'
logging.info(log_string) if master_debug else logging.debug(log_string) logger.info(log_string) if master_debug else logger.debug(log_string)
async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session: async with aiohttp.ClientSession(headers=AUTH_TOKEN) as session:
async with session.delete(req_url) as r: async with session.delete(req_url) as r:
@ -153,8 +156,8 @@ async def db_delete(endpoint: str, object_id: int, api_ver: int = 2, timeout=3):
return js return js
else: else:
e = await r.text() e = await r.text()
logging.error(e) logger.error(e)
raise ValueError(f'DB: {e}') raise DatabaseError(e)
async def get_team_by_abbrev(abbrev: str): async def get_team_by_abbrev(abbrev: str):

View File

@ -13,12 +13,7 @@ from in_game import ai_manager
from in_game.gameplay_models import Play, Session, select, engine, Game, Cardset, Lineup, Team, Player from in_game.gameplay_models import Play, Session, select, engine, Game, Cardset, Lineup, Team, Player
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}' logger = logging.getLogger('discord_app')
# logging.basicConfig(
# filename=f'logs/{date}.log',
# format='%(asctime)s - %(levelname)s - %(message)s',
# level=logging.WARNING
# )
class Admins(commands.Cog): class Admins(commands.Cog):
@ -164,7 +159,7 @@ class Admins(commands.Cog):
total_teams = 0 total_teams = 0
for y in all_teams['teams']: for y in all_teams['teams']:
if not y['is_ai'] and 'gauntlet' not in y['abbrev'].lower(): if not y['is_ai'] and 'gauntlet' not in y['abbrev'].lower():
logging.warning(f'Giving {num_packs} pack(s) to team: {y["abbrev"]}') logger.warning(f'Giving {num_packs} pack(s) to team: {y["abbrev"]}')
await db_post( await db_post(
'packs', 'packs',
payload={'packs': [{ payload={'packs': [{
@ -197,7 +192,7 @@ class Admins(commands.Cog):
await interaction.edit_original_response(content=f'Hmm...I\'m not sure who **{x.upper()}** is.') await interaction.edit_original_response(content=f'Hmm...I\'m not sure who **{x.upper()}** is.')
return return
logging.info(f'give info: {response}') logger.info(f'give info: {response}')
await interaction.edit_original_response(content=f'{response if len(response) > 0 else "All done!"}') await interaction.edit_original_response(content=f'{response if len(response) > 0 else "All done!"}')
@commands.hybrid_command(name='post-guide', help='Mod: Post the ratings guide to team sheet') @commands.hybrid_command(name='post-guide', help='Mod: Post the ratings guide to team sheet')
@ -251,7 +246,7 @@ class Admins(commands.Cog):
await interaction.edit_original_response(content=f'RIP. Failed to process the vR ratings.') await interaction.edit_original_response(content=f'RIP. Failed to process the vR ratings.')
return return
logging.info(f'Data gathered:\n\n{d_player}\n\n{d_bcpc}\n\n{d_positions}\n\n{d_ratings_vl}\n\n{d_ratings_vr}') logger.info(f'Data gathered:\n\n{d_player}\n\n{d_bcpc}\n\n{d_positions}\n\n{d_ratings_vl}\n\n{d_ratings_vr}')
await interaction.edit_original_response( await interaction.edit_original_response(
content='Just spit out the debug info to the log, but processing was successful!') content='Just spit out the debug info to the log, but processing was successful!')
@ -310,7 +305,7 @@ class Admins(commands.Cog):
old_cost = player['cost'] old_cost = player['cost']
old_rarity = old_rarity old_rarity = old_rarity
new_rarity = new_rarity new_rarity = new_rarity
logging.info(f'old_rarity: {old_rarity} / new_rarity: {new_rarity}') logger.info(f'old_rarity: {old_rarity} / new_rarity: {new_rarity}')
if old_rarity == 1: if old_rarity == 1:
if new_rarity == 2: if new_rarity == 2:
@ -473,7 +468,7 @@ class Admins(commands.Cog):
# Patch player with new rarity_id, cost, and positions 1 - 6 # Patch player with new rarity_id, cost, and positions 1 - 6
if len(updates) > 0: if len(updates) > 0:
logging.info(f'Updating {row[1]} - params: {updates}') logger.info(f'Updating {row[1]} - params: {updates}')
await db_patch( await db_patch(
'players', 'players',
object_id=this_player['player_id'], object_id=this_player['player_id'],
@ -486,7 +481,7 @@ class Admins(commands.Cog):
if len(errors) > 0: if len(errors) > 0:
e_string = "\n- ".join(errors) e_string = "\n- ".join(errors)
logging.error(f'update errors:\n{e_string}') logger.error(f'update errors:\n{e_string}')
await ctx.send(f'I encountered the following errors:\n\n{e_string}') await ctx.send(f'I encountered the following errors:\n\n{e_string}')
@app_commands.command(name='reset-cache', description='Reset all cached player cards for gameplay') @app_commands.command(name='reset-cache', description='Reset all cached player cards for gameplay')

View File

@ -21,10 +21,10 @@ from api_calls import db_get, db_post, db_patch, db_delete, get_team_by_abbrev
from help_text import * from help_text import *
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}' # date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
# logging.basicConfig( # logger.basicConfig(
# filename=f'logs/{date}.log', # filename=f'logs/{date}.log',
# format='%(asctime)s - %(levelname)s - %(message)s', # format='%(asctime)s - %(levelname)s - %(message)s',
# level=logging.WARNING # level=logger.WARNING
# ) # )
@ -122,7 +122,7 @@ class Economy(commands.Cog):
# @tasks.loop(minutes=10) # @tasks.loop(minutes=10)
# async def pd_ticker(self): # async def pd_ticker(self):
# now = datetime.datetime.now() # now = datetime.datetime.now()
# logging.info(f'Datetime: {now} / weekday: {now.weekday()}') # logger.info(f'Datetime: {now} / weekday: {now.weekday()}')
# guild = self.bot.get_guild(int(os.environ.get('GUILD_ID'))) # guild = self.bot.get_guild(int(os.environ.get('GUILD_ID')))
# if not guild: # if not guild:
# return # return
@ -183,7 +183,7 @@ class Economy(commands.Cog):
# Check for notifications # Check for notifications
all_notifs = await db_get('notifs', params=[('ack', False)]) all_notifs = await db_get('notifs', params=[('ack', False)])
if not all_notifs: if not all_notifs:
logging.debug(f'No notifications') logger.debug(f'No notifications')
return return
topics = { topics = {
@ -202,7 +202,7 @@ class Economy(commands.Cog):
if line['title'] in topics: if line['title'] in topics:
topics[line['title']]['notifs'].append(line) topics[line['title']]['notifs'].append(line)
logging.info(f'topics:\n{topics}') logger.info(f'topics:\n{topics}')
for topic in topics: for topic in topics:
embed = get_team_embed(title=f'{topic}{"s" if len(topics[topic]["notifs"]) > 1 else ""}') embed = get_team_embed(title=f'{topic}{"s" if len(topics[topic]["notifs"]) > 1 else ""}')
embed.description = topics[topic]['desc'] embed.description = topics[topic]['desc']
@ -219,7 +219,7 @@ class Economy(commands.Cog):
p_list[x['field_name']]['message'] = f'{x["message"]}' p_list[x['field_name']]['message'] = f'{x["message"]}'
p_list[x['field_name']]['count'] += 1 p_list[x['field_name']]['count'] += 1
await db_patch('notifs', object_id=x['id'], params=[('ack', True)]) await db_patch('notifs', object_id=x['id'], params=[('ack', True)])
logging.debug(f'p_list: {p_list}') logger.debug(f'p_list: {p_list}')
this_embed = copy.deepcopy(embed) this_embed = copy.deepcopy(embed)
counter = 1 counter = 1
@ -535,8 +535,8 @@ class Economy(commands.Cog):
daily = await db_get('rewards', params=[ daily = await db_get('rewards', params=[
('name', 'Daily Check-in'), ('team_id', team['id']), ('created_after', midnight) ('name', 'Daily Check-in'), ('team_id', team['id']), ('created_after', midnight)
]) ])
logging.debug(f'midnight: {midnight} / now: {int_timestamp(now)}') logger.debug(f'midnight: {midnight} / now: {int_timestamp(now)}')
logging.debug(f'daily_return: {daily}') logger.debug(f'daily_return: {daily}')
if daily: if daily:
await interaction.edit_original_response( await interaction.edit_original_response(
@ -676,11 +676,11 @@ class Economy(commands.Cog):
'Mario': [], 'Mario': [],
'Team Choice': [] 'Team Choice': []
} }
logging.debug(f'Parsing packs...') logger.debug(f'Parsing packs...')
for pack in p_query['packs']: for pack in p_query['packs']:
p_group = None p_group = None
logging.debug(f'pack: {pack}') logger.debug(f'pack: {pack}')
logging.debug(f'pack cardset: {pack["pack_cardset"]}') logger.debug(f'pack cardset: {pack["pack_cardset"]}')
if pack['pack_team'] is None and pack['pack_cardset'] is None: if pack['pack_team'] is None and pack['pack_cardset'] is None:
if pack['pack_type']['name'] in p_data: if pack['pack_type']['name'] in p_data:
p_group = pack['pack_type']['name'] p_group = pack['pack_type']['name']
@ -712,7 +712,7 @@ class Economy(commands.Cog):
elif pack['pack_type']['name'] == 'Promo Choice': elif pack['pack_type']['name'] == 'Promo Choice':
p_group = f'Promo Choice-Cardset-{pack["pack_cardset"]["id"]}-{pack["pack_cardset"]["name"]}' p_group = f'Promo Choice-Cardset-{pack["pack_cardset"]["id"]}-{pack["pack_cardset"]["name"]}'
logging.info(f'p_group: {p_group}') logger.info(f'p_group: {p_group}')
if p_group is not None: if p_group is not None:
p_count += 1 p_count += 1
if p_group not in p_data: if p_group not in p_data:
@ -768,7 +768,7 @@ class Economy(commands.Cog):
) )
p_query = await db_get('players', object_id=player_id, none_okay=False) p_query = await db_get('players', object_id=player_id, none_okay=False)
logging.debug(f'this_player: {p_query}') logger.debug(f'this_player: {p_query}')
await self.buy_card(interaction, p_query, owner_team) await self.buy_card(interaction, p_query, owner_team)
@ -819,7 +819,7 @@ class Economy(commands.Cog):
return return
this_player = p_query['players'][0] this_player = p_query['players'][0]
logging.debug(f'this_player: {this_player}') logger.debug(f'this_player: {this_player}')
await self.buy_card(interaction, this_player, owner_team) await self.buy_card(interaction, this_player, owner_team)
@ -1020,14 +1020,14 @@ class Economy(commands.Cog):
for card in c_query['cards']: for card in c_query['cards']:
if len(dupe_strings[str_count]) > 1500: if len(dupe_strings[str_count]) > 1500:
str_count += 1 str_count += 1
logging.debug(f'card: {card}') logger.debug(f'card: {card}')
if skip_live and (card['player']['cardset']['id'] == LIVE_CARDSET_ID): if skip_live and (card['player']['cardset']['id'] == LIVE_CARDSET_ID):
logging.debug(f'live series card - skipping') logger.debug(f'live series card - skipping')
elif card['player']['player_id'] not in player_ids: elif card['player']['player_id'] not in player_ids:
logging.debug(f'not a dupe') logger.debug(f'not a dupe')
player_ids.append(card['player']['player_id']) player_ids.append(card['player']['player_id'])
else: else:
logging.info(f'{team["abbrev"]} duplicate card: {card["id"]}') logger.info(f'{team["abbrev"]} duplicate card: {card["id"]}')
dupe_cards.append(card) dupe_cards.append(card)
dupe_ids += f'{card["id"]},' dupe_ids += f'{card["id"]},'
dupe_strings[str_count] += f'{card["player"]["rarity"]["name"]} {card["player"]["p_name"]} - ' \ dupe_strings[str_count] += f'{card["player"]["rarity"]["name"]} {card["player"]["p_name"]} - ' \
@ -1037,12 +1037,12 @@ class Economy(commands.Cog):
await interaction.edit_original_response(content=f'You currently have 0 duplicate cards!') await interaction.edit_original_response(content=f'You currently have 0 duplicate cards!')
return return
logging.info(f'sending first message / length {len(dupe_strings[0])}') logger.info(f'sending first message / length {len(dupe_strings[0])}')
await interaction.edit_original_response( await interaction.edit_original_response(
content=f'You currently have {len(dupe_cards)} duplicate cards:\n\n{dupe_strings[0]}' content=f'You currently have {len(dupe_cards)} duplicate cards:\n\n{dupe_strings[0]}'
) )
for x in dupe_strings[1:]: for x in dupe_strings[1:]:
logging.info(f'checking string: {len(x)}') logger.info(f'checking string: {len(x)}')
if len(x) > 0: if len(x) > 0:
await interaction.channel.send(x) await interaction.channel.send(x)
else: else:
@ -1142,7 +1142,7 @@ class Economy(commands.Cog):
poke_role = get_role(interaction, 'Pokétwo') poke_role = get_role(interaction, 'Pokétwo')
await share_channel(op_ch, poke_role, read_only=True) await share_channel(op_ch, poke_role, read_only=True)
except Exception as e: except Exception as e:
logging.error(f'unable to share sheet with Poketwo') logger.error(f'unable to share sheet with Poketwo')
await interaction.response.send_message( await interaction.response.send_message(
f'Let\'s head down to your private channel: {op_ch.mention}', f'Let\'s head down to your private channel: {op_ch.mention}',
@ -1195,7 +1195,7 @@ class Economy(commands.Cog):
break break
team_string = mlb_anchor_team team_string = mlb_anchor_team
logging.debug(f'team_string: {team_string} / team_choice: {team_choice}') logger.debug(f'team_string: {team_string} / team_choice: {team_choice}')
if not team_choice: if not team_choice:
# Get MLB anchor team # Get MLB anchor team
while True: while True:
@ -1308,7 +1308,7 @@ class Economy(commands.Cog):
roster_counts[pl['rarity']['name']] += 1 roster_counts[pl['rarity']['name']] += 1
for x in get_all_pos(pl): for x in get_all_pos(pl):
roster_counts[x] += 1 roster_counts[x] += 1
logging.warning(f'Roster counts for {team["sname"]}: {roster_counts}') logger.warning(f'Roster counts for {team["sname"]}: {roster_counts}')
# Add anchor position coverage # Add anchor position coverage
update_roster_counts(anchor_players) update_roster_counts(anchor_players)
@ -1572,7 +1572,7 @@ class Economy(commands.Cog):
try: try:
new_sheet = sheets.open_by_url(google_sheet_url) new_sheet = sheets.open_by_url(google_sheet_url)
except Exception as e: except Exception as e:
logging.error(f'Error accessing {team["abbrev"]} sheet: {e}') logger.error(f'Error accessing {team["abbrev"]} sheet: {e}')
current = await db_get('current') current = await db_get('current')
await ctx.send(f'I wasn\'t able to access that sheet. Did you remember to share it with my PD email?' await ctx.send(f'I wasn\'t able to access that sheet. Did you remember to share it with my PD email?'
f'\n\nHere\'s a quick refresher:\n{SHEET_SHARE_STEPS}\n\n' f'\n\nHere\'s a quick refresher:\n{SHEET_SHARE_STEPS}\n\n'
@ -1599,10 +1599,10 @@ class Economy(commands.Cog):
new_r_data.append([int(row[0].value)]) new_r_data.append([int(row[0].value)])
else: else:
new_r_data.append([None]) new_r_data.append([None])
logging.debug(f'new_r_data: {new_r_data}') logger.debug(f'new_r_data: {new_r_data}')
for row in lineups_data: for row in lineups_data:
logging.debug(f'row: {row}') logger.debug(f'row: {row}')
new_l_data.append([ new_l_data.append([
row[0].value if row[0].value != '' else None, row[0].value if row[0].value != '' else None,
int(row[1].value) if row[1].value != '' else None, int(row[1].value) if row[1].value != '' else None,
@ -1611,7 +1611,7 @@ class Economy(commands.Cog):
row[4].value if row[4].value != '' else None, row[4].value if row[4].value != '' else None,
int(row[5].value) if row[5].value != '' else None int(row[5].value) if row[5].value != '' else None
]) ])
logging.debug(f'new_l_data: {new_l_data}') logger.debug(f'new_l_data: {new_l_data}')
new_r_sheet = new_sheet.worksheet_by_title(f'My Rosters') new_r_sheet = new_sheet.worksheet_by_title(f'My Rosters')
new_r_sheet.update_values( new_r_sheet.update_values(
@ -1678,7 +1678,7 @@ class Economy(commands.Cog):
# # # #
# # # Send current data to Sheets # # # Send current data to Sheets
# # if not await self.write_collection(ctx, team, extra=len(roster_data['cut'])): # # if not await self.write_collection(ctx, team, extra=len(roster_data['cut'])):
# # logging.error(f'There was an issue trying to update the {team.sname} roster.') # # logger.error(f'There was an issue trying to update the {team.sname} roster.')
# # await helpers.pause_then_type(ctx, 'Yikes. I had an issue with Sheets. Send help.') # # await helpers.pause_then_type(ctx, 'Yikes. I had an issue with Sheets. Send help.')
# # else: # # else:
# # await helpers.pause_then_type(ctx, 'Alrighty, your sheet is all up to date!') # # await helpers.pause_then_type(ctx, 'Alrighty, your sheet is all up to date!')
@ -1718,7 +1718,7 @@ class Economy(commands.Cog):
try: try:
await give_cards_to_team(team, player_ids=all_player_ids, pack_id=this_pack['id']) await give_cards_to_team(team, player_ids=all_player_ids, pack_id=this_pack['id'])
except Exception as e: except Exception as e:
logging.error(f'failed to create cards: {e}') logger.error(f'failed to create cards: {e}')
raise ConnectionError(f'Failed to distribute these cards.') raise ConnectionError(f'Failed to distribute these cards.')
await question.edit(content=f'Alrighty, now I\'ll refresh their sheet...') await question.edit(content=f'Alrighty, now I\'ll refresh their sheet...')

View File

@ -8,9 +8,9 @@ from discord.ext import commands, tasks
import pygsheets import pygsheets
from api_calls import db_get from api_calls import db_get
from command_logic.logic_gameplay import advance_runners, bunts, doubles, flyballs, get_lineups_from_sheets, checks_log_interaction, complete_play, hit_by_pitch, homeruns, popouts, show_defense_cards, singles, strikeouts, triples, undo_play, walks from command_logic.logic_gameplay import advance_runners, bunts, complete_game, doubles, flyballs, get_lineups_from_sheets, checks_log_interaction, complete_play, hit_by_pitch, homeruns, is_game_over, popouts, show_defense_cards, singles, strikeouts, triples, undo_play, walks
from exceptions import GameNotFoundException, TeamNotFoundException, PlayNotFoundException, GameException from exceptions import GameNotFoundException, TeamNotFoundException, PlayNotFoundException, GameException, log_exception
from helpers import DEFENSE_LITERAL, PD_PLAYERS_ROLE_NAME, team_role, user_has_role, random_gif, random_from_list from helpers import DEFENSE_LITERAL, PD_PLAYERS_ROLE_NAME, get_channel, team_role, user_has_role, random_gif, random_from_list
# from in_game import ai_manager # from in_game import ai_manager
from in_game.ai_manager import get_starting_pitcher, get_starting_lineup from in_game.ai_manager import get_starting_pitcher, get_starting_lineup
@ -18,10 +18,11 @@ from in_game.game_helpers import PUBLIC_FIELDS_CATEGORY_NAME, legal_check
from in_game.gameplay_models import Lineup, Play, Session, engine, player_description, select, Game from in_game.gameplay_models import Lineup, Play, Session, engine, player_description, select, Game
from in_game.gameplay_queries import get_channel_game_or_none, get_active_games_by_team, get_game_lineups, get_team_or_none, get_card_or_none from in_game.gameplay_queries import get_channel_game_or_none, get_active_games_by_team, get_game_lineups, get_team_or_none, get_card_or_none
from utilities.buttons import Confirm from utilities.buttons import Confirm, ask_confirm
CLASSIC_EMBED = True CLASSIC_EMBED = True
logger = logging.getLogger('discord_app')
class Gameplay(commands.Cog): class Gameplay(commands.Cog):
@ -33,24 +34,47 @@ class Gameplay(commands.Cog):
@tasks.loop(count=1) @tasks.loop(count=1)
async def get_sheets(self): async def get_sheets(self):
logging.info(f'Getting sheets') logger.info(f'Getting sheets')
self.sheets = pygsheets.authorize(service_file='storage/paper-dynasty-service-creds.json', retries=1) self.sheets = pygsheets.authorize(service_file='storage/paper-dynasty-service-creds.json', retries=1)
@get_sheets.before_loop @get_sheets.before_loop
async def before_get_sheets(self): async def before_get_sheets(self):
logging.info(f'Waiting to get sheets') logger.info(f'Waiting to get sheets')
await self.bot.wait_until_ready() await self.bot.wait_until_ready()
async def cog_command_error(self, ctx, error): async def cog_command_error(self, ctx, error):
logging.error(msg=error, stack_info=True) logger.error(msg=error, stack_info=True)
await ctx.send(f'{error}\n\nRun !help <command_name> to see the command requirements') await ctx.send(f'{error}\n\nRun !help <command_name> to see the command requirements')
async def slash_error(self, ctx, error): async def slash_error(self, ctx, error):
logging.error(msg=error, stack_info=True) logger.error(msg=error, stack_info=True)
await ctx.send(f'{error[:1600]}') await ctx.send(f'{error[:1600]}')
async def post_play(self, session: Session, interaction: discord.Interaction, this_play: Play, buffer_message: str = None): async def post_play(self, session: Session, interaction: discord.Interaction, this_play: Play, buffer_message: str = None):
if buffer_message is not None: if is_game_over(this_play):
await interaction.edit_original_response(content=f'Looks like this one is over! ')
submit_game = await ask_confirm(
interaction=interaction,
question=f'Final score: {this_play.game.away_team.abbrev} {this_play.away_score} - {this_play.home_score} {this_play.game.home_team.abbrev}\n{this_play.scorebug_ascii}\nShould I go ahead and submit this game or roll it back a play?',
custom_confirm_label='Submit',
custom_cancel_label='Roll Back'
)
if submit_game:
await complete_game(session, interaction, this_play)
return
else:
logger.warning(f'post_play - is_game_over - {interaction.user.display_name} rejected game completion in Game {this_play.game.id}')
cal_channel = get_channel(interaction, 'commissioners-office')
await cal_channel.send(content=f'{interaction.user.display_name} just rejected game completion down in {interaction.channel.mention}')
this_play = undo_play(session, this_play)
await self.post_play(session, interaction, this_play)
await interaction.channel.send(content=f'I let Cal know his bot is stupid')
elif buffer_message is not None:
await interaction.edit_original_response( await interaction.edit_original_response(
content=buffer_message content=buffer_message
) )
@ -65,8 +89,8 @@ class Gameplay(commands.Cog):
) )
async def complete_and_post_play(self, session: Session, interaction: discord.Interaction, this_play: Play, buffer_message: str = None): async def complete_and_post_play(self, session: Session, interaction: discord.Interaction, this_play: Play, buffer_message: str = None):
complete_play(session, this_play) next_play = complete_play(session, this_play)
await self.post_play(session, interaction, this_play, buffer_message) await self.post_play(session, interaction, next_play, buffer_message)
group_new_game = app_commands.Group(name='new-game', description='Start a new baseball game') group_new_game = app_commands.Group(name='new-game', description='Start a new baseball game')
@ -123,7 +147,7 @@ class Gameplay(commands.Cog):
return return
ai_team = away_team if away_team.is_ai else home_team ai_team = away_team if away_team.is_ai else home_team
human_team = away_team if home_team.is_ai else away_team human_team = away_team if home_team.is_ai else home_team
conflict_games = get_active_games_by_team(session, team=human_team) conflict_games = get_active_games_by_team(session, team=human_team)
if len(conflict_games) > 0: if len(conflict_games) > 0:
@ -134,7 +158,7 @@ class Gameplay(commands.Cog):
current = await db_get('current') current = await db_get('current')
week_num = current['week'] week_num = current['week']
logging.info(f'gameplay - new_game_mlb_campaign - Season: {current["season"]} / Week: {week_num} / Away Team: {away_team.description} / Home Team: {home_team.description}') logger.info(f'gameplay - new_game_mlb_campaign - Season: {current["season"]} / Week: {week_num} / Away Team: {away_team.description} / Home Team: {home_team.description}')
def role_error(required_role: str, league_name: str, lower_league: str): def role_error(required_role: str, league_name: str, lower_league: str):
return f'Ope. Looks like you haven\'t received the **{required_role}** role, yet!\n\nTo play **{league_name}** games, you need to defeat all 30 MLB teams in the {lower_league} campaign. You can see your progress with `/record`.\n\nIf you have completed the {lower_league} campaign, go ping Cal to get your new role!' return f'Ope. Looks like you haven\'t received the **{required_role}** role, yet!\n\nTo play **{league_name}** games, you need to defeat all 30 MLB teams in the {lower_league} campaign. You can see your progress with `/record`.\n\nIf you have completed the {lower_league} campaign, go ping Cal to get your new role!'
@ -163,14 +187,14 @@ class Gameplay(commands.Cog):
home_team_id=home_team.id, home_team_id=home_team.id,
channel_id=interaction.channel_id, channel_id=interaction.channel_id,
season=current['season'], season=current['season'],
week_num=week_num, week=week_num,
first_message=None if interaction.message is None else interaction.message.channel.id, first_message=None if interaction.message is None else interaction.message.channel.id,
ai_team='away' if away_team.is_ai else 'home', ai_team='away' if away_team.is_ai else 'home',
game_type=league.value game_type=league.value
) )
game_info_log = f'{league.name} game between {away_team.description} and {home_team.description} / first message: {this_game.first_message}' game_info_log = f'{league.name} game between {away_team.description} and {home_team.description} / first message: {this_game.first_message}'
logging.info(game_info_log) logger.info(game_info_log)
# Get Human SP card # Get Human SP card
human_sp_card = await get_card_or_none(session, card_id=sp_card_id) human_sp_card = await get_card_or_none(session, card_id=sp_card_id)
@ -181,7 +205,7 @@ class Gameplay(commands.Cog):
return return
if human_sp_card.team_id != human_team.id: if human_sp_card.team_id != human_team.id:
logging.error(f'Card_id {sp_card_id} does not belong to {human_team.abbrev} in Game {this_game.id}') logger.error(f'Card_id {sp_card_id} does not belong to {human_team.abbrev} in Game {this_game.id}')
await interaction.channel.send( await interaction.channel.send(
f'Uh oh. Card ID {sp_card_id} is {human_sp_card.player.name} and belongs to {human_sp_card.team.sname}. Will you double check that before we get started?' f'Uh oh. Card ID {sp_card_id} is {human_sp_card.player.name} and belongs to {human_sp_card.team.sname}. Will you double check that before we get started?'
) )
@ -261,29 +285,29 @@ class Gameplay(commands.Cog):
await ctx.send(f'I do not see a game here - are you in the right place?') await ctx.send(f'I do not see a game here - are you in the right place?')
return return
await ctx.send( try:
content=None, await ctx.send(
embed=this_game.get_scorebug_embed(session, full_length=True) content=None,
embed=this_game.get_scorebug_embed(session, full_length=True)
)
except Exception as e:
logger.error(f'Unable to display scorebug while forcing game to end: {e}')
await ctx.send(content='This game is so boned that I can\'t display the scorebug.')
nuke_game = await ask_confirm(
ctx,
question=f'Is this the game I should nuke?',
label_type='yes',
timeout=15,
) )
view = Confirm(responders=[ctx.author], timeout=60, label_type='confirm') # if view.value:
question = await ctx.send(f'Is this the game I should nuke?', view=view) if nuke_game:
await view.wait()
if view.value:
session.delete(this_game) session.delete(this_game)
session.commit() session.commit()
await question.edit( await ctx.channel.send(content=random_gif(random_from_list(['i killed it', 'deed is done', 'gone forever'])))
content=random_gif(random_from_list([
'i killed it', 'deed is done', 'gone forever'
])),
view=None
)
else: else:
await question.edit( await ctx.send(f'It stays. For now.')
content=f'~~Is this the game I should nuke?~~\n\nIt stays.',
view=None
)
@app_commands.command(name='read-lineup', description='Import a saved lineup for this channel\'s PD game.') @app_commands.command(name='read-lineup', description='Import a saved lineup for this channel\'s PD game.')
@app_commands.describe( @app_commands.describe(
@ -315,7 +339,7 @@ class Gameplay(commands.Cog):
lineup_team = this_game.away_team if this_game.ai_team == 'home' else this_game.home_team lineup_team = this_game.away_team if this_game.ai_team == 'home' else this_game.home_team
if interaction.user.id != lineup_team.gmid: if interaction.user.id != lineup_team.gmid:
logging.info(f'{interaction.user.name} tried to run a command in Game {this_game.id} when they aren\'t a GM in the game.') logger.info(f'{interaction.user.name} tried to run a command in Game {this_game.id} when they aren\'t a GM in the game.')
await interaction.edit_original_response(content='Bruh. Only GMs of the active teams can pull lineups.') await interaction.edit_original_response(content='Bruh. Only GMs of the active teams can pull lineups.')
return return
@ -374,7 +398,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log flyball') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log flyball')
this_play = await flyballs(session, interaction, this_play, flyball_type) this_play = await flyballs(session, interaction, this_play, flyball_type)
logging.info(f'log flyball {flyball_type} - this_play: {this_play}') logger.info(f'log flyball {flyball_type} - this_play: {this_play}')
await self.complete_and_post_play( await self.complete_and_post_play(
session, session,
@ -390,7 +414,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log single') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log single')
this_play = await singles(session, interaction, this_play, single_type) this_play = await singles(session, interaction, this_play, single_type)
logging.info(f'log single {single_type} - this_play: {this_play}') logger.info(f'log single {single_type} - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play, buffer_message='Double logged' if ((this_play.on_first or this_play.on_second) and single_type == 'uncapped') else None) await self.complete_and_post_play(session, interaction, this_play, buffer_message='Double logged' if ((this_play.on_first or this_play.on_second) and single_type == 'uncapped') else None)
@ -414,7 +438,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log double') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log double')
this_play = await doubles(session, interaction, this_play, double_type) this_play = await doubles(session, interaction, this_play, double_type)
logging.info(f'log double {double_type} - this_play: {this_play}') logger.info(f'log double {double_type} - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play, buffer_message='Double logged' if (this_play.on_first and double_type == 'uncapped') else None) await self.complete_and_post_play(session, interaction, this_play, buffer_message='Double logged' if (this_play.on_first and double_type == 'uncapped') else None)
@ -424,7 +448,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log triple') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log triple')
this_play = await triples(session, interaction, this_play) this_play = await triples(session, interaction, this_play)
logging.info(f'log triple - this_play: {this_play}') logger.info(f'log triple - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play)
@ -434,7 +458,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log homerun') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log homerun')
this_play = await homeruns(session, interaction, this_play, homerun_type) this_play = await homeruns(session, interaction, this_play, homerun_type)
logging.info(f'log homerun {homerun_type} - this_play: {this_play}') logger.info(f'log homerun {homerun_type} - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play)
@ -444,7 +468,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log walk') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log walk')
this_play = await walks(session, interaction, this_play, walk_type) this_play = await walks(session, interaction, this_play, walk_type)
logging.info(f'log walk {walk_type} - this_play: {this_play}') logger.info(f'log walk {walk_type} - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play)
@ -454,7 +478,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log strikeout') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log strikeout')
this_play = await strikeouts(session, interaction, this_play) this_play = await strikeouts(session, interaction, this_play)
logging.info(f'log strikeout - this_play: {this_play}') logger.info(f'log strikeout - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play)
@ -464,7 +488,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log popout') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log popout')
this_play = await popouts(session, interaction, this_play) this_play = await popouts(session, interaction, this_play)
logging.info(f'log popout - this_play: {this_play}') logger.info(f'log popout - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play)
@ -474,7 +498,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log hit-by-pitch') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log hit-by-pitch')
this_play = await hit_by_pitch(session, interaction, this_play) this_play = await hit_by_pitch(session, interaction, this_play)
logging.info(f'log hit-by-pitch - this_play: {this_play}') logger.info(f'log hit-by-pitch - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play)
@ -484,7 +508,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log bunt') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log bunt')
this_play = await bunts(session, interaction, this_play, bunt_type) this_play = await bunts(session, interaction, this_play, bunt_type)
logging.info(f'log bunt - this_play: {this_play}') logger.info(f'log bunt - this_play: {this_play}')
await self.complete_and_post_play(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play)
@ -494,7 +518,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log undo-play') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='log undo-play')
this_play = undo_play(session, this_play) this_play = undo_play(session, this_play)
logging.info(f'log undo-play - this_play: {this_play}') logger.info(f'log undo-play - this_play: {this_play}')
await self.post_play(session, interaction, this_play) await self.post_play(session, interaction, this_play)
@ -505,7 +529,7 @@ class Gameplay(commands.Cog):
this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='show-card defense') this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='show-card defense')
await show_defense_cards(session, interaction, this_play, position) await show_defense_cards(session, interaction, this_play, position)
logging.info(f'show-card defense - position: {position}') logger.info(f'show-card defense - position: {position}')
async def setup(bot): async def setup(bot):

File diff suppressed because it is too large Load Diff

View File

@ -8,12 +8,8 @@ from discord.ext import commands
from discord.ext.commands import Greedy, Context from discord.ext.commands import Greedy, Context
from typing import Optional, Literal from typing import Optional, Literal
date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
logging.basicConfig( logger = logging.getLogger('discord_app')
filename=f'logs/{date}.log',
format='%(asctime)s - %(levelname)s - %(message)s',
level=logging.WARNING
)
class Owner(commands.Cog): class Owner(commands.Cog):
@ -25,7 +21,7 @@ class Owner(commands.Cog):
async def load(self, ctx, *, cog: str): async def load(self, ctx, *, cog: str):
try: try:
await self.bot.load_extension(f'cogs.{cog}') await self.bot.load_extension(f'cogs.{cog}')
logging.warning(f'Loaded {cog}') logger.warning(f'Loaded {cog}')
except Exception as e: except Exception as e:
await ctx.send(f'**ERROR:** {type(e).__name__} - {e}') await ctx.send(f'**ERROR:** {type(e).__name__} - {e}')
else: else:
@ -36,7 +32,7 @@ class Owner(commands.Cog):
async def unload(self, ctx, *, cog: str): async def unload(self, ctx, *, cog: str):
try: try:
await self.bot.unload_extension(f'cogs.{cog}') await self.bot.unload_extension(f'cogs.{cog}')
logging.warning(f'Unloaded {cog}') logger.warning(f'Unloaded {cog}')
except Exception as e: except Exception as e:
await ctx.send(f'**ERROR:** {type(e).__name__} - {e}') await ctx.send(f'**ERROR:** {type(e).__name__} - {e}')
else: else:
@ -47,9 +43,9 @@ class Owner(commands.Cog):
async def reload(self, ctx, *, cog: str): async def reload(self, ctx, *, cog: str):
try: try:
await self.bot.unload_extension(f'cogs.{cog}') await self.bot.unload_extension(f'cogs.{cog}')
logging.warning(f'Unloaded {cog}') logger.warning(f'Unloaded {cog}')
await self.bot.load_extension(f'cogs.{cog}') await self.bot.load_extension(f'cogs.{cog}')
logging.warning(f'Reloaded {cog}') logger.warning(f'Reloaded {cog}')
except Exception as e: except Exception as e:
await ctx.send(f'**ERROR:** {type(e).__name__} - {e}') await ctx.send(f'**ERROR:** {type(e).__name__} - {e}')
else: else:
@ -63,14 +59,14 @@ class Owner(commands.Cog):
for x in cogs: for x in cogs:
try: try:
await self.bot.unload_extension(f'cogs.{x}') await self.bot.unload_extension(f'cogs.{x}')
logging.warning(f'Unloaded {x}') logger.warning(f'Unloaded {x}')
except Exception as e: except Exception as e:
await ctx.send(f'Failed to unload **{x}**') await ctx.send(f'Failed to unload **{x}**')
for x in cogs: for x in cogs:
try: try:
await self.bot.load_extension(f'cogs.{x}') await self.bot.load_extension(f'cogs.{x}')
logging.warning(f'Loaded {x}') logger.warning(f'Loaded {x}')
except Exception as e: except Exception as e:
await ctx.send(f'Failed to load **{x}**') await ctx.send(f'Failed to load **{x}**')
@ -86,9 +82,9 @@ class Owner(commands.Cog):
# sync = await self.bot.tree.sync() # sync = await self.bot.tree.sync()
# else: # else:
# sync = await self.bot.tree.sync(guild=discord.Object(os.environ.get('GUILD_ID'))) # sync = await self.bot.tree.sync(guild=discord.Object(os.environ.get('GUILD_ID')))
# logging.warning(f'sync: {sync}') # logger.warning(f'sync: {sync}')
# except Exception as e: # except Exception as e:
# logging.error(f'failed to sync: {e}') # logger.error(f'failed to sync: {e}')
# #
# await ctx.send(f'Just ran the sync. Here is the output:\n{sync}') # await ctx.send(f'Just ran the sync. Here is the output:\n{sync}')
@ -101,7 +97,7 @@ class Owner(commands.Cog):
!sync * -> copies all global app commands to current guild and syncs !sync * -> copies all global app commands to current guild and syncs
!sync id_1 id_2 -> syncs guilds with id 1 and 2 !sync id_1 id_2 -> syncs guilds with id 1 and 2
""" """
logging.info(f'{ctx.author.name} has initiated a sync from guild ID {ctx.guild.id}') logger.info(f'{ctx.author.name} has initiated a sync from guild ID {ctx.guild.id}')
if not guilds: if not guilds:
if spec == "~": if spec == "~":
fmt = await ctx.bot.tree.sync(guild=ctx.guild) fmt = await ctx.bot.tree.sync(guild=ctx.guild)

View File

@ -31,12 +31,7 @@ from helpers import PD_PLAYERS_ROLE_NAME, IMAGES, PD_SEASON, random_conf_gif, fu
team_summary_embed, SelectView, SelectPaperdexCardset, SelectPaperdexTeam team_summary_embed, SelectView, SelectPaperdexCardset, SelectPaperdexTeam
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}' logger = logging.getLogger('discord_app')
# logging.basicConfig(
# filename=f'logs/{date}.log',
# format='%(asctime)s - %(levelname)s - %(message)s',
# level=logging.WARNING
# )
def get_ai_records(short_games, long_games): def get_ai_records(short_games, long_games):
@ -133,7 +128,7 @@ def get_ai_records(short_games, long_games):
'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}},
} }
logging.debug(f'running short games...') logger.debug(f'running short games...')
for line in short_games: for line in short_games:
home_win = True if line['home_score'] > line['away_score'] else False home_win = True if line['home_score'] > line['away_score'] else False
@ -147,9 +142,9 @@ def get_ai_records(short_games, long_games):
all_results[line['home_team']['abbrev']]['short']['l'] += 1 if home_win else 0 all_results[line['home_team']['abbrev']]['short']['l'] += 1 if home_win else 0
all_results[line['home_team']['abbrev']]['short']['points'] += 2 if not home_win else 1 all_results[line['home_team']['abbrev']]['short']['points'] += 2 if not home_win else 1
all_results[line['home_team']['abbrev']]['short']['rd'] += line['away_score'] - line['home_score'] all_results[line['home_team']['abbrev']]['short']['rd'] += line['away_score'] - line['home_score']
logging.debug(f'done short games') logger.debug(f'done short games')
logging.debug(f'running league games...') logger.debug(f'running league games...')
league = {None: 'minor', 'minor-league': 'minor', 'major-league': 'major', 'hall-of-fame': 'hof'} league = {None: 'minor', 'minor-league': 'minor', 'major-league': 'major', 'hall-of-fame': 'hof'}
for line in long_games: for line in long_games:
home_win = True if line['home_score'] > line['away_score'] else False home_win = True if line['home_score'] > line['away_score'] else False
@ -166,7 +161,7 @@ def get_ai_records(short_games, long_games):
all_results[line['home_team']['abbrev']][league[line['game_type']]]['points'] += 2 if not home_win else 1 all_results[line['home_team']['abbrev']][league[line['game_type']]]['points'] += 2 if not home_win else 1
all_results[line['home_team']['abbrev']][league[line['game_type']]]['rd'] += \ all_results[line['home_team']['abbrev']][league[line['game_type']]]['rd'] += \
line['away_score'] - line['home_score'] line['away_score'] - line['home_score']
logging.debug(f'done league games') logger.debug(f'done league games')
return all_results return all_results
@ -306,7 +301,7 @@ class Players(commands.Cog):
async def weekly_loop(self): async def weekly_loop(self):
current = await db_get('current') current = await db_get('current')
now = datetime.datetime.now() now = datetime.datetime.now()
logging.debug(f'Datetime: {now} / weekday: {now.weekday()}') logger.debug(f'Datetime: {now} / weekday: {now.weekday()}')
# Begin Freeze # Begin Freeze
# if now.weekday() == 0 and now.hour == 5: # Spring/Summer # if now.weekday() == 0 and now.hour == 5: # Spring/Summer
@ -333,10 +328,10 @@ class Players(commands.Cog):
[self.player_list.append(x['p_name'].lower()) for x in all_players['players'] if x['p_name'].lower() [self.player_list.append(x['p_name'].lower()) for x in all_players['players'] if x['p_name'].lower()
not in self.player_list] not in self.player_list]
logging.info(f'There are now {len(self.player_list)} player names in the fuzzy search list.') logger.info(f'There are now {len(self.player_list)} player names in the fuzzy search list.')
self.cardset_list = [x['name'].lower() for x in all_cardsets['cardsets']] self.cardset_list = [x['name'].lower() for x in all_cardsets['cardsets']]
logging.info(f'There are now {len(self.cardset_list)} cardsets in the fuzzy search list.') logger.info(f'There are now {len(self.cardset_list)} cardsets in the fuzzy search list.')
@build_player_list.before_loop @build_player_list.before_loop
async def before_player_list(self): async def before_player_list(self):
@ -352,7 +347,7 @@ class Players(commands.Cog):
# weekly_games = Result.select_season(current.season).where( # weekly_games = Result.select_season(current.season).where(
# (Result.week == current.week) & (Result.game_type == "baseball") # (Result.week == current.week) & (Result.game_type == "baseball")
# ) # )
# logging.info(f'weekly_games: {weekly_games}') # logger.info(f'weekly_games: {weekly_games}')
# #
# if weekly_games.count() == 0: # if weekly_games.count() == 0:
# return None # return None
@ -398,7 +393,7 @@ class Players(commands.Cog):
# for team in records: # for team in records:
# standings_message += f'**{count}**: {team[3].sname} - {team[1]:.0f} Pts ({team[0]["w"]}-{team[0]["l"]})\n' # standings_message += f'**{count}**: {team[3].sname} - {team[1]:.0f} Pts ({team[0]["w"]}-{team[0]["l"]})\n'
# if count % 24 == 0 or count >= len(records): # if count % 24 == 0 or count >= len(records):
# logging.info(f'standings_message: {standings_message}') # logger.info(f'standings_message: {standings_message}')
# all_embeds[embed_count].add_field(name='Standings', value=standings_message) # all_embeds[embed_count].add_field(name='Standings', value=standings_message)
# all_embeds[embed_count].set_thumbnail(url=self.logo) # all_embeds[embed_count].set_thumbnail(url=self.logo)
# #
@ -482,7 +477,7 @@ class Players(commands.Cog):
all_embeds = [] all_embeds = []
for x in all_cards: for x in all_cards:
all_embeds.extend(await get_card_embeds(x, include_stats=True)) all_embeds.extend(await get_card_embeds(x, include_stats=True))
logging.debug(f'embeds: {all_embeds}') logger.debug(f'embeds: {all_embeds}')
if len(all_embeds) > 1: if len(all_embeds) > 1:
await interaction.edit_original_response(content=f'# {all_players["players"][0]["p_name"]}') await interaction.edit_original_response(content=f'# {all_players["players"][0]["p_name"]}')
@ -827,9 +822,9 @@ class Players(commands.Cog):
all_records[line['home_team']['id']]['losses'] += 1 if not home_win else 0 all_records[line['home_team']['id']]['losses'] += 1 if not home_win else 0
all_records[line['home_team']['id']]['points'] += 2 if home_win else 0 all_records[line['home_team']['id']]['points'] += 2 if home_win else 0
# logging.info(f'all_records:\n\n{all_records}') # logger.info(f'all_records:\n\n{all_records}')
sorted_records = sorted(all_records.items(), key=lambda k_v: k_v[1]['points'], reverse=True) sorted_records = sorted(all_records.items(), key=lambda k_v: k_v[1]['points'], reverse=True)
# logging.info(f'sorted_records: {sorted_records}') # logger.info(f'sorted_records: {sorted_records}')
# await ctx.send(f'sorted: {sorted_records}') # await ctx.send(f'sorted: {sorted_records}')
embed = get_team_embed( embed = get_team_embed(
@ -839,14 +834,14 @@ class Players(commands.Cog):
chunk_string = '' chunk_string = ''
for index, record in enumerate(sorted_records): for index, record in enumerate(sorted_records):
# logging.info(f'index: {index} / record: {record}') # logger.info(f'index: {index} / record: {record}')
team = await db_get('teams', object_id=record[0]) team = await db_get('teams', object_id=record[0])
if team: if team:
chunk_string += f'{record[1]["points"]} pt{"s" if record[1]["points"] != 1 else ""} ' \ chunk_string += f'{record[1]["points"]} pt{"s" if record[1]["points"] != 1 else ""} ' \
f'({record[1]["wins"]}-{record[1]["losses"]}) - {team["sname"]} [{team["ranking"]}]\n' f'({record[1]["wins"]}-{record[1]["losses"]}) - {team["sname"]} [{team["ranking"]}]\n'
else: else:
logging.error(f'Could not find team {record[0]} when running standings.') logger.error(f'Could not find team {record[0]} when running standings.')
if (index + 1) == len(sorted_records): if (index + 1) == len(sorted_records):
embed.add_field( embed.add_field(
@ -879,11 +874,11 @@ class Players(commands.Cog):
# Pull data from Sheets # Pull data from Sheets
async with ctx.typing(): async with ctx.typing():
roster_data = get_rosters(team, self.bot) roster_data = get_rosters(team, self.bot)
logging.debug(f'roster_data: {roster_data}') logger.debug(f'roster_data: {roster_data}')
# Post roster team/card ids and throw error if db says no # Post roster team/card ids and throw error if db says no
for index, roster in enumerate(roster_data): for index, roster in enumerate(roster_data):
logging.debug(f'index: {index} / roster: {roster}') logger.debug(f'index: {index} / roster: {roster}')
if (not specific_roster_num or specific_roster_num == index + 1) and roster: if (not specific_roster_num or specific_roster_num == index + 1) and roster:
this_roster = await db_post( this_roster = await db_post(
'rosters', 'rosters',
@ -983,7 +978,7 @@ class Players(commands.Cog):
except ZeroDivisionError as e: except ZeroDivisionError as e:
return return
except Exception as e: except Exception as e:
logging.error(f'Failed to run {event_name} draft for the {main_team["sname"]}: {e}') logger.error(f'Failed to run {event_name} draft for the {main_team["sname"]}: {e}')
draft_team = await db_get('teams', params=[('abbrev', f'Gauntlet-{main_team["abbrev"]}')]) draft_team = await db_get('teams', params=[('abbrev', f'Gauntlet-{main_team["abbrev"]}')])
await gauntlets.wipe_team(draft_team, interaction) await gauntlets.wipe_team(draft_team, interaction)
await interaction.channel.send( await interaction.channel.send(
@ -1124,7 +1119,7 @@ class Players(commands.Cog):
# # rar_res = Rarity.get(Rarity.name == 'Reserve') # # rar_res = Rarity.get(Rarity.name == 'Reserve')
# # rar_rpl = Rarity.get(Rarity.name == 'Replacement') # # rar_rpl = Rarity.get(Rarity.name == 'Replacement')
# # except Exception as e: # # except Exception as e:
# # logging.error(f'**Error**: (players inv getrars) - {e}') # # logger.error(f'**Error**: (players inv getrars) - {e}')
# # return # # return
# #
# all_embeds = [ # all_embeds = [
@ -1192,7 +1187,7 @@ class Players(commands.Cog):
# await ctx.send('Alright, let me go open that Sheet...') # await ctx.send('Alright, let me go open that Sheet...')
# scorecard = self.sheets.open_by_url(scorecard_url).worksheet_by_title('Results') # scorecard = self.sheets.open_by_url(scorecard_url).worksheet_by_title('Results')
# except Exception as e: # except Exception as e:
# logging.error(f'Unable to access sheet ({scorecard_url}) submitted by {ctx.author.name}') # logger.error(f'Unable to access sheet ({scorecard_url}) submitted by {ctx.author.name}')
# await ctx.message.add_reaction('❌') # await ctx.message.add_reaction('❌')
# await ctx.send(f'{ctx.message.author.mention}, I can\'t access that sheet.') # await ctx.send(f'{ctx.message.author.mention}, I can\'t access that sheet.')
# return # return
@ -1201,7 +1196,7 @@ class Players(commands.Cog):
# try: # try:
# awayteam = Team.get_season(awayabbrev) # awayteam = Team.get_season(awayabbrev)
# hometeam = Team.get_season(homeabbrev) # hometeam = Team.get_season(homeabbrev)
# logging.info(f'Final: {awayabbrev} {awayscore} - {homescore} {homeabbrev}') # logger.info(f'Final: {awayabbrev} {awayscore} - {homescore} {homeabbrev}')
# if awayteam == hometeam: # if awayteam == hometeam:
# await ctx.message.add_reaction('❌') # await ctx.message.add_reaction('❌')
# await helpers.send_to_news( # await helpers.send_to_news(
@ -1212,7 +1207,7 @@ class Players(commands.Cog):
# return # return
# except Exception as e: # except Exception as e:
# error = f'**ERROR:** {type(e).__name__} - {e}' # error = f'**ERROR:** {type(e).__name__} - {e}'
# logging.error(error) # logger.error(error)
# await ctx.message.add_reaction('❌') # await ctx.message.add_reaction('❌')
# await ctx.send(f'Hey, {ctx.author.mention}, I couldn\'t find the teams you mentioned. You put ' # await ctx.send(f'Hey, {ctx.author.mention}, I couldn\'t find the teams you mentioned. You put '
# f'**{awayabbrev}** as the away team and **{homeabbrev}** as the home team.') # f'**{awayabbrev}** as the away team and **{homeabbrev}** as the home team.')
@ -1280,7 +1275,7 @@ class Players(commands.Cog):
# ) # )
# await ctx.message.add_reaction('✅') # await ctx.message.add_reaction('✅')
# #
# logging.info('Checking for credit') # logger.info('Checking for credit')
# # Credit pack for win # # Credit pack for win
# economy = self.bot.get_cog('Economy') # economy = self.bot.get_cog('Economy')
# if awayscore > homescore: # if awayscore > homescore:
@ -1293,19 +1288,19 @@ class Players(commands.Cog):
# # Check values and distribute earnings # # Check values and distribute earnings
# if awayteam.team_value - hometeam.team_value <= 12: # if awayteam.team_value - hometeam.team_value <= 12:
# earnings['away'] = '1 Premium Pack' # earnings['away'] = '1 Premium Pack'
# logging.info(f'{awayteam.sname} earns 1 Premium pack for the win') # logger.info(f'{awayteam.sname} earns 1 Premium pack for the win')
# economy.give_pack(awayteam, 1, 'Premium') # economy.give_pack(awayteam, 1, 'Premium')
# else: # else:
# logging.info(f'{awayteam.sname} earns nothing for the win - team value {awayteam.team_value} vs ' # logger.info(f'{awayteam.sname} earns nothing for the win - team value {awayteam.team_value} vs '
# f'{hometeam.team_value}') # f'{hometeam.team_value}')
# earnings['away'] = f'None - Team was {awayteam.team_value - hometeam.team_value} points higher' # earnings['away'] = f'None - Team was {awayteam.team_value - hometeam.team_value} points higher'
# #
# if hometeam.team_value - awayteam.team_value <= 12: # if hometeam.team_value - awayteam.team_value <= 12:
# earnings['home'] = '1 Standard Pack' # earnings['home'] = '1 Standard Pack'
# logging.info(f'{hometeam.sname} earns 1 Standard pack for the loss') # logger.info(f'{hometeam.sname} earns 1 Standard pack for the loss')
# economy.give_pack(hometeam, 1) # economy.give_pack(hometeam, 1)
# else: # else:
# logging.info(f'{hometeam.sname} earns nothing for the loss - team value {hometeam.team_value} vs ' # logger.info(f'{hometeam.sname} earns nothing for the loss - team value {hometeam.team_value} vs '
# f'{awayteam.team_value}') # f'{awayteam.team_value}')
# earnings['home'] = f'None - Team was {hometeam.team_value - awayteam.team_value} points higher' # earnings['home'] = f'None - Team was {hometeam.team_value - awayteam.team_value} points higher'
# else: # else:
@ -1317,19 +1312,19 @@ class Players(commands.Cog):
# # Check values and distribute earnings # # Check values and distribute earnings
# if hometeam.team_value - awayteam.team_value <= 12: # if hometeam.team_value - awayteam.team_value <= 12:
# earnings['home'] = '1 Premium Pack' # earnings['home'] = '1 Premium Pack'
# logging.info(f'{hometeam.sname} earns 1 Premium pack for the win') # logger.info(f'{hometeam.sname} earns 1 Premium pack for the win')
# economy.give_pack(hometeam, 1, 'Premium') # economy.give_pack(hometeam, 1, 'Premium')
# else: # else:
# logging.info(f'{hometeam.sname} earns nothing for the win - team value {hometeam.team_value} vs ' # logger.info(f'{hometeam.sname} earns nothing for the win - team value {hometeam.team_value} vs '
# f'{awayteam.team_value}') # f'{awayteam.team_value}')
# earnings['home'] = f'None - Team was {hometeam.team_value - awayteam.team_value} points higher' # earnings['home'] = f'None - Team was {hometeam.team_value - awayteam.team_value} points higher'
# #
# if awayteam.team_value - hometeam.team_value <= 12: # if awayteam.team_value - hometeam.team_value <= 12:
# earnings['away'] = '1 Standard Pack' # earnings['away'] = '1 Standard Pack'
# logging.info(f'{awayteam.sname} earns 1 Standard pack for the loss') # logger.info(f'{awayteam.sname} earns 1 Standard pack for the loss')
# economy.give_pack(awayteam, 1) # economy.give_pack(awayteam, 1)
# else: # else:
# logging.info(f'{awayteam.sname} earns nothing for the loss - team value {awayteam.team_value} vs ' # logger.info(f'{awayteam.sname} earns nothing for the loss - team value {awayteam.team_value} vs '
# f'{hometeam.team_value}') # f'{hometeam.team_value}')
# earnings['away'] = f'None - Team was {awayteam.team_value - hometeam.team_value} points higher' # earnings['away'] = f'None - Team was {awayteam.team_value - hometeam.team_value} points higher'
# #
@ -1342,20 +1337,20 @@ class Players(commands.Cog):
# # delta = away_team_value - home_team_value # # delta = away_team_value - home_team_value
# # if delta < 0: # # if delta < 0:
# # increments = divmod(-delta, helpers.TEAM_DELTA_CONSTANT) # # increments = divmod(-delta, helpers.TEAM_DELTA_CONSTANT)
# # # logging.info(f'increments: {increments}') # # # logger.info(f'increments: {increments}')
# # packs = min(increments[0], 5) # # packs = min(increments[0], 5)
# # if packs > 0: # # if packs > 0:
# # earnings['away'] += packs # # earnings['away'] += packs
# # earnings_away.append(f'- {packs} pack{"s" if packs > 1 else ""} for underdog\n') # # earnings_away.append(f'- {packs} pack{"s" if packs > 1 else ""} for underdog\n')
# # else: # # else:
# # increments = divmod(delta, helpers.TEAM_DELTA_CONSTANT) # # increments = divmod(delta, helpers.TEAM_DELTA_CONSTANT)
# # # logging.info(f'increments: {increments}') # # # logger.info(f'increments: {increments}')
# # packs = min(increments[0], 5) # # packs = min(increments[0], 5)
# # if packs > 0: # # if packs > 0:
# # earnings['home'] += packs # # earnings['home'] += packs
# # earnings_home.append(f'- {packs} pack{"s" if packs > 1 else ""} for underdog\n') # # earnings_home.append(f'- {packs} pack{"s" if packs > 1 else ""} for underdog\n')
# #
# # logging.info(f'earn away: {earnings["away"]} / earn home: {earnings["home"]}') # # logger.info(f'earn away: {earnings["away"]} / earn home: {earnings["home"]}')
# # away_packs_remaining = Current.get_by_id(1).packlimit - awayteam.weeklypacks # # away_packs_remaining = Current.get_by_id(1).packlimit - awayteam.weeklypacks
# # home_packs_remaining = Current.get_by_id(1).packlimit - hometeam.weeklypacks # # home_packs_remaining = Current.get_by_id(1).packlimit - hometeam.weeklypacks
# # away_final_earnings = earnings["away"] if away_packs_remaining >= earnings["away"] else max(away_packs_remaining, 0) # # away_final_earnings = earnings["away"] if away_packs_remaining >= earnings["away"] else max(away_packs_remaining, 0)
@ -1365,12 +1360,12 @@ class Players(commands.Cog):
# #
# # economy = self.bot.get_cog('Economy') # # economy = self.bot.get_cog('Economy')
# # if away_final_earnings > 0: # # if away_final_earnings > 0:
# # logging.info(f'away_final_earnings: {away_final_earnings}') # # logger.info(f'away_final_earnings: {away_final_earnings}')
# # economy.give_pack(awayteam, away_final_earnings, True) # # economy.give_pack(awayteam, away_final_earnings, True)
# # else: # # else:
# # away_final_earnings = 0 # # away_final_earnings = 0
# # if home_final_earnings > 0: # # if home_final_earnings > 0:
# # logging.info(f'home_final_earnings: {home_final_earnings}') # # logger.info(f'home_final_earnings: {home_final_earnings}')
# # economy.give_pack(hometeam, home_final_earnings, True) # # economy.give_pack(hometeam, home_final_earnings, True)
# # else: # # else:
# # home_final_earnings = 0 # # home_final_earnings = 0
@ -1643,11 +1638,11 @@ class Players(commands.Cog):
if resp.status_code == 200: if resp.status_code == 200:
return resp.json() return resp.json()
else: else:
logging.warning(resp.text) logger.warning(resp.text)
raise ValueError(f'DB: {resp.text}') raise ValueError(f'DB: {resp.text}')
this_player = await get_one_player(player_name) this_player = await get_one_player(player_name)
logging.debug(f'this_player: {this_player}') logger.debug(f'this_player: {this_player}')
@app_commands.command(name='matchup', description='Simulate a matchup between a pitcher and batter') @app_commands.command(name='matchup', description='Simulate a matchup between a pitcher and batter')
@app_commands.describe( @app_commands.describe(

View File

@ -7,17 +7,19 @@ from sqlmodel import Session, select, func
from sqlalchemy import delete from sqlalchemy import delete
from typing import Literal from typing import Literal
from api_calls import db_delete, db_get, db_post
from exceptions import * from exceptions import *
from helpers import DEFENSE_LITERAL from helpers import DEFENSE_LITERAL, get_channel
from in_game.game_helpers import legal_check from in_game.game_helpers import legal_check
from in_game.gameplay_models import Game, Lineup, Team, Play from in_game.gameplay_models import Game, Lineup, Team, Play
from in_game.gameplay_queries import get_card_or_none, get_channel_game_or_none, get_last_team_play, get_one_lineup, get_sorted_lineups, get_team_or_none, get_players_last_pa from in_game.gameplay_queries import get_card_or_none, get_channel_game_or_none, get_db_ready_decisions, get_db_ready_plays, get_last_team_play, get_one_lineup, get_player_id_from_dict, get_player_name_from_dict, get_player_or_none, get_sorted_lineups, get_team_or_none, get_players_last_pa, post_game_rewards
from utilities.buttons import ButtonOptions, Confirm, ask_confirm from utilities.buttons import ButtonOptions, Confirm, ask_confirm
from utilities.dropdown import DropdownOptions, DropdownView, SelectViewDefense from utilities.dropdown import DropdownOptions, DropdownView, SelectViewDefense
from utilities.embeds import image_embed from utilities.embeds import image_embed
from utilities.pages import Pagination from utilities.pages import Pagination
logger = logging.getLogger('discord_app')
WPA_DF = pd.read_csv(f'storage/wpa_data.csv').set_index('index') WPA_DF = pd.read_csv(f'storage/wpa_data.csv').set_index('index')
@ -78,13 +80,21 @@ def get_wpa(this_play: Play, next_play: Play):
elif old_rd < -6: elif old_rd < -6:
old_rd = -6 old_rd = -6
new_win_ex = WPA_DF.loc[f'{next_play.inning_half}_{next_play.inning_num}_{next_play.starting_outs}_out_{next_play.on_base_code}_obc_{new_rd}_home_run_diff'].home_win_ex # print(f'get_wpa: new_rd = {new_rd} / old_rd = {old_rd}')
if (next_play.inning_num >= 9 and new_rd > 0 and next_play.inning_half == 'bot') or (next_play.inning_num > 9 and new_rd > 0 and next_play.is_new_inning):
# print(f'manually setting new_win_ex to 1.0')
new_win_ex = 1.0
else:
new_win_ex = WPA_DF.loc[f'{next_play.inning_half}_{next_play.inning_num}_{next_play.starting_outs}_out_{next_play.on_base_code}_obc_{new_rd}_home_run_diff'].home_win_ex
# print(f'new_win_ex = {new_win_ex}')
old_win_ex = WPA_DF.loc[f'{this_play.inning_half}_{this_play.inning_num}_{this_play.starting_outs}_out_{this_play.on_base_code}_obc_{old_rd}_home_run_diff'].home_win_ex old_win_ex = WPA_DF.loc[f'{this_play.inning_half}_{this_play.inning_num}_{this_play.starting_outs}_out_{this_play.on_base_code}_obc_{old_rd}_home_run_diff'].home_win_ex
# print(f'old_win_ex = {old_win_ex}')
wpa = round(new_win_ex - old_win_ex, 3) wpa = float(round(new_win_ex - old_win_ex, 3))
# print(f'final wpa: {wpa}')
if this_play.inning_half == 'top': if this_play.inning_half == 'top':
return wpa * -1 return wpa * -1.0
return wpa return wpa
@ -110,7 +120,7 @@ def complete_play(session:Session, this_play: Play):
opponent_play = get_last_team_play(session, this_play.game, this_play.pitcher.team) opponent_play = get_last_team_play(session, this_play.game, this_play.pitcher.team)
nbo = opponent_play.batting_order + 1 nbo = opponent_play.batting_order + 1
except PlayNotFoundException as e: except PlayNotFoundException as e:
logging.info(f'logic_gameplay - complete_play - No last play found for {this_play.pitcher.team.sname}, setting upcoming batting order to 1') logger.info(f'logic_gameplay - complete_play - No last play found for {this_play.pitcher.team.sname}, setting upcoming batting order to 1')
nbo = 1 nbo = 1
finally: finally:
new_batter_team = this_play.game.away_team if nih == 'top' else this_play.game.home_team new_batter_team = this_play.game.away_team if nih == 'top' else this_play.game.home_team
@ -149,14 +159,14 @@ def complete_play(session:Session, this_play: Play):
home_score = this_play.home_score home_score = this_play.home_score
if runs_scored > 0 and this_play.away_score <= this_play.home_score and away_score > home_score: if runs_scored > 0 and this_play.away_score <= this_play.home_score and away_score > home_score:
is_go_ahead = True this_play.is_go_ahead = True
else: else:
away_score = this_play.away_score away_score = this_play.away_score
home_score = this_play.home_score + runs_scored home_score = this_play.home_score + runs_scored
if runs_scored > 0 and this_play.home_score <= this_play.away_score and home_score > away_score: if runs_scored > 0 and this_play.home_score <= this_play.away_score and home_score > away_score:
is_go_ahead = True this_play.is_go_ahead = True
obc = get_obc(on_first, on_second, on_third) obc = get_obc(on_first, on_second, on_third)
@ -183,7 +193,6 @@ def complete_play(session:Session, this_play: Play):
catcher=get_one_lineup(session, this_play.game, new_pitcher_team, position='C'), catcher=get_one_lineup(session, this_play.game, new_pitcher_team, position='C'),
is_new_inning=switch_sides, is_new_inning=switch_sides,
is_tied=away_score == home_score, is_tied=away_score == home_score,
is_go_ahead=is_go_ahead,
on_first=on_first, on_first=on_first,
on_second=on_second, on_second=on_second,
on_third=on_third, on_third=on_third,
@ -203,13 +212,13 @@ def complete_play(session:Session, this_play: Play):
async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, this_team: Team, lineup_num: int, roster_num: int) -> list[Lineup]: async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, this_team: Team, lineup_num: int, roster_num: int) -> list[Lineup]:
logging.debug(f'sheets: {sheets}') logger.debug(f'sheets: {sheets}')
this_sheet = sheets.open_by_key(this_team.gsheet) this_sheet = sheets.open_by_key(this_team.gsheet)
logging.debug(f'this_sheet: {this_sheet}') logger.debug(f'this_sheet: {this_sheet}')
r_sheet = this_sheet.worksheet_by_title('My Rosters') r_sheet = this_sheet.worksheet_by_title('My Rosters')
logging.debug(f'r_sheet: {r_sheet}') logger.debug(f'r_sheet: {r_sheet}')
if lineup_num == 1: if lineup_num == 1:
row_start = 9 row_start = 9
@ -225,15 +234,15 @@ async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, thi
else: else:
l_range = f'L{row_start}:M{row_end}' l_range = f'L{row_start}:M{row_end}'
logging.debug(f'l_range: {l_range}') logger.debug(f'l_range: {l_range}')
raw_cells = r_sheet.range(l_range) raw_cells = r_sheet.range(l_range)
logging.debug(f'raw_cells: {raw_cells}') logger.debug(f'raw_cells: {raw_cells}')
try: try:
lineup_cells = [(row[0].value, int(row[1].value)) for row in raw_cells] lineup_cells = [(row[0].value, int(row[1].value)) for row in raw_cells]
logging.debug(f'lineup_cells: {lineup_cells}') logger.debug(f'lineup_cells: {lineup_cells}')
except ValueError as e: except ValueError as e:
logging.error(f'Could not pull roster for {this_team.abbrev}: {e}') logger.error(f'Could not pull roster for {this_team.abbrev}: {e}')
raise ValueError(f'Uh oh. Looks like your roster might not be saved. I am reading blanks when I try to get the card IDs') raise ValueError(f'Uh oh. Looks like your roster might not be saved. I am reading blanks when I try to get the card IDs')
all_lineups = [] all_lineups = []
@ -269,7 +278,7 @@ async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, thi
all_lineups.append(this_lineup) all_lineups.append(this_lineup)
legal_data = await legal_check([card_ids], difficulty_name=this_game.game_type) legal_data = await legal_check([card_ids], difficulty_name=this_game.game_type)
logging.debug(f'legal_data: {legal_data}') logger.debug(f'legal_data: {legal_data}')
if not legal_data['legal']: if not legal_data['legal']:
raise CardLegalityException(f'The following cards appear to be illegal for this game mode:\n{legal_data["error_string"]}') raise CardLegalityException(f'The following cards appear to be illegal for this game mode:\n{legal_data["error_string"]}')
@ -290,26 +299,26 @@ async def checks_log_interaction(session: Session, interaction: discord.Interact
owner_team = await get_team_or_none(session, gm_id=interaction.user.id) owner_team = await get_team_or_none(session, gm_id=interaction.user.id)
if owner_team is None: if owner_team is None:
logging.exception(f'{command_name} command: No team found for GM ID {interaction.user.id}') logger.exception(f'{command_name} command: No team found for GM ID {interaction.user.id}')
raise TeamNotFoundException(f'Do I know you? I cannot find your team.') raise TeamNotFoundException(f'Do I know you? I cannot find your team.')
if 'gauntlet' in this_game.game_type: if 'gauntlet' in this_game.game_type:
gauntlet_abbrev = f'Gauntlet-{owner_team.abbrev}' gauntlet_abbrev = f'Gauntlet-{owner_team.abbrev}'
owner_team = await get_team_or_none(session, team_abbrev=gauntlet_abbrev) owner_team = await get_team_or_none(session, team_abbrev=gauntlet_abbrev)
if owner_team is None: if owner_team is None:
logging.exception(f'{command_name} command: No gauntlet team found with abbrev {gauntlet_abbrev}') logger.exception(f'{command_name} command: No gauntlet team found with abbrev {gauntlet_abbrev}')
raise TeamNotFoundException(f'Hm, I was not able to find a gauntlet team for you.') raise TeamNotFoundException(f'Hm, I was not able to find a gauntlet team for you.')
if not owner_team.id in [this_game.away_team_id, this_game.home_team_id]: if not owner_team.id in [this_game.away_team_id, this_game.home_team_id]:
if interaction.user.id != 258104532423147520: if interaction.user.id != 258104532423147520:
logging.exception(f'{interaction.user.display_name} tried to run a command in Game {this_game.id} when they aren\'t a GM in the game.') logger.exception(f'{interaction.user.display_name} tried to run a command in Game {this_game.id} when they aren\'t a GM in the game.')
raise TeamNotFoundException('Bruh. Only GMs of the active teams can log plays.') raise TeamNotFoundException('Bruh. Only GMs of the active teams can log plays.')
else: else:
await interaction.channel.send(f'Cal is bypassing the GM check to run the {command_name} command') await interaction.channel.send(f'Cal is bypassing the GM check to run the {command_name} command')
this_play = this_game.current_play_or_none(session) this_play = this_game.current_play_or_none(session)
if this_play is None: if this_play is None:
logging.error(f'{command_name} command: No play found for Game ID {this_game.id} - attempting to initialize play') logger.error(f'{command_name} command: No play found for Game ID {this_game.id} - attempting to initialize play')
this_play = activate_last_play(session, this_game) this_play = activate_last_play(session, this_game)
this_play.locked = True this_play.locked = True
@ -346,6 +355,7 @@ def advance_runners(session: Session, this_play: Play, num_bases: int, is_error:
""" """
No commits No commits
""" """
logger.info(f'Advancing runners {num_bases} bases in game {this_play.game.id}')
this_play.rbi = 0 this_play.rbi = 0
if num_bases == 0: if num_bases == 0:
@ -362,8 +372,7 @@ def advance_runners(session: Session, this_play: Play, num_bases: int, is_error:
this_play.on_second_final = 2 this_play.on_second_final = 2
if this_play.on_third: if this_play.on_third:
this_play.on_third_final = 3 this_play.on_third_final = 3
return
if this_play.on_second: if this_play.on_second:
if this_play.on_third: if this_play.on_third:
if num_bases > 0: if num_bases > 0:
@ -433,7 +442,7 @@ async def show_outfield_cards(session: Session, interaction: discord.Interaction
cf = get_one_lineup(session, this_game=this_play.game, this_team=this_play.pitcher.team, position='CF') cf = get_one_lineup(session, this_game=this_play.game, this_team=this_play.pitcher.team, position='CF')
rf = get_one_lineup(session, this_game=this_play.game, this_team=this_play.pitcher.team, position='RF') rf = get_one_lineup(session, this_game=this_play.game, this_team=this_play.pitcher.team, position='RF')
this_team = this_play.pitcher.team this_team = this_play.pitcher.team
logging.debug(f'lf: {lf.player.name_with_desc}\n\ncf: {cf.player.name_with_desc}\n\nrf: {rf.player.name_with_desc}\n\nteam: {this_team.lname}') logger.debug(f'lf: {lf.player.name_with_desc}\n\ncf: {cf.player.name_with_desc}\n\nrf: {rf.player.name_with_desc}\n\nteam: {this_team.lname}')
view = Pagination([interaction.user], timeout=10) view = Pagination([interaction.user], timeout=10)
view.left_button.label = f'Left Fielder' view.left_button.label = f'Left Fielder'
@ -537,9 +546,9 @@ async def flyballs(session: Session, interaction: discord.Interaction, this_play
log_run_scored(session, this_play.on_third, this_play) log_run_scored(session, this_play.on_third, this_play)
if this_play.starting_outs < 2 and this_play.on_second: if this_play.starting_outs < 2 and this_play.on_second:
logging.debug(f'calling of embed') logger.debug(f'calling of embed')
await show_outfield_cards(session, interaction, this_play) await show_outfield_cards(session, interaction, this_play)
logging.debug(f'done with of embed') logger.debug(f'done with of embed')
runner = this_play.on_second.player runner = this_play.on_second.player
view = Confirm(responders=[interaction.user], timeout=60, label_type='yes') view = Confirm(responders=[interaction.user], timeout=60, label_type='yes')
@ -585,9 +594,9 @@ async def flyballs(session: Session, interaction: discord.Interaction, this_play
this_play.pa, this_play.ab, this_play.outs = 1, 1, 1 this_play.pa, this_play.ab, this_play.outs = 1, 1, 1
if this_play.starting_outs < 2 and this_play.on_third: if this_play.starting_outs < 2 and this_play.on_third:
logging.debug(f'calling of embed') logger.debug(f'calling of embed')
await show_outfield_cards(session, interaction, this_play) await show_outfield_cards(session, interaction, this_play)
logging.debug(f'done with of embed') logger.debug(f'done with of embed')
runner = this_play.on_second.player runner = this_play.on_second.player
view = Confirm(responders=[interaction.user], timeout=60, label_type='yes') view = Confirm(responders=[interaction.user], timeout=60, label_type='yes')
@ -641,7 +650,7 @@ async def flyballs(session: Session, interaction: discord.Interaction, this_play
async def check_uncapped_advance(session: Session, interaction: discord.Interaction, this_play: Play, lead_runner: Lineup, lead_base: int, trail_runner: Lineup, trail_base: int): async def check_uncapped_advance(session: Session, interaction: discord.Interaction, this_play: Play, lead_runner: Lineup, lead_base: int, trail_runner: Lineup, trail_base: int):
this_game = this_play.game this_game = this_play.game
outfielder = await show_outfield_cards(session, interaction, this_play) outfielder = await show_outfield_cards(session, interaction, this_play)
logging.info(f'throw from {outfielder.player.name_with_desc}') logger.info(f'throw from {outfielder.player.name_with_desc}')
def_team = this_play.pitcher.team def_team = this_play.pitcher.team
TO_BASE = { TO_BASE = {
2: 'to second', 2: 'to second',
@ -666,7 +675,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
throw_resp = None throw_resp = None
if this_game.ai_team: if this_game.ai_team:
throw_resp = this_play.managerai.throw_at_uncapped(session, this_game) throw_resp = this_play.managerai.throw_at_uncapped(session, this_game)
logging.info(f'throw_resp: {throw_resp}') logger.info(f'throw_resp: {throw_resp}')
if throw_resp.cutoff: if throw_resp.cutoff:
await interaction.channel.send(f'The {def_team.sname} will cut off the throw {TO_BASE[lead_base]}') await interaction.channel.send(f'The {def_team.sname} will cut off the throw {TO_BASE[lead_base]}')
@ -791,18 +800,18 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
# Lead runner is thrown out # Lead runner is thrown out
if runner_thrown_out: if runner_thrown_out:
logging.info(f'Lead runner is thrown out.') logger.info(f'Lead runner is thrown out.')
this_play.outs += 1 this_play.outs += 1
# Lead runner is safe # Lead runner is safe
else: else:
logging.info(f'Lead runner is safe.') logger.info(f'Lead runner is safe.')
if this_play.on_second == lead_runner: if this_play.on_second == lead_runner:
logging.info(f'setting lead runner on_second_final') logger.info(f'setting lead runner on_second_final')
this_play.on_second_final = None if runner_thrown_out else lead_base this_play.on_second_final = None if runner_thrown_out else lead_base
elif this_play.on_first == lead_runner: elif this_play.on_first == lead_runner:
logging.info(f'setting lead runner on_first') logger.info(f'setting lead runner on_first')
this_play.on_first_final = None if runner_thrown_out else lead_base this_play.on_first_final = None if runner_thrown_out else lead_base
else: else:
log_exception(LineupsMissingException, f'Could not find lead runner to set final destination') log_exception(LineupsMissingException, f'Could not find lead runner to set final destination')
@ -904,14 +913,14 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
# Lead runner is thrown out # Lead runner is thrown out
if is_lead_out: if is_lead_out:
logging.info(f'Lead runner is thrown out.') logger.info(f'Lead runner is thrown out.')
this_play.outs += 1 this_play.outs += 1
if this_play.on_second == lead_runner: if this_play.on_second == lead_runner:
logging.info(f'setting lead runner on_second_final') logger.info(f'setting lead runner on_second_final')
this_play.on_second_final = None if is_lead_out else lead_base this_play.on_second_final = None if is_lead_out else lead_base
elif this_play.on_first == lead_runner: elif this_play.on_first == lead_runner:
logging.info(f'setting lead runner on_first') logger.info(f'setting lead runner on_first')
this_play.on_first_final = None if is_lead_out else lead_base this_play.on_first_final = None if is_lead_out else lead_base
else: else:
log_exception(LineupsMissingException, f'Could not find lead runner to set final destination') log_exception(LineupsMissingException, f'Could not find lead runner to set final destination')
@ -1003,9 +1012,10 @@ async def triples(session: Session, interaction: discord.Interaction, this_play:
async def homeruns(session: Session, interaction: discord.Interaction, this_play: Play, homerun_type: Literal['ballpark', 'no-doubt']): async def homeruns(session: Session, interaction: discord.Interaction, this_play: Play, homerun_type: Literal['ballpark', 'no-doubt']):
this_play.hit, this_play.homerun, this_play.batter_final, this_play.rbi, this_play.run = 1, 1, 4, 1, 1 this_play.hit, this_play.homerun, this_play.batter_final, this_play.run = 1, 1, 4, 1
this_play.bphr = 1 if homerun_type == 'ballpark' else 0 this_play.bphr = 1 if homerun_type == 'ballpark' else 0
this_play = advance_runners(session, this_play, num_bases=4) this_play = advance_runners(session, this_play, num_bases=4)
this_play.rbi += 1
session.add(this_play) session.add(this_play)
session.commit() session.commit()
@ -1098,16 +1108,16 @@ def undo_play(session: Session, this_play: Play):
session.add(last_pa) session.add(last_pa)
last_two_ids = [last_two_plays[0].id, last_two_plays[1].id] last_two_ids = [last_two_plays[0].id, last_two_plays[1].id]
logging.warning(f'Deleting plays: {last_two_ids}') logger.warning(f'Deleting plays: {last_two_ids}')
session.exec(delete(Play).where(Play.id.in_(last_two_ids))) session.exec(delete(Play).where(Play.id.in_(last_two_ids)))
session.commit() session.commit()
try: try:
this_play = this_game.initialize_play(session) this_play = this_game.initialize_play(session)
logging.info(f'Initialized play: {this_play.id}') logger.info(f'Initialized play: {this_play.id}')
except PlayInitException: except PlayInitException:
this_play = activate_last_play(session, this_game) this_play = activate_last_play(session, this_game)
logging.info(f'Re-activated play: {this_play.id}') logger.info(f'Re-activated play: {this_play.id}')
return this_play return this_play
@ -1149,4 +1159,304 @@ async def show_defense_cards(session: Session, interaction: discord.Interaction,
await interaction.edit_original_response(content=None, embed=player_embed, view=dropdown_view) await interaction.edit_original_response(content=None, embed=player_embed, view=dropdown_view)
def is_game_over(this_play: Play) -> bool:
print(f'1: ')
if this_play.inning_num < 9 and (abs(this_play.away_score - this_play.home_score) < 10):
return False
if abs(this_play.away_score - this_play.home_score) >= 10:
if ((this_play.home_score - this_play.away_score) >= 10) and this_play.inning_half == 'bot':
return True
elif ((this_play.away_score - this_play.home_score) >= 10) and this_play.is_new_inning and this_play.inning_half == 'top':
return True
if this_play.inning_num > 9 and this_play.inning_half == 'top' and this_play.is_new_inning and this_play.home_score != this_play.away_score:
return True
if this_play.inning_num >= 9 and this_play.inning_half == 'bot' and this_play.home_score > this_play.away_score:
return True
return False
async def get_game_summary_embed(session: Session, interaction: discord.Interaction, this_play: Play, db_game_id: int, winning_team: Team, losing_team: Team, num_potg: int = 1, num_poop: int = 0):
game_summary = await db_get(f'plays/game-summary/{db_game_id}', params=[('tp_max', num_potg)])
this_game = this_play.game
game_embed = winning_team.embed
game_embed.title = f'{this_game.away_team.lname} {this_play.away_score} @ {this_play.home_score} {this_game.home_team.lname} - F/{this_play.inning_num}'
game_embed.add_field(
name='Location',
value=f'{interaction.guild.get_channel(this_game.channel_id).mention}'
)
game_embed.add_field(name='Game ID', value=f'{db_game_id}')
if this_game.game_type == 'major-league':
game_des = 'Major League'
elif this_game.game_type == 'minor-league':
game_des = 'Minor League'
elif this_game.game_type == 'hall-of-fame':
game_des = 'Hall of Fame'
elif this_game.game_type == 'flashback':
game_des = 'Flashback'
elif this_game.ranked:
game_des = 'Ranked'
elif 'gauntlet' in this_game.game_type:
game_des = 'Gauntlet'
else:
game_des = 'Unlimited'
game_embed.description = f'Score Report - {game_des}'
game_embed.add_field(
name='Box Score',
value=f'```\n'
f'Team | R | H | E |\n'
f'{this_game.away_team.abbrev.replace("Gauntlet-", ""): <4} | {game_summary["runs"]["away"]: >2} | '
f'{game_summary["hits"]["away"]: >2} | {game_summary["errors"]["away"]: >2} |\n'
f'{this_game.home_team.abbrev.replace("Gauntlet-", ""): <4} | {game_summary["runs"]["home"]: >2} | '
f'{game_summary["hits"]["home"]: >2} | {game_summary["errors"]["home"]: >2} |\n'
f'\n```',
inline=False
)
logger.info(f'getting top players string')
potg_string = ''
for tp in game_summary['top-players']:
player_name = f'{get_player_name_from_dict(tp['player'])}'
potg_line = f'{player_name} - '
if 'hr' in tp:
potg_line += f'{tp["hit"]}-{tp["ab"]}'
if tp['hr'] > 0:
num = f'{tp["hr"]} ' if tp["hr"] > 1 else ""
potg_line += f', {num}HR'
if tp['triple'] > 0:
num = f'{tp["triple"]} ' if tp["triple"] > 1 else ""
potg_line += f', {num}3B'
if tp['double'] > 0:
num = f'{tp["double"]} ' if tp["double"] > 1 else ""
potg_line += f', {num}2B'
if tp['run'] > 0:
potg_line += f', {tp["run"]} R'
if tp['rbi'] > 0:
potg_line += f', {tp["rbi"]} RBI'
else:
potg_line = f'{player_name} - {tp["ip"]} IP, {tp["run"]} R'
if tp['run'] != tp['e_run']:
potg_line += f' ({tp["e_run"]} ER)'
potg_line += f', {tp["hit"]} H, {tp["so"]} K'
potg_line += f', {tp["re24"]:.2f} re24\n'
potg_string += potg_line
game_embed.add_field(
name='Players of the Game',
value=potg_string,
inline=False
)
pit_string = f'Win: {game_summary["pitchers"]["win"]["p_name"]}\nLoss: {game_summary["pitchers"]["loss"]["p_name"]}\n'
hold_string = None
for player in game_summary['pitchers']['holds']:
player_name = f'{get_player_name_from_dict(player)}'
if hold_string is None:
hold_string = f'Holds: {player_name}'
else:
hold_string += f', {player_name}'
if hold_string is not None:
pit_string += f'{hold_string}\n'
if game_summary['pitchers']['save'] is not None:
player_name = f'{get_player_name_from_dict(game_summary["pitchers"]["save"])}'
pit_string += f'Save: {player_name}'
game_embed.add_field(
name=f'Pitching',
value=pit_string,
)
def name_list(raw_list: list) -> str:
logger.info(f'raw_list: {raw_list}')
player_dict = {}
for x in raw_list:
if x['player_id'] not in player_dict:
player_dict[x['player_id']] = x
data_dict = {}
for x in raw_list:
if x['player_id'] not in data_dict:
data_dict[x['player_id']] = 1
else:
data_dict[x['player_id']] += 1
r_string = ''
logger.info(f'players: {player_dict} / data: {data_dict}')
first = True
for p_id in data_dict:
r_string += f'{", " if not first else ""}{player_dict[p_id]["p_name"]}'
if data_dict[p_id] > 1:
r_string += f' {data_dict[p_id]}'
first = False
return r_string
logger.info(f'getting running string')
if len(game_summary['running']['sb']) + len(game_summary['running']['csc']) > 0:
run_string = ''
if len(game_summary['running']['sb']) > 0:
run_string += f'SB: {name_list(game_summary["running"]["sb"])}\n'
if len(game_summary['running']['csc']) > 0:
run_string += f'CSc: {name_list(game_summary["running"]["csc"])}'
game_embed.add_field(
name=f'Baserunning',
value=run_string
)
logger.info(f'getting xbh string')
if len(game_summary['xbh']['2b']) + len(game_summary['xbh']['3b']) + len(game_summary['xbh']['hr']) > 0:
bat_string = ''
if len(game_summary['xbh']['2b']) > 0:
bat_string += f'2B: {name_list(game_summary["xbh"]["2b"])}\n'
if len(game_summary['xbh']['3b']) > 0:
bat_string += f'3B: {name_list(game_summary["xbh"]["3b"])}\n'
if len(game_summary['xbh']['hr']) > 0:
bat_string += f'HR: {name_list(game_summary["xbh"]["hr"])}\n'
else:
bat_string = 'Oops! All bitches! No XBH from either team.'
game_embed.add_field(
name='Batting',
value=bat_string,
inline=False
)
return game_embed
async def complete_game(session: Session, interaction: discord.Interaction, this_play: Play):
# if interaction is not None:
# salutation = await interaction.channel.send('GGs, I\'ll tally this game up...')
# Add button with {winning_team} wins! and another with "Roll Back"
this_game = this_play.game
async def roll_back(db_game_id: int, game: bool = True, plays: bool = False, decisions: bool = False):
if decisions:
try:
await db_delete('decisions/game', object_id=db_game_id)
except DatabaseError as e:
logger.warning(f'Could not delete decisions for game {db_game_id}: {e}')
if plays:
try:
await db_delete('plays/game', object_id=db_game_id)
except DatabaseError as e:
logger.warning(f'Could not delete plays for game {db_game_id}: {e}')
if game:
try:
await db_delete('games', object_id=db_game_id)
except DatabaseError as e:
logger.warning(f'Could not delete game {db_game_id}: {e}')
# Post completed game to API
game_data = this_game.model_dump()
game_data['home_team_ranking'] = this_game.home_team.ranking
game_data['away_team_ranking'] = this_game.away_team.ranking
game_data['home_team_value'] = this_game.home_team.team_value
game_data['away_team_value'] = this_game.away_team.team_value
game_data['away_score'] = this_play.away_score
game_data['home_score'] = this_play.home_score
winning_team = this_game.home_team if this_play.home_score > this_play.away_score else this_game.away_team
losing_team = this_game.home_team if this_play.away_score > this_play.home_score else this_game.away_team
try:
db_game = await db_post('games', payload=game_data)
db_ready_plays = get_db_ready_plays(session, this_game, db_game['id'])
db_ready_decisions = get_db_ready_decisions(session, this_game, db_game['id'])
except Exception as e:
await roll_back(db_game['id'])
log_exception(e, msg='Unable to post game to API, rolling back')
# Post game stats to API
try:
resp = await db_post('plays', payload=db_ready_plays)
except Exception as e:
await roll_back(db_game['id'], plays=True)
log_exception(e, msg='Unable to post plays to API, rolling back')
if len(resp) > 0:
pass
try:
resp = await db_post('decisions', payload={'decisions': db_ready_decisions})
except Exception as e:
await roll_back(db_game['id'], plays=True, decisions=True)
log_exception(e, msg='Unable to post decisions to API, rolling back')
if len(resp) > 0:
pass
# Post game rewards (gauntlet and main team)
try:
win_reward, loss_reward = await post_game_rewards(
session,
winning_team=winning_team,
losing_team=losing_team,
this_game=this_game
)
except Exception as e:
await roll_back(db_game['id'], plays=True, decisions=True)
log_exception(e, msg='Error while posting game rewards')
session.delete(this_play)
session.commit()
# Pull game summary for embed
summary_embed = await get_game_summary_embed(
session,
interaction,
this_play,
db_game['id'],
winning_team=winning_team,
losing_team=losing_team,
num_potg=3,
num_poop=1
)
summary_embed.add_field(
name=f'{winning_team.abbrev} Rewards',
value=win_reward
)
summary_embed.add_field(
name=f'{losing_team.abbrev} Rewards',
value=loss_reward
)
summary_embed.add_field(
name='Highlights',
value=f'Please share the highlights in {get_channel(interaction, "pd-news-ticker").mention}!',
inline=False
)
# Create and post game summary to game channel and pd-network-news
news_ticker = get_channel(interaction, 'pd-network-news')
if news_ticker is not None:
await news_ticker.send(content=None, embed=summary_embed)
await interaction.channel.send(content=None, embed=summary_embed)
await interaction.edit_original_response(content=None, embed=summary_embed)
game_id = this_game.id
this_game.active = False
session.add(this_game)
session.commit()
logger.info(f'Just ended game {game_id}')

View File

@ -24,6 +24,7 @@ db = SqliteDatabase(
} }
) )
SBA_DB_URL = 'http://database/api' SBA_DB_URL = 'http://database/api'
logger = logging.getLogger('discord_app')
def param_char(other_params): def param_char(other_params):
@ -43,7 +44,7 @@ def get_sba_team(id_or_abbrev, season=None):
if resp.status_code == 200: if resp.status_code == 200:
return resp.json() return resp.json()
else: else:
logging.warning(resp.text) logger.warning(resp.text)
raise ValueError(f'DB: {resp.text}') raise ValueError(f'DB: {resp.text}')
@ -56,7 +57,7 @@ def get_sba_player(id_or_name, season=None):
if resp.status_code == 200: if resp.status_code == 200:
return resp.json() return resp.json()
else: else:
logging.warning(resp.text) logger.warning(resp.text)
raise ValueError(f'DB: {resp.text}') raise ValueError(f'DB: {resp.text}')
@ -69,25 +70,25 @@ def get_sba_team_by_owner(season, owner_id):
else: else:
return full_resp['teams'][0] return full_resp['teams'][0]
else: else:
logging.warning(resp.text) logger.warning(resp.text)
raise ValueError(f'DB: {resp.text}') raise ValueError(f'DB: {resp.text}')
# def pd_await db_get(endpoint: str, api_ver: int = 1, object_id: int = None, params: list = None, none_okay: bool = True): # def pd_await db_get(endpoint: str, api_ver: int = 1, object_id: int = None, params: list = None, none_okay: bool = True):
# req_url = pd_get_req_url(endpoint, api_ver=api_ver, object_id=object_id, params=params) # req_url = pd_get_req_url(endpoint, api_ver=api_ver, object_id=object_id, params=params)
# logging.info(f'get:\n{endpoint} id: {object_id} params: {params}') # logger.info(f'get:\n{endpoint} id: {object_id} params: {params}')
# #
# resp = requests.get(req_url, timeout=3) # resp = requests.get(req_url, timeout=3)
# if resp.status_code == 200: # if resp.status_code == 200:
# data = resp.json() # data = resp.json()
# logging.info(f'return: {data}') # logger.info(f'return: {data}')
# return data # return data
# elif none_okay: # elif none_okay:
# data = resp.json() # data = resp.json()
# logging.info(f'return: {data}') # logger.info(f'return: {data}')
# return None # return None
# else: # else:
# logging.warning(resp.text) # logger.warning(resp.text)
# raise ValueError(f'DB: {resp.text}') # raise ValueError(f'DB: {resp.text}')
@ -100,10 +101,10 @@ def get_sba_team_by_owner(season, owner_id):
# # resp = requests.get(req_url, timeout=3) # # resp = requests.get(req_url, timeout=3)
# # if resp.status_code == 200: # # if resp.status_code == 200:
# # data = resp.json() # # data = resp.json()
# # logging.info(f'return: {data}') # # logger.info(f'return: {data}')
# # return data['teams'][0] # # return data['teams'][0]
# # else: # # else:
# # logging.warning(resp.text) # # logger.warning(resp.text)
# # raise ValueError(f'PD DB: {resp.text}') # # raise ValueError(f'PD DB: {resp.text}')
@ -293,7 +294,7 @@ async def get_game_team(
if not gm_id and not team_abbrev and not team_id: if not gm_id and not team_abbrev and not team_id:
raise KeyError(f'get_game_team requires either one of gm_id, team_abbrev, or team_id to not be None') raise KeyError(f'get_game_team requires either one of gm_id, team_abbrev, or team_id to not be None')
logging.debug(f'getting game team for game {game.id} / gm_id: {gm_id} / ' logger.debug(f'getting game team for game {game.id} / gm_id: {gm_id} / '
f'tm_abbrev: {team_abbrev} / team_id: {team_id} / game: {game}') f'tm_abbrev: {team_abbrev} / team_id: {team_id} / game: {game}')
if game.is_pd: if game.is_pd:
if team_id: if team_id:
@ -430,7 +431,7 @@ def get_one_lineup(
Lineup.game_id == game_id, Lineup.team_id == team_id, Lineup.position == position, Lineup.game_id == game_id, Lineup.team_id == team_id, Lineup.position == position,
Lineup.active == active Lineup.active == active
) )
logging.debug(f'get_one_lineup / this_lineup: {this_lineup}') logger.debug(f'get_one_lineup / this_lineup: {this_lineup}')
if as_obj: if as_obj:
return this_lineup return this_lineup
@ -538,7 +539,7 @@ def make_sub(lineup_dict: dict):
Lineup.game_id == lineup_dict['game_id'], Lineup.team_id == lineup_dict['team_id'], Lineup.game_id == lineup_dict['game_id'], Lineup.team_id == lineup_dict['team_id'],
Lineup.batting_order == lineup_dict['batting_order'], Lineup.active == True Lineup.batting_order == lineup_dict['batting_order'], Lineup.active == True
) )
logging.debug(f'subbed_player: {subbed_player}') logger.debug(f'subbed_player: {subbed_player}')
if subbed_player: if subbed_player:
subbed_player = patch_lineup(subbed_player.id, active=False) subbed_player = patch_lineup(subbed_player.id, active=False)
@ -549,7 +550,7 @@ def make_sub(lineup_dict: dict):
return_value = convert_stratlineup(new_lineup) return_value = convert_stratlineup(new_lineup)
curr_play = get_current_play(lineup_dict['game_id']) curr_play = get_current_play(lineup_dict['game_id'])
logging.debug(f'\n\nreturn_value: {return_value}\n\ncurr_play: {curr_play}\n\n') logger.debug(f'\n\nreturn_value: {return_value}\n\ncurr_play: {curr_play}\n\n')
# Check current play for updates # Check current play for updates
if curr_play: if curr_play:
@ -576,19 +577,19 @@ def make_sub(lineup_dict: dict):
def undo_subs(game: StratGame, new_play_num: int): def undo_subs(game: StratGame, new_play_num: int):
logging.info(f'get new players') logger.info(f'get new players')
new_players = Lineup.select().where((Lineup.game_id == game.id) & (Lineup.after_play > new_play_num)) new_players = Lineup.select().where((Lineup.game_id == game.id) & (Lineup.after_play > new_play_num))
logging.info(f'new_player count: {new_players.count()}') logger.info(f'new_player count: {new_players.count()}')
replacements = [(x.id, x.replacing_id) for x in new_players] replacements = [(x.id, x.replacing_id) for x in new_players]
for x in replacements: for x in replacements:
logging.info(f'replacing {x[0]} with {x[1]}') logger.info(f'replacing {x[0]} with {x[1]}')
old_player = get_one_lineup(game_id=game.id, lineup_id=x[1]) old_player = get_one_lineup(game_id=game.id, lineup_id=x[1])
logging.info(f'old_player: {old_player}') logger.info(f'old_player: {old_player}')
patch_lineup(old_player.id, active=True) patch_lineup(old_player.id, active=True)
logging.info(f'activated!') logger.info(f'activated!')
logging.info(f'done activating old players') logger.info(f'done activating old players')
Lineup.delete().where((Lineup.game_id == game.id) & (Lineup.after_play > new_play_num)).execute() Lineup.delete().where((Lineup.game_id == game.id) & (Lineup.after_play > new_play_num)).execute()
@ -613,7 +614,7 @@ async def get_player(game, lineup_member, as_dict: bool = True):
player = this_card['player'] player = this_card['player']
player['name'] = player['p_name'] player['name'] = player['p_name']
player['team'] = this_card['team'] player['team'] = this_card['team']
logging.debug(f'player: {player}') logger.debug(f'player: {player}')
return player return player
else: else:
return get_sba_player(lineup_member.player_id) return get_sba_player(lineup_member.player_id)
@ -802,7 +803,7 @@ db.create_tables([Play])
def post_play(play_dict: dict) -> StratPlay: def post_play(play_dict: dict) -> StratPlay:
logging.debug(f'play_dict: {play_dict}') logger.debug(f'play_dict: {play_dict}')
new_play = Play.create(**play_dict) new_play = Play.create(**play_dict)
# return_play = model_to_dict(new_play) # return_play = model_to_dict(new_play)
return_play = convert_stratplay(new_play) return_play = convert_stratplay(new_play)
@ -994,7 +995,7 @@ def get_latest_play(game_id):
def undo_play(game_id): def undo_play(game_id):
p_query = Play.delete().where(Play.game_id == game_id).order_by(-Play.id).limit(1) p_query = Play.delete().where(Play.game_id == game_id).order_by(-Play.id).limit(1)
logging.debug(f'p_query: {p_query}') logger.debug(f'p_query: {p_query}')
count = p_query.execute() count = p_query.execute()
db.close() db.close()
@ -1035,7 +1036,7 @@ def add_run_last_player_ab(lineup: Lineup, is_erun: bool = True):
try: try:
last_ab = Play.select().where(Play.batter == lineup).order_by(-Play.id).get() last_ab = Play.select().where(Play.batter == lineup).order_by(-Play.id).get()
except DoesNotExist as e: except DoesNotExist as e:
logging.error(f'Unable to apply run to Lineup {lineup}') logger.error(f'Unable to apply run to Lineup {lineup}')
else: else:
last_ab.run = 1 last_ab.run = 1
last_ab.e_run = 1 if is_erun else 0 last_ab.e_run = 1 if is_erun else 0
@ -1066,7 +1067,7 @@ def get_dbready_plays(game_id: int, db_game_id: int):
x['game_id'] = db_game_id x['game_id'] = db_game_id
x['on_base_code'] = obc_list[x['on_base_code']] x['on_base_code'] = obc_list[x['on_base_code']]
logging.debug(f'all_plays:\n\n{prep_plays}\n') logger.debug(f'all_plays:\n\n{prep_plays}\n')
return prep_plays return prep_plays
@ -1114,7 +1115,7 @@ def get_or_create_bullpen(ai_team, bot):
if this_pen: if this_pen:
return convert_bullpen_to_strat(this_pen) return convert_bullpen_to_strat(this_pen)
three_days_ago = int(datetime.datetime.timestamp(datetime.datetime.now() - datetime.timedelta(days=3))) * 1000 three_days_ago = int(datetime.datetime.timestamp(datetime.datetime.now() - datetime.timedelta(days=3))) * 1000
logging.debug(f'3da: {three_days_ago} / last_up: {this_pen.last_updated} / L > 3: ' logger.debug(f'3da: {three_days_ago} / last_up: {this_pen.last_updated} / L > 3: '
f'{this_pen.last_updated > three_days_ago}') f'{this_pen.last_updated > three_days_ago}')
if this_pen and this_pen.last_updated > three_days_ago: if this_pen and this_pen.last_updated > three_days_ago:
@ -1128,7 +1129,7 @@ def get_or_create_bullpen(ai_team, bot):
bullpen_range = f'N30:N41' bullpen_range = f'N30:N41'
raw_cells = r_sheet.range(bullpen_range) raw_cells = r_sheet.range(bullpen_range)
logging.debug(f'raw_cells: {raw_cells}') logger.debug(f'raw_cells: {raw_cells}')
bullpen = Bullpen( bullpen = Bullpen(
ai_team_id=ai_team['id'], ai_team_id=ai_team['id'],
@ -1144,7 +1145,7 @@ def get_or_create_bullpen(ai_team, bot):
last_updated=int(datetime.datetime.timestamp(datetime.datetime.now())*1000) last_updated=int(datetime.datetime.timestamp(datetime.datetime.now())*1000)
) )
bullpen.save() bullpen.save()
logging.debug(f'bullpen: {bullpen}') logger.debug(f'bullpen: {bullpen}')
return convert_bullpen_to_strat(bullpen) return convert_bullpen_to_strat(bullpen)
@ -1271,7 +1272,7 @@ def complete_play(play_id, batter_to_base: int = None):
this_play.complete = True this_play.complete = True
this_play.save() this_play.save()
logging.debug(f'starting the inning calc') logger.debug(f'starting the inning calc')
new_inning_half = this_play.inning_half new_inning_half = this_play.inning_half
new_inning_num = this_play.inning_num new_inning_num = this_play.inning_num
if this_play.runner or this_play.wild_pitch or this_play.passed_ball or this_play.pick_off or this_play.balk: if this_play.runner or this_play.wild_pitch or this_play.passed_ball or this_play.pick_off or this_play.balk:
@ -1286,7 +1287,7 @@ def complete_play(play_id, batter_to_base: int = None):
new_on_third = None new_on_third = None
# score_increment = this_play.homerun # score_increment = this_play.homerun
# patch to handle little league home runs TODO: standardize on just _on_final for these # patch to handle little league home runs TODO: standardize on just _on_final for these
logging.debug(f'complete_play - this_play: {this_play}') logger.debug(f'complete_play - this_play: {this_play}')
if this_play.batter_final == 4 or batter_to_base == 4: if this_play.batter_final == 4 or batter_to_base == 4:
this_play.run = 1 this_play.run = 1
score_increment = 1 score_increment = 1
@ -1294,7 +1295,7 @@ def complete_play(play_id, batter_to_base: int = None):
this_play.e_run = 1 this_play.e_run = 1
else: else:
score_increment = 0 score_increment = 0
logging.debug(f'complete_play - score_increment: {score_increment}') logger.debug(f'complete_play - score_increment: {score_increment}')
if this_play.on_first_final == 99: if this_play.on_first_final == 99:
this_play.on_first_final = None this_play.on_first_final = None
@ -1343,7 +1344,7 @@ def complete_play(play_id, batter_to_base: int = None):
new_batting_order = 1 new_batting_order = 1
# Not an inning-ending play # Not an inning-ending play
else: else:
logging.debug(f'starting the obc calc') logger.debug(f'starting the obc calc')
bases_occ = [False, False, False, False] bases_occ = [False, False, False, False]
# Set the occupied bases for the next play and lineup member occupying it # Set the occupied bases for the next play and lineup member occupying it
@ -1407,22 +1408,22 @@ def complete_play(play_id, batter_to_base: int = None):
# A team score # A team score
if score_increment: if score_increment:
logging.debug(f'complete_play: \n\nscore_increment: {score_increment}\n\nnew home score: {new_home_score}\n\n' logger.debug(f'complete_play: \n\nscore_increment: {score_increment}\n\nnew home score: {new_home_score}\n\n'
f'new_away_score: {new_away_score}\n\nthis_play.away_score: {this_play.away_score}\n\n' f'new_away_score: {new_away_score}\n\nthis_play.away_score: {this_play.away_score}\n\n'
f'this_player.home_score: {this_play.home_score}') f'this_player.home_score: {this_play.home_score}')
# Game is now tied # Game is now tied
if new_home_score == new_away_score: if new_home_score == new_away_score:
logging.debug(f'\n\nGame {this_play.game} is now tied\n\n') logger.debug(f'\n\nGame {this_play.game} is now tied\n\n')
this_play.is_tied = 1 this_play.is_tied = 1
# One team took the lead # One team took the lead
elif (this_play.away_score <= this_play.home_score) and (new_away_score > new_home_score): elif (this_play.away_score <= this_play.home_score) and (new_away_score > new_home_score):
logging.debug(f'\n\nTeam {this_play.batter.team_id} took the lead\n\n') logger.debug(f'\n\nTeam {this_play.batter.team_id} took the lead\n\n')
this_play.is_go_ahead = 1 this_play.is_go_ahead = 1
this_play.save() this_play.save()
elif (this_play.home_score <= this_play.away_score) and (new_home_score > new_away_score): elif (this_play.home_score <= this_play.away_score) and (new_home_score > new_away_score):
logging.debug(f'\n\nteam {this_play.batter.team_id} took the lead\n\n') logger.debug(f'\n\nteam {this_play.batter.team_id} took the lead\n\n')
this_play.is_go_ahead = 1 this_play.is_go_ahead = 1
this_play.save() this_play.save()
@ -1447,7 +1448,7 @@ def complete_play(play_id, batter_to_base: int = None):
pitcher = get_one_lineup(this_play.game_id, team_id=new_pteam_id, position='P') pitcher = get_one_lineup(this_play.game_id, team_id=new_pteam_id, position='P')
pitcher_id = pitcher.id if pitcher else None pitcher_id = pitcher.id if pitcher else None
logging.debug(f'done the obc calc') logger.debug(f'done the obc calc')
next_play = Play.create(**{ next_play = Play.create(**{
'game_id': this_play.game.id, 'game_id': this_play.game.id,
'play_num': this_play.play_num + 1, 'play_num': this_play.play_num + 1,
@ -1653,7 +1654,7 @@ def get_fielding_stats(game_id, lineup_id: int = None, team_id: int = None):
'pl_csc': x.pl_csc 'pl_csc': x.pl_csc
}) })
logging.debug(f'fielding_stats: {all_stats}') logger.debug(f'fielding_stats: {all_stats}')
db.close() db.close()
return all_stats return all_stats
@ -1710,7 +1711,7 @@ def get_fielding_stats(game_id, lineup_id: int = None, team_id: int = None):
# 'pl_bplo': x.pl_bplo, # 'pl_bplo': x.pl_bplo,
# }) # })
# done_batters.append(x.batter.id) # done_batters.append(x.batter.id)
# logging.info(f'batting stats: {return_stats}') # logger.info(f'batting stats: {return_stats}')
# #
# elif team_id is not None: # elif team_id is not None:
# batting_stats = Play.select( # batting_stats = Play.select(
@ -1735,7 +1736,7 @@ def get_fielding_stats(game_id, lineup_id: int = None, team_id: int = None):
# fn.SUM(Play.bplo).over(partition_by=[Play.batter.team_id]).alias('tm_bplo') # fn.SUM(Play.bplo).over(partition_by=[Play.batter.team_id]).alias('tm_bplo')
# ).join(Lineup, on=Play.batter).where((Play.game_id == game_id) & (Play.batter.team_id == team_id)) # ).join(Lineup, on=Play.batter).where((Play.game_id == game_id) & (Play.batter.team_id == team_id))
# #
# logging.info(f'batting_stats count: {batting_stats.count()}') # logger.info(f'batting_stats count: {batting_stats.count()}')
# done_batters = [] # done_batters = []
# for x in batting_stats: # for x in batting_stats:
# if x.batter.id not in done_batters: # if x.batter.id not in done_batters:
@ -1773,7 +1774,7 @@ def get_fielding_stats(game_id, lineup_id: int = None, team_id: int = None):
# team_lineups = Lineup.select().where( # team_lineups = Lineup.select().where(
# (Lineup.game_id == game_id) & (Lineup.team_id == team_id) & (Lineup.batting_order < 10) # (Lineup.game_id == game_id) & (Lineup.team_id == team_id) & (Lineup.batting_order < 10)
# ).order_by(Lineup.batting_order) # ).order_by(Lineup.batting_order)
# logging.info(f'team_lineups count: {team_lineups.count()} / lineups: {team_lineups}') # logger.info(f'team_lineups count: {team_lineups.count()} / lineups: {team_lineups}')
# #
# all_stats = [] # all_stats = []
# for line in team_lineups: # for line in team_lineups:
@ -1786,7 +1787,7 @@ def get_pitching_stats(
game_id, lineup_id: int = None, team_id: int = None, in_pow: bool = None, in_innings: list = None): game_id, lineup_id: int = None, team_id: int = None, in_pow: bool = None, in_innings: list = None):
if in_innings is None: if in_innings is None:
in_innings = [x for x in range(1, 30)] in_innings = [x for x in range(1, 30)]
logging.info(f'db_calls_gameplay - get_pitching_stats - in_innings: {in_innings}') logger.info(f'db_calls_gameplay - get_pitching_stats - in_innings: {in_innings}')
pitching_stats = Play.select( pitching_stats = Play.select(
Play.pitcher, Play.pitcher,
fn.SUM(Play.outs).over(partition_by=[Play.pitcher_id]).alias('pl_outs'), fn.SUM(Play.outs).over(partition_by=[Play.pitcher_id]).alias('pl_outs'),
@ -1830,14 +1831,14 @@ def get_pitching_stats(
fn.SUM(Play.balk).over(partition_by=[Play.pitcher.team_id]).alias('tm_balk'), fn.SUM(Play.balk).over(partition_by=[Play.pitcher.team_id]).alias('tm_balk'),
fn.SUM(Play.homerun).over(partition_by=[Play.pitcher.team_id]).alias('tm_homerun'), fn.SUM(Play.homerun).over(partition_by=[Play.pitcher.team_id]).alias('tm_homerun'),
).join(Lineup, on=Play.pitcher).where(Play.game_id == game_id) ).join(Lineup, on=Play.pitcher).where(Play.game_id == game_id)
logging.debug(f'db_calls_gameplay - get_pitching_stats - pitching_stats: {pitching_stats}') logger.debug(f'db_calls_gameplay - get_pitching_stats - pitching_stats: {pitching_stats}')
# This is counging plays with multiple runs scored on 1 ER and the rest unearned # This is counging plays with multiple runs scored on 1 ER and the rest unearned
# earned_runs_pl = Play.select().where( # earned_runs_pl = Play.select().where(
# ((Play.on_first_final == 4) | (Play.on_second_final == 4) | (Play.on_third_final == 4) | # ((Play.on_first_final == 4) | (Play.on_second_final == 4) | (Play.on_third_final == 4) |
# (Play.batter_final == 4)) & (Play.error == 0) # (Play.batter_final == 4)) & (Play.error == 0)
# ).join(Lineup, on=Play.pitcher).where(Play.game_id == game_id) # ).join(Lineup, on=Play.pitcher).where(Play.game_id == game_id)
# logging.info(f'earned_runs: {earned_runs_pl}') # logger.info(f'earned_runs: {earned_runs_pl}')
er_first = Play.select().where( er_first = Play.select().where(
(Play.on_first_final == 4) & (Play.error == 0) (Play.on_first_final == 4) & (Play.error == 0)
@ -1865,7 +1866,7 @@ def get_pitching_stats(
# if in_innings is not None: # if in_innings is not None:
# pitching_stats = pitching_stats.where(Play.inning_num << in_innings) # pitching_stats = pitching_stats.where(Play.inning_num << in_innings)
# logging.info(f'db_calls_gameplay - get_pitching_stats - in_innings: {in_innings} / query: {pitching_stats} / ' # logger.info(f'db_calls_gameplay - get_pitching_stats - in_innings: {in_innings} / query: {pitching_stats} / '
# f'stats: {pitching_stats.count()}') # f'stats: {pitching_stats.count()}')
tm_earned_runs = None tm_earned_runs = None
@ -1933,7 +1934,7 @@ def get_pitching_stats(
done_pitchers.append(x.pitcher_id) done_pitchers.append(x.pitcher_id)
db.close() db.close()
logging.debug(f'pitching stats: {return_pitchers}') logger.debug(f'pitching stats: {return_pitchers}')
return return_pitchers return return_pitchers
@ -1945,7 +1946,7 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
# home_pitchers = [] # [(pitcher, first_play), (pitcher2, their_first_play)] # home_pitchers = [] # [(pitcher, first_play), (pitcher2, their_first_play)]
# last_play = get_current_play(game.id) # last_play = get_current_play(game.id)
logging.debug(f'this game: {game}') logger.debug(f'this game: {game}')
winner = None winner = None
loser = None loser = None
save = None save = None
@ -1957,7 +1958,7 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
away_pitcher = Lineup.get(Lineup.game_id == game.id, Lineup.team_id == game.away_team_id, Lineup.position == 'P') away_pitcher = Lineup.get(Lineup.game_id == game.id, Lineup.team_id == game.away_team_id, Lineup.position == 'P')
home_pitcher = Lineup.get(Lineup.game_id == game.id, Lineup.team_id == game.home_team_id, Lineup.position == 'P') home_pitcher = Lineup.get(Lineup.game_id == game.id, Lineup.team_id == game.home_team_id, Lineup.position == 'P')
gs.extend([away_pitcher.card_id, home_pitcher.card_id]) gs.extend([away_pitcher.card_id, home_pitcher.card_id])
logging.debug(f'SPs: {away_pitcher} / {home_pitcher}') logger.debug(f'SPs: {away_pitcher} / {home_pitcher}')
decisions = { decisions = {
away_pitcher.player_id: DecisionModel( away_pitcher.player_id: DecisionModel(
@ -1979,7 +1980,7 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
} # { <player_id>: DecisionModel } } # { <player_id>: DecisionModel }
for x in Play.select().where(Play.game_id == game.id): for x in Play.select().where(Play.game_id == game.id):
logging.debug(f'checking play num {x.play_num}') logger.debug(f'checking play num {x.play_num}')
if x.inning_half == 'Top' and home_pitcher != x.pitcher: if x.inning_half == 'Top' and home_pitcher != x.pitcher:
if save == home_pitcher: if save == home_pitcher:
if x.home_score > x.away_score: if x.home_score > x.away_score:
@ -2007,7 +2008,7 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
save = away_pitcher save = away_pitcher
if x.is_go_ahead: if x.is_go_ahead:
logging.debug(f'is go ahead: {x}') logger.debug(f'is go ahead: {x}')
if x.on_third_final == 4: if x.on_third_final == 4:
# winning_run = x.on_third # winning_run = x.on_third
# #
@ -2065,7 +2066,7 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
winner = home_pitcher if x.inning_half == 'Bot' else away_pitcher winner = home_pitcher if x.inning_half == 'Bot' else away_pitcher
if x.is_tied: if x.is_tied:
logging.debug(f'is tied: {x}') logger.debug(f'is tied: {x}')
winner, loser = None, None winner, loser = None, None
if save: if save:
b_save.append(save) b_save.append(save)
@ -2101,7 +2102,7 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
return [x.dict() for x in decisions.values()] return [x.dict() for x in decisions.values()]
logging.debug(f'\n\nWin: {winner}\nLose: {loser}\nSave: {save}\nBlown Save: {b_save}\nHolds: {holds}') logger.debug(f'\n\nWin: {winner}\nLose: {loser}\nSave: {save}\nBlown Save: {b_save}\nHolds: {holds}')
return { return {
'winner': winner.card_id, 'winner': winner.card_id,
'loser': loser.card_id, 'loser': loser.card_id,
@ -2400,7 +2401,7 @@ class StratManagerAi(pydantic.BaseModel):
self, this_play, tot_allowed: int, is_starter: bool = False) -> bool: self, this_play, tot_allowed: int, is_starter: bool = False) -> bool:
run_lead = this_play.ai_run_diff() run_lead = this_play.ai_run_diff()
obc = this_play.on_base_code obc = this_play.on_base_code
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: ' logger.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: '
f'outs: {this_play.starting_outs}, obc: {obc}, run_lead: {run_lead}, ' f'outs: {this_play.starting_outs}, obc: {obc}, run_lead: {run_lead}, '
f'tot_allowed: {tot_allowed}') f'tot_allowed: {tot_allowed}')
@ -2408,30 +2409,30 @@ class StratManagerAi(pydantic.BaseModel):
# AI up big # AI up big
if tot_allowed < 5 and is_starter: if tot_allowed < 5 and is_starter:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 1') logger.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 1')
return False return False
elif run_lead > 5 or (run_lead > 2 and self.ahead_aggression > 5): elif run_lead > 5 or (run_lead > 2 and self.ahead_aggression > 5):
if tot_allowed <= lead_target or obc <= 3 or (this_play.starting_outs == 2 and not is_starter): if tot_allowed <= lead_target or obc <= 3 or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 2') logger.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 2')
return False return False
elif run_lead > 2 or (run_lead >= 0 and self.ahead_aggression > 5): elif run_lead > 2 or (run_lead >= 0 and self.ahead_aggression > 5):
if tot_allowed < lead_target or obc <= 1 or (this_play.starting_outs == 2 and not is_starter): if tot_allowed < lead_target or obc <= 1 or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 3') logger.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 3')
return False return False
elif run_lead >= 0 or (run_lead >= -2 and self.behind_aggression > 5): elif run_lead >= 0 or (run_lead >= -2 and self.behind_aggression > 5):
if tot_allowed < 5 or obc <= run_lead or (this_play.starting_outs == 2 and not is_starter): if tot_allowed < 5 or obc <= run_lead or (this_play.starting_outs == 2 and not is_starter):
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 4') logger.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 4')
return False return False
elif run_lead >= -3 and self.behind_aggression > 5: elif run_lead >= -3 and self.behind_aggression > 5:
if tot_allowed < 5 and obc <= 1: if tot_allowed < 5 and obc <= 1:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 5') logger.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 5')
return False return False
elif run_lead <= -5: elif run_lead <= -5:
if is_starter and this_play.inning_num <= 3: if is_starter and this_play.inning_num <= 3:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 6') logger.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 6')
return False return False
if this_play.starting_outs != 0: if this_play.starting_outs != 0:
logging.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 7') logger.info(f'db_calls_gameplay - StratManagerAi - ID: {self.id} - go_to_reliever: False / code 7')
return False return False
return True return True
@ -2453,13 +2454,13 @@ def get_manager(game) -> Optional[StratManagerAi]:
manager_ai_id = ((datetime.datetime.now().day * team_id) % 3) + 1 manager_ai_id = ((datetime.datetime.now().day * team_id) % 3) + 1
if manager_ai_id > 3 or manager_ai_id < 1: if manager_ai_id > 3 or manager_ai_id < 1:
manager_ai_id = 1 manager_ai_id = 1
logging.debug(f'manager id: {manager_ai_id} for game {game}') logger.debug(f'manager id: {manager_ai_id} for game {game}')
try: try:
this_manager = ManagerAi.get_by_id(manager_ai_id) this_manager = ManagerAi.get_by_id(manager_ai_id)
except Exception as e: except Exception as e:
e_message = f'Could not find manager id {manager_ai_id}' e_message = f'Could not find manager id {manager_ai_id}'
logging.error(f'{e_message}: {type(e)}: {e}') logger.error(f'{e_message}: {type(e)}: {e}')
raise KeyError(f'Could not find this AI manager\'s playbook') raise KeyError(f'Could not find this AI manager\'s playbook')
return convert_strat_manager(this_manager) return convert_strat_manager(this_manager)

View File

@ -1,16 +1,23 @@
import logging import logging
from typing import Literal from typing import Literal
logger = logging.getLogger('discord_app')
def log_exception(e: Exception, msg: str = '', level: Literal['debug', 'error', 'info', 'warn'] = 'error'): def log_exception(e: Exception, msg: str = '', level: Literal['debug', 'error', 'info', 'warn'] = 'error'):
if level == 'debug': if level == 'debug':
logging.debug(msg, stack_info=True) logger.debug(msg, exc_info=True, stack_info=True)
elif level == 'error': elif level == 'error':
logging.error(msg, stack_info=True) logger.error(msg, exc_info=True, stack_info=True)
elif level == 'info': elif level == 'info':
logging.info(msg, stack_info=True) logger.info(msg, exc_info=True, stack_info=True)
else: else:
logging.warning(msg, stack_info=True) logger.warning(msg, exc_info=True, stack_info=True)
raise e(msg)
# Check if 'e' is an exception class or instance
if isinstance(e, Exception):
raise e # If 'e' is already an instance of an exception
else:
raise e(msg) # If 'e' is an exception class
class GameException(Exception): class GameException(Exception):
pass pass
@ -38,3 +45,7 @@ class PlayNotFoundException(GameException):
class PlayInitException(GameException): class PlayInitException(GameException):
pass pass
class DatabaseError(GameException):
pass

View File

@ -11,6 +11,9 @@ from helpers import RARITY, get_or_create_role, send_to_channel, get_channel
from api_calls import db_get, db_post, db_delete, db_patch from api_calls import db_get, db_post, db_delete, db_patch
logger = logging.getLogger('discord_app')
async def wipe_team(this_team, interaction: discord.Interaction, delete_team: bool = False, delete_runs: bool = False): async def wipe_team(this_team, interaction: discord.Interaction, delete_team: bool = False, delete_runs: bool = False):
await interaction.edit_original_response(content=f'Looking for cards...') await interaction.edit_original_response(content=f'Looking for cards...')
# Delete cards # Delete cards
@ -273,11 +276,11 @@ async def get_starting_pitcher(this_team, this_game, this_event, this_run):
# timeout=10 # timeout=10
# ) # )
# except ConnectionError as e: # except ConnectionError as e:
# logging.error(f'Could not get pitchers for {this_team["lname"]}: {e}') # logger.error(f'Could not get pitchers for {this_team["lname"]}: {e}')
# raise ConnectionError(f'Error pulling starting pitchers for the {this_team["lname"]}. Cal help plz.') # raise ConnectionError(f'Error pulling starting pitchers for the {this_team["lname"]}. Cal help plz.')
# #
# if pitchers['count'] == 0: # if pitchers['count'] == 0:
# logging.info(f'pitchers is None') # logger.info(f'pitchers is None')
# del params # del params
# params = [ # params = [
# ('mlbclub', this_team['lname']), ('pos_include', 'SP'), # ('mlbclub', this_team['lname']), ('pos_include', 'SP'),
@ -333,7 +336,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
base_params = [('cardset_id', 20), ('cardset_id', 21), ('cardset_id', 22), ('cardset_id', 16), base_params = [('cardset_id', 20), ('cardset_id', 21), ('cardset_id', 22), ('cardset_id', 16),
('cardset_id', 8), ('limit', 8)] ('cardset_id', 8), ('limit', 8)]
else: else:
logging.error(f'run_draft - Event ID {this_event["id"]} not recognized') logger.error(f'run_draft - Event ID {this_event["id"]} not recognized')
raise KeyError(f'Draft data not found for Gauntlet {this_event["id"]}') raise KeyError(f'Draft data not found for Gauntlet {this_event["id"]}')
if draft_team is None: if draft_team is None:
@ -519,7 +522,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
'Reserve': 0, 'Reserve': 0,
'Replacement': 0 'Replacement': 0
} }
logging.info(f'gauntlets.py - run_draft / max_counts: {max_counts}') logger.info(f'gauntlets.py - run_draft / max_counts: {max_counts}')
round_num = 1 round_num = 1
counter = 0 counter = 0
@ -615,7 +618,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
return [top_embed, bot_embed] return [top_embed, bot_embed]
logging.info(f'getting last message') logger.info(f'getting last message')
last_message = await interaction.channel.send(content=None, embeds=get_embeds(include_links=False)) last_message = await interaction.channel.send(content=None, embeds=get_embeds(include_links=False))
async def draft_loop(): async def draft_loop():
@ -624,7 +627,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
while round_num <= 26 and counter < 50: while round_num <= 26 and counter < 50:
counter += 1 counter += 1
params = copy.deepcopy(base_params) params = copy.deepcopy(base_params)
logging.info(f'gauntlets.py - run_draft - event_id {this_event["id"]} / round_num: {round_num} / counter: {counter} / counts: {counts} / max_counts: {max_counts}') logger.info(f'gauntlets.py - run_draft - event_id {this_event["id"]} / round_num: {round_num} / counter: {counter} / counts: {counts} / max_counts: {max_counts}')
# Set rarity based on remaining counts # Set rarity based on remaining counts
if counts['Hall of Fame'] < max_counts['Hall of Fame']: if counts['Hall of Fame'] < max_counts['Hall of Fame']:
@ -671,7 +674,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# Slot 2 - RP # Slot 2 - RP
elif x == 'RP': elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}') logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] > 7: if counts['RP'] > 7:
slot_params = [('pos_exc', 'RP')] slot_params = [('pos_exc', 'RP')]
if counts['SP'] > 5: if counts['SP'] > 5:
@ -708,9 +711,9 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# if len(slot_params) == 0: # if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')] # slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}') logger.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}') logger.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}') logger.info(f'params: {params}')
# No position explicitly requested or denied # No position explicitly requested or denied
if len(slot_params) == 0: if len(slot_params) == 0:
@ -744,7 +747,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break break
if len(this_batch) < 4: if len(this_batch) < 4:
logging.error(f'Pulled less than 4 players in gauntlet draft') logger.error(f'Pulled less than 4 players in gauntlet draft')
p_query = await db_get('players/random', params=params) p_query = await db_get('players/random', params=params)
for i in p_query['players']: for i in p_query['players']:
if i['p_name'] not in p_names and i not in this_batch: if i['p_name'] not in p_names and i not in this_batch:
@ -775,7 +778,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
round_num += 1 round_num += 1
await last_message.edit(content=None, embeds=get_embeds(include_links=False, round_num=round_num)) await last_message.edit(content=None, embeds=get_embeds(include_links=False, round_num=round_num))
logging.info(f'going into draft') logger.info(f'going into draft')
backyard_round = None backyard_round = None
custom_player_round = None custom_player_round = None
if this_event['id'] == 1: if this_event['id'] == 1:
@ -869,7 +872,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# Slot 2 - RP # Slot 2 - RP
elif x == 'RP': elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}') logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] < 8: if counts['RP'] < 8:
slot_params = [('pos_inc', 'RP')] slot_params = [('pos_inc', 'RP')]
elif counts['SP'] < 4: elif counts['SP'] < 4:
@ -906,9 +909,9 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
if len(slot_params) == 0: if len(slot_params) == 0:
slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')] slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}') logger.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}') logger.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}') logger.info(f'params: {params}')
slot_params.extend(params) slot_params.extend(params)
p_query = await db_get('players/random', params=slot_params) p_query = await db_get('players/random', params=slot_params)
@ -924,7 +927,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break break
if len(this_batch) < 4: if len(this_batch) < 4:
logging.error(f'Pulled less than 4 players in gauntlet draft') logger.error(f'Pulled less than 4 players in gauntlet draft')
p_query = await db_get('players/random', params=params) p_query = await db_get('players/random', params=params)
for i in p_query['players']: for i in p_query['players']:
if i['p_name'] not in p_names and i not in this_batch: if i['p_name'] not in p_names and i not in this_batch:
@ -1027,7 +1030,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# Slot 2 - RP # Slot 2 - RP
elif x == 'RP': elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}') logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] > 7: if counts['RP'] > 7:
slot_params = [('pos_exc', 'RP')] slot_params = [('pos_exc', 'RP')]
if counts['SP'] > 5: if counts['SP'] > 5:
@ -1064,9 +1067,9 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# if len(slot_params) == 0: # if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')] # slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}') logger.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}') logger.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}') logger.info(f'params: {params}')
# No position explicitly requested or denied # No position explicitly requested or denied
if len(slot_params) == 0: if len(slot_params) == 0:
@ -1100,7 +1103,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break break
if len(this_batch) < 4: if len(this_batch) < 4:
logging.error(f'Pulled less than 4 players in gauntlet draft') logger.error(f'Pulled less than 4 players in gauntlet draft')
p_query = await db_get('players/random', params=params) p_query = await db_get('players/random', params=params)
for i in p_query['players']: for i in p_query['players']:
if i['p_name'] not in p_names and i not in this_batch: if i['p_name'] not in p_names and i not in this_batch:
@ -1131,7 +1134,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
await last_message.edit(content=None, embeds=get_embeds(include_links=False)) await last_message.edit(content=None, embeds=get_embeds(include_links=False))
elif this_event['id'] == 3: elif this_event['id'] == 3:
while round_num <= 26 and counter < 50: while round_num <= 26 and counter < 50:
logging.info(f'round {round_num}') logger.info(f'round {round_num}')
counter += 1 counter += 1
params = copy.deepcopy(base_params) params = copy.deepcopy(base_params)
@ -1185,7 +1188,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
('min_rarity', RARITY['Replacement']), ('max_rarity', RARITY['Replacement']) ('min_rarity', RARITY['Replacement']), ('max_rarity', RARITY['Replacement'])
]) ])
logging.info(f'starting position loop') logger.info(f'starting position loop')
this_batch = [] this_batch = []
for x in ['SP', 'RP', 'IF', 'OF']: for x in ['SP', 'RP', 'IF', 'OF']:
# Slot 1 - SP # Slot 1 - SP
@ -1205,7 +1208,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# Slot 2 - RP # Slot 2 - RP
elif x == 'RP': elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}') logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] > 7: if counts['RP'] > 7:
slot_params = [('pos_exc', 'RP')] slot_params = [('pos_exc', 'RP')]
if counts['SP'] > 5: if counts['SP'] > 5:
@ -1242,9 +1245,9 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# if len(slot_params) == 0: # if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')] # slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}') logger.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}') logger.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}') logger.info(f'params: {params}')
# No position explicitly requested or denied # No position explicitly requested or denied
if len(slot_params) == 0: if len(slot_params) == 0:
@ -1278,7 +1281,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break break
if len(this_batch) < 4: if len(this_batch) < 4:
logging.error(f'Pulled less than 4 players in gauntlet draft') logger.error(f'Pulled less than 4 players in gauntlet draft')
p_query = await db_get('players/random', params=params) p_query = await db_get('players/random', params=params)
for i in p_query['players']: for i in p_query['players']:
if i['p_name'] not in p_names and i not in this_batch: if i['p_name'] not in p_names and i not in this_batch:
@ -1403,7 +1406,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# Slot 2 - RP # Slot 2 - RP
elif x == 'RP': elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}') logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] > 7: if counts['RP'] > 7:
slot_params = [('pos_exc', 'RP')] slot_params = [('pos_exc', 'RP')]
if counts['SP'] > 5: if counts['SP'] > 5:
@ -1440,9 +1443,9 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# if len(slot_params) == 0: # if len(slot_params) == 0:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')] # slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}') logger.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}') logger.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}') logger.info(f'params: {params}')
# No position explicitly requested or denied # No position explicitly requested or denied
if len(slot_params) == 0: if len(slot_params) == 0:
@ -1476,7 +1479,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break break
if len(this_batch) < 4: if len(this_batch) < 4:
logging.error(f'Pulled less than 4 players in gauntlet draft') logger.error(f'Pulled less than 4 players in gauntlet draft')
p_query = await db_get('players/random', params=params) p_query = await db_get('players/random', params=params)
for i in p_query['players']: for i in p_query['players']:
if i['p_name'] not in p_names and i not in this_batch: if i['p_name'] not in p_names and i not in this_batch:
@ -1508,7 +1511,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
elif this_event['id'] in [5, 6]: elif this_event['id'] in [5, 6]:
await draft_loop() await draft_loop()
else: else:
logging.error(f'run_draft - No draft logic for Event ID {this_event["id"]}') logger.error(f'run_draft - No draft logic for Event ID {this_event["id"]}')
raise KeyError(f'Draft data not found for Gauntlet {this_event["id"]}') raise KeyError(f'Draft data not found for Gauntlet {this_event["id"]}')
if len(all_players) < 26: if len(all_players) < 26:
@ -1545,7 +1548,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
async def get_embed(this_run=None, this_event=None, this_team=None): async def get_embed(this_run=None, this_event=None, this_team=None):
logging.info(f'get_embed - this_run:\n{this_run}\n\nthis_event:\n{this_event}') logger.info(f'get_embed - this_run:\n{this_run}\n\nthis_event:\n{this_event}')
if this_run is None and this_event is None: if this_run is None and this_event is None:
raise KeyError('Must provide either a run or an event to get_embed') raise KeyError('Must provide either a run or an event to get_embed')

View File

@ -439,7 +439,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='⏮️', style=discord.ButtonStyle.blurple) @discord.ui.button(label='⏮️', style=discord.ButtonStyle.blurple)
async def left_button(self, interaction: discord.Interaction, button: discord.ui.Button): async def left_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if interaction.user not in self.responders: if interaction.user not in self.responders:
logging.info(f'{interaction.user} is not in {self.responders}') logger.info(f'{interaction.user} is not in {self.responders}')
return return
self.value = 'left' self.value = 'left'
@ -449,7 +449,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='❌️', style=discord.ButtonStyle.secondary) @discord.ui.button(label='❌️', style=discord.ButtonStyle.secondary)
async def cancel_button(self, interaction: discord.Interaction, button: discord.ui.Button): async def cancel_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if interaction.user not in self.responders: if interaction.user not in self.responders:
logging.info(f'{interaction.user} is not in {self.responders}') logger.info(f'{interaction.user} is not in {self.responders}')
return return
self.value = 'cancel' self.value = 'cancel'
@ -459,7 +459,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='⏭️', style=discord.ButtonStyle.blurple) @discord.ui.button(label='⏭️', style=discord.ButtonStyle.blurple)
async def right_button(self, interaction: discord.Interaction, button: discord.ui.Button): async def right_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if interaction.user not in self.responders: if interaction.user not in self.responders:
logging.info(f'{interaction.user} is not in {self.responders}') logger.info(f'{interaction.user} is not in {self.responders}')
return return
self.value = 'right' self.value = 'right'
@ -585,7 +585,7 @@ class SelectChoicePackTeam(discord.ui.Select):
params.append(('pack_cardset_id', self.cardset_id)) params.append(('pack_cardset_id', self.cardset_id))
p_query = await db_get('packs', params=params) p_query = await db_get('packs', params=params)
if p_query['count'] == 0: if p_query['count'] == 0:
logging.error(f'open-packs - no packs found with params: {params}') logger.error(f'open-packs - no packs found with params: {params}')
raise ValueError(f'Unable to open packs') raise ValueError(f'Unable to open packs')
this_pack = await db_patch('packs', object_id=p_query['packs'][0]['id'], params=[('pack_team_id', team_id)]) this_pack = await db_patch('packs', object_id=p_query['packs'][0]['id'], params=[('pack_team_id', team_id)])
@ -599,9 +599,9 @@ class SelectOpenPack(discord.ui.Select):
super().__init__(placeholder='Select a Pack Type', options=options) super().__init__(placeholder='Select a Pack Type', options=options)
async def callback(self, interaction: discord.Interaction): async def callback(self, interaction: discord.Interaction):
logging.info(f'SelectPackChoice - selection: {self.values[0]}') logger.info(f'SelectPackChoice - selection: {self.values[0]}')
pack_vals = self.values[0].split('-') pack_vals = self.values[0].split('-')
logging.info(f'pack_vals: {pack_vals}') logger.info(f'pack_vals: {pack_vals}')
# Get the selected packs # Get the selected packs
params = [('team_id', self.owner_team['id']), ('opened', False), ('limit', 5), ('exact_match', True)] params = [('team_id', self.owner_team['id']), ('opened', False), ('limit', 5), ('exact_match', True)]
@ -664,7 +664,7 @@ class SelectOpenPack(discord.ui.Select):
p_query = await db_get('packs', params=params) p_query = await db_get('packs', params=params)
if p_query['count'] == 0: if p_query['count'] == 0:
logging.error(f'open-packs - no packs found with params: {params}') logger.error(f'open-packs - no packs found with params: {params}')
raise ValueError(f'Unable to open packs') raise ValueError(f'Unable to open packs')
# Open the packs # Open the packs
@ -694,7 +694,7 @@ class SelectPaperdexCardset(discord.ui.Select):
super().__init__(placeholder='Select a Cardset', options=options) super().__init__(placeholder='Select a Cardset', options=options)
async def callback(self, interaction: discord.Interaction): async def callback(self, interaction: discord.Interaction):
logging.info(f'SelectPaperdexCardset - selection: {self.values[0]}') logger.info(f'SelectPaperdexCardset - selection: {self.values[0]}')
cardset_id = None cardset_id = None
if self.values[0] == '2022 Season': if self.values[0] == '2022 Season':
cardset_id = 3 cardset_id = 3
@ -871,7 +871,7 @@ class SelectBuyPacksCardset(discord.ui.Select):
super().__init__(placeholder='Select a Cardset', options=options) super().__init__(placeholder='Select a Cardset', options=options)
async def callback(self, interaction: discord.Interaction): async def callback(self, interaction: discord.Interaction):
logging.info(f'SelectBuyPacksCardset - selection: {self.values[0]}') logger.info(f'SelectBuyPacksCardset - selection: {self.values[0]}')
cardset_id = None cardset_id = None
if self.values[0] == '2022 Season': if self.values[0] == '2022 Season':
cardset_id = 3 cardset_id = 3
@ -1205,7 +1205,7 @@ class Dropdown(discord.ui.Select):
# Select object, and the values attribute gets a list of the user's # Select object, and the values attribute gets a list of the user's
# selected options. We only want the first one. # selected options. We only want the first one.
# await interaction.response.send_message(f'Your favourite colour is {self.values[0]}') # await interaction.response.send_message(f'Your favourite colour is {self.values[0]}')
logging.info(f'Dropdown callback: {self.custom_callback}') logger.info(f'Dropdown callback: {self.custom_callback}')
await self.custom_callback(interaction, self.values) await self.custom_callback(interaction, self.values)
@ -1554,7 +1554,7 @@ async def create_channel_old(
category=this_category category=this_category
) )
logging.info(f'Creating channel ({channel_name}) in ({category_name})') logger.info(f'Creating channel ({channel_name}) in ({category_name})')
return this_channel return this_channel
@ -1567,7 +1567,7 @@ async def react_and_reply(ctx, reaction, message):
async def send_to_channel(bot, channel_name, content=None, embed=None): async def send_to_channel(bot, channel_name, content=None, embed=None):
guild = bot.get_guild(int(os.environ.get('GUILD_ID'))) guild = bot.get_guild(int(os.environ.get('GUILD_ID')))
if not guild: if not guild:
logging.error('Cannot send to channel - bot not logged in') logger.error('Cannot send to channel - bot not logged in')
return return
this_channel = discord.utils.get(guild.text_channels, name=channel_name) this_channel = discord.utils.get(guild.text_channels, name=channel_name)
@ -1582,11 +1582,11 @@ async def send_to_channel(bot, channel_name, content=None, embed=None):
async def get_or_create_role(ctx, role_name, mentionable=True): async def get_or_create_role(ctx, role_name, mentionable=True):
this_role = discord.utils.get(ctx.guild.roles, name=role_name) this_role = discord.utils.get(ctx.guild.roles, name=role_name)
# logging.info(f'this_role: {this_role} / role_name: {role_name} (POST SEARCH)') # logger.info(f'this_role: {this_role} / role_name: {role_name} (POST SEARCH)')
if not this_role: if not this_role:
this_role = await ctx.guild.create_role(name=role_name, mentionable=mentionable) this_role = await ctx.guild.create_role(name=role_name, mentionable=mentionable)
# logging.info(f'this_role: {this_role} / role_name: {role_name} (PRE RETURN)') # logger.info(f'this_role: {this_role} / role_name: {role_name} (PRE RETURN)')
return this_role return this_role
@ -1682,7 +1682,7 @@ async def create_channel(
category=this_category category=this_category
) )
logging.info(f'Creating channel ({channel_name}) in ({category_name})') logger.info(f'Creating channel ({channel_name}) in ({category_name})')
return this_channel return this_channel
@ -2208,7 +2208,7 @@ async def roll_for_cards(all_packs: list, extra_val=None) -> list:
counts['HoF']['count'] += 1 counts['HoF']['count'] += 1
elif pack['pack_type']['name'] == 'Check-In Player': elif pack['pack_type']['name'] == 'Check-In Player':
logging.info(f'Building Check-In Pack // extra_val (type): {extra_val} {type(extra_val)}') logger.info(f'Building Check-In Pack // extra_val (type): {extra_val} {type(extra_val)}')
# Single Card # Single Card
mod = 0 mod = 0
if isinstance(extra_val, int): if isinstance(extra_val, int):
@ -2278,7 +2278,7 @@ async def roll_for_cards(all_packs: list, extra_val=None) -> list:
pack_ids.append(pack['id']) pack_ids.append(pack['id'])
for pull in pull_notifs: for pull in pull_notifs:
logging.info(f'good pull: {pull}') logger.info(f'good pull: {pull}')
await db_post('notifs', payload={ await db_post('notifs', payload={
'created': int(datetime.datetime.timestamp(datetime.datetime.now())*1000), 'created': int(datetime.datetime.timestamp(datetime.datetime.now())*1000),
'title': 'Rare Pull', 'title': 'Rare Pull',
@ -2318,7 +2318,7 @@ def get_sheets(bot):
try: try:
return bot.get_cog('Players').sheets return bot.get_cog('Players').sheets
except Exception as e: except Exception as e:
logging.error(f'Could not grab sheets auth: {e}') logger.error(f'Could not grab sheets auth: {e}')
raise ConnectionError(f'Bot has not authenticated with discord; please try again in 1 minute.') raise ConnectionError(f'Bot has not authenticated with discord; please try again in 1 minute.')
@ -2329,7 +2329,7 @@ def create_team_sheet(team, email: str, current, bot):
f'{team["lname"]} Roster Sheet v{current["gsheet_version"]}', f'{team["lname"]} Roster Sheet v{current["gsheet_version"]}',
'1539D0imTMjlUx2VF3NPMt7Sv85sb2XAJ' '1539D0imTMjlUx2VF3NPMt7Sv85sb2XAJ'
) )
logging.info(f'new_sheet: {new_sheet}') logger.info(f'new_sheet: {new_sheet}')
this_sheet = sheets.open_by_key(new_sheet['id']) this_sheet = sheets.open_by_key(new_sheet['id'])
this_sheet.share(email, role='writer') this_sheet.share(email, role='writer')
@ -2338,7 +2338,7 @@ def create_team_sheet(team, email: str, current, bot):
crange='B1:B2', crange='B1:B2',
values=[[f'{team["id"]}'], [f'\'{team_hash(team)}']] values=[[f'{team["id"]}'], [f'\'{team_hash(team)}']]
) )
logging.debug(f'this_sheet: {this_sheet}') logger.debug(f'this_sheet: {this_sheet}')
return this_sheet return this_sheet
@ -2422,7 +2422,7 @@ def get_rosters(team, bot, roster_num: Optional[int] = None) -> list:
sheets = get_sheets(bot) sheets = get_sheets(bot)
this_sheet = sheets.open_by_key(team['gsheet']) this_sheet = sheets.open_by_key(team['gsheet'])
r_sheet = this_sheet.worksheet_by_title(f'My Rosters') r_sheet = this_sheet.worksheet_by_title(f'My Rosters')
logging.debug(f'this_sheet: {this_sheet} / r_sheet = {r_sheet}') logger.debug(f'this_sheet: {this_sheet} / r_sheet = {r_sheet}')
all_rosters = [None, None, None] all_rosters = [None, None, None]
@ -2430,7 +2430,7 @@ def get_rosters(team, bot, roster_num: Optional[int] = None) -> list:
if not roster_num or roster_num == 1: if not roster_num or roster_num == 1:
roster_1 = r_sheet.range('B3:B28') roster_1 = r_sheet.range('B3:B28')
roster_name = r_sheet.cell('F30').value roster_name = r_sheet.cell('F30').value
logging.info(f'roster_1: {roster_1}') logger.info(f'roster_1: {roster_1}')
if not roster_1[0][0].value == '': if not roster_1[0][0].value == '':
all_rosters[0] = {'name': roster_name, 'roster_num': 1, 'team_id': team['id'], 'cards': None} all_rosters[0] = {'name': roster_name, 'roster_num': 1, 'team_id': team['id'], 'cards': None}
@ -2440,7 +2440,7 @@ def get_rosters(team, bot, roster_num: Optional[int] = None) -> list:
if not roster_num or roster_num == 2: if not roster_num or roster_num == 2:
roster_2 = r_sheet.range('B29:B54') roster_2 = r_sheet.range('B29:B54')
roster_name = r_sheet.cell('F31').value roster_name = r_sheet.cell('F31').value
logging.info(f'roster_2: {roster_2}') logger.info(f'roster_2: {roster_2}')
if not roster_2[0][0].value == '': if not roster_2[0][0].value == '':
all_rosters[1] = {'name': roster_name, 'roster_num': 2, 'team_id': team['id'], 'cards': None} all_rosters[1] = {'name': roster_name, 'roster_num': 2, 'team_id': team['id'], 'cards': None}
@ -2450,7 +2450,7 @@ def get_rosters(team, bot, roster_num: Optional[int] = None) -> list:
if not roster_num or roster_num == 3: if not roster_num or roster_num == 3:
roster_3 = r_sheet.range('B55:B80') roster_3 = r_sheet.range('B55:B80')
roster_name = r_sheet.cell('F32').value roster_name = r_sheet.cell('F32').value
logging.info(f'roster_3: {roster_3}') logger.info(f'roster_3: {roster_3}')
if not roster_3[0][0].value == '': if not roster_3[0][0].value == '':
all_rosters[2] = {'name': roster_name, 'roster_num': 3, 'team_id': team['id'], 'cards': None} all_rosters[2] = {'name': roster_name, 'roster_num': 3, 'team_id': team['id'], 'cards': None}
@ -2461,11 +2461,11 @@ def get_rosters(team, bot, roster_num: Optional[int] = None) -> list:
def get_roster_lineups(team, bot, roster_num, lineup_num) -> list: def get_roster_lineups(team, bot, roster_num, lineup_num) -> list:
sheets = get_sheets(bot) sheets = get_sheets(bot)
logging.debug(f'sheets: {sheets}') logger.debug(f'sheets: {sheets}')
this_sheet = sheets.open_by_key(team['gsheet']) this_sheet = sheets.open_by_key(team['gsheet'])
logging.debug(f'this_sheet: {this_sheet}') logger.debug(f'this_sheet: {this_sheet}')
r_sheet = this_sheet.worksheet_by_title('My Rosters') r_sheet = this_sheet.worksheet_by_title('My Rosters')
logging.debug(f'r_sheet: {r_sheet}') logger.debug(f'r_sheet: {r_sheet}')
if lineup_num == 1: if lineup_num == 1:
row_start = 9 row_start = 9
@ -2481,17 +2481,17 @@ def get_roster_lineups(team, bot, roster_num, lineup_num) -> list:
else: else:
l_range = f'L{row_start}:M{row_end}' l_range = f'L{row_start}:M{row_end}'
logging.debug(f'l_range: {l_range}') logger.debug(f'l_range: {l_range}')
raw_cells = r_sheet.range(l_range) raw_cells = r_sheet.range(l_range)
logging.debug(f'raw_cells: {raw_cells}') logger.debug(f'raw_cells: {raw_cells}')
try: try:
lineup_cells = [(row[0].value, int(row[1].value)) for row in raw_cells] lineup_cells = [(row[0].value, int(row[1].value)) for row in raw_cells]
except ValueError as e: except ValueError as e:
logging.error(f'Could not pull roster for {team["abbrev"]} due to a ValueError') logger.error(f'Could not pull roster for {team["abbrev"]} due to a ValueError')
raise ValueError(f'Uh oh. Looks like your roster might not be saved. I am reading blanks when I try to ' raise ValueError(f'Uh oh. Looks like your roster might not be saved. I am reading blanks when I try to '
f'get the card IDs') f'get the card IDs')
logging.debug(f'lineup_cells: {lineup_cells}') logger.debug(f'lineup_cells: {lineup_cells}')
return lineup_cells return lineup_cells
@ -2519,7 +2519,7 @@ async def legal_channel(ctx):
elif ctx.channel.name in bad_channels: elif ctx.channel.name in bad_channels:
# await ctx.message.add_reaction('❌') # await ctx.message.add_reaction('❌')
# await ctx.send(f'Slide on down to the {get_channel(ctx, "pd-bot-hole").mention} ;)') # await ctx.send(f'Slide on down to the {get_channel(ctx, "pd-bot-hole").mention} ;)')
# logging.warning(f'{ctx.author.name} posted in illegal channel.') # logger.warning(f'{ctx.author.name} posted in illegal channel.')
# return False # return False
raise discord.app_commands.AppCommandError(f'Slide on down to the {get_channel(ctx, "pd-bot-hole").mention} ;)') raise discord.app_commands.AppCommandError(f'Slide on down to the {get_channel(ctx, "pd-bot-hole").mention} ;)')
else: else:
@ -2589,7 +2589,7 @@ async def team_summary_embed(team, ctx, include_roster: bool = True):
# inline=False # inline=False
# ) # )
# except Exception as e: # except Exception as e:
# logging.error(f'Could not pull rosters for {team["abbrev"]}') # logger.error(f'Could not pull rosters for {team["abbrev"]}')
# embed.add_field( # embed.add_field(
# name='Rosters', # name='Rosters',
# value='Unable to pull current rosters. `/pullroster` to sync.', # value='Unable to pull current rosters. `/pullroster` to sync.',
@ -2756,7 +2756,7 @@ async def paperdex_cardset_embed(team: dict, this_cardset: dict) -> list[discord
else: else:
player['owned'] = False player['owned'] = False
logging.debug(f'player: {player} / type: {type(player)}') logger.debug(f'player: {player} / type: {type(player)}')
coll_data[player['rarity']]['players'].append(player) coll_data[player['rarity']]['players'].append(player)
cover_embed = get_team_embed(f'{team["lname"]} Collection', team=team) cover_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
@ -2777,7 +2777,7 @@ async def paperdex_cardset_embed(team: dict, this_cardset: dict) -> list[discord
chunk_string = '' chunk_string = ''
for index, this_player in enumerate(coll_data[rarity_id]['players']): for index, this_player in enumerate(coll_data[rarity_id]['players']):
logging.debug(f'this_player: {this_player}') logger.debug(f'this_player: {this_player}')
chunk_string += '' if this_player['owned'] else '' chunk_string += '' if this_player['owned'] else ''
chunk_string += f'{this_player["p_name"]}\n' chunk_string += f'{this_player["p_name"]}\n'
@ -2834,7 +2834,7 @@ async def paperdex_team_embed(team: dict, mlb_team: dict) -> list[discord.Embed]
else: else:
player['owned'] = False player['owned'] = False
logging.debug(f'player: {player} / type: {type(player)}') logger.debug(f'player: {player} / type: {type(player)}')
coll_data[x['id']]['players'].append(player) coll_data[x['id']]['players'].append(player)
cover_embed = get_team_embed(f'{team["lname"]} Collection', team=team) cover_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
@ -2856,7 +2856,7 @@ async def paperdex_team_embed(team: dict, mlb_team: dict) -> list[discord.Embed]
chunk_string = '' chunk_string = ''
for index, this_player in enumerate(coll_data[cardset_id]['players']): for index, this_player in enumerate(coll_data[cardset_id]['players']):
logging.debug(f'this_player: {this_player}') logger.debug(f'this_player: {this_player}')
chunk_string += '' if this_player['owned'] else '' chunk_string += '' if this_player['owned'] else ''
chunk_string += f'{this_player["p_name"]}\n' chunk_string += f'{this_player["p_name"]}\n'
@ -2903,7 +2903,7 @@ async def open_st_pr_packs(all_packs: list, team: dict, context):
pack_ids = await roll_for_cards(all_packs) pack_ids = await roll_for_cards(all_packs)
if not pack_ids: if not pack_ids:
logging.error(f'open_packs - unable to roll_for_cards for packs: {all_packs}') logger.error(f'open_packs - unable to roll_for_cards for packs: {all_packs}')
raise ValueError(f'I was not able to unpack these cards') raise ValueError(f'I was not able to unpack these cards')
all_cards = [] all_cards = []
@ -2912,7 +2912,7 @@ async def open_st_pr_packs(all_packs: list, team: dict, context):
all_cards.extend(new_cards['cards']) all_cards.extend(new_cards['cards'])
if not all_cards: if not all_cards:
logging.error(f'open_packs - unable to get cards for packs: {pack_ids}') logger.error(f'open_packs - unable to get cards for packs: {pack_ids}')
raise ValueError(f'I was not able to display these cards') raise ValueError(f'I was not able to display these cards')
# Present cards to opening channel # Present cards to opening channel
@ -2935,7 +2935,7 @@ async def get_choice_from_cards(
{'player': x, 'team': {'lname': 'Paper Dynasty', 'season': PD_SEASON, 'logo': IMAGES['logo']}} {'player': x, 'team': {'lname': 'Paper Dynasty', 'season': PD_SEASON, 'logo': IMAGES['logo']}}
) for x in all_players ) for x in all_players
] ]
logging.debug(f'card embeds: {card_embeds}') logger.debug(f'card embeds: {card_embeds}')
if cover_title is not None and cover_image_url is not None: if cover_title is not None and cover_image_url is not None:
page_num = 0 page_num = 0
@ -3132,7 +3132,7 @@ async def open_choice_pack(this_pack, team: dict, context, cardset_id: Optional[
rarity_id += 3 rarity_id += 3
if len(players) == 0: if len(players) == 0:
logging.error(f'Could not create choice pack') logger.error(f'Could not create choice pack')
raise ConnectionError(f'Could not create choice pack') raise ConnectionError(f'Could not create choice pack')
if type(context) == commands.Context: if type(context) == commands.Context:
@ -3140,7 +3140,7 @@ async def open_choice_pack(this_pack, team: dict, context, cardset_id: Optional[
else: else:
author = context.user author = context.user
logging.info(f'helpers - open_choice_pack - players: {players}') logger.info(f'helpers - open_choice_pack - players: {players}')
# Display them with pagination, prev/next/select # Display them with pagination, prev/next/select
card_embeds = [ card_embeds = [
@ -3149,7 +3149,7 @@ async def open_choice_pack(this_pack, team: dict, context, cardset_id: Optional[
{'player': x, 'team': team} # Show team and dupe info {'player': x, 'team': team} # Show team and dupe info
) for x in players ) for x in players
] ]
logging.debug(f'card embeds: {card_embeds}') logger.debug(f'card embeds: {card_embeds}')
page_num = 0 page_num = 0
view = Pagination([author], timeout=30) view = Pagination([author], timeout=30)
@ -3182,7 +3182,7 @@ async def open_choice_pack(this_pack, team: dict, context, cardset_id: Optional[
try: try:
await give_cards_to_team(team, players=[players[page_num - 1]], pack_id=this_pack['id']) await give_cards_to_team(team, players=[players[page_num - 1]], pack_id=this_pack['id'])
except Exception as e: except Exception as e:
logging.error(f'failed to create cards: {e}') logger.error(f'failed to create cards: {e}')
raise ConnectionError(f'Failed to distribute these cards.') raise ConnectionError(f'Failed to distribute these cards.')
await db_patch('packs', object_id=this_pack['id'], params=[ await db_patch('packs', object_id=this_pack['id'], params=[
@ -3282,13 +3282,13 @@ def random_gif(search_term: str):
else: else:
return data['data']['url'] return data['data']['url']
else: else:
logging.warning(resp.text) logger.warning(resp.text)
raise ValueError(f'DB: {resp.text}') raise ValueError(f'DB: {resp.text}')
def random_from_list(data_list: list): def random_from_list(data_list: list):
item = data_list[random.randint(0, len(data_list) - 1)] item = data_list[random.randint(0, len(data_list) - 1)]
logging.info(f'random_from_list: {item}') logger.info(f'random_from_list: {item}')
return item return item

View File

@ -24,6 +24,7 @@ db = SqliteDatabase(
'synchronous': 0 'synchronous': 0
} }
) )
logger = logging.getLogger('discord_app')
# 2018, 2024, Mario, # 2018, 2024, Mario,
GAUNTLET1_PARAMS = [ GAUNTLET1_PARAMS = [
@ -127,7 +128,7 @@ async def get_or_create_card(player: dict, team: dict) -> int:
]} ]}
) )
if card_id is None: if card_id is None:
logging.error(f'Could not create card for {player["p_name"]} on the {team["lname"]}') logger.error(f'Could not create card for {player["p_name"]} on the {team["lname"]}')
raise DatabaseError(f'Could not create card for {player["p_name"]} on the {team["lname"]}') raise DatabaseError(f'Could not create card for {player["p_name"]} on the {team["lname"]}')
return card_id return card_id
@ -166,7 +167,7 @@ async def build_lineup_graded(team_object: dict, vs_hand: str, league_name: str,
this_guy = copy.deepcopy(x) this_guy = copy.deepcopy(x)
rg_data = next(x for x in batter_rg if x['player_id'] == this_guy['player_id']) rg_data = next(x for x in batter_rg if x['player_id'] == this_guy['player_id'])
grading = batter_grading(vs_hand, rg_data) grading = batter_grading(vs_hand, rg_data)
logging.info(f'player: {this_guy} / grading: {grading}') logger.info(f'player: {this_guy} / grading: {grading}')
this_guy['overall'] = grading['overall'] this_guy['overall'] = grading['overall']
this_guy['raw-bat'] = grading['raw-bat'] this_guy['raw-bat'] = grading['raw-bat']
@ -202,21 +203,21 @@ async def build_lineup_graded(team_object: dict, vs_hand: str, league_name: str,
while len(players) > 0: while len(players) > 0:
# Sort players dict by position with fewest eligible players # Sort players dict by position with fewest eligible players
this_pass_data = sorted(players.items(), key=lambda item: len(item[1])) this_pass_data = sorted(players.items(), key=lambda item: len(item[1]))
logging.info(f'this_pass_data: {this_pass_data}') logger.info(f'this_pass_data: {this_pass_data}')
# Pull one tuple ('<position>', [<player objects>]) # Pull one tuple ('<position>', [<player objects>])
this_pos_data = this_pass_data[0] this_pos_data = this_pass_data[0]
logging.info(f'this_pos_data: {this_pos_data}') logger.info(f'this_pos_data: {this_pos_data}')
# Sort players at this position by blended rating (raw-bat for DH) # Sort players at this position by blended rating (raw-bat for DH)
if this_pos_data[0] == 'dh': if this_pos_data[0] == 'dh':
this_pos = sorted(this_pos_data[1], key=lambda item: item['raw-bat'], reverse=True) this_pos = sorted(this_pos_data[1], key=lambda item: item['raw-bat'], reverse=True)
else: else:
this_pos = sorted(this_pos_data[1], key=lambda item: item['blended'], reverse=True) this_pos = sorted(this_pos_data[1], key=lambda item: item['blended'], reverse=True)
logging.info(f'this_pos: {this_pos}') logger.info(f'this_pos: {this_pos}')
# Add top player to the lineup # Add top player to the lineup
in_lineup.append({'position': copy.deepcopy(this_pos_data[0].upper()), 'player': copy.deepcopy(this_pos[0])}) in_lineup.append({'position': copy.deepcopy(this_pos_data[0].upper()), 'player': copy.deepcopy(this_pos[0])})
logging.info(f'adding player: {this_pos[0]}') logger.info(f'adding player: {this_pos[0]}')
logging.info(f'deleting position: {this_pos_data[0]}') logger.info(f'deleting position: {this_pos_data[0]}')
# Remove this position from consideration # Remove this position from consideration
del players[this_pos_data[0]] del players[this_pos_data[0]]
@ -241,7 +242,7 @@ async def build_lineup(team_object: dict, game_id: int, league_name: str, sp_nam
timeout=6 timeout=6
) )
sorted_players = l_query['array'] sorted_players = l_query['array']
logging.info(f'sorted_players: {sorted_players}') logger.info(f'sorted_players: {sorted_players}')
grp_1 = sorted_players[:3] grp_1 = sorted_players[:3]
grp_2 = sorted_players[3:6] grp_2 = sorted_players[3:6]
@ -253,9 +254,9 @@ async def build_lineup(team_object: dict, game_id: int, league_name: str, sp_nam
lineups = [] lineups = []
i = 1 i = 1
for x in [grp_1, grp_2, grp_3]: for x in [grp_1, grp_2, grp_3]:
logging.debug(f'group: {x}') logger.debug(f'group: {x}')
for y in x: for y in x:
logging.debug(f'y: {y}') logger.debug(f'y: {y}')
card_id = await get_or_create_card(y[1]['player'], team_object) card_id = await get_or_create_card(y[1]['player'], team_object)
lineups.append({ lineups.append({
@ -269,7 +270,7 @@ async def build_lineup(team_object: dict, game_id: int, league_name: str, sp_nam
}) })
i += 1 i += 1
logging.info(f'build_lineup - final lineup: {lineups}') logger.info(f'build_lineup - final lineup: {lineups}')
return lineups return lineups
@ -281,7 +282,7 @@ async def get_starting_lineup(session: Session, team: Team, game: Game, league_n
timeout=6 timeout=6
) )
sorted_players = l_query['array'] sorted_players = l_query['array']
logging.debug(f'ai_manager - get_starting_lineup - sorted_players: {sorted_players}') logger.debug(f'ai_manager - get_starting_lineup - sorted_players: {sorted_players}')
grp_1 = sorted_players[:3] grp_1 = sorted_players[:3]
grp_2 = sorted_players[3:6] grp_2 = sorted_players[3:6]
@ -293,9 +294,9 @@ async def get_starting_lineup(session: Session, team: Team, game: Game, league_n
lineups = [] lineups = []
i = 1 i = 1
for x in [grp_1, grp_2, grp_3]: for x in [grp_1, grp_2, grp_3]:
logging.debug(f'ai_manager - get_starting_lineup - group: {x}') logger.debug(f'ai_manager - get_starting_lineup - group: {x}')
for y in x: for y in x:
logging.debug(f'ai_manager - get_starting_lineup - y: {y}') logger.debug(f'ai_manager - get_starting_lineup - y: {y}')
this_player = await get_player_or_none(session, get_player_id_from_dict(y[1]['player'])) this_player = await get_player_or_none(session, get_player_id_from_dict(y[1]['player']))
this_card = await get_or_create_ai_card(session, player=this_player, team=team) this_card = await get_or_create_ai_card(session, player=this_player, team=team)
@ -309,7 +310,7 @@ async def get_starting_lineup(session: Session, team: Team, game: Game, league_n
)) ))
i += 1 i += 1
logging.debug(f'ai_manager - get_starting_lineup - final lineup: {lineups}') logger.debug(f'ai_manager - get_starting_lineup - final lineup: {lineups}')
return lineups return lineups
@ -365,13 +366,13 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
for x in used_players: for x in used_players:
used_ids.append(f'{x.player_id}') used_ids.append(f'{x.player_id}')
logging.debug(f'used ids: {used_ids}') logger.debug(f'used ids: {used_ids}')
id_string = "&used_pitcher_ids=".join(used_ids) id_string = "&used_pitcher_ids=".join(used_ids)
this_game = this_play.game this_game = this_play.game
ai_score = this_play.away_score if this_game.away_team_id == ai_team['id'] else this_play.home_score ai_score = this_play.away_score if this_game.away_team_id == ai_team['id'] else this_play.home_score
human_score = this_play.home_score if this_game.away_team_id == ai_team['id'] else this_play.away_score human_score = this_play.home_score if this_game.away_team_id == ai_team['id'] else this_play.away_score
logging.debug(f'scores - ai: {ai_score} / human: {human_score}') logger.debug(f'scores - ai: {ai_score} / human: {human_score}')
if abs(ai_score - human_score) >= 7: if abs(ai_score - human_score) >= 7:
need = 'length' need = 'length'
elif this_play.inning_num >= 9 and abs(ai_score - human_score) <= 3: elif this_play.inning_num >= 9 and abs(ai_score - human_score) <= 3:
@ -383,7 +384,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
else: else:
need = 'length' need = 'length'
logging.debug(f'need: {need}') logger.debug(f'need: {need}')
rp_query = await db_get(f'teams/{ai_team["id"]}/rp/{league_name.split("-run")[0]}' rp_query = await db_get(f'teams/{ai_team["id"]}/rp/{league_name.split("-run")[0]}'
f'?need={need}&used_pitcher_ids={id_string}{get_cardset_string(this_game)}') f'?need={need}&used_pitcher_ids={id_string}{get_cardset_string(this_game)}')
card_id = await get_or_create_card(rp_query, ai_team) card_id = await get_or_create_card(rp_query, ai_team)
@ -408,7 +409,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
# for x in used_players: # for x in used_players:
# c_query = await db_get('cards', object_id=x.card_id) # c_query = await db_get('cards', object_id=x.card_id)
# used_codes.append(c_query["player"]["strat_code"]) # used_codes.append(c_query["player"]["strat_code"])
# logging.info(f'get_rp - used_players: {used_codes}') # logger.info(f'get_rp - used_players: {used_codes}')
# #
# reliever = None # reliever = None
# attempts = 0 # attempts = 0
@ -440,7 +441,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
# if attempts == 1: # if attempts == 1:
# # Try to get long man # # Try to get long man
# if this_play.inning_num < 6: # if this_play.inning_num < 6:
# logging.info(f'get_rp - game {this_play.game.id} try for long man') # logger.info(f'get_rp - game {this_play.game.id} try for long man')
# params.append(('pos_include', 'SP')) # params.append(('pos_include', 'SP'))
# # use_best = True # # use_best = True
# #
@ -448,7 +449,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
# elif this_play.inning_num > 8: # elif this_play.inning_num > 8:
# if (this_play.inning_half == 'top' and this_play.home_score >= this_play.away_score) or \ # if (this_play.inning_half == 'top' and this_play.home_score >= this_play.away_score) or \
# (this_play.inning_half == 'bot' and this_play.away_score >= this_play.home_score): # (this_play.inning_half == 'bot' and this_play.away_score >= this_play.home_score):
# logging.info(f'get_rp - game {this_play.game.id} try for closer') # logger.info(f'get_rp - game {this_play.game.id} try for closer')
# params.append(('pos_include', 'CP')) # params.append(('pos_include', 'CP'))
# use_best = True # use_best = True
# else: # else:
@ -456,7 +457,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
# #
# # Try to exclude long men # # Try to exclude long men
# elif attempts == 1: # elif attempts == 1:
# logging.info(f'get_rp - game {this_play.game.id} try to exclude long men') # logger.info(f'get_rp - game {this_play.game.id} try to exclude long men')
# params.append(('pos_exclude', 'SP')) # params.append(('pos_exclude', 'SP'))
# #
# try: # try:
@ -466,7 +467,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
# timeout=10 # timeout=10
# ) # )
# except ConnectionError as e: # except ConnectionError as e:
# logging.error(f'Could not get pitchers for {ai_team["lname"]}: {e}') # logger.error(f'Could not get pitchers for {ai_team["lname"]}: {e}')
# raise ConnectionError(f'Error pulling starting pitchers for the {ai_team["lname"]}. Cal help plz.') # raise ConnectionError(f'Error pulling starting pitchers for the {ai_team["lname"]}. Cal help plz.')
# #
# if pitchers['count'] > 0: # if pitchers['count'] > 0:
@ -519,12 +520,12 @@ async def pitching_ai_note(this_play: StratPlay, this_pitcher: dict):
# # Pitcher Substitutions # # Pitcher Substitutions
# new_pitcher = None # new_pitcher = None
# if last_inning_ender and last_inning_ender.pitcher != this_play.pitcher: # if last_inning_ender and last_inning_ender.pitcher != this_play.pitcher:
# logging.debug(f'{this_pitcher["team"]["sname"]} not making a change.') # logger.debug(f'{this_pitcher["team"]["sname"]} not making a change.')
# #
# ai_note += f'- have {this_pitcher["p_name"]} finish the inning\n' # ai_note += f'- have {this_pitcher["p_name"]} finish the inning\n'
# #
# elif this_play.is_new_inning and this_play.game.short_game and this_play.inning_num != 1: # elif this_play.is_new_inning and this_play.game.short_game and this_play.inning_num != 1:
# logging.debug(f'{this_pitcher["team"]["sname"]} going the to pen.') # logger.debug(f'{this_pitcher["team"]["sname"]} going the to pen.')
# #
# if len(used_pitchers) < 8: # if len(used_pitchers) < 8:
# make_sub(await get_relief_pitcher( # make_sub(await get_relief_pitcher(
@ -607,10 +608,10 @@ async def check_pitching_sub(this_play: StratPlay, ai_team: dict):
) )
p_stats = get_pitching_stats(this_play.game.id, lineup_id=this_play.pitcher.id) p_stats = get_pitching_stats(this_play.game.id, lineup_id=this_play.pitcher.id)
if len(p_stats) == 0: if len(p_stats) == 0:
logging.info(f'ai_manager - check_pitching_sub: no stats recorded yet, returning None') logger.info(f'ai_manager - check_pitching_sub: no stats recorded yet, returning None')
return False return False
ps = p_stats[0] ps = p_stats[0]
logging.info(f'ai_manager - check_pitching_sub: pitcher does have stats') logger.info(f'ai_manager - check_pitching_sub: pitcher does have stats')
this_ai = get_manager(this_play.game) this_ai = get_manager(this_play.game)
this_pc = await data_cache.get_pd_pitchingcard(this_play.pitcher.player_id, variant=this_play.pitcher.variant) this_pc = await data_cache.get_pd_pitchingcard(this_play.pitcher.player_id, variant=this_play.pitcher.variant)
@ -632,7 +633,7 @@ async def check_pitching_sub(this_play: StratPlay, ai_team: dict):
if rp_pitcard.card.relief_rating == 1: if rp_pitcard.card.relief_rating == 1:
patch_play(this_play.id, in_pow=True) patch_play(this_play.id, in_pow=True)
except Exception as e: except Exception as e:
logging.info(f'ai_manager - check_pitching_sub - could not pull card for {rp_lineup.player_id}') logger.info(f'ai_manager - check_pitching_sub - could not pull card for {rp_lineup.player_id}')
return await get_player(this_play.game, rp_lineup) return await get_player(this_play.game, rp_lineup)
return None return None
@ -655,7 +656,7 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
) )
p_stats = get_pitching_stats(this_play.game.id, lineup_id=this_play.pitcher.id) p_stats = get_pitching_stats(this_play.game.id, lineup_id=this_play.pitcher.id)
if len(p_stats) == 0: if len(p_stats) == 0:
logging.info(f'ai_manager - is_pitcher_fatigued: no stats recorded yet, returning False') logger.info(f'ai_manager - is_pitcher_fatigued: no stats recorded yet, returning False')
return False return False
ps = p_stats[0] ps = p_stats[0]
@ -665,7 +666,7 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
try: try:
this_pc = await data_cache.get_pd_pitchingcard(this_play.pitcher.player_id, variant=this_play.pitcher.variant) this_pc = await data_cache.get_pd_pitchingcard(this_play.pitcher.player_id, variant=this_play.pitcher.variant)
except: except:
logging.info( logger.info(
f'ai_manager - is_pitcher_fatigued: could not pull pitching card for {this_play.pitcher.player_id}, ' f'ai_manager - is_pitcher_fatigued: could not pull pitching card for {this_play.pitcher.player_id}, '
f'returning False') f'returning False')
return False return False
@ -674,45 +675,45 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
# Check starter fatigue # Check starter fatigue
if len(used_pitchers) == 1: if len(used_pitchers) == 1:
if ps['pl_runs'] >= 7: if ps['pl_runs'] >= 7:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 7+, returning True') logger.info(f'ai_manager - is_pitcher_fatigued: starter allowed 7+, returning True')
return True return True
elif ps['pl_runs'] >= 6: elif ps['pl_runs'] >= 6:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 6+, checking for fatigue') logger.info(f'ai_manager - is_pitcher_fatigued: starter allowed 6+, checking for fatigue')
f_query = get_pitching_stats( f_query = get_pitching_stats(
this_play.game.id, this_play.game.id,
lineup_id=this_play.pitcher.id, lineup_id=this_play.pitcher.id,
in_innings=[this_play.inning_num, this_play.inning_num - 1] in_innings=[this_play.inning_num, this_play.inning_num - 1]
) )
if f_query[0]['pl_in_runs'] >= 6: if f_query[0]['pl_in_runs'] >= 6:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 6 in 2, returning True') logger.info(f'ai_manager - is_pitcher_fatigued: starter allowed 6 in 2, returning True')
patch_lineup(this_play.pitcher.id, is_fatigued=True) patch_lineup(this_play.pitcher.id, is_fatigued=True)
return True return True
elif ps['pl_runs'] >= 5: elif ps['pl_runs'] >= 5:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 5+, checking for fatigue') logger.info(f'ai_manager - is_pitcher_fatigued: starter allowed 5+, checking for fatigue')
f_query = get_pitching_stats( f_query = get_pitching_stats(
this_play.game.id, this_play.game.id,
lineup_id=this_play.pitcher.id, lineup_id=this_play.pitcher.id,
in_innings=[this_play.inning_num] in_innings=[this_play.inning_num]
) )
if f_query[0]['pl_in_runs'] >= 5: if f_query[0]['pl_in_runs'] >= 5:
logging.info(f'ai_manager - is_pitcher_fatigued: starter allowed 5 in 1, returning True') logger.info(f'ai_manager - is_pitcher_fatigued: starter allowed 5 in 1, returning True')
patch_lineup(this_play.pitcher.id, is_fatigued=True) patch_lineup(this_play.pitcher.id, is_fatigued=True)
return True return True
innof_work = math.ceil((ps['pl_outs'] + 1) / 3) innof_work = math.ceil((ps['pl_outs'] + 1) / 3)
if innof_work < pof_weakness: if innof_work < pof_weakness:
logging.info(f'ai_manager - is_pitcher_fatigued: not point of weakness, returning False') logger.info(f'ai_manager - is_pitcher_fatigued: not point of weakness, returning False')
return False return False
elif innof_work == pof_weakness: elif innof_work == pof_weakness:
patch_play(this_play.id, in_pow=True) patch_play(this_play.id, in_pow=True)
pow_stats = get_pitching_stats(this_play.game.id, lineup_id=this_play.pitcher.id, in_pow=True) pow_stats = get_pitching_stats(this_play.game.id, lineup_id=this_play.pitcher.id, in_pow=True)
if len(pow_stats) == 0: if len(pow_stats) == 0:
logging.info(f'ai_manager - is_pitcher_fatigued: in point of weakness, no stats recorded, returning False') logger.info(f'ai_manager - is_pitcher_fatigued: in point of weakness, no stats recorded, returning False')
return False return False
pows = pow_stats[0] pows = pow_stats[0]
if pows['pl_hit'] + pows['pl_bb'] + pows['pl_hbp'] < 3: if pows['pl_hit'] + pows['pl_bb'] + pows['pl_hbp'] < 3:
logging.info(f'ai_manager - is_pitcher_fatigued: in point of weakness, not fatigued, returning False') logger.info(f'ai_manager - is_pitcher_fatigued: in point of weakness, not fatigued, returning False')
return False return False
elif innof_work > pof_weakness: elif innof_work > pof_weakness:
@ -720,7 +721,7 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
patch_lineup(this_play.pitcher.id, is_fatigued=True) patch_lineup(this_play.pitcher.id, is_fatigued=True)
return True return True
logging.info(f'ai_manager - is_pitcher_fatigued: beyond point of weakness, fatigued, returning True') logger.info(f'ai_manager - is_pitcher_fatigued: beyond point of weakness, fatigued, returning True')
patch_lineup(this_play.pitcher.id, is_fatigued=True) patch_lineup(this_play.pitcher.id, is_fatigued=True)
return True return True

View File

@ -10,6 +10,7 @@ PLAYER_CACHE = {}
TEAM_CACHE = {} TEAM_CACHE = {}
BATTINGCARD_CACHE = {} # { <player_id: int>: { <variant: int>: BattingWrapper } } BATTINGCARD_CACHE = {} # { <player_id: int>: { <variant: int>: BattingWrapper } }
PITCHINGCARD_CACHE = {} # { <player_id: int>: { <variant: int>: PitchingWrapper } } PITCHINGCARD_CACHE = {} # { <player_id: int>: { <variant: int>: PitchingWrapper } }
logger = logging.getLogger('discord_app')
@dataclass @dataclass
@ -265,19 +266,19 @@ async def get_pd_player(player_id, as_dict: Optional[bool] = True, skip_cache: b
if player_id in PLAYER_CACHE and not skip_cache: if player_id in PLAYER_CACHE and not skip_cache:
tdelta = datetime.datetime.now() - PLAYER_CACHE[player_id].created tdelta = datetime.datetime.now() - PLAYER_CACHE[player_id].created
if tdelta.total_seconds() < 1209600: if tdelta.total_seconds() < 1209600:
logging.debug(f'this_player: {PLAYER_CACHE[player_id]}') logger.debug(f'this_player: {PLAYER_CACHE[player_id]}')
if as_dict: if as_dict:
return PLAYER_CACHE[player_id].to_dict() return PLAYER_CACHE[player_id].to_dict()
else: else:
return PLAYER_CACHE[player_id] return PLAYER_CACHE[player_id]
else: else:
logging.error(f'Refreshing player {player_id} in cache...') logger.error(f'Refreshing player {player_id} in cache...')
this_player = await db_get('players', object_id=player_id) this_player = await db_get('players', object_id=player_id)
for bad_key in ['mlbplayer', 'paperdex']: for bad_key in ['mlbplayer', 'paperdex']:
if bad_key in this_player: if bad_key in this_player:
del this_player[bad_key] del this_player[bad_key]
logging.debug(f'this_player: {this_player}') logger.debug(f'this_player: {this_player}')
PLAYER_CACHE[player_id] = Player(**this_player) PLAYER_CACHE[player_id] = Player(**this_player)
if as_dict: if as_dict:
@ -289,13 +290,13 @@ async def get_pd_team(team_or_gm_id, as_dict: bool = True, skip_cache: bool = Fa
if team_or_gm_id in TEAM_CACHE and not skip_cache: if team_or_gm_id in TEAM_CACHE and not skip_cache:
tdelta = datetime.datetime.now() - TEAM_CACHE[team_or_gm_id].created tdelta = datetime.datetime.now() - TEAM_CACHE[team_or_gm_id].created
if tdelta.total_seconds() < 1209600: if tdelta.total_seconds() < 1209600:
logging.info(f'this_team: {TEAM_CACHE[team_or_gm_id]}') logger.info(f'this_team: {TEAM_CACHE[team_or_gm_id]}')
if as_dict: if as_dict:
return TEAM_CACHE[team_or_gm_id].to_dict() return TEAM_CACHE[team_or_gm_id].to_dict()
else: else:
return TEAM_CACHE[team_or_gm_id] return TEAM_CACHE[team_or_gm_id]
else: else:
logging.error(f'Refreshing team {team_or_gm_id} in cache...') logger.error(f'Refreshing team {team_or_gm_id} in cache...')
this_team = await db_get('teams', object_id=team_or_gm_id, params=[('inc_packs', False)]) this_team = await db_get('teams', object_id=team_or_gm_id, params=[('inc_packs', False)])
if this_team is None: if this_team is None:
@ -304,7 +305,7 @@ async def get_pd_team(team_or_gm_id, as_dict: bool = True, skip_cache: bool = Fa
raise KeyError(f'No team found for ID {team_or_gm_id}') raise KeyError(f'No team found for ID {team_or_gm_id}')
this_team = t_query['teams'][0] this_team = t_query['teams'][0]
logging.info(f'this_team: {this_team}') logger.info(f'this_team: {this_team}')
TEAM_CACHE[team_or_gm_id] = Team(**this_team) TEAM_CACHE[team_or_gm_id] = Team(**this_team)
if as_dict: if as_dict:
@ -316,7 +317,7 @@ async def get_pd_battingcard(player_id: int, variant: Optional[int] = 0):
if player_id in BATTINGCARD_CACHE and variant in BATTINGCARD_CACHE[player_id]: if player_id in BATTINGCARD_CACHE and variant in BATTINGCARD_CACHE[player_id]:
tdelta = datetime.datetime.now() - BATTINGCARD_CACHE[player_id][variant].created tdelta = datetime.datetime.now() - BATTINGCARD_CACHE[player_id][variant].created
if tdelta.total_seconds() < 609600: if tdelta.total_seconds() < 609600:
logging.info(f'this_battingcard: {BATTINGCARD_CACHE[player_id][variant]}') logger.info(f'this_battingcard: {BATTINGCARD_CACHE[player_id][variant]}')
return BATTINGCARD_CACHE[player_id][variant] return BATTINGCARD_CACHE[player_id][variant]
vl_data, vr_data = None, None vl_data, vr_data = None, None
@ -334,23 +335,23 @@ async def get_pd_battingcard(player_id: int, variant: Optional[int] = 0):
if None in [vl_data, vr_data]: if None in [vl_data, vr_data]:
raise KeyError(f'Could not find batting card ratings for player {player_id} variant {variant}') raise KeyError(f'Could not find batting card ratings for player {player_id} variant {variant}')
logging.info(f'prepping the batting card') logger.info(f'prepping the batting card')
bc_data = vl_data['battingcard'] bc_data = vl_data['battingcard']
bc_data['player_id'] = player_id bc_data['player_id'] = player_id
del bc_data['id'], bc_data['player'] del bc_data['id'], bc_data['player']
this_bc = BattingCard(**bc_data) this_bc = BattingCard(**bc_data)
logging.info(f'prepping the vl ratings') logger.info(f'prepping the vl ratings')
vl_ratings = vl_data vl_ratings = vl_data
del vl_ratings['battingcard'], vl_ratings['id'], vl_ratings['vs_hand'] del vl_ratings['battingcard'], vl_ratings['id'], vl_ratings['vs_hand']
this_vl = BattingRatings(**vl_ratings) this_vl = BattingRatings(**vl_ratings)
logging.info(f'prepping the vl ratings') logger.info(f'prepping the vl ratings')
vr_ratings = vr_data vr_ratings = vr_data
del vr_ratings['battingcard'], vr_ratings['id'], vr_ratings['vs_hand'] del vr_ratings['battingcard'], vr_ratings['id'], vr_ratings['vs_hand']
this_vr = BattingRatings(**vr_ratings) this_vr = BattingRatings(**vr_ratings)
logging.info(f'prepping the wrapper') logger.info(f'prepping the wrapper')
this_wrapper = BattingWrapper( this_wrapper = BattingWrapper(
card=this_bc, card=this_bc,
ratings_vl=this_vl, ratings_vl=this_vl,
@ -369,7 +370,7 @@ async def get_pd_pitchingcard(player_id: int, variant: Optional[int] = 0):
if player_id in PITCHINGCARD_CACHE and variant in PITCHINGCARD_CACHE[player_id]: if player_id in PITCHINGCARD_CACHE and variant in PITCHINGCARD_CACHE[player_id]:
tdelta = datetime.datetime.now() - PITCHINGCARD_CACHE[player_id][variant].created tdelta = datetime.datetime.now() - PITCHINGCARD_CACHE[player_id][variant].created
if tdelta.total_seconds() < 609600: if tdelta.total_seconds() < 609600:
logging.debug(f'this_pitchingcard: {PITCHINGCARD_CACHE[player_id][variant]}') logger.debug(f'this_pitchingcard: {PITCHINGCARD_CACHE[player_id][variant]}')
return PITCHINGCARD_CACHE[player_id][variant] return PITCHINGCARD_CACHE[player_id][variant]
vl_data, vr_data = None, None vl_data, vr_data = None, None
@ -387,23 +388,23 @@ async def get_pd_pitchingcard(player_id: int, variant: Optional[int] = 0):
if None in [vl_data, vr_data]: if None in [vl_data, vr_data]:
raise KeyError(f'Could not find pitching card ratings for player {player_id} variant {variant}') raise KeyError(f'Could not find pitching card ratings for player {player_id} variant {variant}')
logging.debug(f'prepping the pitching card') logger.debug(f'prepping the pitching card')
pc_data = vl_data['pitchingcard'] pc_data = vl_data['pitchingcard']
pc_data['player_id'] = player_id pc_data['player_id'] = player_id
del pc_data['id'], pc_data['player'] del pc_data['id'], pc_data['player']
this_pc = PitchingCard(**pc_data) this_pc = PitchingCard(**pc_data)
logging.debug(f'prepping the vl ratings') logger.debug(f'prepping the vl ratings')
vl_ratings = vl_data vl_ratings = vl_data
del vl_ratings['pitchingcard'], vl_ratings['id'], vl_ratings['vs_hand'] del vl_ratings['pitchingcard'], vl_ratings['id'], vl_ratings['vs_hand']
this_vl = PitchingRatings(**vl_ratings) this_vl = PitchingRatings(**vl_ratings)
logging.debug(f'prepping the vr ratings') logger.debug(f'prepping the vr ratings')
vr_ratings = vr_data vr_ratings = vr_data
del vr_ratings['pitchingcard'], vr_ratings['id'], vr_ratings['vs_hand'] del vr_ratings['pitchingcard'], vr_ratings['id'], vr_ratings['vs_hand']
this_vr = PitchingRatings(**vr_ratings) this_vr = PitchingRatings(**vr_ratings)
logging.debug(f'prepping the wrapper') logger.debug(f'prepping the wrapper')
this_wrapper = PitchingWrapper( this_wrapper = PitchingWrapper(
card=this_pc, card=this_pc,
ratings_vl=this_vl, ratings_vl=this_vl,

View File

@ -12,6 +12,7 @@ from helpers import Pagination, get_team_embed, image_embed, Confirm
from typing import Literal, Optional from typing import Literal, Optional
PUBLIC_FIELDS_CATEGORY_NAME = 'Public Fields' PUBLIC_FIELDS_CATEGORY_NAME = 'Public Fields'
logger = logging.getLogger('discord_app')
def single_onestar(this_play: StratPlay, comp_play: bool = True): def single_onestar(this_play: StratPlay, comp_play: bool = True):
@ -58,12 +59,12 @@ async def next_pitcher(this_play: StratPlay, ai_team, bot):
used_pitchers = await get_team_lineups( used_pitchers = await get_team_lineups(
game_id=this_play.game.id, team_id=ai_team['id'], inc_inactive=True, pitchers_only=True, as_string=False game_id=this_play.game.id, team_id=ai_team['id'], inc_inactive=True, pitchers_only=True, as_string=False
) )
logging.debug(f'\n\nused_pitchers: {used_pitchers}') logger.debug(f'\n\nused_pitchers: {used_pitchers}')
used_ids = [x.card_id for x in used_pitchers] used_ids = [x.card_id for x in used_pitchers]
logging.debug(f'used_ids: {used_ids}') logger.debug(f'used_ids: {used_ids}')
bullpen = get_or_create_bullpen(ai_team, bot) bullpen = get_or_create_bullpen(ai_team, bot)
logging.debug(f'bullpen: {bullpen}') logger.debug(f'bullpen: {bullpen}')
if this_play.game.short_game: if this_play.game.short_game:
if this_play.inning_num == 1: if this_play.inning_num == 1:
@ -124,7 +125,7 @@ def starting_pitcher(ai_team, bot, is_home):
rotation_range = f'I4:I8' rotation_range = f'I4:I8'
raw_cells = r_sheet.range(rotation_range) raw_cells = r_sheet.range(rotation_range)
d_100 = random.randint(1, 100) d_100 = random.randint(1, 100)
logging.info(f'raw_cells: {raw_cells} / d_100: {d_100}') logger.info(f'raw_cells: {raw_cells} / d_100: {d_100}')
if is_home: if is_home:
if d_100 <= 30: if d_100 <= 30:
@ -195,7 +196,7 @@ async def show_outfield_cards(interaction: discord.Interaction, this_play: Strat
this_play.game.id, team_id=this_play.pitcher.team_id, position='RF', active=True this_play.game.id, team_id=this_play.pitcher.team_id, position='RF', active=True
)) ))
this_team = await db_get('teams', object_id=this_play.pitcher.team_id) this_team = await db_get('teams', object_id=this_play.pitcher.team_id)
logging.debug(f'lf: {lf_player}\n\ncf: {cf_player}\n\nrf: {rf_player}\n\nteam: {this_team["lname"]}') logger.debug(f'lf: {lf_player}\n\ncf: {cf_player}\n\nrf: {rf_player}\n\nteam: {this_team["lname"]}')
view = Pagination([interaction.user], timeout=6) view = Pagination([interaction.user], timeout=6)
view.left_button.label = f'Left Fielder' view.left_button.label = f'Left Fielder'
@ -275,14 +276,14 @@ def runner_on_third(this_play: StratPlay):
def gb_result_1(this_play: StratPlay) -> Optional[int]: def gb_result_1(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 1') logger.info(f'GB 1')
advance_runners(this_play.id, num_bases=0) advance_runners(this_play.id, num_bases=0)
patch_play(this_play.id, pa=1, ab=1, outs=1) patch_play(this_play.id, pa=1, ab=1, outs=1)
return None return None
def gb_result_2(this_play: StratPlay) -> Optional[int]: def gb_result_2(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 2') logger.info(f'GB 2')
num_outs = 2 if this_play.starting_outs <= 1 else 1 num_outs = 2 if this_play.starting_outs <= 1 else 1
patch_play(this_play.id, pa=1, ab=1, outs=num_outs, on_first_final=False) patch_play(this_play.id, pa=1, ab=1, outs=num_outs, on_first_final=False)
@ -296,7 +297,7 @@ def gb_result_2(this_play: StratPlay) -> Optional[int]:
def gb_result_3(this_play: StratPlay) -> Optional[int]: def gb_result_3(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 3') logger.info(f'GB 3')
if this_play.starting_outs < 2: if this_play.starting_outs < 2:
advance_runners(this_play.id, num_bases=1) advance_runners(this_play.id, num_bases=1)
patch_play(this_play.id, pa=1, ab=1, outs=1) patch_play(this_play.id, pa=1, ab=1, outs=1)
@ -304,7 +305,7 @@ def gb_result_3(this_play: StratPlay) -> Optional[int]:
def gb_result_4(this_play: StratPlay) -> Optional[int]: def gb_result_4(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 4') logger.info(f'GB 4')
patch_play(this_play.id, pa=1, ab=1, outs=1, on_first_final=False) patch_play(this_play.id, pa=1, ab=1, outs=1, on_first_final=False)
if this_play.starting_outs < 2: if this_play.starting_outs < 2:
if runner_on_second(this_play): if runner_on_second(this_play):
@ -316,7 +317,7 @@ def gb_result_4(this_play: StratPlay) -> Optional[int]:
def gb_result_5(this_play: StratPlay, to_mif: bool) -> Optional[int]: def gb_result_5(this_play: StratPlay, to_mif: bool) -> Optional[int]:
logging.info(f'GB 5') logger.info(f'GB 5')
patch_play(this_play.id, pa=1, ab=1, outs=1) patch_play(this_play.id, pa=1, ab=1, outs=1)
if to_mif: if to_mif:
gb_result_3(this_play) gb_result_3(this_play)
@ -327,7 +328,7 @@ def gb_result_5(this_play: StratPlay, to_mif: bool) -> Optional[int]:
def gb_result_6(this_play: StratPlay, to_right_side: bool) -> Optional[int]: def gb_result_6(this_play: StratPlay, to_right_side: bool) -> Optional[int]:
logging.info(f'GB 6') logger.info(f'GB 6')
patch_play(this_play.id, pa=1, ab=1, outs=1) patch_play(this_play.id, pa=1, ab=1, outs=1)
if to_right_side: if to_right_side:
gb_result_3(this_play) gb_result_3(this_play)
@ -338,24 +339,24 @@ def gb_result_6(this_play: StratPlay, to_right_side: bool) -> Optional[int]:
def gb_result_7(this_play: StratPlay) -> Optional[int]: def gb_result_7(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 7') logger.info(f'GB 7')
patch_play(this_play.id, pa=1, ab=1, outs=1) patch_play(this_play.id, pa=1, ab=1, outs=1)
advance_runners(this_play.id, num_bases=1, only_forced=True) advance_runners(this_play.id, num_bases=1, only_forced=True)
return None return None
def gb_result_8(this_play: StratPlay) -> Optional[int]: def gb_result_8(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 8') logger.info(f'GB 8')
return gb_result_7(this_play) return gb_result_7(this_play)
def gb_result_9(this_play: StratPlay) -> Optional[int]: def gb_result_9(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 9') logger.info(f'GB 9')
return gb_result_7(this_play) return gb_result_7(this_play)
def gb_result_10(this_play: StratPlay) -> Optional[int]: def gb_result_10(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 10') logger.info(f'GB 10')
num_outs = 2 if this_play.starting_outs <= 1 else 1 num_outs = 2 if this_play.starting_outs <= 1 else 1
patch_play(this_play.id, pa=1, ab=1, outs=num_outs, on_third_final=False) patch_play(this_play.id, pa=1, ab=1, outs=num_outs, on_third_final=False)
advance_one_runner(this_play.id, from_base=2, num_bases=1) advance_one_runner(this_play.id, from_base=2, num_bases=1)
@ -365,13 +366,13 @@ def gb_result_10(this_play: StratPlay) -> Optional[int]:
def gb_result_11(this_play: StratPlay) -> Optional[int]: def gb_result_11(this_play: StratPlay) -> Optional[int]:
logging.info(f'GB 11') logger.info(f'GB 11')
patch_play(this_play.id, pa=1, ab=1, outs=1, on_first_final=2, on_second_final=3, on_third_final=False) patch_play(this_play.id, pa=1, ab=1, outs=1, on_first_final=2, on_second_final=3, on_third_final=False)
return 1 return 1
async def gb_decide(this_play: StratPlay, interaction: discord.Interaction, runner: dict, from_base: int): async def gb_decide(this_play: StratPlay, interaction: discord.Interaction, runner: dict, from_base: int):
logging.info(f'GB Decide') logger.info(f'GB Decide')
ai_is_batting = ai_batting(this_play.game, this_play) ai_is_batting = ai_batting(this_play.game, this_play)
ai_manager = get_manager(this_play.game) ai_manager = get_manager(this_play.game)
bases = ['first', 'second', 'third'] bases = ['first', 'second', 'third']
@ -445,7 +446,7 @@ async def gb_decide(this_play: StratPlay, interaction: discord.Interaction, runn
async def gb_result_12(this_play: StratPlay, defender: Literal['1b-2b', '3b', 'ss-p-c'], async def gb_result_12(this_play: StratPlay, defender: Literal['1b-2b', '3b', 'ss-p-c'],
interaction: discord.Interaction) -> Optional[int]: interaction: discord.Interaction) -> Optional[int]:
logging.info(f'GB 12') logger.info(f'GB 12')
if defender == '1b-2b': if defender == '1b-2b':
return gb_result_3(this_play) return gb_result_3(this_play)
elif defender == '3b': elif defender == '3b':
@ -457,7 +458,7 @@ async def gb_result_12(this_play: StratPlay, defender: Literal['1b-2b', '3b', 's
def gb_result_13(this_play: StratPlay, defender: Literal['c-3b', 'else']) -> Optional[int]: def gb_result_13(this_play: StratPlay, defender: Literal['c-3b', 'else']) -> Optional[int]:
logging.info(f'GB 13') logger.info(f'GB 13')
if defender == 'c-3b': if defender == 'c-3b':
num_outs = 2 if this_play.starting_outs <= 1 else 1 num_outs = 2 if this_play.starting_outs <= 1 else 1
patch_play(this_play.id, on_second_final=False, on_first_final=False, pa=1, ab=1, outs=num_outs) patch_play(this_play.id, on_second_final=False, on_first_final=False, pa=1, ab=1, outs=num_outs)

View File

@ -13,10 +13,13 @@ from exceptions import *
from in_game.managerai_responses import JumpResponse, TagResponse, ThrowResponse, UncappedRunResponse from in_game.managerai_responses import JumpResponse, TagResponse, ThrowResponse, UncappedRunResponse
logger = logging.getLogger('discord_app')
sqlite_url = 'sqlite:///storage/gameplay.db' sqlite_url = 'sqlite:///storage/gameplay.db'
connect_args = {"check_same_thread": False} connect_args = {"check_same_thread": False}
engine = create_engine(sqlite_url, echo=False, connect_args=connect_args) engine = create_engine(sqlite_url, echo=False, connect_args=connect_args)
CACHE_LIMIT = 1209600 # in seconds CACHE_LIMIT = 1209600 # in seconds
SBA_COLOR = 'a6ce39'
SBA_LOGO = 'https://sombaseball.ddns.net/static/images/sba-logo.png'
class ManagerAiBase(SQLModel): class ManagerAiBase(SQLModel):
@ -74,6 +77,16 @@ class Team(TeamBase, table=True):
lineups: list['Lineup'] = Relationship(back_populates='team', cascade_delete=True) lineups: list['Lineup'] = Relationship(back_populates='team', cascade_delete=True)
# away_games: list['Game'] = Relationship(back_populates='away_team') # away_games: list['Game'] = Relationship(back_populates='away_team')
# home_games: list['Game'] = Relationship(back_populates='home_team') # home_games: list['Game'] = Relationship(back_populates='home_team')
@property
def embed(self) -> discord.Embed:
embed = discord.Embed(
title=f'{self.lname}',
color=int(self.color, 16) if self.color else int(SBA_COLOR, 16)
)
embed.set_footer(text=f'Paper Dynasty Season {self.season}', icon_url=SBA_LOGO)
embed.set_thumbnail(url=self.logo if self.logo else SBA_LOGO)
return embed
class Game(SQLModel, table=True): class Game(SQLModel, table=True):
@ -86,7 +99,7 @@ class Game(SQLModel, table=True):
is_pd: bool | None = Field(default=True) is_pd: bool | None = Field(default=True)
ranked: bool | None = Field(default=False) ranked: bool | None = Field(default=False)
short_game: bool | None = Field(default=False) short_game: bool | None = Field(default=False)
week_num: int | None = Field(default=None) week: int | None = Field(default=None)
game_num: int | None = Field(default=None) game_num: int | None = Field(default=None)
away_roster_id: int | None = Field(default=None) away_roster_id: int | None = Field(default=None)
home_roster_id: int | None = Field(default=None) home_roster_id: int | None = Field(default=None)
@ -148,11 +161,11 @@ class Game(SQLModel, table=True):
gt_string = ' - Flashback' gt_string = ' - Flashback'
elif 'exhibition' in self.game_type: elif 'exhibition' in self.game_type:
gt_string = ' - Exhibition' gt_string = ' - Exhibition'
logging.info(f'gameplay_models - Game.get_scorebug_embed - this_game: {self} / gt_string: {gt_string}') logger.info(f'gameplay_models - Game.get_scorebug_embed - this_game: {self} / gt_string: {gt_string}')
embed = discord.Embed( embed = discord.Embed(
title=f'{self.away_team.sname} @ {self.home_team.sname}{gt_string}', title=f'{self.away_team.sname} @ {self.home_team.sname}{gt_string}',
color=int('a6ce39', 16) color=int(SBA_COLOR, 16)
) )
curr_play = self.current_play_or_none(session) curr_play = self.current_play_or_none(session)
@ -161,7 +174,7 @@ class Game(SQLModel, table=True):
try: try:
curr_play = self.initialize_play(session) curr_play = self.initialize_play(session)
except LineupsMissingException as e: except LineupsMissingException as e:
logging.debug(f'gameplay_models - Game.get_scorebug_embed - Could not initialize play') logger.debug(f'gameplay_models - Game.get_scorebug_embed - Could not initialize play')
if curr_play is not None: if curr_play is not None:
embed.add_field( embed.add_field(
@ -187,7 +200,7 @@ class Game(SQLModel, table=True):
baserunner_string += f'On Second: {curr_play.on_second.player.name_card_link('batting')}\n' baserunner_string += f'On Second: {curr_play.on_second.player.name_card_link('batting')}\n'
if curr_play.on_third is not None: if curr_play.on_third is not None:
baserunner_string += f'On Third: {curr_play.on_third.player.name_card_link('batting')}' baserunner_string += f'On Third: {curr_play.on_third.player.name_card_link('batting')}'
logging.info(f'gameplay_models - Game.get_scorebug_embed - baserunner_string: {baserunner_string}') logger.info(f'gameplay_models - Game.get_scorebug_embed - baserunner_string: {baserunner_string}')
if len(baserunner_string) > 0: if len(baserunner_string) > 0:
embed.add_field(name=' ', value=' ', inline=False) embed.add_field(name=' ', value=' ', inline=False)
@ -195,7 +208,7 @@ class Game(SQLModel, table=True):
embed.add_field(name='Catcher', value=curr_play.catcher.player.name_card_link('batter')) embed.add_field(name='Catcher', value=curr_play.catcher.player.name_card_link('batter'))
ai_note = curr_play.ai_note ai_note = curr_play.ai_note
logging.info(f'gameplay_models - Game.get_scorebug_embed - ai_note: {ai_note}') logger.info(f'gameplay_models - Game.get_scorebug_embed - ai_note: {ai_note}')
if len(ai_note) > 0: if len(ai_note) > 0:
gm_name = self.home_team.gmname if self.ai_team == 'home' else self.away_team.gmname gm_name = self.home_team.gmname if self.ai_team == 'home' else self.away_team.gmname
embed.add_field(name=f'{gm_name} will...', value=ai_note, inline=False) embed.add_field(name=f'{gm_name} will...', value=ai_note, inline=False)
@ -300,7 +313,7 @@ class ManagerAi(ManagerAiBase, table=True):
def get_new_ai(this_session: Session): def get_new_ai(this_session: Session):
all_ai = this_session.exec(select(ManagerAi.id)).all() all_ai = this_session.exec(select(ManagerAi.id)).all()
if len(all_ai) == 0: if len(all_ai) == 0:
logging.info(f'Creating ManagerAI records') logger.info(f'Creating ManagerAI records')
new_ai = [ new_ai = [
ManagerAi( ManagerAi(
name='Balanced' name='Balanced'
@ -560,7 +573,7 @@ class PlayerBase(SQLModel):
elif self.image2 is not None and 'pitching' in self.image2: elif self.image2 is not None and 'pitching' in self.image2:
return self.image2 return self.image2
else: else:
logging.error(f'gameplay_models - PlayerBase - pitching card url not found for {self.id}. {self.description} {self.name}') logger.error(f'gameplay_models - PlayerBase - pitching card url not found for {self.id}. {self.description} {self.name}')
return self.image return self.image
@property @property
@ -570,7 +583,7 @@ class PlayerBase(SQLModel):
elif self.image2 is not None and 'batting' in self.image2: elif self.image2 is not None and 'batting' in self.image2:
return self.image2 return self.image2
else: else:
logging.error(f'gameplay_models - PlayerBase - batting card url not found for {self.id}. {self.description} {self.name}') logger.error(f'gameplay_models - PlayerBase - batting card url not found for {self.id}. {self.description} {self.name}')
return self.image return self.image
def name_card_link(self, which: Literal['pitching', 'batting']): def name_card_link(self, which: Literal['pitching', 'batting']):
@ -593,7 +606,7 @@ class Player(PlayerBase, table=True):
def player_description(player: Player = None, player_dict: dict = None) -> str: def player_description(player: Player = None, player_dict: dict = None) -> str:
if player is None and player_dict is None: if player is None and player_dict is None:
err = 'One of "player" or "player_dict" must be included to get full description' err = 'One of "player" or "player_dict" must be included to get full description'
logging.error(f'gameplay_models - player_description - {err}') logger.error(f'gameplay_models - player_description - {err}')
raise TypeError(err) raise TypeError(err)
if player is not None: if player is not None:

View File

@ -1,23 +1,47 @@
import datetime import datetime
import logging import logging
import math
import pydantic
from sqlalchemy import func from sqlalchemy import func
from api_calls import db_get, db_post from api_calls import db_get, db_post
from in_game.gameplay_models import CACHE_LIMIT, Card, CardBase, Lineup, Player, PlayerBase, Session, Team, TeamBase, select, or_, Game, Play from in_game.gameplay_models import CACHE_LIMIT, Card, CardBase, Lineup, Player, PlayerBase, Session, Team, TeamBase, select, or_, Game, Play
from exceptions import log_exception, PlayNotFoundException from exceptions import DatabaseError, log_exception, PlayNotFoundException
logger = logging.getLogger('discord_app')
class DecisionModel(pydantic.BaseModel):
game_id: int
season: int
week: int
pitcher_id: int
pitcher_team_id: int
win: int = 0
loss: int = 0
hold: int = 0
is_save: int = 0
is_start: bool = False
b_save: int = 0
irunners: int = 0
irunners_scored: int = 0
rest_ip: float = 0
rest_required: int = 0
game_finished: int = 0
def get_games_by_channel(session: Session, channel_id: int) -> list[Game]: def get_games_by_channel(session: Session, channel_id: int) -> list[Game]:
logging.info(f'Getting games in channel {channel_id}') logger.info(f'Getting games in channel {channel_id}')
return session.exec(select(Game).where(Game.channel_id == channel_id, Game.active)).all() return session.exec(select(Game).where(Game.channel_id == channel_id, Game.active)).all()
def get_channel_game_or_none(session: Session, channel_id: int) -> Game | None: def get_channel_game_or_none(session: Session, channel_id: int) -> Game | None:
logging.info(f'Getting one game from channel {channel_id}') logger.info(f'Getting one game from channel {channel_id}')
all_games = get_games_by_channel(session, channel_id) all_games = get_games_by_channel(session, channel_id)
if len(all_games) > 1: if len(all_games) > 1:
err = 'Too many games found in get_channel_game_or_none' err = 'Too many games found in get_channel_game_or_none'
logging.error(f'cogs.gameplay - get_channel_game_or_none - channel_id: {channel_id} / {err}') logger.error(f'cogs.gameplay - get_channel_game_or_none - channel_id: {channel_id} / {err}')
raise Exception(err) raise Exception(err)
elif len(all_games) == 0: elif len(all_games) == 0:
return None return None
@ -25,16 +49,16 @@ def get_channel_game_or_none(session: Session, channel_id: int) -> Game | None:
def get_active_games_by_team(session: Session, team: Team) -> list[Game]: def get_active_games_by_team(session: Session, team: Team) -> list[Game]:
logging.info(f'Getting game for team {team.lname}') logger.info(f'Getting game for team {team.lname}')
return session.exec(select(Game).where(Game.active, or_(Game.away_team_id == team.id, Game.home_team_id == team.id))).all() return session.exec(select(Game).where(Game.active, or_(Game.away_team_id == team.id, Game.home_team_id == team.id))).all()
async def get_team_or_none( async def get_team_or_none(
session: Session, team_id: int | None = None, gm_id: int | None = None, team_abbrev: str | None = None, skip_cache: bool = False) -> Team | None: session: Session, team_id: int | None = None, gm_id: int | None = None, team_abbrev: str | None = None, skip_cache: bool = False) -> Team | None:
logging.info(f'Getting team or none / team_id: {team_id} / gm_id: {gm_id} / team_abbrev: {team_abbrev} / skip_cache: {skip_cache}') logger.info(f'Getting team or none / team_id: {team_id} / gm_id: {gm_id} / team_abbrev: {team_abbrev} / skip_cache: {skip_cache}')
if team_id is None and gm_id is None and team_abbrev is None: if team_id is None and gm_id is None and team_abbrev is None:
err = 'One of "team_id", "gm_id", or "team_abbrev" must be included in search' err = 'One of "team_id", "gm_id", or "team_abbrev" must be included in search'
logging.error(f'gameplay_models - get_team - {err}') logger.error(f'gameplay_models - get_team - {err}')
raise TypeError(err) raise TypeError(err)
if not skip_cache: if not skip_cache:
@ -48,9 +72,9 @@ async def get_team_or_none(
this_team = session.exec(statement).one_or_none() this_team = session.exec(statement).one_or_none()
if this_team is not None: if this_team is not None:
logging.debug(f'we found a team: {this_team} / created: {this_team.created}') logger.debug(f'we found a team: {this_team} / created: {this_team.created}')
tdelta = datetime.datetime.now() - this_team.created tdelta = datetime.datetime.now() - this_team.created
logging.debug(f'tdelta: {tdelta}') logger.debug(f'tdelta: {tdelta}')
if tdelta.total_seconds() < CACHE_LIMIT: if tdelta.total_seconds() < CACHE_LIMIT:
return this_team return this_team
else: else:
@ -58,11 +82,11 @@ async def get_team_or_none(
session.commit() session.commit()
def cache_team(json_data: dict) -> Team: def cache_team(json_data: dict) -> Team:
# logging.info(f'gameplay_models - get_team - cache_team - writing a team to cache: {json_data}') # logger.info(f'gameplay_models - get_team - cache_team - writing a team to cache: {json_data}')
valid_team = TeamBase.model_validate(json_data, from_attributes=True) valid_team = TeamBase.model_validate(json_data, from_attributes=True)
# logging.info(f'gameplay_models - get_team - cache_team - valid_team: {valid_team}') # logger.info(f'gameplay_models - get_team - cache_team - valid_team: {valid_team}')
db_team = Team.model_validate(valid_team) db_team = Team.model_validate(valid_team)
# logging.info(f'gameplay_models - get_team - cache_team - db_team: {db_team}') # logger.info(f'gameplay_models - get_team - cache_team - db_team: {db_team}')
session.add(db_team) session.add(db_team)
session.commit() session.commit()
session.refresh(db_team) session.refresh(db_team)
@ -89,14 +113,14 @@ async def get_team_or_none(
async def get_player_or_none(session: Session, player_id: int, skip_cache: bool = False) -> Player | None: async def get_player_or_none(session: Session, player_id: int, skip_cache: bool = False) -> Player | None:
logging.info(f'gameplay_models - get_player_or_none - player_id: {player_id}') logger.info(f'gameplay_models - get_player_or_none - player_id: {player_id}')
if not skip_cache: if not skip_cache:
this_player = session.get(Player, player_id) this_player = session.get(Player, player_id)
if this_player is not None: if this_player is not None:
logging.info(f'we found a cached player: {this_player} / created: {this_player.created}') logger.info(f'we found a cached player: {this_player} / created: {this_player.created}')
tdelta = datetime.datetime.now() - this_player.created tdelta = datetime.datetime.now() - this_player.created
logging.debug(f'tdelta: {tdelta}') logger.debug(f'tdelta: {tdelta}')
if tdelta.total_seconds() < CACHE_LIMIT: if tdelta.total_seconds() < CACHE_LIMIT:
return this_player return this_player
else: else:
@ -104,7 +128,7 @@ async def get_player_or_none(session: Session, player_id: int, skip_cache: bool
session.commit() session.commit()
def cache_player(json_data: dict) -> Player: def cache_player(json_data: dict) -> Player:
logging.info(f'gameplay_models - get_player_or_none - cache_player - caching player data: {json_data}') logger.info(f'gameplay_models - get_player_or_none - cache_player - caching player data: {json_data}')
valid_player = PlayerBase.model_validate(json_data, from_attributes=True) valid_player = PlayerBase.model_validate(json_data, from_attributes=True)
db_player = Player.model_validate(valid_player) db_player = Player.model_validate(valid_player)
session.add(db_player) session.add(db_player)
@ -124,32 +148,39 @@ async def get_player_or_none(session: Session, player_id: int, skip_cache: bool
def get_player_id_from_dict(json_data: dict) -> int: def get_player_id_from_dict(json_data: dict) -> int:
logging.info(f'Getting player from dict {json_data}') logger.info(f'Getting player from dict {json_data}')
if 'player_id' in json_data: if 'player_id' in json_data:
return json_data['player_id'] return json_data['player_id']
elif 'id' in json_data: elif 'id' in json_data:
return json_data['id'] return json_data['id']
err = 'Player ID could not be extracted from json data' log_exception(KeyError, 'Player ID could not be extracted from json data')
logging.error(f'{err}: {json_data}')
raise KeyError(err)
def get_player_name_from_dict(json_data: dict) -> str:
logger.info(f'Getting player from dict {json_data}')
if 'name' in json_data:
return json_data['name']
elif 'p_name' in json_data:
return json_data['p_name']
log_exception(KeyError, 'Player name could not be extracted from json data')
async def get_or_create_ai_card(session: Session, player: Player, team: Team, skip_cache: bool = False, dev_mode: bool = False) -> Card: async def get_or_create_ai_card(session: Session, player: Player, team: Team, skip_cache: bool = False, dev_mode: bool = False) -> Card:
logging.info(f'Getting or creating card for {player.name_with_desc} on the {team.sname}') logger.info(f'Getting or creating card for {player.name_with_desc} on the {team.sname}')
if not team.is_ai: if not team.is_ai:
err = f'Cannot create AI cards for human teams' err = f'Cannot create AI cards for human teams'
logging.error(f'gameplay_models - get_or_create_ai_card: {err}') logger.error(f'gameplay_models - get_or_create_ai_card: {err}')
raise TypeError(err) raise TypeError(err)
logging.info(f'gameplay_models - get_or_create_ai_card - player.id: {player.id} / team.id: {team.id}') logger.info(f'gameplay_models - get_or_create_ai_card - player.id: {player.id} / team.id: {team.id}')
if not skip_cache: if not skip_cache:
c_query = session.exec(select(Card).where(Card.player == player, Card.team == team)).all() c_query = session.exec(select(Card).where(Card.player == player, Card.team == team)).all()
if len(c_query) > 0: if len(c_query) > 0:
this_card = c_query[0] this_card = c_query[0]
logging.info(f'we found a cached card: {this_card} / created: {this_card.created}') logger.info(f'we found a cached card: {this_card} / created: {this_card.created}')
tdelta = datetime.datetime.now() - this_card.created tdelta = datetime.datetime.now() - this_card.created
logging.debug(f'tdelta: {tdelta}') logger.debug(f'tdelta: {tdelta}')
if tdelta.total_seconds() < CACHE_LIMIT: if tdelta.total_seconds() < CACHE_LIMIT:
return this_card return this_card
else: else:
@ -160,7 +191,7 @@ async def get_or_create_ai_card(session: Session, player: Player, team: Team, sk
c_query = await db_get('cards', params=[('team_id', t.id), ('player_id', p.id)]) c_query = await db_get('cards', params=[('team_id', t.id), ('player_id', p.id)])
if c_query['count'] > 0: if c_query['count'] > 0:
json_data = c_query['cards'][0] json_data = c_query['cards'][0]
logging.info(f'gameplay_models - get_or_create_ai_card - pull_card - caching json_data: {json_data}') logger.info(f'gameplay_models - get_or_create_ai_card - pull_card - caching json_data: {json_data}')
json_data['team_id'] = json_data['team']['id'] json_data['team_id'] = json_data['team']['id']
json_data['player_id'] = get_player_id_from_dict(json_data['player']) json_data['player_id'] = get_player_id_from_dict(json_data['player'])
valid_card = CardBase.model_validate(c_query['cards'][0], from_attributes=True) valid_card = CardBase.model_validate(c_query['cards'][0], from_attributes=True)
@ -176,7 +207,7 @@ async def get_or_create_ai_card(session: Session, player: Player, team: Team, sk
if this_card is not None: if this_card is not None:
return this_card return this_card
logging.info(f'gameplay_models - get_or_create_ai_card: creating {player.description} {player.name} card for {team.abbrev}') logger.info(f'gameplay_models - get_or_create_ai_card: creating {player.description} {player.name} card for {team.abbrev}')
if dev_mode: if dev_mode:
this_card = Card(player=player, team=team) this_card = Card(player=player, team=team)
@ -197,19 +228,19 @@ async def get_or_create_ai_card(session: Session, player: Player, team: Team, sk
return this_card return this_card
err = f'Could not create {player.name} card for {team.abbrev}' err = f'Could not create {player.name} card for {team.abbrev}'
logging.error(f'gameplay_models - get_or_create_ai_card - {err}') logger.error(f'gameplay_models - get_or_create_ai_card - {err}')
raise LookupError(err) raise LookupError(err)
async def get_card_or_none(session: Session, card_id: int, skip_cache: bool = False) -> Card | None: async def get_card_or_none(session: Session, card_id: int, skip_cache: bool = False) -> Card | None:
logging.info(f'Getting card {card_id}') logger.info(f'Getting card {card_id}')
if not skip_cache: if not skip_cache:
this_card = session.get(Card, card_id) this_card = session.get(Card, card_id)
if this_card is not None: if this_card is not None:
logging.info(f'we found a cached card: {this_card} / created: {this_card.created}') logger.info(f'we found a cached card: {this_card} / created: {this_card.created}')
tdelta = datetime.datetime.now() - this_card.created tdelta = datetime.datetime.now() - this_card.created
logging.debug(f'tdelta: {tdelta}') logger.debug(f'tdelta: {tdelta}')
if tdelta.total_seconds() < CACHE_LIMIT: if tdelta.total_seconds() < CACHE_LIMIT:
return this_card return this_card
else: else:
@ -243,7 +274,7 @@ async def get_card_or_none(session: Session, card_id: int, skip_cache: bool = Fa
def get_game_lineups(session: Session, this_game: Game, specific_team: Team = None, is_active: bool = None) -> list[Lineup]: def get_game_lineups(session: Session, this_game: Game, specific_team: Team = None, is_active: bool = None) -> list[Lineup]:
logging.info(f'Getting lineups for game {this_game.id} / specific_team: {specific_team} / is_active: {is_active}') logger.info(f'Getting lineups for game {this_game.id} / specific_team: {specific_team} / is_active: {is_active}')
st = select(Lineup).where(Lineup.game == this_game) st = select(Lineup).where(Lineup.game == this_game)
if specific_team is not None: if specific_team is not None:
@ -255,7 +286,7 @@ def get_game_lineups(session: Session, this_game: Game, specific_team: Team = No
def get_players_last_pa(session: Session, lineup_member: Lineup, none_okay: bool = False): def get_players_last_pa(session: Session, lineup_member: Lineup, none_okay: bool = False):
logging.info(f'Getting last AB for {lineup_member.player.name_with_desc} on the {lineup_member.team.lname}') logger.info(f'Getting last AB for {lineup_member.player.name_with_desc} on the {lineup_member.team.lname}')
last_pa = session.exec(select(Play).where(Play.game == lineup_member.game, Play.batter == lineup_member).order_by(Play.id.desc()).limit(1)).all() last_pa = session.exec(select(Play).where(Play.game == lineup_member.game, Play.batter == lineup_member).order_by(Play.id.desc()).limit(1)).all()
if len(last_pa) == 1: if len(last_pa) == 1:
return last_pa[0] return last_pa[0]
@ -267,7 +298,7 @@ def get_players_last_pa(session: Session, lineup_member: Lineup, none_okay: bool
def get_one_lineup(session: Session, this_game: Game, this_team: Team, active: bool = True, position: str = None, batting_order: int = None) -> Lineup: def get_one_lineup(session: Session, this_game: Game, this_team: Team, active: bool = True, position: str = None, batting_order: int = None) -> Lineup:
logging.info(f'Getting one lineup / this_game: {this_game.id} / this_team: {this_team.lname} / active: {active}, position: {position}, batting_order: {batting_order}') logger.info(f'Getting one lineup / this_game: {this_game.id} / this_team: {this_team.lname} / active: {active}, position: {position}, batting_order: {batting_order}')
if position is None and batting_order is None: if position is None and batting_order is None:
raise KeyError('Position or batting order must be provided for get_one_lineup') raise KeyError('Position or batting order must be provided for get_one_lineup')
@ -281,7 +312,7 @@ def get_one_lineup(session: Session, this_game: Game, this_team: Team, active: b
def get_last_team_play(session: Session, this_game: Game, this_team: Team, none_okay: bool = False): def get_last_team_play(session: Session, this_game: Game, this_team: Team, none_okay: bool = False):
logging.info(f'Getting last play for the {this_team.lname} in game {this_game.id}') logger.info(f'Getting last play for the {this_team.lname} in game {this_game.id}')
last_play = session.exec(select(Play).join(Lineup, onclause=Lineup.id == Play.batter_id).where(Play.game == this_game, Lineup.team == this_team).order_by(Play.id.desc()).limit(1)).all() last_play = session.exec(select(Play).join(Lineup, onclause=Lineup.id == Play.batter_id).where(Play.game == this_game, Lineup.team == this_team).order_by(Play.id.desc()).limit(1)).all()
if len(last_play) == 1: if len(last_play) == 1:
@ -294,7 +325,7 @@ def get_last_team_play(session: Session, this_game: Game, this_team: Team, none_
def get_sorted_lineups(session: Session, this_game: Game, this_team: Team) -> list[Lineup]: def get_sorted_lineups(session: Session, this_game: Game, this_team: Team) -> list[Lineup]:
logging.info(f'Getting sorted lineups for the {this_team.lname} in game {this_game.id}') logger.info(f'Getting sorted lineups for the {this_team.lname} in game {this_game.id}')
custom_order = {'P': 1, 'C': 2, '1B': 3, '2B': 4, '3B': 5, 'SS': 6, 'LF': 7, 'CF': 8, 'RF': 9} custom_order = {'P': 1, 'C': 2, '1B': 3, '2B': 4, '3B': 5, 'SS': 6, 'LF': 7, 'CF': 8, 'RF': 9}
all_lineups = session.exec(select(Lineup).where(Lineup.game == this_game, Lineup.active == True, Lineup.team == this_team)).all() all_lineups = session.exec(select(Lineup).where(Lineup.game == this_game, Lineup.active == True, Lineup.team == this_team)).all()
@ -302,3 +333,254 @@ def get_sorted_lineups(session: Session, this_game: Game, this_team: Team) -> li
sorted_lineups = sorted(all_lineups, key=lambda x: custom_order.get(x.position, float('inf'))) sorted_lineups = sorted(all_lineups, key=lambda x: custom_order.get(x.position, float('inf')))
return sorted_lineups return sorted_lineups
def get_db_ready_plays(session: Session, this_game: Game, db_game_id: int):
logger.info(f'Getting db ready plays for game {this_game.id}')
all_plays = session.exec(select(Play).where(Play.game == this_game)).all()
obc_list = ['000', '001', '010', '100', '011', '101', '110', '111']
return_plays = []
for play in all_plays:
dump = play.model_dump()
dump['game_id'] = db_game_id
dump['on_base_code'] = obc_list[play.on_base_code]
dump['batter_id'] = play.batter.player.id
dump['pitcher_id'] = play.pitcher.player.id
dump['catcher_id'] = play.catcher.player.id
if 'runner_id' in dump and dump['runner_id'] is not None:
dump['runner_id'] = play.runner.player.id
if 'defender_id' in dump and dump['defender_id'] is not None:
dump['defender_id'] = play.defender.player.id
if 'on_first_id' in dump and dump['on_first_id'] is not None:
dump['on_first_id'] = play.on_first.player.id
if 'on_second_id' in dump and dump['on_second_id'] is not None:
dump['on_second_id'] = play.on_second.player.id
if 'on_third_id' in dump and dump['on_third_id'] is not None:
dump['on_third_id'] = play.on_third.player.id
return_plays.append(dump)
return {'plays': return_plays}
def get_db_ready_decisions(session: Session, this_game: Game, db_game_id: int) -> list[DecisionModel]:
logger.info(f'Game {this_game.id} | Getting db ready decisions for game {this_game.id}')
winner = None
loser = None
save = None
away_starter = None
home_starter = None
away_finisher = None
home_finisher = None
b_save = []
holds = []
away_pitcher = None
home_pitcher = None
decisions = {
# { <player_id>: DecisionModel }
}
final_inning = session.exec(select(func.max(Play.inning_num)).where(Play.game == this_game)).one()
# Get starting pitchers and update this as a pointer for the play crawl
for play in session.exec(select(Play).where(Play.game == this_game)).all():
logger.info(f'Game {this_game.id} | Crawling play #{play.play_num}')
runs_scored = 0
if play.inning_half == 'top':
if home_starter is None:
logger.info(f'Game {this_game.id} | Setting home starter to {play.pitcher.player.name_with_desc} on play #{play.play_num}')
home_starter = play.pitcher
if home_finisher is None:
logger.info(f'Game {this_game.id} | Setting home finisher to {play.pitcher.player.name_with_desc} on play #{play.play_num}')
home_finisher = play.pitcher
if home_pitcher != play.pitcher:
logger.info(f'Game {this_game.id} | Setting home pitcher to {play.pitcher.player.name_with_desc} on play #{play.play_num}')
home_pitcher = play.pitcher
if save == play.pitcher:
if play.home_score > play.away_score:
if play.pitcher not in holds:
logger.info(f'Game {this_game.id} | Appending {play.pitcher.player.name_with_desc} to holds on play #{play.play_num}')
holds.append(play.pitcher)
else:
if play.pitcher not in b_save:
logger.info(f'Game {this_game.id} | Appending {play.pitcher.player.name_with_desc} to blown saves on play #{play.play_num}')
b_save.append(play.pitcher)
elif play.home_score > play.away_score and play.home_score - play.away_score <= 3 and home_pitcher != home_starter and play.inning_num + 2 >= final_inning:
logger.info(f'Game {this_game.id} | Setting {play.pitcher.player.name_with_desc} to save on play #{play.play_num}')
save = home_pitcher
elif play.inning_half == 'bot':
if away_starter is None:
logger.info(f'Game {this_game.id} | Setting away starter to {play.pitcher.player.name_with_desc} on play #{play.play_num}')
away_starter = play.pitcher
if away_finisher is None:
logger.info(f'Game {this_game.id} | Setting away finisher to {play.pitcher.player.name_with_desc} on play #{play.play_num}')
away_finisher = play.pitcher
if away_pitcher != play.pitcher:
logger.info(f'Game {this_game.id} | Setting away pitcher to {play.pitcher.player.name_with_desc} on play #{play.play_num}')
away_pitcher = play.pitcher
if save == play.pitcher:
if play.away_score > play.home_score:
if play.pitcher not in holds:
logger.info(f'Game {this_game.id} | Appending {play.pitcher.player.name_with_desc} to holds on play #{play.play_num}')
holds.append(play.pitcher)
else:
if play.pitcher not in b_save:
logger.info(f'Game {this_game.id} | Appending {play.pitcher.player.name_with_desc} to blown saves on play #{play.play_num}')
b_save.append(play.pitcher)
if play.is_go_ahead:
run_diff = play.home_score - play.away_score
for x in [play.on_first_final, play.on_second_final, play.on_third_final, play.batter_final]:
runs_scored += 1 if x == 4 else 0
if play.inning_half == 'top':
run_diff -= runs_scored
else:
run_diff += runs_scored
logger.info(f'run_diff for go-ahead: {run_diff}')
logger.info(f'go-ahead play: {play}')
count = 1
for runner, dest in [(play.on_third, play.on_third_final), (play.on_second, play.on_second_final), (play.on_first, play.on_first_final), (play.batter, play.batter_final)]:
logger.info(f'Game {this_game.id} | Looking for go-ahead runner / runner, dest: {runner}, {dest} / count: {count}')
if dest == 4 and count == abs(run_diff):
winning_play = get_players_last_pa(session, runner)
loser = winning_play.pitcher
logger.info(f'Game {this_game.id} | Setting loser to {loser} on play #{play.play_num}')
if save == loser:
logger.info(f'Game {this_game.id} | Appending {loser} to blown saves on play #{play.play_num}')
b_save.append(loser)
winner = home_pitcher if play.inning_half == 'bot' else away_pitcher
logger.info(f'Game {this_game.id} | Setting winner to {winner} on play #{play.play_num}')
break
count += 1
if winner is None:
logger.info(f'Game {this_game.id} | Setting winner to {winner} by default on play #{play.play_num}')
winner = home_pitcher if play.inning_half == 'bot' else away_pitcher
if loser is None:
logger.info(f'Game {this_game.id} | Setting loser to {loser} by default on play #{play.play_num}')
loser = play.pitcher
if play.is_tied and runs_scored == 0:
logger.info(f'Game {this_game.id} | Clearing winner and loser on play #{play.play_num}')
winner, loser = None, None
if save is not None:
logger.info(f'Game {this_game.id} | Appending current save pitcher {save.player.name_with_desc} to blown saves and clearing save on play #{play.play_num}')
b_save.append(save)
save = None
if play.pitcher_id not in decisions:
logger.info(f'Game {this_game.id} | Adding {play.pitcher.player.name} to decisions dict on play #{play.play_num}')
decisions[play.pitcher.player_id] = DecisionModel(
game_id=db_game_id,
season=this_game.season,
week=0 if this_game.week is None else this_game.week,
pitcher_id=play.pitcher.player_id,
pitcher_team_id=play.pitcher.team_id
)
logger.info(f'winner: {winner} / loser: {loser}')
decisions[winner.player_id].win = 1
decisions[loser.player_id].loss = 1
decisions[away_starter.player_id].is_start = True
decisions[home_starter.player_id].is_start = True
decisions[away_finisher.player_id].game_finished = 1
decisions[home_finisher.player_id].game_finished = 1
for lineup in holds:
decisions[lineup.player_id].hold = 1
if save is not None:
decisions[save.player_id].is_save = 1
decisions[save.player_id].hold = 0
for lineup in b_save:
decisions[lineup.player_id].b_save = 1
decisions[lineup.player_id].save = 0
return [x.model_dump() for x in decisions.values()]
async def post_game_rewards(session: Session, winning_team: Team, losing_team: Team, this_game: Game):
wr_query = await db_get(
'gamerewards', params=[('name', f'{"Short" if this_game.short_game else "Full"} Game Win')])
lr_query = await db_get(
'gamerewards', params=[('name', f'{"Short" if this_game.short_game else "Full"} Game Loss')])
if not wr_query['count'] or not lr_query['count']:
raise DatabaseError(f'Game rewards were not found. Leaving this game active.')
win_reward = wr_query['gamerewards'][0]
loss_reward = lr_query['gamerewards'][0]
win_string = f'1x {win_reward["pack_type"]["name"]} Pack\n'
# Post Campaign Team Choice packs
if this_game.ai_team is not None and losing_team.is_ai and 'gauntlet' not in this_game.game_type and not this_game.short_game:
g_query = await db_get('games', params=[('team1_id', winning_team.id), ('season', this_game.season), ('forfeit', False)])
win_points = 0
for x in g_query['games']:
if (x['away_score'] > x['home_score'] and x['away_team']['id'] == winning_team.id) or (x['home_score'] > x['away_score'] and x['home_team']['id'] == winning_team.id):
if x['game_type'] == 'minor-league':
win_points += 1
elif x['game_type'] in ['major-league', 'flashback']:
win_points += 2
elif x['game_type'] == 'hall-of-fame':
win_points += 3
if this_game.game_type == 'minor-league':
this_game_points = 1
elif this_game.game_type in ['major-league', 'flashback']:
this_game_points = 2
else:
this_game_points = 3
pre_game_points = win_points - this_game_points
if math.floor(win_points / 6) > math.floor(pre_game_points / 6):
await db_post('packs/one', payload={
'team_id': winning_team.id,
'pack_type_id': 8,
'pack_team_id': losing_team.id
})
win_string += f'1x {losing_team.abbrev} Team Choice pack\n'
win_string += f'{win_reward["money"]}\n'
loss_string = f'{loss_reward["money"]}\n'
if 'gauntlet' in this_game.game_type:
winning_abbrev = winning_team.abbrev.lower()
if 'gauntlet' in winning_abbrev:
winning_team = await get_team_or_none(session, team_abbrev=winning_abbrev.split('-')[1])
if winning_team is None:
raise DatabaseError(f'Main team not found for {winning_abbrev}')
losing_abbrev = losing_team.abbrev.lower()
if 'gauntlet' in losing_abbrev:
losing_team = await get_team_or_none(session, team_abbrev=losing_abbrev.split('-')[1])
if losing_team is None:
raise DatabaseError(f'Main team not found for {losing_abbrev}')
await db_post('packs/one', payload={'team_id': winning_team.id, 'pack_type_id': win_reward['pack_type']['id']})
await db_post(f'teams/{winning_team.id}/money/{win_reward["money"]}')
await db_post(f'teams/{losing_team.id}/money/{loss_reward["money"]}')
return win_string, loss_string

View File

@ -7,26 +7,29 @@ from in_game import data_cache
from dataclasses import asdict, fields from dataclasses import asdict, fields
logger = logging.getLogger('discord_app')
def get_result(pitcher: data_cache.PitchingWrapper, batter: data_cache.BattingWrapper): def get_result(pitcher: data_cache.PitchingWrapper, batter: data_cache.BattingWrapper):
which = random.choice(['pitcher', 'batter']) which = random.choice(['pitcher', 'batter'])
logging.info(f'in_game.simulations - get_result - which: {which}') logger.info(f'in_game.simulations - get_result - which: {which}')
unused_fields = ['avg', 'obp', 'slg', 'pull_rate', 'center_rate', 'slap_rate'] unused_fields = ['avg', 'obp', 'slg', 'pull_rate', 'center_rate', 'slap_rate']
pit_hand = pitcher.card.hand pit_hand = pitcher.card.hand
bat_hand = batter.card.hand bat_hand = batter.card.hand
if which == 'pitcher': if which == 'pitcher':
logging.info(f'in_game.simulations - get_result - grabbing pitcher card chances') logger.info(f'in_game.simulations - get_result - grabbing pitcher card chances')
ch_data = pitcher.ratings_vl if bat_hand.upper() == 'L' else pitcher.ratings_vr ch_data = pitcher.ratings_vl if bat_hand.upper() == 'L' else pitcher.ratings_vr
logging.info(f'ch_data: {ch_data}') logger.info(f'ch_data: {ch_data}')
# for field in fields(ch_data): # for field in fields(ch_data):
# if field.name not in unused_fields: # if field.name not in unused_fields:
# ch_results.append(field.name) # ch_results.append(field.name)
# ch_probs.append(getattr(data_cache.PitchingRatings, field.name)) # ch_probs.append(getattr(data_cache.PitchingRatings, field.name))
else: else:
logging.info(f'in_game.simulations - get_result - grabbing batter card chances') logger.info(f'in_game.simulations - get_result - grabbing batter card chances')
ch_data = batter.ratings_vl if pit_hand.upper() == 'L' else batter.ratings_vr ch_data = batter.ratings_vl if pit_hand.upper() == 'L' else batter.ratings_vr
logging.info(f'ch_data: {ch_data}') logger.info(f'ch_data: {ch_data}')
# for field in fields(ch_data): # for field in fields(ch_data):
# if field.name not in unused_fields: # if field.name not in unused_fields:
# ch_results.append(field.name) # ch_results.append(field.name)
@ -39,10 +42,10 @@ def get_result(pitcher: data_cache.PitchingWrapper, batter: data_cache.BattingWr
ch_results = list(ch_dict.keys()) ch_results = list(ch_dict.keys())
ch_probs = list(ch_dict.values()) ch_probs = list(ch_dict.values())
logging.info(f'ch_results: {ch_results}') logger.info(f'ch_results: {ch_results}')
logging.info(f'ch_probs: {ch_probs}') logger.info(f'ch_probs: {ch_probs}')
result = random.choices(ch_results, ch_probs) result = random.choices(ch_results, ch_probs)
logging.info(f'result: {result}') logger.info(f'result: {result}')
return result[0] return result[0]

View File

@ -1,7 +1,7 @@
import discord import discord
import datetime import datetime
import logging import logging
# import logging.handlers from logging.handlers import RotatingFileHandler
import asyncio import asyncio
import os import os
@ -19,27 +19,30 @@ elif raw_log_level == 'WARN':
else: else:
log_level = logging.ERROR log_level = logging.ERROR
date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}' # date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
logging.basicConfig( # logger.basicConfig(
filename=f'logs/{date}.log', # filename=f'logs/{date}.log',
format='%(asctime)s - %(levelname)s - %(message)s', # format='%(asctime)s - %(levelname)s - %(message)s',
level=log_level # level=log_level
)
# logging.getLogger('discord.http').setLevel(logging.INFO)
# logger = logging.getLogger('discord')
# logger.setLevel(log_level)
# handler = logging.handlers.RotatingFileHandler(
# filename='discord.log',
# encoding='utf-8',
# maxBytes=32 * 1024 * 1024, # 32 MiB
# backupCount=5, # Rotate through 5 files
# ) # )
# logger.getLogger('discord.http').setLevel(logger.INFO)
logger = logging.getLogger('discord_app')
logger.setLevel(log_level)
handler = RotatingFileHandler(
filename='logs/discord.log',
# encoding='utf-8',
maxBytes=32 * 1024 * 1024, # 32 MiB
backupCount=5, # Rotate through 5 files
)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# dt_fmt = '%Y-%m-%d %H:%M:%S' # dt_fmt = '%Y-%m-%d %H:%M:%S'
# formatter = logging.Formatter('[{asctime}] [{levelname:<8}] {name}: {message}', dt_fmt, style='{') # formatter = logger.Formatter('[{asctime}] [{levelname:<8}] {name}: {message}', dt_fmt, style='{')
# handler.setFormatter(formatter) # handler.setFormatter(formatter)
# logger.addHandler(handler) logger.addHandler(handler)
COGS = [ COGS = [
'cogs.owner', 'cogs.owner',
@ -62,9 +65,9 @@ bot = commands.Bot(command_prefix='.',
@bot.event @bot.event
async def on_ready(): async def on_ready():
logging.info('Logged in as:') logger.info('Logged in as:')
logging.info(bot.user.name) logger.info(bot.user.name)
logging.info(bot.user.id) logger.info(bot.user.id)
# @bot.tree.error # @bot.tree.error
@ -77,10 +80,10 @@ async def main():
for c in COGS: for c in COGS:
try: try:
await bot.load_extension(c) await bot.load_extension(c)
logging.info(f'Loaded cog: {c}') logger.info(f'Loaded cog: {c}')
except Exception as e: except Exception as e:
logging.error(f'Failed to load cog: {c}') logger.error(f'Failed to load cog: {c}')
logging.error(f'{e}') logger.error(f'{e}')
async with bot: async with bot:
await bot.start(os.environ.get('BOT_TOKEN')) await bot.start(os.environ.get('BOT_TOKEN'))

View File

@ -166,7 +166,7 @@ async def test_strikeouts(session: Session):
game_1 = session.get(Game, 1) game_1 = session.get(Game, 1)
play_1 = session.get(Play, 1) play_1 = session.get(Play, 1)
play_1 = await strikeouts(session, None, game_1, play_1) play_1 = await strikeouts(session, None, play_1)
assert play_1.so == 1 assert play_1.so == 1
assert play_1.outs == 1 assert play_1.outs == 1
@ -181,13 +181,13 @@ async def test_doubles(session: Session):
assert play_2.play_num == 2 assert play_2.play_num == 2
play_2_ghost_1 = await doubles(session, None, game_1, play_2, double_type='***') play_2_ghost_1 = await doubles(session, None, play_2, double_type='***')
assert play_2_ghost_1.double == 1 assert play_2_ghost_1.double == 1
assert play_2_ghost_1.on_first_final == 4 assert play_2_ghost_1.on_first_final == 4
assert play_2_ghost_1.rbi == 1 assert play_2_ghost_1.rbi == 1
play_2_ghost_2 = await doubles(session, None, game_1, play_2, double_type='**') play_2_ghost_2 = await doubles(session, None, play_2, double_type='**')
assert play_2_ghost_2.double == 1 assert play_2_ghost_2.double == 1
assert play_2_ghost_2.rbi == 0 assert play_2_ghost_2.rbi == 0

View File

@ -42,8 +42,8 @@ def session_fixture():
session.commit() session.commit()
game_1 = Game(away_team_id=31, home_team_id=400, channel_id=1234, season=9, ai_team='away', game_type='minor-league') game_1 = Game(away_team_id=31, home_team_id=400, channel_id=1234, season=9, ai_team='away', game_type='minor-league')
game_2 = Game(away_team_id=69, home_team_id=420, channel_id=5678, season=9, active=False, is_pd=True, ranked=True, week_num=6, game_num=9, away_roster_id=69, home_roster_id=420, first_message=12345678, ai_team='home', game_type='minor-league') game_2 = Game(away_team_id=69, home_team_id=420, channel_id=5678, season=9, active=False, is_pd=True, ranked=True, week=6, game_num=9, away_roster_id=69, home_roster_id=420, first_message=12345678, ai_team='home', game_type='minor-league')
game_3 = Game(away_team_id=69, home_team_id=420, channel_id=5678, season=9, active=True, is_pd=True, ranked=True, week_num=6, game_num=10, away_roster_id=69, home_roster_id=420, first_message=34567890, ai_team='home', game_type='minor-league') game_3 = Game(away_team_id=69, home_team_id=420, channel_id=5678, season=9, active=True, is_pd=True, ranked=True, week=6, game_num=10, away_roster_id=69, home_roster_id=420, first_message=34567890, ai_team='home', game_type='minor-league')
session.add(game_1) session.add(game_1)
session.add(game_2) session.add(game_2)

View File

@ -1,11 +1,11 @@
import pytest import pytest
from sqlalchemy import delete as sadelete from sqlalchemy import delete as sadelete
from sqlalchemy.sql.functions import sum, count from sqlalchemy.sql.functions import sum, count
from sqlmodel import Session, delete from sqlmodel import Session, delete, func
from command_logic.logic_gameplay import complete_play, singles, undo_play from command_logic.logic_gameplay import complete_play, homeruns, is_game_over, singles, strikeouts, undo_play
from in_game.gameplay_models import Game, Lineup, GameCardsetLink, Play, select from in_game.gameplay_models import Game, Lineup, GameCardsetLink, Play, Team, select
from in_game.gameplay_queries import get_channel_game_or_none, get_active_games_by_team from in_game.gameplay_queries import get_channel_game_or_none, get_active_games_by_team, get_db_ready_decisions
from tests.factory import session_fixture from tests.factory import session_fixture
@ -20,7 +20,7 @@ def test_create_game(session: Session):
assert game_1.active == True assert game_1.active == True
assert game_1.is_pd == True assert game_1.is_pd == True
assert game_1.ranked == False assert game_1.ranked == False
assert game_1.week_num == None assert game_1.week == None
assert game_1.game_num == None assert game_1.game_num == None
assert game_1.away_roster_id == None assert game_1.away_roster_id == None
assert game_1.home_roster_id == None assert game_1.home_roster_id == None
@ -30,7 +30,7 @@ def test_create_game(session: Session):
assert game_2.active == False assert game_2.active == False
assert game_2.is_pd == True assert game_2.is_pd == True
assert game_2.ranked == True assert game_2.ranked == True
assert game_2.week_num == 6 assert game_2.week == 6
assert game_2.game_num == 9 assert game_2.game_num == 9
assert game_2.away_roster_id == 69 assert game_2.away_roster_id == 69
assert game_2.home_roster_id == 420 assert game_2.home_roster_id == 420
@ -76,14 +76,15 @@ def test_games_by_channel(session: Session):
def test_games_by_team(session: Session): def test_games_by_team(session: Session):
assert len(get_active_games_by_team(session, team_id=69)) == 1 team_69 = session.get(Team, 69)
assert len(get_active_games_by_team(session, team=team_69)) == 1
game_2 = session.get(Game, 2) game_2 = session.get(Game, 2)
game_2.active = True game_2.active = True
session.add(game_2) session.add(game_2)
session.commit() session.commit()
assert len(get_active_games_by_team(session, team_id=69)) == 2 assert len(get_active_games_by_team(session, team=team_69)) == 2
game_3 = session.get(Game, 3) game_3 = session.get(Game, 3)
game_3.active = False game_3.active = False
@ -92,7 +93,7 @@ def test_games_by_team(session: Session):
session.add(game_2) session.add(game_2)
session.commit() session.commit()
assert len(get_active_games_by_team(session, team_id=69)) == 0 assert len(get_active_games_by_team(session, team=team_69)) == 0
def test_delete_game(session: Session): def test_delete_game(session: Session):
@ -200,3 +201,49 @@ async def test_undo_play(session: Session):
assert new_play.play_num == 4 assert new_play.play_num == 4
assert new_play.on_second == on_second_play_4 assert new_play.on_second == on_second_play_4
def test_game_model_dump(session: Session):
game_1 = session.get(Game, 1)
game_data = game_1.model_dump()
assert game_data['active'] == True
assert game_data['away_team_id'] == 31
assert game_data['home_team_id'] == 400
assert game_data['game_type'] == 'minor-league'
def test_final_inning(session: Session):
game_1 = session.get(Game, 1)
final_inning = session.exec(select(func.max(Play.inning_num)).where(Play.game == game_1)).one()
assert final_inning == 1
async def test_db_ready_decisions(session: Session):
game_1 = session.get(Game, 1)
this_play = game_1.initialize_play(session)
assert this_play.play_num == 2
this_play = await strikeouts(session, None, this_play)
this_play = complete_play(session, this_play)
this_play = await strikeouts(session, None, this_play)
this_play = complete_play(session, this_play)
assert this_play.starting_outs == 0
assert this_play.inning_half == 'bot'
this_play = await homeruns(session, None, this_play, 'no-doubt')
this_play = complete_play(session, this_play)
decisions = get_db_ready_decisions(session, game_1, 69)
assert len(decisions) == 2
assert decisions[0]['pitcher_team_id'] == 400
assert decisions[1]['pitcher_team_id'] == 31
assert decisions[0]['game_finished'] == 1
assert decisions[0]['is_start'] == True
assert decisions[1]['game_finished'] == 1
assert decisions[1]['is_start'] == True

View File

@ -55,7 +55,7 @@ def test_get_one_lineup(session: Session):
assert leadoff.position == 'C' assert leadoff.position == 'C'
with pytest.raises(KeyError) as exc_info: with pytest.raises(KeyError) as exc_info:
get_one_lineup(session, session, this_game, this_game.away_team) get_one_lineup(session, this_game, this_game.away_team)
assert str(exc_info) == "<ExceptionInfo KeyError('Position or batting order must be provided for get_one_lineup') tblen=2>" assert str(exc_info) == "<ExceptionInfo KeyError('Position or batting order must be provided for get_one_lineup') tblen=2>"

View File

@ -1,10 +1,10 @@
import pytest import pytest
from sqlmodel import Session, select, func from sqlmodel import Session, select, func
from command_logic.logic_gameplay import complete_play, singles, undo_play from command_logic.logic_gameplay import complete_play, homeruns, is_game_over, singles, strikeouts, undo_play, walks
from db_calls_gameplay import advance_runners from db_calls_gameplay import advance_runners
from in_game.gameplay_models import Lineup, Play, Game from in_game.gameplay_models import Lineup, Play, Game
from in_game.gameplay_queries import get_last_team_play from in_game.gameplay_queries import get_db_ready_plays, get_last_team_play
from tests.factory import session_fixture from tests.factory import session_fixture
@ -107,3 +107,63 @@ async def test_undo_play(session: Session):
assert len(all_plays) == 3 assert len(all_plays) == 3
def test_db_ready_plays(session: Session):
game_1 = session.get(Game, 1)
play_2 = game_1.initialize_play(session)
db_ready_plays = get_db_ready_plays(session, game_1, 69)
plays = db_ready_plays['plays']
assert len(plays) == 2
assert plays[0]['game_id'] == 69
assert plays[0]['on_first_id'] == None
assert plays[0]['catcher_id'] == 11
print(f'obc from return: {plays[0]["on_base_code"]}')
assert plays[0]['on_base_code'] == '000'
async def test_is_game_over(session: Session):
game_1 = session.get(Game, 1)
this_play = game_1.initialize_play(session)
assert is_game_over(this_play) == False
assert this_play.play_num == 2
assert this_play.starting_outs == 1
this_play = await strikeouts(session, None, this_play)
next_play = complete_play(session, this_play)
assert this_play.wpa == -0.015
this_play = await strikeouts(session, None, next_play)
this_play = complete_play(session, this_play)
assert this_play.starting_outs == 0
assert this_play.inning_half == 'bot'
this_play.inning_num = 9
session.add(this_play)
session.commit()
session.refresh(this_play)
this_play = await strikeouts(session, None, this_play)
this_play = complete_play(session, this_play)
this_play = await homeruns(session, None, this_play, 'no-doubt')
next_play = complete_play(session, this_play)
assert is_game_over(next_play) == True
assert this_play.wpa == 0.402
async def test_walks(session: Session):
game_1 = session.get(Game, 1)
play_2 = game_1.initialize_play(session)
this_play = await walks(session, None, play_2)
this_play = complete_play(session, this_play)
assert this_play.on_base_code == 1

View File

@ -57,7 +57,7 @@ def test_player_id_from_dict(session: Session):
with pytest.raises(KeyError) as exc_info: with pytest.raises(KeyError) as exc_info:
get_player_id_from_dict({}) get_player_id_from_dict({})
assert str(exc_info) == "<ExceptionInfo KeyError('Player ID could not be extracted from json data') tblen=2>" assert str(exc_info) == "<ExceptionInfo KeyError('Player ID could not be extracted from json data') tblen=3>"
def test_player_card_link(session: Session): def test_player_card_link(session: Session):

View File

@ -111,11 +111,14 @@ class ButtonOptions(discord.ui.View):
self.stop() self.stop()
async def ask_confirm(interaction: discord.Interaction, question: str, label_type: Literal['yes', 'confirm'] = 'confirm', timeout: int = 60, delete_question: bool = True, custom_confirm_label: str = None, custom_cancel_label: str = None) -> bool: async def ask_confirm(interaction: discord.Interaction, question: str, label_type: Literal['yes', 'confirm'] = 'confirm', timeout: int = 60, delete_question: bool = True, custom_confirm_label: str = None, custom_cancel_label: str = None, embed: discord.Embed = None, delete_embed: bool = False) -> bool:
""" """
button_callbacks: keys are button values, values are async functions button_callbacks: keys are button values, values are async functions
""" """
view = Confirm(responders=[interaction.user], timeout=timeout, label_type=label_type) try:
view = Confirm(responders=[interaction.user], timeout=timeout, label_type=label_type)
except AttributeError:
view = Confirm(responders=[interaction.author], timeout=timeout, label_type=label_type)
if custom_confirm_label: if custom_confirm_label:
view.confirm.label = custom_confirm_label view.confirm.label = custom_confirm_label
if custom_cancel_label: if custom_cancel_label:
@ -127,9 +130,13 @@ async def ask_confirm(interaction: discord.Interaction, question: str, label_typ
if view.value: if view.value:
if delete_question: if delete_question:
await question.delete() await question.delete()
else:
await question.edit(content=question, view=None)
return True return True
else: else:
if delete_question: if delete_question:
await question.delete() await question.delete()
else:
await question.edit(content=question, view=None)
return False return False

View File

@ -4,7 +4,10 @@ import logging
from sqlmodel import Session from sqlmodel import Session
from in_game.gameplay_models import Lineup, Play from in_game.gameplay_models import Lineup, Play
from in_game.gameplay_queries import get_sorted_lineups
logger = logging.getLogger('discord_app')
class DropdownOptions(discord.ui.Select): class DropdownOptions(discord.ui.Select):
def __init__(self, option_list: list, placeholder: str = 'Make your selection', min_values: int = 1, max_values: int = 1, callback=None): def __init__(self, option_list: list, placeholder: str = 'Make your selection', min_values: int = 1, max_values: int = 1, callback=None):
@ -35,7 +38,7 @@ class DropdownOptions(discord.ui.Select):
# Select object, and the values attribute gets a list of the user's # Select object, and the values attribute gets a list of the user's
# selected options. We only want the first one. # selected options. We only want the first one.
# await interaction.response.send_message(f'Your favourite colour is {self.values[0]}') # await interaction.response.send_message(f'Your favourite colour is {self.values[0]}')
logging.info(f'Dropdown callback: {self.custom_callback}') logger.info(f'Dropdown callback: {self.custom_callback}')
await self.custom_callback(interaction, self.values) await self.custom_callback(interaction, self.values)
@ -60,7 +63,7 @@ class SelectViewDefense(discord.ui.Select):
super().__init__(options=options) super().__init__(options=options)
async def callback(self, interaction: discord.Interaction): async def callback(self, interaction: discord.Interaction):
logging.info(f'SelectViewDefense - selection: {self.values[0]}') logger.info(f'SelectViewDefense - selection: {self.values[0]}')
this_lineup = self.session.get(Lineup, self.values[0]) this_lineup = self.session.get(Lineup, self.values[0])
self.embed.set_image(url=this_lineup.player.image) self.embed.set_image(url=this_lineup.player.image)
@ -81,86 +84,3 @@ class SelectViewDefense(discord.ui.Select):
) )
await interaction.response.edit_message(content=None, embed=self.embed, view=new_view) await interaction.response.edit_message(content=None, embed=self.embed, view=new_view)
class SelectOpenPack(discord.ui.Select):
def __init__(self, options: list, team: dict):
self.owner_team = team
super().__init__(placeholder='Select a Pack Type', options=options)
async def callback(self, interaction: discord.Interaction):
logging.info(f'SelectPackChoice - selection: {self.values[0]}')
pack_vals = self.values[0].split('-')
logging.info(f'pack_vals: {pack_vals}')
# Get the selected packs
params = [('team_id', self.owner_team['id']), ('opened', False), ('limit', 5), ('exact_match', True)]
open_type = 'standard'
if 'Standard' in pack_vals:
open_type = 'standard'
params.append(('pack_type_id', 1))
elif 'Premium' in pack_vals:
open_type = 'standard'
params.append(('pack_type_id', 3))
elif 'Daily' in pack_vals:
params.append(('pack_type_id', 4))
elif 'Promo Choice' in pack_vals:
open_type = 'choice'
params.append(('pack_type_id', 9))
elif 'MVP' in pack_vals:
open_type = 'choice'
params.append(('pack_type_id', 5))
elif 'All Star' in pack_vals:
open_type = 'choice'
params.append(('pack_type_id', 6))
elif 'Mario' in pack_vals:
open_type = 'choice'
params.append(('pack_type_id', 7))
elif 'Team Choice' in pack_vals:
open_type = 'choice'
params.append(('pack_type_id', 8))
else:
raise KeyError(f'Cannot identify pack details: {pack_vals}')
# If team isn't already set on team choice pack, make team pack selection now
await interaction.response.edit_message(view=None)
cardset_id = None
if 'Team Choice' in pack_vals and 'Cardset' in pack_vals:
# cardset_id = pack_vals[2]
cardset_index = pack_vals.index('Cardset')
cardset_id = pack_vals[cardset_index + 1]
params.append(('pack_cardset_id', cardset_id))
if 'Team' not in pack_vals:
view = SelectView(
[SelectChoicePackTeam('AL', self.owner_team, cardset_id),
SelectChoicePackTeam('NL', self.owner_team, cardset_id)],
timeout=30
)
await interaction.channel.send(
content=None,
view=view
)
return
params.append(('pack_team_id', pack_vals[pack_vals.index('Team') + 1]))
else:
if 'Team' in pack_vals:
params.append(('pack_team_id', pack_vals[pack_vals.index('Team') + 1]))
if 'Cardset' in pack_vals:
cardset_id = pack_vals[pack_vals.index('Cardset') + 1]
params.append(('pack_cardset_id', cardset_id))
p_query = await db_get('packs', params=params)
if p_query['count'] == 0:
logging.error(f'open-packs - no packs found with params: {params}')
raise ValueError(f'Unable to open packs')
# Open the packs
if open_type == 'standard':
await open_st_pr_packs(p_query['packs'], self.owner_team, interaction)
elif open_type == 'choice':
await open_choice_pack(p_query['packs'][0], self.owner_team, interaction, cardset_id)

View File

@ -2,6 +2,9 @@ import discord
import logging import logging
logger = logging.getLogger('discord_app')
class Pagination(discord.ui.View): class Pagination(discord.ui.View):
def __init__(self, responders: list, timeout: float = 300.0): def __init__(self, responders: list, timeout: float = 300.0):
super().__init__(timeout=timeout) super().__init__(timeout=timeout)
@ -14,7 +17,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='⏮️', style=discord.ButtonStyle.blurple) @discord.ui.button(label='⏮️', style=discord.ButtonStyle.blurple)
async def left_button(self, interaction: discord.Interaction, button: discord.ui.Button): async def left_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if interaction.user not in self.responders: if interaction.user not in self.responders:
logging.info(f'{interaction.user} is not in {self.responders}') logger.info(f'{interaction.user} is not in {self.responders}')
return return
self.value = 'left' self.value = 'left'
@ -24,7 +27,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='❌️', style=discord.ButtonStyle.secondary) @discord.ui.button(label='❌️', style=discord.ButtonStyle.secondary)
async def cancel_button(self, interaction: discord.Interaction, button: discord.ui.Button): async def cancel_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if interaction.user not in self.responders: if interaction.user not in self.responders:
logging.info(f'{interaction.user} is not in {self.responders}') logger.info(f'{interaction.user} is not in {self.responders}')
return return
self.value = 'cancel' self.value = 'cancel'
@ -34,7 +37,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='⏭️', style=discord.ButtonStyle.blurple) @discord.ui.button(label='⏭️', style=discord.ButtonStyle.blurple)
async def right_button(self, interaction: discord.Interaction, button: discord.ui.Button): async def right_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if interaction.user not in self.responders: if interaction.user not in self.responders:
logging.info(f'{interaction.user} is not in {self.responders}') logger.info(f'{interaction.user} is not in {self.responders}')
return return
self.value = 'right' self.value = 'right'