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 os
from exceptions import DatabaseError
AUTH_TOKEN = {'Authorization': f'Bearer {os.environ.get("API_TOKEN")}'}
try:
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'
master_debug = True
PLAYER_CACHE = {}
logger = logging.getLogger('discord_app')
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):
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:
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,
timeout: int = 3):
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}'
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 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
elif none_okay:
e = await r.text()
logging.error(e)
logger.error(e)
return None
else:
e = await r.text()
logging.error(e)
raise ValueError(f'DB: {e}')
logger.error(e)
raise DatabaseError(e)
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)
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 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
else:
e = await r.text()
logging.error(e)
raise ValueError(f'DB: {e}')
logger.error(e)
raise DatabaseError(e)
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)
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 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
else:
e = await r.text()
logging.error(e)
raise ValueError(f'DB: {e}')
logger.error(e)
raise DatabaseError(e)
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)
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 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
else:
e = await r.text()
logging.error(e)
raise ValueError(f'DB: {e}')
logger.error(e)
raise DatabaseError(e)
# retries = 0
# 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)
# break
# 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:
# 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.')
@ -131,19 +134,19 @@ async def db_put(endpoint: str, api_ver: int = 2, payload: dict = None, timeout:
# data = resp.json()
# log_string = f'{data}'
# 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:
# 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
# else:
# logging.warning(resp.text)
# logger.warning(resp.text)
# raise ValueError(f'DB: {resp.text}')
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)
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 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
else:
e = await r.text()
logging.error(e)
raise ValueError(f'DB: {e}')
logger.error(e)
raise DatabaseError(e)
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
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
# logging.basicConfig(
# filename=f'logs/{date}.log',
# format='%(asctime)s - %(levelname)s - %(message)s',
# level=logging.WARNING
# )
logger = logging.getLogger('discord_app')
class Admins(commands.Cog):
@ -164,7 +159,7 @@ class Admins(commands.Cog):
total_teams = 0
for y in all_teams['teams']:
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(
'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.')
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!"}')
@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.')
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(
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_rarity = old_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 new_rarity == 2:
@ -473,7 +468,7 @@ class Admins(commands.Cog):
# Patch player with new rarity_id, cost, and positions 1 - 6
if len(updates) > 0:
logging.info(f'Updating {row[1]} - params: {updates}')
logger.info(f'Updating {row[1]} - params: {updates}')
await db_patch(
'players',
object_id=this_player['player_id'],
@ -486,7 +481,7 @@ class Admins(commands.Cog):
if len(errors) > 0:
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}')
@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 *
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
# logging.basicConfig(
# logger.basicConfig(
# filename=f'logs/{date}.log',
# 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)
# async def pd_ticker(self):
# 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')))
# if not guild:
# return
@ -183,7 +183,7 @@ class Economy(commands.Cog):
# Check for notifications
all_notifs = await db_get('notifs', params=[('ack', False)])
if not all_notifs:
logging.debug(f'No notifications')
logger.debug(f'No notifications')
return
topics = {
@ -202,7 +202,7 @@ class Economy(commands.Cog):
if line['title'] in topics:
topics[line['title']]['notifs'].append(line)
logging.info(f'topics:\n{topics}')
logger.info(f'topics:\n{topics}')
for topic in topics:
embed = get_team_embed(title=f'{topic}{"s" if len(topics[topic]["notifs"]) > 1 else ""}')
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']]['count'] += 1
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)
counter = 1
@ -535,8 +535,8 @@ class Economy(commands.Cog):
daily = await db_get('rewards', params=[
('name', 'Daily Check-in'), ('team_id', team['id']), ('created_after', midnight)
])
logging.debug(f'midnight: {midnight} / now: {int_timestamp(now)}')
logging.debug(f'daily_return: {daily}')
logger.debug(f'midnight: {midnight} / now: {int_timestamp(now)}')
logger.debug(f'daily_return: {daily}')
if daily:
await interaction.edit_original_response(
@ -676,11 +676,11 @@ class Economy(commands.Cog):
'Mario': [],
'Team Choice': []
}
logging.debug(f'Parsing packs...')
logger.debug(f'Parsing packs...')
for pack in p_query['packs']:
p_group = None
logging.debug(f'pack: {pack}')
logging.debug(f'pack cardset: {pack["pack_cardset"]}')
logger.debug(f'pack: {pack}')
logger.debug(f'pack cardset: {pack["pack_cardset"]}')
if pack['pack_team'] is None and pack['pack_cardset'] is None:
if pack['pack_type']['name'] in p_data:
p_group = pack['pack_type']['name']
@ -712,7 +712,7 @@ class Economy(commands.Cog):
elif pack['pack_type']['name'] == 'Promo Choice':
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:
p_count += 1
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)
logging.debug(f'this_player: {p_query}')
logger.debug(f'this_player: {p_query}')
await self.buy_card(interaction, p_query, owner_team)
@ -819,7 +819,7 @@ class Economy(commands.Cog):
return
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)
@ -1020,14 +1020,14 @@ class Economy(commands.Cog):
for card in c_query['cards']:
if len(dupe_strings[str_count]) > 1500:
str_count += 1
logging.debug(f'card: {card}')
logger.debug(f'card: {card}')
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:
logging.debug(f'not a dupe')
logger.debug(f'not a dupe')
player_ids.append(card['player']['player_id'])
else:
logging.info(f'{team["abbrev"]} duplicate card: {card["id"]}')
logger.info(f'{team["abbrev"]} duplicate card: {card["id"]}')
dupe_cards.append(card)
dupe_ids += f'{card["id"]},'
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!')
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(
content=f'You currently have {len(dupe_cards)} duplicate cards:\n\n{dupe_strings[0]}'
)
for x in dupe_strings[1:]:
logging.info(f'checking string: {len(x)}')
logger.info(f'checking string: {len(x)}')
if len(x) > 0:
await interaction.channel.send(x)
else:
@ -1142,7 +1142,7 @@ class Economy(commands.Cog):
poke_role = get_role(interaction, 'Pokétwo')
await share_channel(op_ch, poke_role, read_only=True)
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(
f'Let\'s head down to your private channel: {op_ch.mention}',
@ -1195,7 +1195,7 @@ class Economy(commands.Cog):
break
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:
# Get MLB anchor team
while True:
@ -1308,7 +1308,7 @@ class Economy(commands.Cog):
roster_counts[pl['rarity']['name']] += 1
for x in get_all_pos(pl):
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
update_roster_counts(anchor_players)
@ -1572,7 +1572,7 @@ class Economy(commands.Cog):
try:
new_sheet = sheets.open_by_url(google_sheet_url)
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')
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'
@ -1599,10 +1599,10 @@ class Economy(commands.Cog):
new_r_data.append([int(row[0].value)])
else:
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:
logging.debug(f'row: {row}')
logger.debug(f'row: {row}')
new_l_data.append([
row[0].value if row[0].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,
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.update_values(
@ -1678,7 +1678,7 @@ class Economy(commands.Cog):
# #
# # # Send current data to Sheets
# # 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.')
# # else:
# # await helpers.pause_then_type(ctx, 'Alrighty, your sheet is all up to date!')
@ -1718,7 +1718,7 @@ class Economy(commands.Cog):
try:
await give_cards_to_team(team, player_ids=all_player_ids, pack_id=this_pack['id'])
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.')
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
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 exceptions import GameNotFoundException, TeamNotFoundException, PlayNotFoundException, GameException
from helpers import DEFENSE_LITERAL, PD_PLAYERS_ROLE_NAME, team_role, user_has_role, random_gif, random_from_list
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, log_exception
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.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_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
logger = logging.getLogger('discord_app')
class Gameplay(commands.Cog):
@ -33,24 +34,47 @@ class Gameplay(commands.Cog):
@tasks.loop(count=1)
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)
@get_sheets.before_loop
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()
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')
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]}')
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(
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):
complete_play(session, this_play)
await self.post_play(session, interaction, this_play, buffer_message)
next_play = complete_play(session, this_play)
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')
@ -123,7 +147,7 @@ class Gameplay(commands.Cog):
return
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)
if len(conflict_games) > 0:
@ -134,7 +158,7 @@ class Gameplay(commands.Cog):
current = await db_get('current')
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):
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,
channel_id=interaction.channel_id,
season=current['season'],
week_num=week_num,
week=week_num,
first_message=None if interaction.message is None else interaction.message.channel.id,
ai_team='away' if away_team.is_ai else 'home',
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}'
logging.info(game_info_log)
logger.info(game_info_log)
# Get Human SP card
human_sp_card = await get_card_or_none(session, card_id=sp_card_id)
@ -181,7 +205,7 @@ class Gameplay(commands.Cog):
return
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(
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?')
return
await ctx.send(
content=None,
embed=this_game.get_scorebug_embed(session, full_length=True)
try:
await ctx.send(
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')
question = await ctx.send(f'Is this the game I should nuke?', view=view)
await view.wait()
if view.value:
# if view.value:
if nuke_game:
session.delete(this_game)
session.commit()
await question.edit(
content=random_gif(random_from_list([
'i killed it', 'deed is done', 'gone forever'
])),
view=None
)
await ctx.channel.send(content=random_gif(random_from_list(['i killed it', 'deed is done', 'gone forever'])))
else:
await question.edit(
content=f'~~Is this the game I should nuke?~~\n\nIt stays.',
view=None
)
await ctx.send(f'It stays. For now.')
@app_commands.command(name='read-lineup', description='Import a saved lineup for this channel\'s PD game.')
@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
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.')
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_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(
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_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)
@ -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_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)
@ -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_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)
@ -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_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)
@ -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_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)
@ -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_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)
@ -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_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)
@ -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_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)
@ -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_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)
@ -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_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)
@ -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')
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):

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 typing import Optional, Literal
date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
logging.basicConfig(
filename=f'logs/{date}.log',
format='%(asctime)s - %(levelname)s - %(message)s',
level=logging.WARNING
)
logger = logging.getLogger('discord_app')
class Owner(commands.Cog):
@ -25,7 +21,7 @@ class Owner(commands.Cog):
async def load(self, ctx, *, cog: str):
try:
await self.bot.load_extension(f'cogs.{cog}')
logging.warning(f'Loaded {cog}')
logger.warning(f'Loaded {cog}')
except Exception as e:
await ctx.send(f'**ERROR:** {type(e).__name__} - {e}')
else:
@ -36,7 +32,7 @@ class Owner(commands.Cog):
async def unload(self, ctx, *, cog: str):
try:
await self.bot.unload_extension(f'cogs.{cog}')
logging.warning(f'Unloaded {cog}')
logger.warning(f'Unloaded {cog}')
except Exception as e:
await ctx.send(f'**ERROR:** {type(e).__name__} - {e}')
else:
@ -47,9 +43,9 @@ class Owner(commands.Cog):
async def reload(self, ctx, *, cog: str):
try:
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}')
logging.warning(f'Reloaded {cog}')
logger.warning(f'Reloaded {cog}')
except Exception as e:
await ctx.send(f'**ERROR:** {type(e).__name__} - {e}')
else:
@ -63,14 +59,14 @@ class Owner(commands.Cog):
for x in cogs:
try:
await self.bot.unload_extension(f'cogs.{x}')
logging.warning(f'Unloaded {x}')
logger.warning(f'Unloaded {x}')
except Exception as e:
await ctx.send(f'Failed to unload **{x}**')
for x in cogs:
try:
await self.bot.load_extension(f'cogs.{x}')
logging.warning(f'Loaded {x}')
logger.warning(f'Loaded {x}')
except Exception as e:
await ctx.send(f'Failed to load **{x}**')
@ -86,9 +82,9 @@ class Owner(commands.Cog):
# sync = await self.bot.tree.sync()
# else:
# 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:
# 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}')
@ -101,7 +97,7 @@ class Owner(commands.Cog):
!sync * -> copies all global app commands to current guild and syncs
!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 spec == "~":
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
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
# logging.basicConfig(
# filename=f'logs/{date}.log',
# format='%(asctime)s - %(levelname)s - %(message)s',
# level=logging.WARNING
# )
logger = logging.getLogger('discord_app')
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}},
}
logging.debug(f'running short games...')
logger.debug(f'running short games...')
for line in short_games:
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']['points'] += 2 if not home_win else 1
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'}
for line in long_games:
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']]]['rd'] += \
line['away_score'] - line['home_score']
logging.debug(f'done league games')
logger.debug(f'done league games')
return all_results
@ -306,7 +301,7 @@ class Players(commands.Cog):
async def weekly_loop(self):
current = await db_get('current')
now = datetime.datetime.now()
logging.debug(f'Datetime: {now} / weekday: {now.weekday()}')
logger.debug(f'Datetime: {now} / weekday: {now.weekday()}')
# Begin Freeze
# 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()
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']]
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
async def before_player_list(self):
@ -352,7 +347,7 @@ class Players(commands.Cog):
# weekly_games = Result.select_season(current.season).where(
# (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:
# return None
@ -398,7 +393,7 @@ class Players(commands.Cog):
# for team in records:
# 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):
# 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].set_thumbnail(url=self.logo)
#
@ -482,7 +477,7 @@ class Players(commands.Cog):
all_embeds = []
for x in all_cards:
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:
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']]['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)
# logging.info(f'sorted_records: {sorted_records}')
# logger.info(f'sorted_records: {sorted_records}')
# await ctx.send(f'sorted: {sorted_records}')
embed = get_team_embed(
@ -839,14 +834,14 @@ class Players(commands.Cog):
chunk_string = ''
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])
if team:
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'
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):
embed.add_field(
@ -879,11 +874,11 @@ class Players(commands.Cog):
# Pull data from Sheets
async with ctx.typing():
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
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:
this_roster = await db_post(
'rosters',
@ -983,7 +978,7 @@ class Players(commands.Cog):
except ZeroDivisionError as e:
return
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"]}')])
await gauntlets.wipe_team(draft_team, interaction)
await interaction.channel.send(
@ -1124,7 +1119,7 @@ class Players(commands.Cog):
# # rar_res = Rarity.get(Rarity.name == 'Reserve')
# # rar_rpl = Rarity.get(Rarity.name == 'Replacement')
# # except Exception as e:
# # logging.error(f'**Error**: (players inv getrars) - {e}')
# # logger.error(f'**Error**: (players inv getrars) - {e}')
# # return
#
# all_embeds = [
@ -1192,7 +1187,7 @@ class Players(commands.Cog):
# await ctx.send('Alright, let me go open that Sheet...')
# scorecard = self.sheets.open_by_url(scorecard_url).worksheet_by_title('Results')
# 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.send(f'{ctx.message.author.mention}, I can\'t access that sheet.')
# return
@ -1201,7 +1196,7 @@ class Players(commands.Cog):
# try:
# awayteam = Team.get_season(awayabbrev)
# hometeam = Team.get_season(homeabbrev)
# logging.info(f'Final: {awayabbrev} {awayscore} - {homescore} {homeabbrev}')
# logger.info(f'Final: {awayabbrev} {awayscore} - {homescore} {homeabbrev}')
# if awayteam == hometeam:
# await ctx.message.add_reaction('❌')
# await helpers.send_to_news(
@ -1212,7 +1207,7 @@ class Players(commands.Cog):
# return
# except Exception as e:
# error = f'**ERROR:** {type(e).__name__} - {e}'
# logging.error(error)
# logger.error(error)
# await ctx.message.add_reaction('❌')
# 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.')
@ -1280,7 +1275,7 @@ class Players(commands.Cog):
# )
# await ctx.message.add_reaction('✅')
#
# logging.info('Checking for credit')
# logger.info('Checking for credit')
# # Credit pack for win
# economy = self.bot.get_cog('Economy')
# if awayscore > homescore:
@ -1293,19 +1288,19 @@ class Players(commands.Cog):
# # Check values and distribute earnings
# if awayteam.team_value - hometeam.team_value <= 12:
# 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')
# 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}')
# earnings['away'] = f'None - Team was {awayteam.team_value - hometeam.team_value} points higher'
#
# if hometeam.team_value - awayteam.team_value <= 12:
# 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)
# 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}')
# earnings['home'] = f'None - Team was {hometeam.team_value - awayteam.team_value} points higher'
# else:
@ -1317,19 +1312,19 @@ class Players(commands.Cog):
# # Check values and distribute earnings
# if hometeam.team_value - awayteam.team_value <= 12:
# 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')
# 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}')
# earnings['home'] = f'None - Team was {hometeam.team_value - awayteam.team_value} points higher'
#
# if awayteam.team_value - hometeam.team_value <= 12:
# 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)
# 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}')
# 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
# # if delta < 0:
# # increments = divmod(-delta, helpers.TEAM_DELTA_CONSTANT)
# # # logging.info(f'increments: {increments}')
# # # logger.info(f'increments: {increments}')
# # packs = min(increments[0], 5)
# # if packs > 0:
# # earnings['away'] += packs
# # earnings_away.append(f'- {packs} pack{"s" if packs > 1 else ""} for underdog\n')
# # else:
# # increments = divmod(delta, helpers.TEAM_DELTA_CONSTANT)
# # # logging.info(f'increments: {increments}')
# # # logger.info(f'increments: {increments}')
# # packs = min(increments[0], 5)
# # if packs > 0:
# # earnings['home'] += packs
# # 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
# # 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)
@ -1365,12 +1360,12 @@ class Players(commands.Cog):
#
# # economy = self.bot.get_cog('Economy')
# # 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)
# # else:
# # away_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)
# # else:
# # home_final_earnings = 0
@ -1643,11 +1638,11 @@ class Players(commands.Cog):
if resp.status_code == 200:
return resp.json()
else:
logging.warning(resp.text)
logger.warning(resp.text)
raise ValueError(f'DB: {resp.text}')
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.describe(

View File

@ -7,17 +7,19 @@ from sqlmodel import Session, select, func
from sqlalchemy import delete
from typing import Literal
from api_calls import db_delete, db_get, db_post
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.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.dropdown import DropdownOptions, DropdownView, SelectViewDefense
from utilities.embeds import image_embed
from utilities.pages import Pagination
logger = logging.getLogger('discord_app')
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:
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
# 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':
return wpa * -1
return wpa * -1.0
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)
nbo = opponent_play.batting_order + 1
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
finally:
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
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:
away_score = this_play.away_score
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:
is_go_ahead = True
this_play.is_go_ahead = True
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'),
is_new_inning=switch_sides,
is_tied=away_score == home_score,
is_go_ahead=is_go_ahead,
on_first=on_first,
on_second=on_second,
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]:
logging.debug(f'sheets: {sheets}')
logger.debug(f'sheets: {sheets}')
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')
logging.debug(f'r_sheet: {r_sheet}')
logger.debug(f'r_sheet: {r_sheet}')
if lineup_num == 1:
row_start = 9
@ -225,15 +234,15 @@ async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, thi
else:
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)
logging.debug(f'raw_cells: {raw_cells}')
logger.debug(f'raw_cells: {raw_cells}')
try:
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:
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')
all_lineups = []
@ -269,7 +278,7 @@ async def get_lineups_from_sheets(session: Session, sheets, this_game: Game, thi
all_lineups.append(this_lineup)
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']:
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)
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.')
if 'gauntlet' in this_game.game_type:
gauntlet_abbrev = f'Gauntlet-{owner_team.abbrev}'
owner_team = await get_team_or_none(session, team_abbrev=gauntlet_abbrev)
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.')
if not owner_team.id in [this_game.away_team_id, this_game.home_team_id]:
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.')
else:
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)
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.locked = True
@ -346,6 +355,7 @@ def advance_runners(session: Session, this_play: Play, num_bases: int, is_error:
"""
No commits
"""
logger.info(f'Advancing runners {num_bases} bases in game {this_play.game.id}')
this_play.rbi = 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
if this_play.on_third:
this_play.on_third_final = 3
return
if this_play.on_second:
if this_play.on_third:
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')
rf = get_one_lineup(session, this_game=this_play.game, this_team=this_play.pitcher.team, position='RF')
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.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)
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)
logging.debug(f'done with of embed')
logger.debug(f'done with of embed')
runner = this_play.on_second.player
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
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)
logging.debug(f'done with of embed')
logger.debug(f'done with of embed')
runner = this_play.on_second.player
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):
this_game = this_play.game
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
TO_BASE = {
2: 'to second',
@ -666,7 +675,7 @@ async def check_uncapped_advance(session: Session, interaction: discord.Interact
throw_resp = None
if this_game.ai_team:
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:
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
if runner_thrown_out:
logging.info(f'Lead runner is thrown out.')
logger.info(f'Lead runner is thrown out.')
this_play.outs += 1
# Lead runner is safe
else:
logging.info(f'Lead runner is safe.')
logger.info(f'Lead runner is safe.')
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
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
else:
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
if is_lead_out:
logging.info(f'Lead runner is thrown out.')
logger.info(f'Lead runner is thrown out.')
this_play.outs += 1
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
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
else:
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']):
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 = advance_runners(session, this_play, num_bases=4)
this_play.rbi += 1
session.add(this_play)
session.commit()
@ -1098,16 +1108,16 @@ def undo_play(session: Session, this_play: Play):
session.add(last_pa)
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.commit()
try:
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:
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
@ -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)
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'
logger = logging.getLogger('discord_app')
def param_char(other_params):
@ -43,7 +44,7 @@ def get_sba_team(id_or_abbrev, season=None):
if resp.status_code == 200:
return resp.json()
else:
logging.warning(resp.text)
logger.warning(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:
return resp.json()
else:
logging.warning(resp.text)
logger.warning(resp.text)
raise ValueError(f'DB: {resp.text}')
@ -69,25 +70,25 @@ def get_sba_team_by_owner(season, owner_id):
else:
return full_resp['teams'][0]
else:
logging.warning(resp.text)
logger.warning(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):
# 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)
# if resp.status_code == 200:
# data = resp.json()
# logging.info(f'return: {data}')
# logger.info(f'return: {data}')
# return data
# elif none_okay:
# data = resp.json()
# logging.info(f'return: {data}')
# logger.info(f'return: {data}')
# return None
# else:
# logging.warning(resp.text)
# logger.warning(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)
# # if resp.status_code == 200:
# # data = resp.json()
# # logging.info(f'return: {data}')
# # logger.info(f'return: {data}')
# # return data['teams'][0]
# # else:
# # logging.warning(resp.text)
# # logger.warning(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:
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}')
if game.is_pd:
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.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:
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.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:
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)
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
if curr_play:
@ -576,19 +577,19 @@ def make_sub(lineup_dict: dict):
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))
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]
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])
logging.info(f'old_player: {old_player}')
logger.info(f'old_player: {old_player}')
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()
@ -613,7 +614,7 @@ async def get_player(game, lineup_member, as_dict: bool = True):
player = this_card['player']
player['name'] = player['p_name']
player['team'] = this_card['team']
logging.debug(f'player: {player}')
logger.debug(f'player: {player}')
return player
else:
return get_sba_player(lineup_member.player_id)
@ -802,7 +803,7 @@ db.create_tables([Play])
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)
# return_play = model_to_dict(new_play)
return_play = convert_stratplay(new_play)
@ -994,7 +995,7 @@ def get_latest_play(game_id):
def undo_play(game_id):
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()
db.close()
@ -1035,7 +1036,7 @@ def add_run_last_player_ab(lineup: Lineup, is_erun: bool = True):
try:
last_ab = Play.select().where(Play.batter == lineup).order_by(-Play.id).get()
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:
last_ab.run = 1
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['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
@ -1114,7 +1115,7 @@ def get_or_create_bullpen(ai_team, bot):
if this_pen:
return convert_bullpen_to_strat(this_pen)
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}')
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'
raw_cells = r_sheet.range(bullpen_range)
logging.debug(f'raw_cells: {raw_cells}')
logger.debug(f'raw_cells: {raw_cells}')
bullpen = Bullpen(
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)
)
bullpen.save()
logging.debug(f'bullpen: {bullpen}')
logger.debug(f'bullpen: {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.save()
logging.debug(f'starting the inning calc')
logger.debug(f'starting the inning calc')
new_inning_half = this_play.inning_half
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:
@ -1286,7 +1287,7 @@ def complete_play(play_id, batter_to_base: int = None):
new_on_third = None
# score_increment = this_play.homerun
# 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:
this_play.run = 1
score_increment = 1
@ -1294,7 +1295,7 @@ def complete_play(play_id, batter_to_base: int = None):
this_play.e_run = 1
else:
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:
this_play.on_first_final = None
@ -1343,7 +1344,7 @@ def complete_play(play_id, batter_to_base: int = None):
new_batting_order = 1
# Not an inning-ending play
else:
logging.debug(f'starting the obc calc')
logger.debug(f'starting the obc calc')
bases_occ = [False, False, False, False]
# 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
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'this_player.home_score: {this_play.home_score}')
# Game is now tied
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
# One team took the lead
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.save()
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.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_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(**{
'game_id': this_play.game.id,
'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
})
logging.debug(f'fielding_stats: {all_stats}')
logger.debug(f'fielding_stats: {all_stats}')
db.close()
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,
# })
# 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:
# 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')
# ).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 = []
# for x in batting_stats:
# 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(
# (Lineup.game_id == game_id) & (Lineup.team_id == team_id) & (Lineup.batting_order < 10)
# ).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 = []
# 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):
if in_innings is None:
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(
Play.pitcher,
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.homerun).over(partition_by=[Play.pitcher.team_id]).alias('tm_homerun'),
).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
# earned_runs_pl = Play.select().where(
# ((Play.on_first_final == 4) | (Play.on_second_final == 4) | (Play.on_third_final == 4) |
# (Play.batter_final == 4)) & (Play.error == 0)
# ).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(
(Play.on_first_final == 4) & (Play.error == 0)
@ -1865,7 +1866,7 @@ def get_pitching_stats(
# if in_innings is not None:
# 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()}')
tm_earned_runs = None
@ -1933,7 +1934,7 @@ def get_pitching_stats(
done_pitchers.append(x.pitcher_id)
db.close()
logging.debug(f'pitching stats: {return_pitchers}')
logger.debug(f'pitching stats: {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)]
# last_play = get_current_play(game.id)
logging.debug(f'this game: {game}')
logger.debug(f'this game: {game}')
winner = None
loser = 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')
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])
logging.debug(f'SPs: {away_pitcher} / {home_pitcher}')
logger.debug(f'SPs: {away_pitcher} / {home_pitcher}')
decisions = {
away_pitcher.player_id: DecisionModel(
@ -1979,7 +1980,7 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
} # { <player_id>: DecisionModel }
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 save == home_pitcher:
if x.home_score > x.away_score:
@ -2007,7 +2008,7 @@ def get_pitching_decisions(game: StratGame, db_game_id: int):
save = away_pitcher
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:
# 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
if x.is_tied:
logging.debug(f'is tied: {x}')
logger.debug(f'is tied: {x}')
winner, loser = None, None
if 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()]
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 {
'winner': winner.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:
run_lead = this_play.ai_run_diff()
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'tot_allowed: {tot_allowed}')
@ -2408,30 +2409,30 @@ class StratManagerAi(pydantic.BaseModel):
# AI up big
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
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):
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
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):
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
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):
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
elif run_lead >= -3 and self.behind_aggression > 5:
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
elif run_lead <= -5:
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
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 True
@ -2453,13 +2454,13 @@ def get_manager(game) -> Optional[StratManagerAi]:
manager_ai_id = ((datetime.datetime.now().day * team_id) % 3) + 1
if manager_ai_id > 3 or 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:
this_manager = ManagerAi.get_by_id(manager_ai_id)
except Exception as e:
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')
return convert_strat_manager(this_manager)

View File

@ -1,16 +1,23 @@
import logging
from typing import Literal
logger = logging.getLogger('discord_app')
def log_exception(e: Exception, msg: str = '', level: Literal['debug', 'error', 'info', 'warn'] = 'error'):
if level == 'debug':
logging.debug(msg, stack_info=True)
logger.debug(msg, exc_info=True, stack_info=True)
elif level == 'error':
logging.error(msg, stack_info=True)
logger.error(msg, exc_info=True, stack_info=True)
elif level == 'info':
logging.info(msg, stack_info=True)
logger.info(msg, exc_info=True, stack_info=True)
else:
logging.warning(msg, stack_info=True)
raise e(msg)
logger.warning(msg, exc_info=True, stack_info=True)
# 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):
pass
@ -38,3 +45,7 @@ class PlayNotFoundException(GameException):
class PlayInitException(GameException):
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
logger = logging.getLogger('discord_app')
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...')
# Delete cards
@ -273,11 +276,11 @@ async def get_starting_pitcher(this_team, this_game, this_event, this_run):
# timeout=10
# )
# 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.')
#
# if pitchers['count'] == 0:
# logging.info(f'pitchers is None')
# logger.info(f'pitchers is None')
# del params
# params = [
# ('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),
('cardset_id', 8), ('limit', 8)]
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"]}')
if draft_team is None:
@ -519,7 +522,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
'Reserve': 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
counter = 0
@ -615,7 +618,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
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))
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:
counter += 1
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
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
elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}')
logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] > 7:
slot_params = [('pos_exc', 'RP')]
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:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}')
logger.info(f'this_batch: {this_batch}')
logger.info(f'slot_params: {slot_params}')
logger.info(f'params: {params}')
# No position explicitly requested or denied
if len(slot_params) == 0:
@ -744,7 +747,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break
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)
for i in p_query['players']:
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
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
custom_player_round = None
if this_event['id'] == 1:
@ -869,7 +872,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# Slot 2 - RP
elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}')
logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] < 8:
slot_params = [('pos_inc', 'RP')]
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:
slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}')
logger.info(f'this_batch: {this_batch}')
logger.info(f'slot_params: {slot_params}')
logger.info(f'params: {params}')
slot_params.extend(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
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)
for i in p_query['players']:
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
elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}')
logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] > 7:
slot_params = [('pos_exc', 'RP')]
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:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}')
logger.info(f'this_batch: {this_batch}')
logger.info(f'slot_params: {slot_params}')
logger.info(f'params: {params}')
# No position explicitly requested or denied
if len(slot_params) == 0:
@ -1100,7 +1103,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break
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)
for i in p_query['players']:
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))
elif this_event['id'] == 3:
while round_num <= 26 and counter < 50:
logging.info(f'round {round_num}')
logger.info(f'round {round_num}')
counter += 1
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'])
])
logging.info(f'starting position loop')
logger.info(f'starting position loop')
this_batch = []
for x in ['SP', 'RP', 'IF', 'OF']:
# Slot 1 - SP
@ -1205,7 +1208,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
# Slot 2 - RP
elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}')
logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] > 7:
slot_params = [('pos_exc', 'RP')]
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:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}')
logger.info(f'this_batch: {this_batch}')
logger.info(f'slot_params: {slot_params}')
logger.info(f'params: {params}')
# No position explicitly requested or denied
if len(slot_params) == 0:
@ -1278,7 +1281,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break
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)
for i in p_query['players']:
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
elif x == 'RP':
logging.info(f'counts[RP]: {counts["RP"]}')
logger.info(f'counts[RP]: {counts["RP"]}')
if counts['RP'] > 7:
slot_params = [('pos_exc', 'RP')]
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:
# slot_params = [('pos_exc', 'LF'), ('pos_exc', 'CF'), ('pos_exc', 'RF')]
logging.info(f'this_batch: {this_batch}')
logging.info(f'slot_params: {slot_params}')
logging.info(f'params: {params}')
logger.info(f'this_batch: {this_batch}')
logger.info(f'slot_params: {slot_params}')
logger.info(f'params: {params}')
# No position explicitly requested or denied
if len(slot_params) == 0:
@ -1476,7 +1479,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event, dra
break
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)
for i in p_query['players']:
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]:
await draft_loop()
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"]}')
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):
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:
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)
async def left_button(self, interaction: discord.Interaction, button: discord.ui.Button):
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
self.value = 'left'
@ -449,7 +449,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='❌️', style=discord.ButtonStyle.secondary)
async def cancel_button(self, interaction: discord.Interaction, button: discord.ui.Button):
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
self.value = 'cancel'
@ -459,7 +459,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='⏭️', style=discord.ButtonStyle.blurple)
async def right_button(self, interaction: discord.Interaction, button: discord.ui.Button):
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
self.value = 'right'
@ -585,7 +585,7 @@ class SelectChoicePackTeam(discord.ui.Select):
params.append(('pack_cardset_id', self.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}')
logger.error(f'open-packs - no packs found with params: {params}')
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)])
@ -599,9 +599,9 @@ class SelectOpenPack(discord.ui.Select):
super().__init__(placeholder='Select a Pack Type', options=options)
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('-')
logging.info(f'pack_vals: {pack_vals}')
logger.info(f'pack_vals: {pack_vals}')
# Get the selected packs
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)
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')
# Open the packs
@ -694,7 +694,7 @@ class SelectPaperdexCardset(discord.ui.Select):
super().__init__(placeholder='Select a Cardset', options=options)
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
if self.values[0] == '2022 Season':
cardset_id = 3
@ -871,7 +871,7 @@ class SelectBuyPacksCardset(discord.ui.Select):
super().__init__(placeholder='Select a Cardset', options=options)
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
if self.values[0] == '2022 Season':
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
# selected options. We only want the first one.
# 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)
@ -1554,7 +1554,7 @@ async def create_channel_old(
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
@ -1567,7 +1567,7 @@ async def react_and_reply(ctx, reaction, message):
async def send_to_channel(bot, channel_name, content=None, embed=None):
guild = bot.get_guild(int(os.environ.get('GUILD_ID')))
if not guild:
logging.error('Cannot send to channel - bot not logged in')
logger.error('Cannot send to channel - bot not logged in')
return
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):
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:
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
@ -1682,7 +1682,7 @@ async def create_channel(
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
@ -2208,7 +2208,7 @@ async def roll_for_cards(all_packs: list, extra_val=None) -> list:
counts['HoF']['count'] += 1
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
mod = 0
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'])
for pull in pull_notifs:
logging.info(f'good pull: {pull}')
logger.info(f'good pull: {pull}')
await db_post('notifs', payload={
'created': int(datetime.datetime.timestamp(datetime.datetime.now())*1000),
'title': 'Rare Pull',
@ -2318,7 +2318,7 @@ def get_sheets(bot):
try:
return bot.get_cog('Players').sheets
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.')
@ -2329,7 +2329,7 @@ def create_team_sheet(team, email: str, current, bot):
f'{team["lname"]} Roster Sheet v{current["gsheet_version"]}',
'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.share(email, role='writer')
@ -2338,7 +2338,7 @@ def create_team_sheet(team, email: str, current, bot):
crange='B1:B2',
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
@ -2422,7 +2422,7 @@ def get_rosters(team, bot, roster_num: Optional[int] = None) -> list:
sheets = get_sheets(bot)
this_sheet = sheets.open_by_key(team['gsheet'])
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]
@ -2430,7 +2430,7 @@ def get_rosters(team, bot, roster_num: Optional[int] = None) -> list:
if not roster_num or roster_num == 1:
roster_1 = r_sheet.range('B3:B28')
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 == '':
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:
roster_2 = r_sheet.range('B29:B54')
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 == '':
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:
roster_3 = r_sheet.range('B55:B80')
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 == '':
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:
sheets = get_sheets(bot)
logging.debug(f'sheets: {sheets}')
logger.debug(f'sheets: {sheets}')
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')
logging.debug(f'r_sheet: {r_sheet}')
logger.debug(f'r_sheet: {r_sheet}')
if lineup_num == 1:
row_start = 9
@ -2481,17 +2481,17 @@ def get_roster_lineups(team, bot, roster_num, lineup_num) -> list:
else:
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)
logging.debug(f'raw_cells: {raw_cells}')
logger.debug(f'raw_cells: {raw_cells}')
try:
lineup_cells = [(row[0].value, int(row[1].value)) for row in raw_cells]
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 '
f'get the card IDs')
logging.debug(f'lineup_cells: {lineup_cells}')
logger.debug(f'lineup_cells: {lineup_cells}')
return lineup_cells
@ -2519,7 +2519,7 @@ async def legal_channel(ctx):
elif ctx.channel.name in bad_channels:
# await ctx.message.add_reaction('❌')
# 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
raise discord.app_commands.AppCommandError(f'Slide on down to the {get_channel(ctx, "pd-bot-hole").mention} ;)')
else:
@ -2589,7 +2589,7 @@ async def team_summary_embed(team, ctx, include_roster: bool = True):
# inline=False
# )
# 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(
# name='Rosters',
# 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:
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)
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 = ''
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 += f'{this_player["p_name"]}\n'
@ -2834,7 +2834,7 @@ async def paperdex_team_embed(team: dict, mlb_team: dict) -> list[discord.Embed]
else:
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)
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 = ''
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 += 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)
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')
all_cards = []
@ -2912,7 +2912,7 @@ async def open_st_pr_packs(all_packs: list, team: dict, context):
all_cards.extend(new_cards['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')
# 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']}}
) 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:
page_num = 0
@ -3132,7 +3132,7 @@ async def open_choice_pack(this_pack, team: dict, context, cardset_id: Optional[
rarity_id += 3
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')
if type(context) == commands.Context:
@ -3140,7 +3140,7 @@ async def open_choice_pack(this_pack, team: dict, context, cardset_id: Optional[
else:
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
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
) for x in players
]
logging.debug(f'card embeds: {card_embeds}')
logger.debug(f'card embeds: {card_embeds}')
page_num = 0
view = Pagination([author], timeout=30)
@ -3182,7 +3182,7 @@ async def open_choice_pack(this_pack, team: dict, context, cardset_id: Optional[
try:
await give_cards_to_team(team, players=[players[page_num - 1]], pack_id=this_pack['id'])
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.')
await db_patch('packs', object_id=this_pack['id'], params=[
@ -3282,13 +3282,13 @@ def random_gif(search_term: str):
else:
return data['data']['url']
else:
logging.warning(resp.text)
logger.warning(resp.text)
raise ValueError(f'DB: {resp.text}')
def random_from_list(data_list: list):
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

View File

@ -24,6 +24,7 @@ db = SqliteDatabase(
'synchronous': 0
}
)
logger = logging.getLogger('discord_app')
# 2018, 2024, Mario,
GAUNTLET1_PARAMS = [
@ -127,7 +128,7 @@ async def get_or_create_card(player: dict, team: dict) -> int:
]}
)
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"]}')
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)
rg_data = next(x for x in batter_rg if x['player_id'] == this_guy['player_id'])
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['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:
# Sort players dict by position with fewest eligible players
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>])
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)
if this_pos_data[0] == 'dh':
this_pos = sorted(this_pos_data[1], key=lambda item: item['raw-bat'], reverse=True)
else:
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
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]}')
logging.info(f'deleting position: {this_pos_data[0]}')
logger.info(f'adding player: {this_pos[0]}')
logger.info(f'deleting position: {this_pos_data[0]}')
# Remove this position from consideration
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
)
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_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 = []
i = 1
for x in [grp_1, grp_2, grp_3]:
logging.debug(f'group: {x}')
logger.debug(f'group: {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)
lineups.append({
@ -269,7 +270,7 @@ async def build_lineup(team_object: dict, game_id: int, league_name: str, sp_nam
})
i += 1
logging.info(f'build_lineup - final lineup: {lineups}')
logger.info(f'build_lineup - final lineup: {lineups}')
return lineups
@ -281,7 +282,7 @@ async def get_starting_lineup(session: Session, team: Team, game: Game, league_n
timeout=6
)
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_2 = sorted_players[3:6]
@ -293,9 +294,9 @@ async def get_starting_lineup(session: Session, team: Team, game: Game, league_n
lineups = []
i = 1
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:
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_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
logging.debug(f'ai_manager - get_starting_lineup - final lineup: {lineups}')
logger.debug(f'ai_manager - get_starting_lineup - final lineup: {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:
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)
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
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:
need = 'length'
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:
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]}'
f'?need={need}&used_pitcher_ids={id_string}{get_cardset_string(this_game)}')
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:
# c_query = await db_get('cards', object_id=x.card_id)
# 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
# attempts = 0
@ -440,7 +441,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
# if attempts == 1:
# # Try to get long man
# 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'))
# # 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:
# 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):
# 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'))
# use_best = True
# else:
@ -456,7 +457,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
#
# # Try to exclude long men
# 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'))
#
# try:
@ -466,7 +467,7 @@ async def get_relief_pitcher(this_play: StratPlay, ai_team: dict, league_name: s
# timeout=10
# )
# 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.')
#
# if pitchers['count'] > 0:
@ -519,12 +520,12 @@ async def pitching_ai_note(this_play: StratPlay, this_pitcher: dict):
# # Pitcher Substitutions
# new_pitcher = None
# 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'
#
# 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:
# 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)
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
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_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:
patch_play(this_play.id, in_pow=True)
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 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)
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
ps = p_stats[0]
@ -665,7 +666,7 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
try:
this_pc = await data_cache.get_pd_pitchingcard(this_play.pitcher.player_id, variant=this_play.pitcher.variant)
except:
logging.info(
logger.info(
f'ai_manager - is_pitcher_fatigued: could not pull pitching card for {this_play.pitcher.player_id}, '
f'returning False')
return False
@ -674,45 +675,45 @@ async def is_pitcher_fatigued(this_play: StratPlay) -> bool:
# Check starter fatigue
if len(used_pitchers) == 1:
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
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(
this_play.game.id,
lineup_id=this_play.pitcher.id,
in_innings=[this_play.inning_num, this_play.inning_num - 1]
)
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)
return True
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(
this_play.game.id,
lineup_id=this_play.pitcher.id,
in_innings=[this_play.inning_num]
)
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)
return True
innof_work = math.ceil((ps['pl_outs'] + 1) / 3)
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
elif innof_work == pof_weakness:
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)
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
pows = pow_stats[0]
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
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)
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)
return True

View File

@ -10,6 +10,7 @@ PLAYER_CACHE = {}
TEAM_CACHE = {}
BATTINGCARD_CACHE = {} # { <player_id: int>: { <variant: int>: BattingWrapper } }
PITCHINGCARD_CACHE = {} # { <player_id: int>: { <variant: int>: PitchingWrapper } }
logger = logging.getLogger('discord_app')
@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:
tdelta = datetime.datetime.now() - PLAYER_CACHE[player_id].created
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:
return PLAYER_CACHE[player_id].to_dict()
else:
return PLAYER_CACHE[player_id]
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)
for bad_key in ['mlbplayer', 'paperdex']:
if bad_key in this_player:
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)
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:
tdelta = datetime.datetime.now() - TEAM_CACHE[team_or_gm_id].created
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:
return TEAM_CACHE[team_or_gm_id].to_dict()
else:
return TEAM_CACHE[team_or_gm_id]
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)])
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}')
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)
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]:
tdelta = datetime.datetime.now() - BATTINGCARD_CACHE[player_id][variant].created
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]
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]:
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['player_id'] = player_id
del bc_data['id'], bc_data['player']
this_bc = BattingCard(**bc_data)
logging.info(f'prepping the vl ratings')
logger.info(f'prepping the vl ratings')
vl_ratings = vl_data
del vl_ratings['battingcard'], vl_ratings['id'], vl_ratings['vs_hand']
this_vl = BattingRatings(**vl_ratings)
logging.info(f'prepping the vl ratings')
logger.info(f'prepping the vl ratings')
vr_ratings = vr_data
del vr_ratings['battingcard'], vr_ratings['id'], vr_ratings['vs_hand']
this_vr = BattingRatings(**vr_ratings)
logging.info(f'prepping the wrapper')
logger.info(f'prepping the wrapper')
this_wrapper = BattingWrapper(
card=this_bc,
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]:
tdelta = datetime.datetime.now() - PITCHINGCARD_CACHE[player_id][variant].created
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]
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]:
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['player_id'] = player_id
del pc_data['id'], pc_data['player']
this_pc = PitchingCard(**pc_data)
logging.debug(f'prepping the vl ratings')
logger.debug(f'prepping the vl ratings')
vl_ratings = vl_data
del vl_ratings['pitchingcard'], vl_ratings['id'], vl_ratings['vs_hand']
this_vl = PitchingRatings(**vl_ratings)
logging.debug(f'prepping the vr ratings')
logger.debug(f'prepping the vr ratings')
vr_ratings = vr_data
del vr_ratings['pitchingcard'], vr_ratings['id'], vr_ratings['vs_hand']
this_vr = PitchingRatings(**vr_ratings)
logging.debug(f'prepping the wrapper')
logger.debug(f'prepping the wrapper')
this_wrapper = PitchingWrapper(
card=this_pc,
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
PUBLIC_FIELDS_CATEGORY_NAME = 'Public Fields'
logger = logging.getLogger('discord_app')
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(
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]
logging.debug(f'used_ids: {used_ids}')
logger.debug(f'used_ids: {used_ids}')
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.inning_num == 1:
@ -124,7 +125,7 @@ def starting_pitcher(ai_team, bot, is_home):
rotation_range = f'I4:I8'
raw_cells = r_sheet.range(rotation_range)
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 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_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.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]:
logging.info(f'GB 1')
logger.info(f'GB 1')
advance_runners(this_play.id, num_bases=0)
patch_play(this_play.id, pa=1, ab=1, outs=1)
return None
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
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]:
logging.info(f'GB 3')
logger.info(f'GB 3')
if this_play.starting_outs < 2:
advance_runners(this_play.id, num_bases=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]:
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)
if this_play.starting_outs < 2:
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]:
logging.info(f'GB 5')
logger.info(f'GB 5')
patch_play(this_play.id, pa=1, ab=1, outs=1)
if to_mif:
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]:
logging.info(f'GB 6')
logger.info(f'GB 6')
patch_play(this_play.id, pa=1, ab=1, outs=1)
if to_right_side:
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]:
logging.info(f'GB 7')
logger.info(f'GB 7')
patch_play(this_play.id, pa=1, ab=1, outs=1)
advance_runners(this_play.id, num_bases=1, only_forced=True)
return None
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)
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)
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
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)
@ -365,13 +366,13 @@ def gb_result_10(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)
return 1
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_manager = get_manager(this_play.game)
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'],
interaction: discord.Interaction) -> Optional[int]:
logging.info(f'GB 12')
logger.info(f'GB 12')
if defender == '1b-2b':
return gb_result_3(this_play)
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]:
logging.info(f'GB 13')
logger.info(f'GB 13')
if defender == 'c-3b':
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)

View File

@ -13,10 +13,13 @@ from exceptions import *
from in_game.managerai_responses import JumpResponse, TagResponse, ThrowResponse, UncappedRunResponse
logger = logging.getLogger('discord_app')
sqlite_url = 'sqlite:///storage/gameplay.db'
connect_args = {"check_same_thread": False}
engine = create_engine(sqlite_url, echo=False, connect_args=connect_args)
CACHE_LIMIT = 1209600 # in seconds
SBA_COLOR = 'a6ce39'
SBA_LOGO = 'https://sombaseball.ddns.net/static/images/sba-logo.png'
class ManagerAiBase(SQLModel):
@ -74,6 +77,16 @@ class Team(TeamBase, table=True):
lineups: list['Lineup'] = Relationship(back_populates='team', cascade_delete=True)
# away_games: list['Game'] = Relationship(back_populates='away_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):
@ -86,7 +99,7 @@ class Game(SQLModel, table=True):
is_pd: bool | None = Field(default=True)
ranked: 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)
away_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'
elif 'exhibition' in self.game_type:
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(
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)
@ -161,7 +174,7 @@ class Game(SQLModel, table=True):
try:
curr_play = self.initialize_play(session)
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:
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'
if curr_play.on_third is not None:
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:
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'))
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:
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)
@ -300,7 +313,7 @@ class ManagerAi(ManagerAiBase, table=True):
def get_new_ai(this_session: Session):
all_ai = this_session.exec(select(ManagerAi.id)).all()
if len(all_ai) == 0:
logging.info(f'Creating ManagerAI records')
logger.info(f'Creating ManagerAI records')
new_ai = [
ManagerAi(
name='Balanced'
@ -560,7 +573,7 @@ class PlayerBase(SQLModel):
elif self.image2 is not None and 'pitching' in self.image2:
return self.image2
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
@property
@ -570,7 +583,7 @@ class PlayerBase(SQLModel):
elif self.image2 is not None and 'batting' in self.image2:
return self.image2
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
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:
if player is None and player_dict is None:
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)
if player is not None:

View File

@ -1,23 +1,47 @@
import datetime
import logging
import math
import pydantic
from sqlalchemy import func
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 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]:
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()
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)
if len(all_games) > 1:
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)
elif len(all_games) == 0:
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]:
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()
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:
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:
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)
if not skip_cache:
@ -48,9 +72,9 @@ async def get_team_or_none(
this_team = session.exec(statement).one_or_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
logging.debug(f'tdelta: {tdelta}')
logger.debug(f'tdelta: {tdelta}')
if tdelta.total_seconds() < CACHE_LIMIT:
return this_team
else:
@ -58,11 +82,11 @@ async def get_team_or_none(
session.commit()
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)
# 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)
# 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.commit()
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:
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:
this_player = session.get(Player, player_id)
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
logging.debug(f'tdelta: {tdelta}')
logger.debug(f'tdelta: {tdelta}')
if tdelta.total_seconds() < CACHE_LIMIT:
return this_player
else:
@ -104,7 +128,7 @@ async def get_player_or_none(session: Session, player_id: int, skip_cache: bool
session.commit()
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)
db_player = Player.model_validate(valid_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:
logging.info(f'Getting player from dict {json_data}')
logger.info(f'Getting player from dict {json_data}')
if 'player_id' in json_data:
return json_data['player_id']
elif 'id' in json_data:
return json_data['id']
err = 'Player ID could not be extracted from json data'
logging.error(f'{err}: {json_data}')
raise KeyError(err)
log_exception(KeyError, 'Player ID could not be extracted from json data')
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:
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:
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)
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:
c_query = session.exec(select(Card).where(Card.player == player, Card.team == team)).all()
if len(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
logging.debug(f'tdelta: {tdelta}')
logger.debug(f'tdelta: {tdelta}')
if tdelta.total_seconds() < CACHE_LIMIT:
return this_card
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)])
if c_query['count'] > 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['player_id'] = get_player_id_from_dict(json_data['player'])
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:
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:
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
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)
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:
this_card = session.get(Card, card_id)
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
logging.debug(f'tdelta: {tdelta}')
logger.debug(f'tdelta: {tdelta}')
if tdelta.total_seconds() < CACHE_LIMIT:
return this_card
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]:
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)
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):
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()
if len(last_pa) == 1:
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:
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:
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):
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()
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]:
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}
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')))
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
logger = logging.getLogger('discord_app')
def get_result(pitcher: data_cache.PitchingWrapper, batter: data_cache.BattingWrapper):
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']
pit_hand = pitcher.card.hand
bat_hand = batter.card.hand
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
logging.info(f'ch_data: {ch_data}')
logger.info(f'ch_data: {ch_data}')
# for field in fields(ch_data):
# if field.name not in unused_fields:
# ch_results.append(field.name)
# ch_probs.append(getattr(data_cache.PitchingRatings, field.name))
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
logging.info(f'ch_data: {ch_data}')
logger.info(f'ch_data: {ch_data}')
# for field in fields(ch_data):
# if field.name not in unused_fields:
# 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_probs = list(ch_dict.values())
logging.info(f'ch_results: {ch_results}')
logging.info(f'ch_probs: {ch_probs}')
logger.info(f'ch_results: {ch_results}')
logger.info(f'ch_probs: {ch_probs}')
result = random.choices(ch_results, ch_probs)
logging.info(f'result: {result}')
logger.info(f'result: {result}')
return result[0]

View File

@ -1,7 +1,7 @@
import discord
import datetime
import logging
# import logging.handlers
from logging.handlers import RotatingFileHandler
import asyncio
import os
@ -19,27 +19,30 @@ elif raw_log_level == 'WARN':
else:
log_level = logging.ERROR
date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
logging.basicConfig(
filename=f'logs/{date}.log',
format='%(asctime)s - %(levelname)s - %(message)s',
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
# date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
# logger.basicConfig(
# filename=f'logs/{date}.log',
# format='%(asctime)s - %(levelname)s - %(message)s',
# level=log_level
# )
# 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'
# 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)
# logger.addHandler(handler)
logger.addHandler(handler)
COGS = [
'cogs.owner',
@ -62,9 +65,9 @@ bot = commands.Bot(command_prefix='.',
@bot.event
async def on_ready():
logging.info('Logged in as:')
logging.info(bot.user.name)
logging.info(bot.user.id)
logger.info('Logged in as:')
logger.info(bot.user.name)
logger.info(bot.user.id)
# @bot.tree.error
@ -77,10 +80,10 @@ async def main():
for c in COGS:
try:
await bot.load_extension(c)
logging.info(f'Loaded cog: {c}')
logger.info(f'Loaded cog: {c}')
except Exception as e:
logging.error(f'Failed to load cog: {c}')
logging.error(f'{e}')
logger.error(f'Failed to load cog: {c}')
logger.error(f'{e}')
async with bot:
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)
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.outs == 1
@ -181,13 +181,13 @@ async def test_doubles(session: Session):
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.on_first_final == 4
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.rbi == 0

View File

@ -42,8 +42,8 @@ def session_fixture():
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_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_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_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=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_2)

View File

@ -1,11 +1,11 @@
import pytest
from sqlalchemy import delete as sadelete
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 in_game.gameplay_models import Game, Lineup, GameCardsetLink, Play, select
from in_game.gameplay_queries import get_channel_game_or_none, get_active_games_by_team
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, Team, select
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
@ -20,7 +20,7 @@ def test_create_game(session: Session):
assert game_1.active == True
assert game_1.is_pd == True
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.away_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.is_pd == 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.away_roster_id == 69
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):
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.active = True
session.add(game_2)
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.active = False
@ -92,7 +93,7 @@ def test_games_by_team(session: Session):
session.add(game_2)
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):
@ -200,3 +201,49 @@ async def test_undo_play(session: Session):
assert new_play.play_num == 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'
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>"

View File

@ -1,10 +1,10 @@
import pytest
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 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
@ -107,3 +107,63 @@ async def test_undo_play(session: Session):
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:
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):

View File

@ -111,11 +111,14 @@ class ButtonOptions(discord.ui.View):
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
"""
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:
view.confirm.label = custom_confirm_label
if custom_cancel_label:
@ -127,9 +130,13 @@ async def ask_confirm(interaction: discord.Interaction, question: str, label_typ
if view.value:
if delete_question:
await question.delete()
else:
await question.edit(content=question, view=None)
return True
else:
if delete_question:
await question.delete()
else:
await question.edit(content=question, view=None)
return False

View File

@ -4,7 +4,10 @@ import logging
from sqlmodel import Session
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):
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
# selected options. We only want the first one.
# 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)
@ -60,7 +63,7 @@ class SelectViewDefense(discord.ui.Select):
super().__init__(options=options)
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])
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)
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
logger = logging.getLogger('discord_app')
class Pagination(discord.ui.View):
def __init__(self, responders: list, timeout: float = 300.0):
super().__init__(timeout=timeout)
@ -14,7 +17,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='⏮️', style=discord.ButtonStyle.blurple)
async def left_button(self, interaction: discord.Interaction, button: discord.ui.Button):
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
self.value = 'left'
@ -24,7 +27,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='❌️', style=discord.ButtonStyle.secondary)
async def cancel_button(self, interaction: discord.Interaction, button: discord.ui.Button):
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
self.value = 'cancel'
@ -34,7 +37,7 @@ class Pagination(discord.ui.View):
@discord.ui.button(label='⏭️', style=discord.ButtonStyle.blurple)
async def right_button(self, interaction: discord.Interaction, button: discord.ui.Button):
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
self.value = 'right'