diff --git a/cogs/gameplay.py b/cogs/gameplay.py index 224bb2f..12112fe 100644 --- a/cogs/gameplay.py +++ b/cogs/gameplay.py @@ -14,24 +14,92 @@ import sqlalchemy from sqlmodel import func, or_ from api_calls import db_get -from command_logic.logic_gameplay import bunts, chaos, complete_game, defender_dropdown_view, doubles, flyballs, frame_checks, get_full_roster_from_sheets, checks_log_interaction, complete_play, get_scorebug_embed, groundballs, hit_by_pitch, homeruns, is_game_over, lineouts, manual_end_game, new_game_checks, new_game_conflicts, popouts, read_lineup, relief_pitcher_dropdown_view, select_ai_reliever, show_defense_cards, singles, starting_pitcher_dropdown_view, steals, strikeouts, sub_batter_dropdown_view, substitute_player, triples, undo_play, update_game_settings, walks, xchecks, activate_last_play +from command_logic.logic_gameplay import ( + bunts, + chaos, + complete_game, + defender_dropdown_view, + doubles, + flyballs, + frame_checks, + get_full_roster_from_sheets, + checks_log_interaction, + complete_play, + get_scorebug_embed, + groundballs, + hit_by_pitch, + homeruns, + is_game_over, + lineouts, + manual_end_game, + new_game_checks, + new_game_conflicts, + popouts, + read_lineup, + relief_pitcher_dropdown_view, + select_ai_reliever, + show_defense_cards, + singles, + starting_pitcher_dropdown_view, + steals, + strikeouts, + sub_batter_dropdown_view, + substitute_player, + triples, + undo_play, + update_game_settings, + walks, + xchecks, + activate_last_play, +) from command_logic.play_context import locked_play from dice import ab_roll from exceptions import * import gauntlets -from helpers import CARDSETS, DEFENSE_LITERAL, DEFENSE_NO_PITCHER_LITERAL, PD_PLAYERS_ROLE_NAME, SELECT_CARDSET_OPTIONS, Dropdown, get_channel, send_to_channel, team_role, user_has_role, random_gif, random_from_list +from helpers import ( + CARDSETS, + DEFENSE_LITERAL, + DEFENSE_NO_PITCHER_LITERAL, + PD_PLAYERS_ROLE_NAME, + SELECT_CARDSET_OPTIONS, + Dropdown, + get_channel, + send_to_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 from in_game.game_helpers import PUBLIC_FIELDS_CATEGORY_NAME, legal_check -from in_game.gameplay_models import GameCardsetLink, Lineup, Play, Session, engine, player_description, select, Game -from in_game.gameplay_queries import get_all_positions, get_cardset_or_none, get_one_lineup, get_plays_by_pitcher, get_position, get_channel_game_or_none, get_active_games_by_team, get_game_lineups, get_team_or_none +from in_game.gameplay_models import ( + GameCardsetLink, + Lineup, + Play, + Session, + engine, + player_description, + select, + Game, +) +from in_game.gameplay_queries import ( + get_all_positions, + get_cardset_or_none, + get_one_lineup, + get_plays_by_pitcher, + get_position, + get_channel_game_or_none, + get_active_games_by_team, + get_game_lineups, + get_team_or_none, +) from utilities.buttons import Confirm, ScorebugButtons, ask_confirm, ask_with_buttons from utilities.dropdown import DropdownView - -logger = logging.getLogger('discord_app') +logger = logging.getLogger("discord_app") CLASSIC_EMBED = True CARDSETS @@ -44,75 +112,97 @@ class Gameplay(commands.Cog): self.get_sheets.start() self.live_scorecard.start() - + @tasks.loop(count=1) async def get_sheets(self): - logger.info(f'Getting sheets') - self.sheets = pygsheets.authorize(service_file='storage/paper-dynasty-service-creds.json', retries=1) + logger.info(f"Getting sheets") + self.sheets = pygsheets.authorize( + service_file="storage/paper-dynasty-service-creds.json", retries=1 + ) @tasks.loop(minutes=1) async def live_scorecard(self): try: - logger.info(f'Checking live scorecard loop') - - guild = self.bot.get_guild(int(os.environ.get('GUILD_ID'))) - score_channel = discord.utils.get(guild.text_channels, name='live-pd-scores') + logger.info(f"Checking live scorecard loop") + + guild_id = os.environ.get("GUILD_ID") + if not guild_id: + logger.error("GUILD_ID env var is not set") + return + guild = self.bot.get_guild(int(guild_id)) + score_channel = discord.utils.get( + guild.text_channels, name="live-pd-scores" + ) if score_channel is None: - logger.error(f'Could not find live-pd-channel') + logger.error(f"Could not find live-pd-channel") return if len(self.game_states) == 0: - logger.info(f'No active game_states') - return - + logger.info(f"No active game_states") + return + player_role = discord.utils.get(guild.roles, name=PD_PLAYERS_ROLE_NAME) all_embeds = [] - logger.info(f'player role: {player_role}') + logger.info(f"player role: {player_role}") with Session(engine) as session: for key in self.game_states: - if not self.game_states[key]['ack']: + if not self.game_states[key]["ack"]: this_game = session.get(Game, key) if this_game is None: - log_exception(GameNotFoundException, f'Could not pull game #{key} for live scorecard') - + log_exception( + GameNotFoundException, + f"Could not pull game #{key} for live scorecard", + ) + if not this_game.active: - logger.info(f'Game {this_game.id} is complete, removing from game_states') + logger.info( + f"Game {this_game.id} is complete, removing from game_states" + ) del self.game_states[key] - + else: try: - logger.info(f'Appending scorebug for Game {this_game.id}') - this_channel = discord.utils.get(guild.text_channels, id=this_game.channel_id) - logger.info(f'this_channel: {this_channel}') - - this_embed = await get_scorebug_embed(session, this_game, full_length=False, live_scorecard=True) + logger.info( + f"Appending scorebug for Game {this_game.id}" + ) + this_channel = discord.utils.get( + guild.text_channels, id=this_game.channel_id + ) + logger.info(f"this_channel: {this_channel}") + + this_embed = await get_scorebug_embed( + session, + this_game, + full_length=False, + live_scorecard=True, + ) this_embed.set_image(url=None) this_embed.insert_field_at( index=0, - name='Ballpark', - value=f'{this_channel.mention}' + name="Ballpark", + value=f"{this_channel.mention}", ) all_embeds.append(this_embed) - self.game_states[key]['ack'] = True + self.game_states[key]["ack"] = True except Exception as e: - logger.error(f'Unable to add to game_states: {e}') - logger.error(f'Game: {this_game.id}') - + logger.error(f"Unable to add to game_states: {e}") + logger.error(f"Game: {this_game.id}") + if len(all_embeds) == 0: - logger.info(f'No active game embeds, returning') + logger.info(f"No active game embeds, returning") await score_channel.set_permissions(player_role, read_messages=False) return - + async for message in score_channel.history(limit=25): await message.delete() await score_channel.set_permissions(player_role, read_messages=True) await score_channel.send(content=None, embeds=all_embeds) except Exception as e: - logger.error(f'Failed running live scorecard: {e}') + logger.error(f"Failed running live scorecard: {e}") # try: # await send_to_channel(self.bot, 'commissioners-office', f'PD Live Scorecard just failed: {e}') # except Exception as e: @@ -124,22 +214,33 @@ class Gameplay(commands.Cog): @get_sheets.before_loop async def before_get_sheets(self): - logger.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): logger.error(msg=error, stack_info=True) - await ctx.send(f'{error}\n\nRun !help to see the command requirements') + await ctx.send( + f"{error}\n\nRun !help to see the command requirements" + ) async def slash_error(self, ctx, error): 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, full_length: bool = False): - logger.info(f'post_play - Posting new play: {this_play}') + await ctx.send(f"{error[:1600]}") + + async def post_play( + self, + session: Session, + interaction: discord.Interaction, + this_play: Play, + buffer_message: str = None, + full_length: bool = False, + ): + logger.info(f"post_play - Posting new play: {this_play}") if this_play is None: - logger.info(f'this_play is None, searching for game in channel {interaction.channel.id}') + logger.info( + f"this_play is None, searching for game in channel {interaction.channel.id}" + ) this_game = get_channel_game_or_none(session, interaction.channel.id) try: this_play = activate_last_play(session, this_game) @@ -147,294 +248,384 @@ class Gameplay(commands.Cog): this_play = this_game.initialize_play(session) finally: if this_play is None: - log_exception(PlayNotFoundException, f'Attempting to display gamestate, but cannot find current play') + log_exception( + PlayNotFoundException, + f"Attempting to display gamestate, but cannot find current play", + ) if is_game_over(this_play): - logger.info(f'Game {this_play.game.id} seems to be over') - await interaction.edit_original_response(content=f'Looks like this one is over!') + logger.info(f"Game {this_play.game.id} seems to be over") + 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' + 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: - logger.info(f'post_play - is_game_over - {interaction.user.display_name} rejected game completion') + logger.info( + f"post_play - is_game_over - {interaction.user.display_name} rejected game completion" + ) await complete_game(session, interaction, this_play, self.bot) return else: - logger.warning(f'post_play - is_game_over - {interaction.user.display_name} rejected game completion in Game {this_play.game.id}') + 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}') + 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') - + await interaction.channel.send( + content=f"I let Cal know his bot is stupid" + ) + if this_play.pitcher.is_fatigued and not this_play.ai_is_batting: if this_play.managerai.replace_pitcher(session, this_play.game): - logger.info(f'Running a pitcher sub') - await interaction.edit_original_response(content='The AI is making a pitching change...') - new_pitcher_card = await select_ai_reliever(session, this_play.pitcher.team, this_play) - new_pitcher_lineup = substitute_player(session, this_play, this_play.pitcher, new_pitcher_card, 'P') - logger.info(f'Sub complete') + logger.info(f"Running a pitcher sub") + await interaction.edit_original_response( + content="The AI is making a pitching change..." + ) + new_pitcher_card = await select_ai_reliever( + session, this_play.pitcher.team, this_play + ) + new_pitcher_lineup = substitute_player( + session, this_play, this_play.pitcher, new_pitcher_card, "P" + ) + logger.info(f"Sub complete") scorebug_buttons, this_ab_roll = None, None - scorebug_embed = await get_scorebug_embed(session, this_play.game, full_length=full_length, classic=CLASSIC_EMBED) - - if this_play.game.roll_buttons and interaction.user.id in [this_play.game.away_team.gmid, this_play.game.home_team.gmid]: - logger.info(f'Including scorebug buttons') + scorebug_embed = await get_scorebug_embed( + session, this_play.game, full_length=full_length, classic=CLASSIC_EMBED + ) + + if this_play.game.roll_buttons and interaction.user.id in [ + this_play.game.away_team.gmid, + this_play.game.home_team.gmid, + ]: + logger.info(f"Including scorebug buttons") scorebug_buttons = ScorebugButtons(this_play, scorebug_embed, timeout=8) - - if this_play.on_base_code == 0 and this_play.game.auto_roll and not this_play.batter.team.is_ai and not this_play.is_new_inning: - logger.info(f'Rolling ab') - this_ab_roll = ab_roll(this_play.batter.team, this_play.game, allow_chaos=False) + + if ( + this_play.on_base_code == 0 + and this_play.game.auto_roll + and not this_play.batter.team.is_ai + and not this_play.is_new_inning + ): + logger.info(f"Rolling ab") + this_ab_roll = ab_roll( + this_play.batter.team, this_play.game, allow_chaos=False + ) scorebug_buttons = None if this_ab_roll is not None and this_ab_roll.d_six_one > 3: - logger.info(f'Setting embed image to pitcher') + logger.info(f"Setting embed image to pitcher") scorebug_embed.set_image(url=this_play.pitcher.player.pitcher_card_url) - + if buffer_message is not None: - logger.info(f'Posting buffered message') - await interaction.edit_original_response( - content=buffer_message - ) + logger.info(f"Posting buffered message") + await interaction.edit_original_response(content=buffer_message) sb_message = await interaction.channel.send( - content=None, - embed=scorebug_embed, - view=scorebug_buttons + content=None, embed=scorebug_embed, view=scorebug_buttons ) else: - logger.info(f'Posting unbuffered message') + logger.info(f"Posting unbuffered message") sb_message = await interaction.edit_original_response( - content=None, - embed=scorebug_embed, - view=scorebug_buttons + content=None, embed=scorebug_embed, view=scorebug_buttons ) - + if this_ab_roll is not None: - logger.info(f'Posting ab roll') - await interaction.channel.send( - content=None, - embeds=this_ab_roll.embeds - ) - + logger.info(f"Posting ab roll") + await interaction.channel.send(content=None, embeds=this_ab_roll.embeds) + if scorebug_buttons is not None: - logger.info(f'Posting scorebug buttons roll') + logger.info(f"Posting scorebug buttons roll") await scorebug_buttons.wait() if not scorebug_buttons.value: await sb_message.edit(view=None) - async def complete_and_post_play(self, session: Session, interaction: discord.Interaction, this_play: Play, buffer_message: str = None): + async def complete_and_post_play( + self, + session: Session, + interaction: discord.Interaction, + this_play: Play, + buffer_message: str = None, + ): next_play = complete_play(session, this_play) - logger.info(f'Completed play {this_play.id}') - - logger.info(f'Updating self.game_states') - self.game_states[this_play.game.id] = {'play': this_play, 'ack': False} - logger.info(f'New state: {self.game_states}') + logger.info(f"Completed play {this_play.id}") + + logger.info(f"Updating self.game_states") + self.game_states[this_play.game.id] = {"play": this_play, "ack": False} + logger.info(f"New state: {self.game_states}") await self.post_play(session, interaction, next_play, buffer_message) - + def kickstart_live_scorecard(self): try: self.live_scorecard.start() - logger.info(f'Kick started the live scorecard') + logger.info(f"Kick started the live scorecard") except RuntimeError as e: - logger.info(f'Live scorecard is already running') + logger.info(f"Live scorecard is already running") - @commands.command(name='test-write', help='Test concurrent db writes', hidden=True) + @commands.command(name="test-write", help="Test concurrent db writes", hidden=True) @commands.is_owner() async def test_write_command(self, ctx): - await ctx.send(f'I am going to open a connection, delay, then try to write') + await ctx.send(f"I am going to open a connection, delay, then try to write") with Session(engine) as session: ncb_team = await get_team_or_none(session, team_id=31) - await ctx.send(f'The {ncb_team.lname} has_guide value is: {ncb_team.has_guide}. Now to delay for 10 seconds...') + await ctx.send( + f"The {ncb_team.lname} has_guide value is: {ncb_team.has_guide}. Now to delay for 10 seconds..." + ) ncb_team.has_guide = not ncb_team.has_guide session.add(ncb_team) await asyncio.sleep(10) - await ctx.send(f'Now to attempt committing the NCB change...') + await ctx.send(f"Now to attempt committing the NCB change...") session.commit() - await ctx.send(f'Am I alive? Did it work?') + await ctx.send(f"Am I alive? Did it work?") - group_new_game = app_commands.Group(name='new-game', description='Start a new baseball game') - - @group_new_game.command(name='mlb-campaign', description='Start a new MLB campaign game against an AI') + group_new_game = app_commands.Group( + name="new-game", description="Start a new baseball game" + ) + + @group_new_game.command( + name="mlb-campaign", description="Start a new MLB campaign game against an AI" + ) @app_commands.choices( league=[ - Choice(value='minor-league', name='Minor League'), - Choice(value='flashback', name='Flashback'), - Choice(value='major-league', name='Major League'), - Choice(value='hall-of-fame', name='Hall of Fame') + Choice(value="minor-league", name="Minor League"), + Choice(value="flashback", name="Flashback"), + Choice(value="major-league", name="Major League"), + Choice(value="hall-of-fame", name="Hall of Fame"), ], roster=[ - Choice(value='1', name='Primary'), - Choice(value='2', name='Secondary'), - Choice(value='3', name='Ranked') - ] + Choice(value="1", name="Primary"), + Choice(value="2", name="Secondary"), + Choice(value="3", name="Ranked"), + ], ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def new_game_mlb_campaign_command( - self, interaction: discord.Interaction, league: Choice[str], away_team_abbrev: str, home_team_abbrev: str, roster: Choice[str]): + self, + interaction: discord.Interaction, + league: Choice[str], + away_team_abbrev: str, + home_team_abbrev: str, + roster: Choice[str], + ): await interaction.response.defer() self.kickstart_live_scorecard() with Session(engine) as session: - teams = await new_game_checks(session, interaction, away_team_abbrev, home_team_abbrev) + teams = await new_game_checks( + session, interaction, away_team_abbrev, home_team_abbrev + ) if teams is None: - logger.error(f'Received None from new_game_checks, cancelling new game') + logger.error(f"Received None from new_game_checks, cancelling new game") return - - away_team = teams['away_team'] - home_team = teams['home_team'] + + away_team = teams["away_team"] + home_team = teams["home_team"] ai_team = away_team if away_team.is_ai else home_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: + await interaction.edit_original_response( + content=f"Ope. The {human_team.sname} are already playing over in {interaction.guild.get_channel(conflict_games[0].channel_id).mention}" + ) + return conflict_games = get_active_games_by_team(session, team=human_team) if len(conflict_games) > 0: await interaction.edit_original_response( - content=f'Ope. The {human_team.sname} are already playing over in {interaction.guild.get_channel(conflict_games[0].channel_id).mention}' + content=f"Ope. The {human_team.sname} are already playing over in {interaction.guild.get_channel(conflict_games[0].channel_id).mention}" ) return - - - conflict_games = get_active_games_by_team(session, team=human_team) - if len(conflict_games) > 0: - await interaction.edit_original_response( - content=f'Ope. The {human_team.sname} are already playing over in {interaction.guild.get_channel(conflict_games[0].channel_id).mention}' - ) - return - - current = await db_get('current') - week_num = current['week'] - logger.info(f'gameplay - new_game_mlb_campaign - Season: {current["season"]} / Week: {week_num} / Away Team: {away_team.description} / Home Team: {home_team.description}') + + current = await db_get("current") + week_num = current["week"] + 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!' + 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!" - if league.value == 'flashback': - if not user_has_role(interaction.user, 'PD - Major League'): + if league.value == "flashback": + if not user_has_role(interaction.user, "PD - Major League"): await interaction.edit_original_response( - content=role_error('PD - Major League', league_name='Flashback', lower_league='Minor League') + content=role_error( + "PD - Major League", + league_name="Flashback", + lower_league="Minor League", + ) ) return - elif league.value == 'major-league': - if not user_has_role(interaction.user, 'PD - Major League'): + elif league.value == "major-league": + if not user_has_role(interaction.user, "PD - Major League"): await interaction.edit_original_response( - content=role_error('PD - Major League', league_name='Major League', lower_league='Minor League') + content=role_error( + "PD - Major League", + league_name="Major League", + lower_league="Minor League", + ) ) return - elif league.value == 'hall-of-fame': - if not user_has_role(interaction.user, 'PD - Hall of Fame'): + elif league.value == "hall-of-fame": + if not user_has_role(interaction.user, "PD - Hall of Fame"): await interaction.edit_original_response( - content=role_error('PD - Hall of Fame', league_name='Hall of Fame', lower_league='Major League') + content=role_error( + "PD - Hall of Fame", + league_name="Hall of Fame", + lower_league="Major League", + ) ) return - + this_game = Game( away_team_id=away_team.id, home_team_id=home_team.id, away_roster_id=69 if away_team.is_ai else int(roster.value), home_roster_id=69 if home_team.is_ai else int(roster.value), channel_id=interaction.channel_id, - season=current['season'], + season=current["season"], 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 + 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}' + game_info_log = f"{league.name} game between {away_team.description} and {home_team.description} / first message: {this_game.first_message}" logger.info(game_info_log) # Get AI SP await interaction.edit_original_response( - content=f'{ai_team.gmname} is looking for a Starting Pitcher...' + content=f"{ai_team.gmname} is looking for a Starting Pitcher..." ) ai_sp_lineup = await get_starting_pitcher( session, ai_team, this_game, True if home_team.is_ai else False, - league.value + league.value, + ) + logger.info( + f"Chosen SP in Game {this_game.id}: {ai_sp_lineup.player.name_with_desc}" ) - logger.info(f'Chosen SP in Game {this_game.id}: {ai_sp_lineup.player.name_with_desc}') await interaction.edit_original_response( - content=f'The {ai_team.sname} are starting **{ai_sp_lineup.player.name_with_desc}**:\n\n{ai_sp_lineup.player.pitcher_card_url}' + content=f"The {ai_team.sname} are starting **{ai_sp_lineup.player.name_with_desc}**:\n\n{ai_sp_lineup.player.pitcher_card_url}" ) # Get AI Lineup final_message = await interaction.channel.send( - content=f'{ai_team.gmname} is filling out the {ai_team.sname} lineup card...' + content=f"{ai_team.gmname} is filling out the {ai_team.sname} lineup card..." ) - logger.info(f'Pulling lineup...') + logger.info(f"Pulling lineup...") batter_lineups = await get_starting_lineup( session, team=ai_team, game=this_game, league_name=this_game.league_name, - sp_name=ai_sp_lineup.player.name + sp_name=ai_sp_lineup.player.name, ) # Check for last game settings - logger.info(f'Checking human team\'s automation preferences...') - g_query = session.exec(select(Game).where(or_(Game.home_team == human_team, Game.away_team == human_team)).order_by(Game.id.desc()).limit(1)).all() + logger.info(f"Checking human team's automation preferences...") + g_query = session.exec( + select(Game) + .where(or_(Game.home_team == human_team, Game.away_team == human_team)) + .order_by(Game.id.desc()) + .limit(1) + ).all() if len(g_query) > 0: last_game = g_query[0] this_game.auto_roll = last_game.auto_roll this_game.roll_buttons = last_game.roll_buttons - logger.info(f'Setting auto_roll to {last_game.auto_roll} and roll_buttons to {last_game.roll_buttons}') - + logger.info( + f"Setting auto_roll to {last_game.auto_roll} and roll_buttons to {last_game.roll_buttons}" + ) + # Commit game and lineups session.add(this_game) session.commit() - - await final_message.edit(content=f'The {ai_team.sname} lineup is in, pulling in scouting data...') + + await final_message.edit( + content=f"The {ai_team.sname} lineup is in, pulling in scouting data..." + ) for batter in batter_lineups: pos_count = await get_all_positions( - session=session, - this_card=batter.card + session=session, this_card=batter.card ) if pos_count != 0: - logger.info(f'logged position ratings for {batter.player.name_with_desc}') + logger.info( + f"logged position ratings for {batter.player.name_with_desc}" + ) else: - logger.warning(f'received no positions for {batter.player.name_with_desc}') - if batter.position not in ['P', 'DH']: - log_exception(PositionNotFoundException, f'{batter.player.name_with_desc} is listed at {batter.position} but no ratings were found.') - - logger.info(f'Pulling team roles') + logger.warning( + f"received no positions for {batter.player.name_with_desc}" + ) + if batter.position not in ["P", "DH"]: + log_exception( + PositionNotFoundException, + f"{batter.player.name_with_desc} is listed at {batter.position} but no ratings were found.", + ) + + logger.info(f"Pulling team roles") away_role = await team_role(interaction, this_game.away_team) home_role = await team_role(interaction, this_game.home_team) - logger.info(f'Building scorebug embed') + logger.info(f"Building scorebug embed") embed = await get_scorebug_embed(session, this_game) embed.clear_fields() embed.add_field( - name=f'{ai_team.abbrev} Lineup', - value=this_game.team_lineup(session, ai_team) + name=f"{ai_team.abbrev} Lineup", + value=this_game.team_lineup(session, ai_team), + ) + + logger.info(f"Pulling and caching full {human_team.abbrev} roster") + done = await get_full_roster_from_sheets( + session, + interaction, + self.sheets, + this_game, + human_team, + int(roster.value), ) - - logger.info(f'Pulling and caching full {human_team.abbrev} roster') - done = await get_full_roster_from_sheets(session, interaction, self.sheets, this_game, human_team, int(roster.value)) roster_choice = await ask_with_buttons( interaction, - ['vs Left', 'vs Right'], - 'Which lineup will you be using?', + ["vs Left", "vs Right"], + "Which lineup will you be using?", delete_question=False, - confirmation_message='Got it!' + confirmation_message="Got it!", + ) + + sp_view = starting_pitcher_dropdown_view( + session, + this_game, + human_team, + this_game.league_name, + [interaction.user], + ) + await interaction.channel.send( + content=f"### {human_team.lname} Starting Pitcher", view=sp_view ) - sp_view = starting_pitcher_dropdown_view(session, this_game, human_team, this_game.league_name, [interaction.user]) - await interaction.channel.send(content=f'### {human_team.lname} Starting Pitcher', view=sp_view) - try: await asyncio.sleep(5) this_play = await read_lineup( @@ -443,38 +634,44 @@ class Gameplay(commands.Cog): this_game=this_game, lineup_team=human_team, sheets_auth=self.sheets, - lineup_num=1 if roster_choice == 'vs Right' else 2, - league_name=this_game.game_type + lineup_num=1 if roster_choice == "vs Right" else 2, + league_name=this_game.game_type, ) except PositionNotFoundException as e: - logger.error(f'Position validation failed during lineup load: {e}') + logger.error(f"Position validation failed during lineup load: {e}") this_game.active = False session.add(this_game) session.commit() await interaction.channel.send(content=str(e)) return except LineupsMissingException as e: - logger.error(f'Attempting to start game, pausing for 5 seconds: {e}') + logger.error(f"Attempting to start game, pausing for 5 seconds: {e}") await asyncio.sleep(5) - + try: this_play = this_game.current_play_or_none(session) - await self.post_play(session, interaction, this_play, buffer_message='Game on!') + await self.post_play( + session, interaction, this_play, buffer_message="Game on!" + ) except LineupsMissingException as e: await interaction.channel.send( - content=f'Run `/gamestate` once you have selected a Starting Pitcher to get going!' + content=f"Run `/gamestate` once you have selected a Starting Pitcher to get going!" ) - @group_new_game.command(name='gauntlet', description='Start a new Gauntlet game against an AI') + @group_new_game.command( + name="gauntlet", description="Start a new Gauntlet game against an AI" + ) @app_commands.choices( roster=[ - Choice(value='1', name='Primary'), - Choice(value='2', name='Secondary'), - Choice(value='3', name='Ranked') + Choice(value="1", name="Primary"), + Choice(value="2", name="Secondary"), + Choice(value="3", name="Ranked"), ] ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - async def new_game_gauntlet_command(self, interaction: discord.Interaction, roster: Choice[str]): + async def new_game_gauntlet_command( + self, interaction: discord.Interaction, roster: Choice[str] + ): await interaction.response.defer() self.kickstart_live_scorecard() @@ -485,168 +682,178 @@ class Gameplay(commands.Cog): return main_team = await get_team_or_none( - session, - gm_id=interaction.user.id, - main_team=True + session, gm_id=interaction.user.id, main_team=True ) human_team = await get_team_or_none( - session, - gm_id=interaction.user.id, - gauntlet_team=True + session, gm_id=interaction.user.id, gauntlet_team=True ) if not main_team: await interaction.edit_original_response( - content=f'I don\'t see a team for you, yet. You can sign up with the `/newteam` command!' + content=f"I don't see a team for you, yet. You can sign up with the `/newteam` command!" ) return - + if not human_team: await interaction.edit_original_response( - content=f'I don\'t see an active run for you. You can get started with the `/gauntlets start` command!' + content=f"I don't see an active run for you. You can get started with the `/gauntlets start` command!" ) return - e_query = await db_get('events', params=[('active', True)]) - if e_query['count'] == 0: + e_query = await db_get("events", params=[("active", True)]) + if e_query["count"] == 0: await interaction.edit_original_response( - content=f'Hm. It looks like there aren\'t any active gauntlets. What do we even pay Cal for?' + content=f"Hm. It looks like there aren't any active gauntlets. What do we even pay Cal for?" ) return - - elif e_query['count'] == 1: - this_event = e_query['events'][0] + + elif e_query["count"] == 1: + this_event = e_query["events"][0] r_query = await db_get( - 'gauntletruns', - params=[('team_id', human_team.id), ('gauntlet_id', this_event['id']), ('is_active', True)] + "gauntletruns", + params=[ + ("team_id", human_team.id), + ("gauntlet_id", this_event["id"]), + ("is_active", True), + ], ) - if r_query['count'] == 0: + if r_query["count"] == 0: await interaction.edit_original_response( - content=f'I don\'t see an active run for you. If you would like to start a new one, run ' - f'`/gauntlets start {this_event["name"]}` and we can get you started in no time!' + content=f"I don't see an active run for you. If you would like to start a new one, run " + f'`/gauntlets start {this_event["name"]}` and we can get you started in no time!' ) return - this_run = r_query['runs'][0] - + this_run = r_query["runs"][0] + else: r_query = await db_get( - 'gauntletruns', - params=[('team_id', human_team.id), ('is_active', True)] + "gauntletruns", + params=[("team_id", human_team.id), ("is_active", True)], ) - if r_query['count'] == 0: + if r_query["count"] == 0: await interaction.edit_original_response( - content=f'I don\'t see an active run for you. If you would like to start a new one, run ' - f'`/gauntlets start {e_query["events"][0]["name"]}` and we can get you started in no time!' + content=f"I don't see an active run for you. If you would like to start a new one, run " + f'`/gauntlets start {e_query["events"][0]["name"]}` and we can get you started in no time!' ) return else: - this_run = r_query['runs'][0] - this_event = r_query['runs'][0]['gauntlet'] + this_run = r_query["runs"][0] + this_event = r_query["runs"][0]["gauntlet"] # If not new or after draft, create new AI game is_home = gauntlets.is_home_team(human_team, this_event, this_run) - ai_team = await gauntlets.get_opponent(session, human_team, this_event, this_run) + ai_team = await gauntlets.get_opponent( + session, human_team, this_event, this_run + ) if ai_team is None: await interaction.edit_original_response( - content=f'Yike. I\'m not sure who your next opponent is. Plz ping the shit out of Cal!' + content=f"Yike. I'm not sure who your next opponent is. Plz ping the shit out of Cal!" ) return else: - logger.info(f'opponent: {ai_team}') + logger.info(f"opponent: {ai_team}") ai_role = await team_role(interaction, ai_team) human_role = await team_role(interaction, main_team) away_role = ai_role if is_home else human_role home_role = human_role if is_home else ai_role - + conflict_games = get_active_games_by_team(session, team=human_team) if len(conflict_games) > 0: await interaction.edit_original_response( - content=f'Ope. The {human_team.sname} are already playing over in {interaction.guild.get_channel(conflict_games[0].channel_id).mention}' + content=f"Ope. The {human_team.sname} are already playing over in {interaction.guild.get_channel(conflict_games[0].channel_id).mention}" ) return - - current = await db_get('current') + + current = await db_get("current") game_code = gauntlets.get_game_code(human_team, this_event, this_run) - + this_game = Game( away_team_id=ai_team.id if is_home else human_team.id, home_team_id=human_team.id if is_home else ai_team.id, channel_id=interaction.channel_id, - season=current['season'], - week=current['week'], - first_message=None if interaction.message is None else interaction.message.id, - ai_team='away' if is_home else 'home', + season=current["season"], + week=current["week"], + first_message=( + None if interaction.message is None else interaction.message.id + ), + ai_team="away" if is_home else "home", away_roster_id=69 if is_home else int(roster.value), home_roster_id=int(roster.value) if is_home else 69, - game_type=game_code + game_type=game_code, ) logger.info( - f'Game between {human_team.abbrev} and {ai_team.abbrev} is initializing!' + f"Game between {human_team.abbrev} and {ai_team.abbrev} is initializing!" ) - + # Get AI SP await interaction.edit_original_response( - content=f'{ai_team.gmname} is looking for a Starting Pitcher...' + content=f"{ai_team.gmname} is looking for a Starting Pitcher..." ) ai_sp_lineup = await gauntlets.get_starting_pitcher( - session, - ai_team, - this_game, - this_event, - this_run + session, ai_team, this_game, this_event, this_run + ) + logger.info( + f"Chosen SP in Game {this_game.id}: {ai_sp_lineup.player.name_with_desc}" ) - logger.info(f'Chosen SP in Game {this_game.id}: {ai_sp_lineup.player.name_with_desc}') await interaction.edit_original_response( - content=f'The {ai_team.sname} are starting **{ai_sp_lineup.player.name_with_desc}**:\n\n{ai_sp_lineup.player.pitcher_card_url}' + content=f"The {ai_team.sname} are starting **{ai_sp_lineup.player.name_with_desc}**:\n\n{ai_sp_lineup.player.pitcher_card_url}" ) # Get AI Lineup final_message = await interaction.channel.send( - content=f'{ai_team.gmname} is filling out the {ai_team.sname} lineup card...' + content=f"{ai_team.gmname} is filling out the {ai_team.sname} lineup card..." ) - logger.info(f'Pulling lineup in Game {this_game.id}') + logger.info(f"Pulling lineup in Game {this_game.id}") batter_lineups = await get_starting_lineup( session, team=ai_team, game=this_game, league_name=f'gauntlet-{this_event["id"]}', - sp_name=ai_sp_lineup.player.name + sp_name=ai_sp_lineup.player.name, ) # Check for last game settings - logger.info(f'Checking human team\'s automation preferences...') - g_query = session.exec(select(Game).where(or_(Game.home_team == human_team, Game.away_team == human_team)).order_by(Game.id.desc()).limit(1)).all() + logger.info(f"Checking human team's automation preferences...") + g_query = session.exec( + select(Game) + .where(or_(Game.home_team == human_team, Game.away_team == human_team)) + .order_by(Game.id.desc()) + .limit(1) + ).all() if len(g_query) > 0: last_game = g_query[0] this_game.auto_roll = last_game.auto_roll this_game.roll_buttons = last_game.roll_buttons - logger.info(f'Setting auto_roll to {last_game.auto_roll} and roll_buttons to {last_game.roll_buttons}') - + logger.info( + f"Setting auto_roll to {last_game.auto_roll} and roll_buttons to {last_game.roll_buttons}" + ) + # Commit game and lineups session.add(this_game) session.commit() - await final_message.edit(content=f'The {ai_team.sname} lineup is in, pulling in scouting data...') + await final_message.edit( + content=f"The {ai_team.sname} lineup is in, pulling in scouting data..." + ) for batter in batter_lineups: - await get_all_positions( - session=session, - this_card=batter.card - ) + await get_all_positions(session=session, this_card=batter.card) embed = await get_scorebug_embed(session, this_game) embed.clear_fields() embed.add_field( - name=f'{ai_team.abbrev} Lineup', - value=this_game.team_lineup(session, ai_team) + name=f"{ai_team.abbrev} Lineup", + value=this_game.team_lineup(session, ai_team), ) # Get pitchers from rosterlinks - done = await get_full_roster_from_sheets(session, interaction, self.sheets, this_game, human_team, 1) + done = await get_full_roster_from_sheets( + session, interaction, self.sheets, this_game, human_team, 1 + ) # if done: # sp_view = starting_pitcher_dropdown_view(session, this_game, human_team, game_type=this_game.league_name, responders=[interaction.user]) # sp_message = await interaction.channel.send(content=f'### {human_team.lname} Starting Pitcher', view=sp_view) @@ -658,10 +865,10 @@ class Gameplay(commands.Cog): roster_choice = await ask_with_buttons( interaction, - ['vs Left', 'vs Right'], - 'Which lineup will you be using?', + ["vs Left", "vs Right"], + "Which lineup will you be using?", delete_question=False, - confirmation_message='Got it!' + confirmation_message="Got it!", ) # Read the 9 field players from sheets (this will fail to initialize play without SP) @@ -672,11 +879,11 @@ class Gameplay(commands.Cog): this_game=this_game, lineup_team=human_team, sheets_auth=self.sheets, - lineup_num=1 if roster_choice == 'vs Right' else 2, - league_name=this_game.game_type + lineup_num=1 if roster_choice == "vs Right" else 2, + league_name=this_game.game_type, ) except PositionNotFoundException as e: - logger.error(f'Position validation failed during lineup load: {e}') + logger.error(f"Position validation failed during lineup load: {e}") this_game.active = False session.add(this_game) session.commit() @@ -684,48 +891,73 @@ class Gameplay(commands.Cog): return except LineupsMissingException as e: # Expected - can't initialize play without SP yet - logger.info(f'Field player lineup read from sheets, waiting for SP selection: {e}') + logger.info( + f"Field player lineup read from sheets, waiting for SP selection: {e}" + ) - sp_view = starting_pitcher_dropdown_view(session, this_game, human_team, this_game.league_name, [interaction.user]) - await interaction.channel.send(content=f'### {human_team.lname} Starting Pitcher', view=sp_view) + sp_view = starting_pitcher_dropdown_view( + session, + this_game, + human_team, + this_game.league_name, + [interaction.user], + ) + await interaction.channel.send( + content=f"### {human_team.lname} Starting Pitcher", view=sp_view + ) # Don't try to initialize play immediately - wait for user to select SP # The play will be initialized when they run /gamestate await interaction.channel.send( - content=f'Once you\'ve selected your Starting Pitcher, run `/gamestate` to get the game started!' + content=f"Once you've selected your Starting Pitcher, run `/gamestate` to get the game started!" ) - @group_new_game.command(name='exhibition', description='Start a new custom game against an AI') + @group_new_game.command( + name="exhibition", description="Start a new custom game against an AI" + ) @app_commands.choices( roster=[ - Choice(value='1', name='Primary'), - Choice(value='2', name='Secondary'), - Choice(value='3', name='Ranked') + Choice(value="1", name="Primary"), + Choice(value="2", name="Secondary"), + Choice(value="3", name="Ranked"), ] ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - async def new_game_exhibition_command(self, interaction: discord.Interaction, away_team_abbrev: str, home_team_abbrev: str, roster: Choice[str], cardsets: Literal['Minor League', 'Major League', 'Hall of Fame', 'Flashback', 'Custom'] = 'Custom'): + async def new_game_exhibition_command( + self, + interaction: discord.Interaction, + away_team_abbrev: str, + home_team_abbrev: str, + roster: Choice[str], + cardsets: Literal[ + "Minor League", "Major League", "Hall of Fame", "Flashback", "Custom" + ] = "Custom", + ): await interaction.response.defer() self.kickstart_live_scorecard() with Session(engine) as session: - teams = await new_game_checks(session, interaction, away_team_abbrev, home_team_abbrev) + teams = await new_game_checks( + session, interaction, away_team_abbrev, home_team_abbrev + ) if teams is None: - logger.error(f'Received None from new_game_checks, cancelling new game') + logger.error(f"Received None from new_game_checks, cancelling new game") return - - away_team = teams['away_team'] - home_team = teams['home_team'] + + away_team = teams["away_team"] + home_team = teams["home_team"] if not away_team.is_ai ^ home_team.is_ai: await interaction.edit_original_response( - content=f'I don\'t see an AI team in this Exhibition game. Run `/new-game exhibition` again with an AI for a custom game or `/new-game ` for a PvP game.' + content=f"I don't see an AI team in this Exhibition game. Run `/new-game exhibition` again with an AI for a custom game or `/new-game ` for a PvP game." ) return - current = await db_get('current') - week_num = current['week'] - logger.info(f'gameplay - new_game_mlb_campaign - Season: {current["season"]} / Week: {week_num} / Away Team: {away_team.description} / Home Team: {home_team.description}') + current = await db_get("current") + week_num = current["week"] + logger.info( + f'gameplay - new_game_mlb_campaign - Season: {current["season"]} / Week: {week_num} / Away Team: {away_team.description} / Home Team: {home_team.description}' + ) ai_team = away_team if away_team.is_ai else home_team human_team = away_team if home_team.is_ai else home_team @@ -736,130 +968,150 @@ class Gameplay(commands.Cog): away_roster_id=69 if away_team.is_ai else int(roster.value), home_roster_id=69 if home_team.is_ai else int(roster.value), channel_id=interaction.channel_id, - season=current['season'], + season=current["season"], week=week_num, - first_message=None if interaction.message is None else interaction.message.id, - ai_team='away' if away_team.is_ai else 'home', - game_type='exhibition' + first_message=( + None if interaction.message is None else interaction.message.id + ), + ai_team="away" if away_team.is_ai else "home", + game_type="exhibition", ) async def new_game_setup(): # Get AI SP await interaction.edit_original_response( - content=f'{ai_team.gmname} is looking for a Starting Pitcher...' + content=f"{ai_team.gmname} is looking for a Starting Pitcher..." ) ai_sp_lineup = await get_starting_pitcher( session, ai_team, this_game, True if home_team.is_ai else False, - 'exhibition' + "exhibition", ) - logger.info(f'Chosen SP: {ai_sp_lineup.player.name_with_desc}') + logger.info(f"Chosen SP: {ai_sp_lineup.player.name_with_desc}") session.add(ai_sp_lineup) await interaction.edit_original_response( - content=f'The {ai_team.sname} are starting **{ai_sp_lineup.player.name_with_desc}**:\n\n{ai_sp_lineup.player.pitcher_card_url}' - ) + content=f"The {ai_team.sname} are starting **{ai_sp_lineup.player.name_with_desc}**:\n\n{ai_sp_lineup.player.pitcher_card_url}" + ) # Get AI Lineup final_message = await interaction.channel.send( - content=f'{ai_team.gmname} is filling out the {ai_team.sname} lineup card...' + content=f"{ai_team.gmname} is filling out the {ai_team.sname} lineup card..." ) - logger.info(f'Pulling lineup...') + logger.info(f"Pulling lineup...") batter_lineups = await get_starting_lineup( session, team=ai_team, game=this_game, league_name=this_game.league_name, - sp_name=ai_sp_lineup.player.name + sp_name=ai_sp_lineup.player.name, ) for x in batter_lineups: session.add(x) # Check for last game settings - logger.info(f'Checking human team\'s automation preferences...') - g_query = session.exec(select(Game).where(or_(Game.home_team == human_team, Game.away_team == human_team)).order_by(Game.id.desc()).limit(1)).all() + logger.info(f"Checking human team's automation preferences...") + g_query = session.exec( + select(Game) + .where( + or_(Game.home_team == human_team, Game.away_team == human_team) + ) + .order_by(Game.id.desc()) + .limit(1) + ).all() if len(g_query) > 0: last_game = g_query[0] this_game.auto_roll = last_game.auto_roll this_game.roll_buttons = last_game.roll_buttons - logger.info(f'Setting auto_roll to {last_game.auto_roll} and roll_buttons to {last_game.roll_buttons}') - + logger.info( + f"Setting auto_roll to {last_game.auto_roll} and roll_buttons to {last_game.roll_buttons}" + ) + # Commit game and lineups session.add(this_game) session.commit() - - await final_message.edit(content=f'The {ai_team.sname} lineup is in, pulling in scouting data...') + + await final_message.edit( + content=f"The {ai_team.sname} lineup is in, pulling in scouting data..." + ) for batter in batter_lineups: - await get_all_positions( - session=session, - this_card=batter.card - ) - - logger.info(f'Pulling team roles') + await get_all_positions(session=session, this_card=batter.card) + + logger.info(f"Pulling team roles") away_role = await team_role(interaction, this_game.away_team) home_role = await team_role(interaction, this_game.home_team) - logger.info(f'Building scorebug embed') + logger.info(f"Building scorebug embed") embed = await get_scorebug_embed(session, this_game) embed.clear_fields() embed.add_field( - name=f'{ai_team.abbrev} Lineup', - value=this_game.team_lineup(session, ai_team) + name=f"{ai_team.abbrev} Lineup", + value=this_game.team_lineup(session, ai_team), + ) + + logger.info(f"Pulling and caching full {human_team.abbrev} roster") + done = await get_full_roster_from_sheets( + session, + interaction, + self.sheets, + this_game, + human_team, + int(roster.value), ) - - logger.info(f'Pulling and caching full {human_team.abbrev} roster') - done = await get_full_roster_from_sheets(session, interaction, self.sheets, this_game, human_team, int(roster.value)) if done: - sp_view = starting_pitcher_dropdown_view(session, this_game, human_team, this_game.league_name, [interaction.user]) - await interaction.channel.send(content=f'### {human_team.lname} Starting Pitcher', view=sp_view) + sp_view = starting_pitcher_dropdown_view( + session, + this_game, + human_team, + this_game.league_name, + [interaction.user], + ) + await interaction.channel.send( + content=f"### {human_team.lname} Starting Pitcher", view=sp_view + ) await final_message.edit( - content=f'{away_role.mention} @ {home_role.mention} is set!\n\n' - f'Go ahead and set your lineup with the `/set lineup` command!', - embed=embed + content=f"{away_role.mention} @ {home_role.mention} is set!\n\n" + f"Go ahead and set your lineup with the `/set lineup` command!", + embed=embed, ) - if cardsets != 'Custom': + if cardsets != "Custom": c_list = CARDSETS[cardsets] - for row in c_list['primary']: + for row in c_list["primary"]: this_cardset = await get_cardset_or_none(session, cardset_id=row) if this_cardset is not None: this_link = GameCardsetLink( - game=this_game, - cardset=this_cardset, - priority=1 + game=this_game, cardset=this_cardset, priority=1 ) session.add(this_link) - - for row in c_list['secondary']: + + for row in c_list["secondary"]: this_cardset = await get_cardset_or_none(session, cardset_id=row) this_link = GameCardsetLink( - game=this_game, - cardset=this_cardset, - priority=2 + game=this_game, cardset=this_cardset, priority=2 ) await new_game_setup() - + else: + async def my_callback(interaction: discord.Interaction, values): - logger.info(f'Setting custom cardsets inside callback') + logger.info(f"Setting custom cardsets inside callback") await interaction.response.defer(thinking=True) - logger.info(f'values: {values}') + logger.info(f"values: {values}") for cardset_id in values: - logger.info(f'Getting cardset: {cardset_id}') + logger.info(f"Getting cardset: {cardset_id}") this_cardset = await get_cardset_or_none(session, cardset_id) - logger.info(f'this_cardset: {this_cardset}') + logger.info(f"this_cardset: {this_cardset}") this_link = GameCardsetLink( - game=this_game, - cardset=this_cardset, - priority=1 + game=this_game, cardset=this_cardset, priority=1 ) session.add(this_link) - - logger.info(f'Done processing links') + + logger.info(f"Done processing links") session.commit() await interaction.edit_original_response(content="Got it...") @@ -867,41 +1119,49 @@ class Gameplay(commands.Cog): my_dropdown = Dropdown( option_list=SELECT_CARDSET_OPTIONS, - placeholder='Select up to 8 cardsets to include', + placeholder="Select up to 8 cardsets to include", callback=my_callback, - max_values=len(SELECT_CARDSET_OPTIONS) + max_values=len(SELECT_CARDSET_OPTIONS), ) view = DropdownView([my_dropdown]) - await interaction.edit_original_response( - content=None, - view=view - ) + await interaction.edit_original_response(content=None, view=view) # TODO: add new-game ranked - @group_new_game.command(name='unlimited', description='Start a new Unlimited game against another human') + @group_new_game.command( + name="unlimited", description="Start a new Unlimited game against another human" + ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - async def new_game_unlimited_command(self, interaction: discord.Interaction, away_team_abbrev: str, home_team_abbrev: str): + async def new_game_unlimited_command( + self, + interaction: discord.Interaction, + away_team_abbrev: str, + home_team_abbrev: str, + ): await interaction.response.defer() self.kickstart_live_scorecard() with Session(engine) as session: - teams = await new_game_checks(session, interaction, away_team_abbrev, home_team_abbrev) + teams = await new_game_checks( + session, interaction, away_team_abbrev, home_team_abbrev + ) if teams is None: - logger.error(f'Received None from new_game_checks, cancelling new game') + logger.error(f"Received None from new_game_checks, cancelling new game") return - - away_team = teams['away_team'] - home_team = teams['home_team'] + + away_team = teams["away_team"] + home_team = teams["home_team"] if away_team.is_ai or home_team.is_ai: await interaction.edit_original_response( - content=f'Unlimited games are for two human-run teams. To play against the AI, you can play `mlb-campaign`, `gauntlet`, or `exhibition` game modes.' + content=f"Unlimited games are for two human-run teams. To play against the AI, you can play `mlb-campaign`, `gauntlet`, or `exhibition` game modes." ) return - current = await db_get('current') - week_num = current['week'] - logger.info(f'gameplay - new_game_unlimited - Season: {current["season"]} / Week: {week_num} / Away Team: {away_team.description} / Home Team: {home_team.description}') + current = await db_get("current") + week_num = current["week"] + logger.info( + f'gameplay - new_game_unlimited - Season: {current["season"]} / Week: {week_num} / Away Team: {away_team.description} / Home Team: {home_team.description}' + ) this_game = Game( away_team_id=away_team.id, @@ -909,14 +1169,16 @@ class Gameplay(commands.Cog): away_roster_id=None, home_roster_id=None, channel_id=interaction.channel_id, - season=current['season'], + season=current["season"], week=week_num, - first_message=None if interaction.message is None else interaction.message.id, - game_type='exhibition' + first_message=( + None if interaction.message is None else interaction.message.id + ), + game_type="exhibition", ) await interaction.edit_original_response( - content=f'Let\'s get set up for **{away_team.lname}** @ **{home_team.lname}**!' + content=f"Let's get set up for **{away_team.lname}** @ **{home_team.lname}**!" ) away_role = await team_role(interaction, away_team) @@ -924,83 +1186,94 @@ class Gameplay(commands.Cog): away_roster_id = await ask_with_buttons( interaction=interaction, - button_options=[ - 'Primary', 'Secondary', 'Ranked' - ], - question=f'{away_role.mention}\nWhich roster should I pull for you?', + button_options=["Primary", "Secondary", "Ranked"], + question=f"{away_role.mention}\nWhich roster should I pull for you?", delete_question=False, - confirmation_message=f'Got it! As soon as the {home_team.sname} select their roster, I will pull them both in at once.' + confirmation_message=f"Got it! As soon as the {home_team.sname} select their roster, I will pull them both in at once.", ) home_roster_id = await ask_with_buttons( interaction=interaction, - button_options=[ - 'Primary', 'Secondary', 'Ranked' - ], - question=f'{home_role.mention}\nWhich roster should I pull for you?', + button_options=["Primary", "Secondary", "Ranked"], + question=f"{home_role.mention}\nWhich roster should I pull for you?", delete_question=False, - confirmation_message=f'Got it! Off to Sheets I go for the {away_team.abbrev} roster...' + confirmation_message=f"Got it! Off to Sheets I go for the {away_team.abbrev} roster...", ) if away_roster_id and home_roster_id: - if away_roster_id == 'Primary': + if away_roster_id == "Primary": away_roster_id = 1 - elif away_roster_id == 'Secondary': + elif away_roster_id == "Secondary": away_roster_id = 2 else: away_roster_id = 3 - if home_roster_id == 'Primary': + if home_roster_id == "Primary": home_roster_id = 1 - elif home_roster_id == 'Secondary': + elif home_roster_id == "Secondary": home_roster_id = 2 else: home_roster_id = 3 - logger.info(f'Setting roster IDs - away: {away_roster_id} / home: {home_roster_id}') + logger.info( + f"Setting roster IDs - away: {away_roster_id} / home: {home_roster_id}" + ) this_game.away_roster_id = away_roster_id this_game.home_roster_id = home_roster_id session.add(this_game) session.commit() - - logger.info(f'Pulling away team\'s roster') - away_roster = await get_full_roster_from_sheets(session, interaction, self.sheets, this_game, away_team, away_roster_id) + + logger.info(f"Pulling away team's roster") + away_roster = await get_full_roster_from_sheets( + session, interaction, self.sheets, this_game, away_team, away_roster_id + ) # if away_roster: - logger.info(f'Pulling home team\'s roster') + logger.info(f"Pulling home team's roster") await interaction.channel.send( - content=f'And now for the {home_team.abbrev} sheet...' + content=f"And now for the {home_team.abbrev} sheet..." ) - home_roster = await get_full_roster_from_sheets(session, interaction, self.sheets, this_game, home_team,home_roster_id) - - # if home_roster: - await interaction.channel.send( - content=f'{away_role.mention} @ {home_role.mention}\n\nThe game is set, both of you may run `/set ` to start!' + home_roster = await get_full_roster_from_sheets( + session, interaction, self.sheets, this_game, home_team, home_roster_id ) + # if home_roster: + await interaction.channel.send( + content=f"{away_role.mention} @ {home_role.mention}\n\nThe game is set, both of you may run `/set ` to start!" + ) - @commands.command(name='force-endgame', help='Mod: Force a game to end without stats') + @commands.command( + name="force-endgame", help="Mod: Force a game to end without stats" + ) async def force_end_game_command(self, ctx: commands.Context): with Session(engine) as session: this_game = get_channel_game_or_none(session, ctx.channel.id) if this_game is None: - await ctx.send(f'I do not see a game here - are you in the right place?') + await ctx.send( + f"I do not see a game here - are you in the right place?" + ) return - + try: await ctx.send( - content=None, - embed=await get_scorebug_embed(session, this_game, full_length=True) + content=None, + embed=await get_scorebug_embed( + session, this_game, 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.') + 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', + question=f"Is this the game I should nuke?", + label_type="yes", timeout=15, ) @@ -1009,53 +1282,68 @@ class Gameplay(commands.Cog): this_game.active = False session.add(this_game) session.commit() - await ctx.channel.send(content=random_gif(random_from_list(['i killed it', 'deed is done', 'gone forever']))) + await ctx.channel.send( + content=random_gif( + random_from_list( + ["i killed it", "deed is done", "gone forever"] + ) + ) + ) else: - await ctx.send(f'It stays. For now.') + await ctx.send(f"It stays. For now.") - group_set_rosters = app_commands.Group(name='set', description='Set SP and lineup') + group_set_rosters = app_commands.Group(name="set", description="Set SP and lineup") - @group_set_rosters.command(name='lineup', description='Import a saved lineup for this channel\'s PD game.') - @app_commands.describe( - lineup='Which handedness lineup are you using?' + @group_set_rosters.command( + name="lineup", description="Import a saved lineup for this channel's PD game." ) + @app_commands.describe(lineup="Which handedness lineup are you using?") @app_commands.choices( - lineup=[ - Choice(value='1', name='v Right'), - Choice(value='2', name='v Left') - ] + lineup=[Choice(value="1", name="v Right"), Choice(value="2", name="v Left")] ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - async def read_lineup_command(self, interaction: discord.Interaction, lineup: Choice[str]): + async def read_lineup_command( + self, interaction: discord.Interaction, lineup: Choice[str] + ): await interaction.response.defer() with Session(engine) as session: this_game = get_channel_game_or_none(session, interaction.channel_id) if this_game is None: await interaction.edit_original_response( - content=f'Hm. I don\'t see a game going on in this channel. Am I drunk?' + content=f"Hm. I don't see a game going on in this channel. Am I drunk?" ) return - + if this_game.away_team.gmid == interaction.user.id: this_team = this_game.away_team elif this_game.home_team.gmid == interaction.user.id: this_team = this_game.home_team else: - 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.') + 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 - + all_lineups = get_game_lineups(session, this_game, this_team) if len(all_lineups) > 1: - play_count = session.exec(select(func.count(Play.id)).where(Play.game == this_game, Play.complete == True)).one() + play_count = session.exec( + select(func.count(Play.id)).where( + Play.game == this_game, Play.complete == True + ) + ).one() if play_count > 0: await interaction.edit_original_response( content=f'Since {play_count} play{"s" if play_count != 1 else ""} ha{"ve" if play_count != 1 else "s"} been logged, you will have to run `/substitution batter` to replace any of your batters.' ) return - logger.info(f'lineup: {lineup} / value: {lineup.value} / name: {lineup.name}') + logger.info( + f"lineup: {lineup} / value: {lineup.value} / name: {lineup.name}" + ) try: this_play = await read_lineup( session, @@ -1064,20 +1352,22 @@ class Gameplay(commands.Cog): lineup_team=this_team, sheets_auth=self.sheets, lineup_num=int(lineup.value), - league_name=this_game.game_type + league_name=this_game.game_type, ) except PositionNotFoundException as e: - logger.error(f'Position validation failed during lineup load: {e}') + logger.error(f"Position validation failed during lineup load: {e}") await interaction.edit_original_response(content=str(e)) return except LineupsMissingException as e: - await interaction.edit_original_response(content='Run `/set starting-pitcher` to select your SP') + await interaction.edit_original_response( + content="Run `/set starting-pitcher` to select your SP" + ) return - + if this_play is not None: await self.post_play(session, interaction, this_play) - @group_set_rosters.command(name='starting-pitcher') + @group_set_rosters.command(name="starting-pitcher") @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def set_starting_pitcher(self, interaction: discord.Interaction): await interaction.response.defer() @@ -1086,417 +1376,709 @@ class Gameplay(commands.Cog): this_game = get_channel_game_or_none(session, interaction.channel_id) if this_game is None: await interaction.edit_original_response( - content=f'Hm. I don\'t see a game going on in this channel. Am I drunk?' + content=f"Hm. I don't see a game going on in this channel. Am I drunk?" ) return - + if this_game.away_team.gmid == interaction.user.id: this_team = this_game.away_team elif this_game.home_team.gmid == interaction.user.id: this_team = this_game.home_team else: - 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.') + 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 - + try: - check_sp = get_one_lineup(session, this_game, this_team, position='P') - play_count = session.exec(select(func.count(Play.id)).where(Play.game == this_game, Play.complete == True, Play.pitcher == check_sp)).one() + check_sp = get_one_lineup(session, this_game, this_team, position="P") + play_count = session.exec( + select(func.count(Play.id)).where( + Play.game == this_game, + Play.complete == True, + Play.pitcher == check_sp, + ) + ).one() if play_count > 0: await interaction.edit_original_response( content=f'Since {play_count} play{"s" if play_count != 1 else ""} ha{"ve" if play_count != 1 else "s"} been logged, you will have to run `/substitution pitcher` to replace {check_sp.player.name}.' ) return - + except sqlalchemy.exc.NoResultFound as e: # if 'NoResultFound' not in str(e): # logger.error(f'Error checking for existing sp: {e}') # log_exception(e, 'Unable to check your lineup for an existing SP') # else: - logger.info(f'No pitcher in game, good to go') + logger.info(f"No pitcher in game, good to go") check_sp = None if check_sp is not None: - logger.info(f'Already an SP in Game {this_game.id}, asking if we should swap') + logger.info( + f"Already an SP in Game {this_game.id}, asking if we should swap" + ) swap_sp = await ask_confirm( interaction, - question=f'{check_sp.player.name} is already scheduled to start this game - would you like to switch?', - label_type='yes' + question=f"{check_sp.player.name} is already scheduled to start this game - would you like to switch?", + label_type="yes", ) if not swap_sp: - logger.info(f'No swap being made') - await interaction.edit_original_response(content=f'We will leave {check_sp.player.name} on the lineup card.') + logger.info(f"No swap being made") + await interaction.edit_original_response( + content=f"We will leave {check_sp.player.name} on the lineup card." + ) return - + session.delete(check_sp) session.commit() - sp_view = starting_pitcher_dropdown_view(session, this_game, this_team, game_type=this_game.league_name, responders=[interaction.user]) - await interaction.edit_original_response(content=f'### {this_team.lname} Starting Pitcher', view=sp_view) - - @app_commands.command(name='gamestate', description='Post the current game state') - async def gamestate_command(self, interaction: discord.Interaction, include_lineups: bool = False): + sp_view = starting_pitcher_dropdown_view( + session, + this_game, + this_team, + game_type=this_game.league_name, + responders=[interaction.user], + ) + await interaction.edit_original_response( + content=f"### {this_team.lname} Starting Pitcher", view=sp_view + ) + + @app_commands.command(name="gamestate", description="Post the current game state") + async def gamestate_command( + self, interaction: discord.Interaction, include_lineups: bool = False + ): await interaction.response.defer(ephemeral=True, thinking=True) with Session(engine) as session: this_game = get_channel_game_or_none(session, interaction.channel_id) if this_game is None: await interaction.edit_original_response( - content=f'Hm. I don\'t see a game going on in this channel. Am I drunk?' + content=f"Hm. I don't see a game going on in this channel. Am I drunk?" ) return - + this_play = this_game.current_play_or_none(session) try: - await self.post_play(session, interaction, this_play, full_length=include_lineups, buffer_message=None if this_game.human_team.gmid != interaction.user.id else 'Posting current play') + await self.post_play( + session, + interaction, + this_play, + full_length=include_lineups, + buffer_message=( + None + if this_game.human_team.gmid != interaction.user.id + else "Posting current play" + ), + ) except LineupsMissingException as e: - logger.info(f'Could not post full scorebug embed, posting lineups') - ai_team = this_game.away_team if this_game.ai_team == 'away' else this_game.home_team + logger.info(f"Could not post full scorebug embed, posting lineups") + ai_team = ( + this_game.away_team + if this_game.ai_team == "away" + else this_game.home_team + ) embed = await get_scorebug_embed(session, this_game) embed.clear_fields() embed.add_field( - name=f'{ai_team.abbrev} Lineup', - value=this_game.team_lineup(session, ai_team) + name=f"{ai_team.abbrev} Lineup", + value=this_game.team_lineup(session, ai_team), ) - @app_commands.command(name='settings-ingame', description='Change in-game settings') + @app_commands.command(name="settings-ingame", description="Change in-game settings") @app_commands.describe( roll_buttons='Display the "Roll AB" and "Check Jump" buttons along with the scorebug', - auto_roll='When there are no baserunners, automatically roll the next AB' + auto_roll="When there are no baserunners, automatically roll the next AB", ) - async def game_settings_command(self, interaction: discord.Interaction, roll_buttons: bool = None, auto_roll: bool = None): + async def game_settings_command( + self, + interaction: discord.Interaction, + roll_buttons: bool = None, + auto_roll: bool = None, + ): with Session(engine) as session: - this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='settings-ingame', lock_play=False) + this_game, owner_team, this_play = await checks_log_interaction( + session, interaction, command_name="settings-ingame", lock_play=False + ) - await interaction.edit_original_response(content=None, embed=await update_game_settings( - session, - interaction, - this_game, - roll_buttons=roll_buttons, - auto_roll=auto_roll - )) + await interaction.edit_original_response( + content=None, + embed=await update_game_settings( + session, + interaction, + this_game, + roll_buttons=roll_buttons, + auto_roll=auto_roll, + ), + ) - @app_commands.command(name='end-game', description='End the current game in this channel') + @app_commands.command( + name="end-game", description="End the current game in this channel" + ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def end_game_command(self, interaction: discord.Interaction): with Session(engine) as session: - async with locked_play(session, interaction, 'end-game') as (this_game, owner_team, this_play): - await manual_end_game(session, interaction, this_game, current_play=this_play) + async with locked_play(session, interaction, "end-game") as ( + this_game, + owner_team, + this_play, + ): + await manual_end_game( + session, interaction, this_game, current_play=this_play + ) - group_substitution = app_commands.Group(name='substitute', description='Make a substitution in active game') + group_substitution = app_commands.Group( + name="substitute", description="Make a substitution in active game" + ) - @group_substitution.command(name='batter', description='Make a batter substitution') - async def sub_batter_command(self, interaction: discord.Interaction, batting_order: Literal['this-spot', '1', '2', '3', '4', '5', '6', '7', '8', '9'] = 'this-spot'): + @group_substitution.command(name="batter", description="Make a batter substitution") + async def sub_batter_command( + self, + interaction: discord.Interaction, + batting_order: Literal[ + "this-spot", "1", "2", "3", "4", "5", "6", "7", "8", "9" + ] = "this-spot", + ): with Session(engine) as session: - this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='substitute batter', lock_play=False) - - if batting_order == 'this-spot': - if this_play.batter.team != owner_team: - logger.info(f'Batting order not included while on defense; returning') + this_game, owner_team, this_play = await checks_log_interaction( + session, interaction, command_name="substitute batter", lock_play=False + ) - await interaction.edit_original_response(content=f'When you make a defensive substitution, please include the batting order where they should enter.') + if batting_order == "this-spot": + if this_play.batter.team != owner_team: + logger.info( + f"Batting order not included while on defense; returning" + ) + + await interaction.edit_original_response( + content=f"When you make a defensive substitution, please include the batting order where they should enter." + ) return this_order = this_play.batting_order else: this_order = int(batting_order) - logger.info(f'sub batter - this_play: {this_play}') - bat_view = sub_batter_dropdown_view(session, this_game, owner_team, this_order, [interaction.user]) - await interaction.edit_original_response(content=f'### {owner_team.lname} Substitution', view=bat_view) - - @group_substitution.command(name='pitcher', description='Make a pitching substitution') - async def sub_pitcher_command(self, interaction: discord.Interaction, batting_order: Literal['dh-spot', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] = '10'): + logger.info(f"sub batter - this_play: {this_play}") + bat_view = sub_batter_dropdown_view( + session, this_game, owner_team, this_order, [interaction.user] + ) + await interaction.edit_original_response( + content=f"### {owner_team.lname} Substitution", view=bat_view + ) + + @group_substitution.command( + name="pitcher", description="Make a pitching substitution" + ) + async def sub_pitcher_command( + self, + interaction: discord.Interaction, + batting_order: Literal[ + "dh-spot", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" + ] = "10", + ): with Session(engine) as session: - this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='substitute pitcher', lock_play=False) + this_game, owner_team, this_play = await checks_log_interaction( + session, interaction, command_name="substitute pitcher", lock_play=False + ) if owner_team != this_play.pitcher.team: - logger.warning(f'User {interaction.user.name} ({owner_team.abbrev}) tried to run a sub for the {this_play.pitcher.team.lname}') + logger.warning( + f"User {interaction.user.name} ({owner_team.abbrev}) tried to run a sub for the {this_play.pitcher.team.lname}" + ) await interaction.edit_original_response( - content=f'Please run pitcher subs when your team is on defense. If you are pinch-hitting for a pitcher already in the lineup, use `/substitute batter`' + content=f"Please run pitcher subs when your team is on defense. If you are pinch-hitting for a pitcher already in the lineup, use `/substitute batter`" ) return - - if batting_order != '10' and this_play.pitcher.batting_order == 10: + + if batting_order != "10" and this_play.pitcher.batting_order == 10: forfeit_dh = await ask_confirm( - interaction, - f'Are you sure you want to forfeit the DH?' + interaction, f"Are you sure you want to forfeit the DH?" ) if not forfeit_dh: await interaction.edit_original_response( - content=f'Fine, be that way.' + content=f"Fine, be that way." ) return - + if not this_play.is_new_inning: - pitcher_plays = get_plays_by_pitcher(session, this_game, this_play.pitcher) + pitcher_plays = get_plays_by_pitcher( + session, this_game, this_play.pitcher + ) batters_faced = sum(1 for x in pitcher_plays if x.pa == 1) if batters_faced < 3: await interaction.edit_original_response( - content=f'Looks like **{this_play.pitcher.player.name}** has only faced {batters_faced} of the 3-batter minimum.' + content=f"Looks like **{this_play.pitcher.player.name}** has only faced {batters_faced} of the 3-batter minimum." ) return - rp_view = relief_pitcher_dropdown_view(session, this_game, this_play.pitcher.team, batting_order, responders=[interaction.user]) + rp_view = relief_pitcher_dropdown_view( + session, + this_game, + this_play.pitcher.team, + batting_order, + responders=[interaction.user], + ) rp_message = await interaction.edit_original_response( - content=f'### {this_play.pitcher.team.lname} Relief Pitcher', - view=rp_view + content=f"### {this_play.pitcher.team.lname} Relief Pitcher", + view=rp_view, ) - @group_substitution.command(name='defense', description='Make a defensive substitution or move defenders between positions') - async def sub_defense_command(self, interaction: discord.Interaction, new_position: DEFENSE_NO_PITCHER_LITERAL): + @group_substitution.command( + name="defense", + description="Make a defensive substitution or move defenders between positions", + ) + async def sub_defense_command( + self, interaction: discord.Interaction, new_position: DEFENSE_NO_PITCHER_LITERAL + ): with Session(engine) as session: - this_game, owner_team, this_play = await checks_log_interaction(session, interaction, command_name='substitute defense', lock_play=False) + this_game, owner_team, this_play = await checks_log_interaction( + session, interaction, command_name="substitute defense", lock_play=False + ) defense_view = await defender_dropdown_view( session=session, this_game=this_game, human_team=owner_team, new_position=new_position, - responders=[interaction.user] + responders=[interaction.user], ) defense_message = await interaction.edit_original_response( - content=f'### {owner_team.lname} {new_position} Change', - view=defense_view + content=f"### {owner_team.lname} {new_position} Change", + view=defense_view, ) - group_log = app_commands.Group(name='log', description='Log a play in this channel\'s game') + group_log = app_commands.Group( + name="log", description="Log a play in this channel's game" + ) - @group_log.command(name='flyball', description='Flyballs: a, b, ballpark, bq, c') - async def log_flyball(self, interaction: discord.Interaction, flyball_type: Literal['a', 'b', 'ballpark', 'b?', 'c']): + @group_log.command(name="flyball", description="Flyballs: a, b, ballpark, bq, c") + async def log_flyball( + self, + interaction: discord.Interaction, + flyball_type: Literal["a", "b", "ballpark", "b?", "c"], + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log flyball') as (this_game, owner_team, this_play): - logger.info(f'log flyball {flyball_type} - this_play: {this_play}') - this_play = await flyballs(session, interaction, this_play, flyball_type) + async with locked_play(session, interaction, "log flyball") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log flyball {flyball_type} - this_play: {this_play}") + this_play = await flyballs( + session, interaction, this_play, flyball_type + ) await self.complete_and_post_play( session, interaction, this_play, - buffer_message='Flyball logged' if this_play.starting_outs + this_play.outs < 3 and ((this_play.on_second and flyball_type in ['b', 'ballpark']) or (this_play.on_third and flyball_type == 'b?')) else None + buffer_message=( + "Flyball logged" + if this_play.starting_outs + this_play.outs < 3 + and ( + (this_play.on_second and flyball_type in ["b", "ballpark"]) + or (this_play.on_third and flyball_type == "b?") + ) + else None + ), ) - - @group_log.command(name='frame-pitch', description=f'Walk/strikeout split; determined by home plate umpire') + + @group_log.command( + name="frame-pitch", + description=f"Walk/strikeout split; determined by home plate umpire", + ) async def log_frame_check(self, interaction: discord.Interaction): with Session(engine) as session: - async with locked_play(session, interaction, 'log frame-check') as (this_game, owner_team, this_play): - logger.info(f'log frame-check - this_play: {this_play}') + async with locked_play(session, interaction, "log frame-check") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log frame-check - this_play: {this_play}") this_play = await frame_checks(session, interaction, this_play) + await self.complete_and_post_play( + session, interaction, this_play, buffer_message="Frame check logged" + ) + + @group_log.command( + name="lineout", description="Lineouts: one out, ballpark, max outs" + ) + async def log_lineout( + self, + interaction: discord.Interaction, + lineout_type: Literal["one-out", "ballpark", "max-outs"], + ): + with Session(engine) as session: + async with locked_play(session, interaction, "log lineout") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log lineout - this_play: {this_play}") + this_play = await lineouts( + session, interaction, this_play, lineout_type + ) + await self.complete_and_post_play( session, interaction, this_play, - buffer_message='Frame check logged' + buffer_message=( + "Lineout logged" if this_play.on_base_code > 3 else None + ), ) - - @group_log.command(name='lineout', description='Lineouts: one out, ballpark, max outs') - async def log_lineout(self, interaction: discord.Interaction, lineout_type: Literal['one-out', 'ballpark', 'max-outs']): - with Session(engine) as session: - async with locked_play(session, interaction, 'log lineout') as (this_game, owner_team, this_play): - logger.info(f'log lineout - this_play: {this_play}') - this_play = await lineouts(session, interaction, this_play, lineout_type) - await self.complete_and_post_play(session, interaction, this_play, buffer_message='Lineout logged' if this_play.on_base_code > 3 else None) - - @group_log.command(name='single', description='Singles: *, **, ballpark, uncapped') + @group_log.command(name="single", description="Singles: *, **, ballpark, uncapped") async def log_single( - self, interaction: discord.Interaction, single_type: Literal['*', '**', 'ballpark', 'uncapped']): + self, + interaction: discord.Interaction, + single_type: Literal["*", "**", "ballpark", "uncapped"], + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log single') as (this_game, owner_team, this_play): - logger.info(f'log single {single_type} - this_play: {this_play}') + async with locked_play(session, interaction, "log single") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log single {single_type} - this_play: {this_play}") this_play = await singles(session, interaction, this_play, single_type) - await self.complete_and_post_play(session, interaction, this_play, buffer_message='Single logged' if ((this_play.on_first or this_play.on_second) and single_type == 'uncapped') else None) + await self.complete_and_post_play( + session, + interaction, + this_play, + buffer_message=( + "Single logged" + if ( + (this_play.on_first or this_play.on_second) + and single_type == "uncapped" + ) + else None + ), + ) - @group_log.command(name='double', description='Doubles: **, ***, uncapped') - async def log_double(self, interaction: discord.Interaction, double_type: Literal['**', '***', 'uncapped']): + @group_log.command(name="double", description="Doubles: **, ***, uncapped") + async def log_double( + self, + interaction: discord.Interaction, + double_type: Literal["**", "***", "uncapped"], + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log double') as (this_game, owner_team, this_play): - logger.info(f'log double {double_type} - this_play: {this_play}') + async with locked_play(session, interaction, "log double") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log double {double_type} - this_play: {this_play}") this_play = await doubles(session, interaction, this_play, double_type) - 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) - - @group_log.command(name='triple', description='Triples: no sub-types') + 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 + ), + ) + + @group_log.command(name="triple", description="Triples: no sub-types") async def log_triple(self, interaction: discord.Interaction): with Session(engine) as session: - async with locked_play(session, interaction, 'log triple') as (this_game, owner_team, this_play): - logger.info(f'log triple - this_play: {this_play}') + async with locked_play(session, interaction, "log triple") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log triple - this_play: {this_play}") this_play = await triples(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play) - @group_log.command(name='homerun', description='Home Runs: ballpark, no-doubt') - async def log_homerun(self, interaction: discord.Interaction, homerun_type: Literal['ballpark', 'no-doubt']): + @group_log.command(name="homerun", description="Home Runs: ballpark, no-doubt") + async def log_homerun( + self, + interaction: discord.Interaction, + homerun_type: Literal["ballpark", "no-doubt"], + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log homerun') as (this_game, owner_team, this_play): - logger.info(f'log homerun {homerun_type} - this_play: {this_play}') - this_play = await homeruns(session, interaction, this_play, homerun_type) + async with locked_play(session, interaction, "log homerun") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log homerun {homerun_type} - this_play: {this_play}") + this_play = await homeruns( + session, interaction, this_play, homerun_type + ) await self.complete_and_post_play(session, interaction, this_play) - - @group_log.command(name='walk', description='Walks: unintentional (default), intentional') - async def log_walk(self, interaction: discord.Interaction, walk_type: Literal['unintentional', 'intentional'] = 'unintentional'): + + @group_log.command( + name="walk", description="Walks: unintentional (default), intentional" + ) + async def log_walk( + self, + interaction: discord.Interaction, + walk_type: Literal["unintentional", "intentional"] = "unintentional", + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log walk') as (this_game, owner_team, this_play): - logger.info(f'log walk {walk_type} - this_play: {this_play}') + async with locked_play(session, interaction, "log walk") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log walk {walk_type} - this_play: {this_play}") this_play = await walks(session, interaction, this_play, walk_type) await self.complete_and_post_play(session, interaction, this_play) - @group_log.command(name='strikeout', description='Strikeout') + @group_log.command(name="strikeout", description="Strikeout") async def log_strikeout(self, interaction: discord.Interaction): with Session(engine) as session: - async with locked_play(session, interaction, 'log strikeout') as (this_game, owner_team, this_play): - logger.info(f'log strikeout - this_play: {this_play}') + async with locked_play(session, interaction, "log strikeout") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log strikeout - this_play: {this_play}") this_play = await strikeouts(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play) - @group_log.command(name='popout', description='Popout') + @group_log.command(name="popout", description="Popout") async def log_popout(self, interaction: discord.Interaction): with Session(engine) as session: - async with locked_play(session, interaction, 'log popout') as (this_game, owner_team, this_play): - logger.info(f'log popout - this_play: {this_play}') + async with locked_play(session, interaction, "log popout") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log popout - this_play: {this_play}") this_play = await popouts(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play) - @group_log.command(name='groundball', description='Groundballs: a, b, c') - async def log_groundball(self, interaction: discord.Interaction, groundball_type: Literal['a', 'b', 'c']): + @group_log.command(name="groundball", description="Groundballs: a, b, c") + async def log_groundball( + self, interaction: discord.Interaction, groundball_type: Literal["a", "b", "c"] + ): with Session(engine) as session: - async with locked_play(session, interaction, f'log groundball {groundball_type}') as (this_game, owner_team, this_play): - logger.info(f'log groundball {groundball_type} - this_play: {this_play}') - this_play = await groundballs(session, interaction, this_play, groundball_type) + async with locked_play( + session, interaction, f"log groundball {groundball_type}" + ) as (this_game, owner_team, this_play): + logger.info( + f"log groundball {groundball_type} - this_play: {this_play}" + ) + this_play = await groundballs( + session, interaction, this_play, groundball_type + ) await self.complete_and_post_play(session, interaction, this_play) - @group_log.command(name='hit-by-pitch', description='Hit by pitch: batter to first; runners advance if forced') + @group_log.command( + name="hit-by-pitch", + description="Hit by pitch: batter to first; runners advance if forced", + ) async def log_hit_by_pitch(self, interaction: discord.Interaction): with Session(engine) as session: - async with locked_play(session, interaction, 'log hit-by-pitch') as (this_game, owner_team, this_play): - logger.info(f'log hit-by-pitch - this_play: {this_play}') + async with locked_play(session, interaction, "log hit-by-pitch") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log hit-by-pitch - this_play: {this_play}") this_play = await hit_by_pitch(session, interaction, this_play) await self.complete_and_post_play(session, interaction, this_play) - - @group_log.command(name='chaos', description='Chaos: wild-pitch, passed-ball, balk, pickoff') - async def log_chaos(self, interaction: discord.Interaction, chaos_type: Literal['wild-pitch', 'passed-ball', 'balk', 'pickoff']): + + @group_log.command( + name="chaos", description="Chaos: wild-pitch, passed-ball, balk, pickoff" + ) + async def log_chaos( + self, + interaction: discord.Interaction, + chaos_type: Literal["wild-pitch", "passed-ball", "balk", "pickoff"], + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log chaos') as (this_game, owner_team, this_play): + async with locked_play(session, interaction, "log chaos") as ( + this_game, + owner_team, + this_play, + ): if this_play.on_base_code == 0: await interaction.edit_original_response( - content=f'There cannot be chaos when the bases are empty.' + content=f"There cannot be chaos when the bases are empty." ) return - logger.info(f'log chaos - this_play: {this_play}') + logger.info(f"log chaos - this_play: {this_play}") this_play = await chaos(session, interaction, this_play, chaos_type) await self.complete_and_post_play(session, interaction, this_play) - @group_log.command(name='bunt', description='Bunts: sacrifice, bad, popout, double-play, defense') - async def log_sac_bunt(self, interaction: discord.Interaction, bunt_type: Literal['sacrifice', 'bad', 'popout', 'double-play', 'defense']): + @group_log.command( + name="bunt", description="Bunts: sacrifice, bad, popout, double-play, defense" + ) + async def log_sac_bunt( + self, + interaction: discord.Interaction, + bunt_type: Literal["sacrifice", "bad", "popout", "double-play", "defense"], + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log bunt') as (this_game, owner_team, this_play): + async with locked_play(session, interaction, "log bunt") as ( + this_game, + owner_team, + this_play, + ): if this_play.on_base_code == 0: await interaction.edit_original_response( - content=f'You cannot bunt when the bases are empty.' + content=f"You cannot bunt when the bases are empty." ) return elif this_play.starting_outs == 2: await interaction.edit_original_response( - content=f'You cannot bunt with two outs.' + content=f"You cannot bunt with two outs." ) return - logger.info(f'log bunt - this_play: {this_play}') + logger.info(f"log bunt - this_play: {this_play}") this_play = await bunts(session, interaction, this_play, bunt_type) await self.complete_and_post_play(session, interaction, this_play) - @group_log.command(name='stealing', description='Running: stolen-base, caught-stealing') - @app_commands.describe(to_base='Base the runner is advancing to; 2 for 2nd, 3 for 3rd, 4 for Home') - async def log_stealing(self, interaction: discord.Interaction, running_type: Literal['stolen-base', 'caught-stealing', 'steal-plus-overthrow'], to_base: Literal[2, 3, 4]): + @group_log.command( + name="stealing", description="Running: stolen-base, caught-stealing" + ) + @app_commands.describe( + to_base="Base the runner is advancing to; 2 for 2nd, 3 for 3rd, 4 for Home" + ) + async def log_stealing( + self, + interaction: discord.Interaction, + running_type: Literal["stolen-base", "caught-stealing", "steal-plus-overthrow"], + to_base: Literal[2, 3, 4], + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log stealing') as (this_game, owner_team, this_play): - if (to_base == 2 and this_play.on_first is None) or (to_base == 3 and this_play.on_second is None) or (to_base == 4 and this_play.on_third is None): - logger.info(f'Illegal steal attempt') + async with locked_play(session, interaction, "log stealing") as ( + this_game, + owner_team, + this_play, + ): + if ( + (to_base == 2 and this_play.on_first is None) + or (to_base == 3 and this_play.on_second is None) + or (to_base == 4 and this_play.on_third is None) + ): + logger.info(f"Illegal steal attempt") await interaction.edit_original_response( - content=f'I don\'t see a runner there.' + content=f"I don't see a runner there." ) return - if (to_base == 3 and this_play.on_third is not None) or (to_base == 2 and this_play.on_second is not None): - logger.info(f'Stealing runner is blocked') + if (to_base == 3 and this_play.on_third is not None) or ( + to_base == 2 and this_play.on_second is not None + ): + logger.info(f"Stealing runner is blocked") if to_base == 3: - content = f'{this_play.on_second.player.name} is blocked by {this_play.on_third.player.name}' + content = f"{this_play.on_second.player.name} is blocked by {this_play.on_third.player.name}" else: - content = f'{this_play.on_first.player.name} is blocked by {this_play.on_second.player.name}' + content = f"{this_play.on_first.player.name} is blocked by {this_play.on_second.player.name}" - await interaction.edit_original_response( - content=content - ) + await interaction.edit_original_response(content=content) return - logger.info(f'log stealing - this_play: {this_play}') - this_play = await steals(session, interaction, this_play, running_type, to_base) + logger.info(f"log stealing - this_play: {this_play}") + this_play = await steals( + session, interaction, this_play, running_type, to_base + ) await self.complete_and_post_play(session, interaction, this_play) - @group_log.command(name='xcheck', description='Defender makes an x-check') - @app_commands.choices(position=[ - Choice(name='Pitcher', value='P'), - Choice(name='Catcher', value='C'), - Choice(name='First Base', value='1B'), - Choice(name='Second Base', value='2B'), - Choice(name='Third Base', value='3B'), - Choice(name='Shortstop', value='SS'), - Choice(name='Left Field', value='LF'), - Choice(name='Center Field', value='CF'), - Choice(name='Right Field', value='RF'), - ]) - async def log_xcheck_command(self, interaction: discord.Interaction, position: Choice[str]): + @group_log.command(name="xcheck", description="Defender makes an x-check") + @app_commands.choices( + position=[ + Choice(name="Pitcher", value="P"), + Choice(name="Catcher", value="C"), + Choice(name="First Base", value="1B"), + Choice(name="Second Base", value="2B"), + Choice(name="Third Base", value="3B"), + Choice(name="Shortstop", value="SS"), + Choice(name="Left Field", value="LF"), + Choice(name="Center Field", value="CF"), + Choice(name="Right Field", value="RF"), + ] + ) + async def log_xcheck_command( + self, interaction: discord.Interaction, position: Choice[str] + ): with Session(engine) as session: - async with locked_play(session, interaction, 'log xcheck') as (this_game, owner_team, this_play): - logger.info(f'log xcheck - this_play: {this_play}') - this_play = await xchecks(session, interaction, this_play, position.value) + async with locked_play(session, interaction, "log xcheck") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log xcheck - this_play: {this_play}") + this_play = await xchecks( + session, interaction, this_play, position.value + ) - await self.complete_and_post_play(session, interaction, this_play, buffer_message='X-Check logged') + await self.complete_and_post_play( + session, interaction, this_play, buffer_message="X-Check logged" + ) - - @group_log.command(name='undo-play', description='Roll back most recent play from the log') + @group_log.command( + name="undo-play", description="Roll back most recent play from the log" + ) async def log_undo_play_command(self, interaction: discord.Interaction): with Session(engine) as session: - async with locked_play(session, interaction, 'log undo-play') as (this_game, owner_team, this_play): - logger.info(f'log undo-play - this_play: {this_play}') + async with locked_play(session, interaction, "log undo-play") as ( + this_game, + owner_team, + this_play, + ): + logger.info(f"log undo-play - this_play: {this_play}") original_play = this_play this_play = undo_play(session, this_play) - original_play.locked = False # prevent finally from committing deleted row + original_play.locked = ( + False # prevent finally from committing deleted row + ) await self.post_play(session, interaction, this_play) - group_show = app_commands.Group(name='show-card', description='Display the player card for an active player') - - @group_show.command(name='defense', description='Display a defender\'s player card') - async def show_defense_command(self, interaction: discord.Interaction, position: DEFENSE_LITERAL): + group_show = app_commands.Group( + name="show-card", description="Display the player card for an active player" + ) + + @group_show.command(name="defense", description="Display a defender's player card") + async def show_defense_command( + self, interaction: discord.Interaction, position: DEFENSE_LITERAL + ): with Session(engine) as session: # Read-only command - no play locking needed await interaction.response.defer(thinking=True) this_game = get_channel_game_or_none(session, interaction.channel_id) if this_game is None: - await interaction.edit_original_response(content="I don't see an active game in this channel.") + await interaction.edit_original_response( + content="I don't see an active game in this channel." + ) return this_play = this_game.current_play_or_none(session) if this_play is None: - await interaction.edit_original_response(content="No active play found.") + await interaction.edit_original_response( + content="No active play found." + ) return - logger.info(f'show-card defense - position: {position}') + logger.info(f"show-card defense - position: {position}") await show_defense_cards(session, interaction, this_play, position) async def setup(bot): - await bot.add_cog(Gameplay(bot)) \ No newline at end of file + await bot.add_cog(Gameplay(bot)) diff --git a/cogs/players.py b/cogs/players.py index 4dfc233..cc3ad7d 100644 --- a/cogs/players.py +++ b/cogs/players.py @@ -19,6 +19,7 @@ from sqlmodel import Session import gauntlets import helpers + # import in_game.data_cache # import in_game.simulations # import in_game @@ -28,210 +29,389 @@ from in_game.gameplay_queries import get_team_or_none from in_game.simulations import get_pos_embeds, get_result from in_game.gameplay_models import Lineup, Play, Session, engine from api_calls import db_get, db_post, db_patch, get_team_by_abbrev -from helpers import ACTIVE_EVENT_LITERAL, PD_PLAYERS_ROLE_NAME, IMAGES, PD_SEASON, random_conf_gif, fuzzy_player_search, ALL_MLB_TEAMS, \ - fuzzy_search, get_channel, display_cards, get_card_embeds, get_team_embed, cardset_search, get_blank_team_card, \ - get_team_by_owner, get_rosters, get_roster_sheet, legal_channel, app_legal_channel, random_conf_word, embed_pagination, get_cal_user, \ - team_summary_embed, SelectView, SelectPaperdexCardset, SelectPaperdexTeam, get_context_user +from helpers import ( + ACTIVE_EVENT_LITERAL, + PD_PLAYERS_ROLE_NAME, + IMAGES, + PD_SEASON, + random_conf_gif, + fuzzy_player_search, + ALL_MLB_TEAMS, + fuzzy_search, + get_channel, + display_cards, + get_card_embeds, + get_team_embed, + cardset_search, + get_blank_team_card, + get_team_by_owner, + get_rosters, + get_roster_sheet, + legal_channel, + app_legal_channel, + random_conf_word, + embed_pagination, + get_cal_user, + team_summary_embed, + SelectView, + SelectPaperdexCardset, + SelectPaperdexTeam, + get_context_user, +) from utilities.buttons import ask_with_buttons from utilities.autocomplete import cardset_autocomplete, player_autocomplete - -logger = logging.getLogger('discord_app') +logger = logging.getLogger("discord_app") def get_ai_records(short_games, long_games): all_results = { - 'ARI': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'ATL': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'BAL': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'BOS': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'CHC': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'CHW': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'CIN': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'CLE': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'COL': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'DET': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'HOU': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'KCR': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'LAA': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'LAD': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'MIA': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'MIL': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'MIN': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'NYM': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'NYY': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'OAK': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'PHI': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'PIT': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'SDP': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'SEA': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'SFG': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'STL': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'TBR': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'TEX': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'TOR': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, - 'WSN': { - 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, - 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, + "ARI": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "ATL": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "BAL": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "BOS": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "CHC": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "CHW": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "CIN": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "CLE": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "COL": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "DET": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "HOU": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "KCR": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "LAA": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "LAD": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "MIA": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "MIL": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "MIN": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "NYM": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "NYY": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "OAK": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "PHI": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "PIT": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "SDP": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "SEA": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "SFG": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "STL": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "TBR": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "TEX": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "TOR": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, + "WSN": { + "short": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "minor": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "major": {"w": 0, "l": 0, "rd": 0, "points": 0}, + "hof": {"w": 0, "l": 0, "rd": 0, "points": 0}, + }, } - logger.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 + home_win = True if line["home_score"] > line["away_score"] else False - if line['away_team']['is_ai']: - all_results[line['away_team']['abbrev']]['short']['w'] += 1 if home_win else 0 - all_results[line['away_team']['abbrev']]['short']['l'] += 1 if not home_win else 0 - all_results[line['away_team']['abbrev']]['short']['points'] += 2 if home_win else 1 - all_results[line['away_team']['abbrev']]['short']['rd'] += line['home_score'] - line['away_score'] - elif line['home_team']['is_ai']: - all_results[line['home_team']['abbrev']]['short']['w'] += 1 if not home_win else 0 - all_results[line['home_team']['abbrev']]['short']['l'] += 1 if home_win else 0 - all_results[line['home_team']['abbrev']]['short']['points'] += 2 if not home_win else 1 - all_results[line['home_team']['abbrev']]['short']['rd'] += line['away_score'] - line['home_score'] - logger.debug(f'done short games') + if line["away_team"]["is_ai"]: + all_results[line["away_team"]["abbrev"]]["short"]["w"] += ( + 1 if home_win else 0 + ) + all_results[line["away_team"]["abbrev"]]["short"]["l"] += ( + 1 if not home_win else 0 + ) + all_results[line["away_team"]["abbrev"]]["short"]["points"] += ( + 2 if home_win else 1 + ) + all_results[line["away_team"]["abbrev"]]["short"]["rd"] += ( + line["home_score"] - line["away_score"] + ) + elif line["home_team"]["is_ai"]: + all_results[line["home_team"]["abbrev"]]["short"]["w"] += ( + 1 if not home_win else 0 + ) + all_results[line["home_team"]["abbrev"]]["short"]["l"] += ( + 1 if home_win else 0 + ) + all_results[line["home_team"]["abbrev"]]["short"]["points"] += ( + 2 if not home_win else 1 + ) + all_results[line["home_team"]["abbrev"]]["short"]["rd"] += ( + line["away_score"] - line["home_score"] + ) + logger.debug(f"done short games") - logger.debug(f'running league games...') - league = {None: 'minor', 'minor-league': 'minor', 'major-league': 'major', 'hall-of-fame': 'hof'} + 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 + home_win = True if line["home_score"] > line["away_score"] else False - if line['away_team']['is_ai']: - all_results[line['away_team']['abbrev']][league[line['game_type']]]['w'] += 1 if home_win else 0 - all_results[line['away_team']['abbrev']][league[line['game_type']]]['l'] += 1 if not home_win else 0 - all_results[line['away_team']['abbrev']][league[line['game_type']]]['points'] += 2 if home_win else 1 - all_results[line['away_team']['abbrev']][league[line['game_type']]]['rd'] += \ - line['home_score'] - line['away_score'] - elif line['home_team']['is_ai']: - all_results[line['home_team']['abbrev']][league[line['game_type']]]['w'] += 1 if not home_win else 0 - all_results[line['home_team']['abbrev']][league[line['game_type']]]['l'] += 1 if home_win else 0 - 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'] - logger.debug(f'done league games') + if line["away_team"]["is_ai"]: + all_results[line["away_team"]["abbrev"]][league[line["game_type"]]][ + "w" + ] += (1 if home_win else 0) + all_results[line["away_team"]["abbrev"]][league[line["game_type"]]][ + "l" + ] += (1 if not home_win else 0) + all_results[line["away_team"]["abbrev"]][league[line["game_type"]]][ + "points" + ] += (2 if home_win else 1) + all_results[line["away_team"]["abbrev"]][league[line["game_type"]]][ + "rd" + ] += (line["home_score"] - line["away_score"]) + elif line["home_team"]["is_ai"]: + all_results[line["home_team"]["abbrev"]][league[line["game_type"]]][ + "w" + ] += (1 if not home_win else 0) + all_results[line["home_team"]["abbrev"]][league[line["game_type"]]][ + "l" + ] += (1 if home_win else 0) + 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"]) + logger.debug(f"done league games") return all_results def get_record_embed_legacy(embed: discord.Embed, results: dict, league: str): - ale_points = results["BAL"][league]["points"] + results["BOS"][league]["points"] + \ - results["NYY"][league]["points"] + results["TBR"][league]["points"] + results["TOR"][league]["points"] - alc_points = results["CLE"][league]["points"] + results["CHW"][league]["points"] + \ - results["DET"][league]["points"] + results["KCR"][league]["points"] + results["MIN"][league]["points"] - alw_points = results["HOU"][league]["points"] + results["LAA"][league]["points"] + \ - results["OAK"][league]["points"] + results["SEA"][league]["points"] + results["TEX"][league]["points"] - nle_points = results["ATL"][league]["points"] + results["MIA"][league]["points"] + \ - results["NYM"][league]["points"] + results["PHI"][league]["points"] + results["WSN"][league]["points"] - nlc_points = results["CHC"][league]["points"] + results["CIN"][league]["points"] + \ - results["MIL"][league]["points"] + results["PIT"][league]["points"] + results["STL"][league]["points"] - nlw_points = results["ARI"][league]["points"] + results["COL"][league]["points"] + \ - results["LAD"][league]["points"] + results["SDP"][league]["points"] + results["SFG"][league]["points"] + ale_points = ( + results["BAL"][league]["points"] + + results["BOS"][league]["points"] + + results["NYY"][league]["points"] + + results["TBR"][league]["points"] + + results["TOR"][league]["points"] + ) + alc_points = ( + results["CLE"][league]["points"] + + results["CHW"][league]["points"] + + results["DET"][league]["points"] + + results["KCR"][league]["points"] + + results["MIN"][league]["points"] + ) + alw_points = ( + results["HOU"][league]["points"] + + results["LAA"][league]["points"] + + results["OAK"][league]["points"] + + results["SEA"][league]["points"] + + results["TEX"][league]["points"] + ) + nle_points = ( + results["ATL"][league]["points"] + + results["MIA"][league]["points"] + + results["NYM"][league]["points"] + + results["PHI"][league]["points"] + + results["WSN"][league]["points"] + ) + nlc_points = ( + results["CHC"][league]["points"] + + results["CIN"][league]["points"] + + results["MIL"][league]["points"] + + results["PIT"][league]["points"] + + results["STL"][league]["points"] + ) + nlw_points = ( + results["ARI"][league]["points"] + + results["COL"][league]["points"] + + results["LAD"][league]["points"] + + results["SDP"][league]["points"] + + results["SFG"][league]["points"] + ) embed.add_field( - name=f'AL East ({ale_points} pts)', + name=f"AL East ({ale_points} pts)", value=f'BAL: {results["BAL"][league]["w"]} - {results["BAL"][league]["l"]} ({results["BAL"][league]["rd"]} RD)\n' - f'BOS: {results["BOS"][league]["w"]} - {results["BOS"][league]["l"]} ({results["BOS"][league]["rd"]} RD)\n' - f'NYY: {results["NYY"][league]["w"]} - {results["NYY"][league]["l"]} ({results["NYY"][league]["rd"]} RD)\n' - f'TBR: {results["TBR"][league]["w"]} - {results["TBR"][league]["l"]} ({results["TBR"][league]["rd"]} RD)\n' - f'TOR: {results["TOR"][league]["w"]} - {results["TOR"][league]["l"]} ({results["TOR"][league]["rd"]} RD)\n' + f'BOS: {results["BOS"][league]["w"]} - {results["BOS"][league]["l"]} ({results["BOS"][league]["rd"]} RD)\n' + f'NYY: {results["NYY"][league]["w"]} - {results["NYY"][league]["l"]} ({results["NYY"][league]["rd"]} RD)\n' + f'TBR: {results["TBR"][league]["w"]} - {results["TBR"][league]["l"]} ({results["TBR"][league]["rd"]} RD)\n' + f'TOR: {results["TOR"][league]["w"]} - {results["TOR"][league]["l"]} ({results["TOR"][league]["rd"]} RD)\n', ) embed.add_field( - name=f'AL Central ({alc_points} pts)', + name=f"AL Central ({alc_points} pts)", value=f'CLE: {results["CLE"][league]["w"]} - {results["CLE"][league]["l"]} ({results["CLE"][league]["rd"]} RD)\n' - f'CHW: {results["CHW"][league]["w"]} - {results["CHW"][league]["l"]} ({results["CHW"][league]["rd"]} RD)\n' - f'DET: {results["DET"][league]["w"]} - {results["DET"][league]["l"]} ({results["DET"][league]["rd"]} RD)\n' - f'KCR: {results["KCR"][league]["w"]} - {results["KCR"][league]["l"]} ({results["KCR"][league]["rd"]} RD)\n' - f'MIN: {results["MIN"][league]["w"]} - {results["MIN"][league]["l"]} ({results["MIN"][league]["rd"]} RD)\n' + f'CHW: {results["CHW"][league]["w"]} - {results["CHW"][league]["l"]} ({results["CHW"][league]["rd"]} RD)\n' + f'DET: {results["DET"][league]["w"]} - {results["DET"][league]["l"]} ({results["DET"][league]["rd"]} RD)\n' + f'KCR: {results["KCR"][league]["w"]} - {results["KCR"][league]["l"]} ({results["KCR"][league]["rd"]} RD)\n' + f'MIN: {results["MIN"][league]["w"]} - {results["MIN"][league]["l"]} ({results["MIN"][league]["rd"]} RD)\n', ) embed.add_field( - name=f'AL West ({alw_points} pts)', + name=f"AL West ({alw_points} pts)", value=f'HOU: {results["HOU"][league]["w"]} - {results["HOU"][league]["l"]} ({results["HOU"][league]["rd"]} RD)\n' - f'LAA: {results["LAA"][league]["w"]} - {results["LAA"][league]["l"]} ({results["LAA"][league]["rd"]} RD)\n' - f'OAK: {results["OAK"][league]["w"]} - {results["OAK"][league]["l"]} ({results["OAK"][league]["rd"]} RD)\n' - f'SEA: {results["SEA"][league]["w"]} - {results["SEA"][league]["l"]} ({results["SEA"][league]["rd"]} RD)\n' - f'TEX: {results["TEX"][league]["w"]} - {results["TEX"][league]["l"]} ({results["TEX"][league]["rd"]} RD)\n' + f'LAA: {results["LAA"][league]["w"]} - {results["LAA"][league]["l"]} ({results["LAA"][league]["rd"]} RD)\n' + f'OAK: {results["OAK"][league]["w"]} - {results["OAK"][league]["l"]} ({results["OAK"][league]["rd"]} RD)\n' + f'SEA: {results["SEA"][league]["w"]} - {results["SEA"][league]["l"]} ({results["SEA"][league]["rd"]} RD)\n' + f'TEX: {results["TEX"][league]["w"]} - {results["TEX"][league]["l"]} ({results["TEX"][league]["rd"]} RD)\n', ) embed.add_field( - name=f'NL East ({nle_points} pts)', + name=f"NL East ({nle_points} pts)", value=f'ATL: {results["ATL"][league]["w"]} - {results["ATL"][league]["l"]} ({results["ATL"][league]["rd"]} RD)\n' - f'MIA: {results["MIA"][league]["w"]} - {results["MIA"][league]["l"]} ({results["MIA"][league]["rd"]} RD)\n' - f'NYM: {results["NYM"][league]["w"]} - {results["NYM"][league]["l"]} ({results["NYM"][league]["rd"]} RD)\n' - f'PHI: {results["PHI"][league]["w"]} - {results["PHI"][league]["l"]} ({results["PHI"][league]["rd"]} RD)\n' - f'WSN: {results["WSN"][league]["w"]} - {results["WSN"][league]["l"]} ({results["WSN"][league]["rd"]} RD)\n' + f'MIA: {results["MIA"][league]["w"]} - {results["MIA"][league]["l"]} ({results["MIA"][league]["rd"]} RD)\n' + f'NYM: {results["NYM"][league]["w"]} - {results["NYM"][league]["l"]} ({results["NYM"][league]["rd"]} RD)\n' + f'PHI: {results["PHI"][league]["w"]} - {results["PHI"][league]["l"]} ({results["PHI"][league]["rd"]} RD)\n' + f'WSN: {results["WSN"][league]["w"]} - {results["WSN"][league]["l"]} ({results["WSN"][league]["rd"]} RD)\n', ) embed.add_field( - name=f'NL Central ({nlc_points} pts)', + name=f"NL Central ({nlc_points} pts)", value=f'CHC: {results["CHC"][league]["w"]} - {results["CHC"][league]["l"]} ({results["CHC"][league]["rd"]} RD)\n' - f'CHW: {results["CIN"][league]["w"]} - {results["CIN"][league]["l"]} ({results["CIN"][league]["rd"]} RD)\n' - f'MIL: {results["MIL"][league]["w"]} - {results["MIL"][league]["l"]} ({results["MIL"][league]["rd"]} RD)\n' - f'PIT: {results["PIT"][league]["w"]} - {results["PIT"][league]["l"]} ({results["PIT"][league]["rd"]} RD)\n' - f'STL: {results["STL"][league]["w"]} - {results["STL"][league]["l"]} ({results["STL"][league]["rd"]} RD)\n' + f'CHW: {results["CIN"][league]["w"]} - {results["CIN"][league]["l"]} ({results["CIN"][league]["rd"]} RD)\n' + f'MIL: {results["MIL"][league]["w"]} - {results["MIL"][league]["l"]} ({results["MIL"][league]["rd"]} RD)\n' + f'PIT: {results["PIT"][league]["w"]} - {results["PIT"][league]["l"]} ({results["PIT"][league]["rd"]} RD)\n' + f'STL: {results["STL"][league]["w"]} - {results["STL"][league]["l"]} ({results["STL"][league]["rd"]} RD)\n', ) embed.add_field( - name=f'NL West ({nlw_points} pts)', + name=f"NL West ({nlw_points} pts)", value=f'ARI: {results["ARI"][league]["w"]} - {results["ARI"][league]["l"]} ({results["ARI"][league]["rd"]} RD)\n' - f'COL: {results["COL"][league]["w"]} - {results["COL"][league]["l"]} ({results["COL"][league]["rd"]} RD)\n' - f'LAD: {results["LAD"][league]["w"]} - {results["LAD"][league]["l"]} ({results["LAD"][league]["rd"]} RD)\n' - f'SDP: {results["SDP"][league]["w"]} - {results["SDP"][league]["l"]} ({results["SDP"][league]["rd"]} RD)\n' - f'SFG: {results["SFG"][league]["w"]} - {results["SFG"][league]["l"]} ({results["SFG"][league]["rd"]} RD)\n' + f'COL: {results["COL"][league]["w"]} - {results["COL"][league]["l"]} ({results["COL"][league]["rd"]} RD)\n' + f'LAD: {results["LAD"][league]["w"]} - {results["LAD"][league]["l"]} ({results["LAD"][league]["rd"]} RD)\n' + f'SDP: {results["SDP"][league]["w"]} - {results["SDP"][league]["l"]} ({results["SDP"][league]["rd"]} RD)\n' + f'SFG: {results["SFG"][league]["w"]} - {results["SFG"][league]["l"]} ({results["SFG"][league]["rd"]} RD)\n', ) return embed @@ -240,52 +420,52 @@ def get_record_embed_legacy(embed: discord.Embed, results: dict, league: str): def get_record_embed(team: dict, results: dict, league: str): embed = get_team_embed(league, team) embed.add_field( - name=f'AL East', + name=f"AL East", value=f'BAL: {results["BAL"][0]} - {results["BAL"][1]} ({results["BAL"][2]} RD)\n' - f'BOS: {results["BOS"][0]} - {results["BOS"][1]} ({results["BOS"][2]} RD)\n' - f'NYY: {results["NYY"][0]} - {results["NYY"][1]} ({results["NYY"][2]} RD)\n' - f'TBR: {results["TBR"][0]} - {results["TBR"][1]} ({results["TBR"][2]} RD)\n' - f'TOR: {results["TOR"][0]} - {results["TOR"][1]} ({results["TOR"][2]} RD)\n' + f'BOS: {results["BOS"][0]} - {results["BOS"][1]} ({results["BOS"][2]} RD)\n' + f'NYY: {results["NYY"][0]} - {results["NYY"][1]} ({results["NYY"][2]} RD)\n' + f'TBR: {results["TBR"][0]} - {results["TBR"][1]} ({results["TBR"][2]} RD)\n' + f'TOR: {results["TOR"][0]} - {results["TOR"][1]} ({results["TOR"][2]} RD)\n', ) embed.add_field( - name=f'AL Central', + name=f"AL Central", value=f'CLE: {results["CLE"][0]} - {results["CLE"][1]} ({results["CLE"][2]} RD)\n' - f'CHW: {results["CHW"][0]} - {results["CHW"][1]} ({results["CHW"][2]} RD)\n' - f'DET: {results["DET"][0]} - {results["DET"][1]} ({results["DET"][2]} RD)\n' - f'KCR: {results["KCR"][0]} - {results["KCR"][1]} ({results["KCR"][2]} RD)\n' - f'MIN: {results["MIN"][0]} - {results["MIN"][1]} ({results["MIN"][2]} RD)\n' + f'CHW: {results["CHW"][0]} - {results["CHW"][1]} ({results["CHW"][2]} RD)\n' + f'DET: {results["DET"][0]} - {results["DET"][1]} ({results["DET"][2]} RD)\n' + f'KCR: {results["KCR"][0]} - {results["KCR"][1]} ({results["KCR"][2]} RD)\n' + f'MIN: {results["MIN"][0]} - {results["MIN"][1]} ({results["MIN"][2]} RD)\n', ) embed.add_field( - name=f'AL West', + name=f"AL West", value=f'HOU: {results["HOU"][0]} - {results["HOU"][1]} ({results["HOU"][2]} RD)\n' - f'LAA: {results["LAA"][0]} - {results["LAA"][1]} ({results["LAA"][2]} RD)\n' - f'OAK: {results["OAK"][0]} - {results["OAK"][1]} ({results["OAK"][2]} RD)\n' - f'SEA: {results["SEA"][0]} - {results["SEA"][1]} ({results["SEA"][2]} RD)\n' - f'TEX: {results["TEX"][0]} - {results["TEX"][1]} ({results["TEX"][2]} RD)\n' + f'LAA: {results["LAA"][0]} - {results["LAA"][1]} ({results["LAA"][2]} RD)\n' + f'OAK: {results["OAK"][0]} - {results["OAK"][1]} ({results["OAK"][2]} RD)\n' + f'SEA: {results["SEA"][0]} - {results["SEA"][1]} ({results["SEA"][2]} RD)\n' + f'TEX: {results["TEX"][0]} - {results["TEX"][1]} ({results["TEX"][2]} RD)\n', ) embed.add_field( - name=f'NL East', + name=f"NL East", value=f'ATL: {results["ATL"][0]} - {results["ATL"][1]} ({results["ATL"][2]} RD)\n' - f'MIA: {results["MIA"][0]} - {results["MIA"][1]} ({results["MIA"][2]} RD)\n' - f'NYM: {results["NYM"][0]} - {results["NYM"][1]} ({results["NYM"][2]} RD)\n' - f'PHI: {results["PHI"][0]} - {results["PHI"][1]} ({results["PHI"][2]} RD)\n' - f'WSN: {results["WSN"][0]} - {results["WSN"][1]} ({results["WSN"][2]} RD)\n' + f'MIA: {results["MIA"][0]} - {results["MIA"][1]} ({results["MIA"][2]} RD)\n' + f'NYM: {results["NYM"][0]} - {results["NYM"][1]} ({results["NYM"][2]} RD)\n' + f'PHI: {results["PHI"][0]} - {results["PHI"][1]} ({results["PHI"][2]} RD)\n' + f'WSN: {results["WSN"][0]} - {results["WSN"][1]} ({results["WSN"][2]} RD)\n', ) embed.add_field( - name=f'NL Central', + name=f"NL Central", value=f'CHC: {results["CHC"][0]} - {results["CHC"][1]} ({results["CHC"][2]} RD)\n' - f'CIN: {results["CIN"][0]} - {results["CIN"][1]} ({results["CIN"][2]} RD)\n' - f'MIL: {results["MIL"][0]} - {results["MIL"][1]} ({results["MIL"][2]} RD)\n' - f'PIT: {results["PIT"][0]} - {results["PIT"][1]} ({results["PIT"][2]} RD)\n' - f'STL: {results["STL"][0]} - {results["STL"][1]} ({results["STL"][2]} RD)\n' + f'CIN: {results["CIN"][0]} - {results["CIN"][1]} ({results["CIN"][2]} RD)\n' + f'MIL: {results["MIL"][0]} - {results["MIL"][1]} ({results["MIL"][2]} RD)\n' + f'PIT: {results["PIT"][0]} - {results["PIT"][1]} ({results["PIT"][2]} RD)\n' + f'STL: {results["STL"][0]} - {results["STL"][1]} ({results["STL"][2]} RD)\n', ) embed.add_field( - name=f'NL West', + name=f"NL West", value=f'ARI: {results["ARI"][0]} - {results["ARI"][1]} ({results["ARI"][2]} RD)\n' - f'COL: {results["COL"][0]} - {results["COL"][1]} ({results["COL"][2]} RD)\n' - f'LAD: {results["LAD"][0]} - {results["LAD"][1]} ({results["LAD"][2]} RD)\n' - f'SDP: {results["SDP"][0]} - {results["SDP"][1]} ({results["SDP"][2]} RD)\n' - f'SFG: {results["SFG"][0]} - {results["SFG"][1]} ({results["SFG"][2]} RD)\n' + f'COL: {results["COL"][0]} - {results["COL"][1]} ({results["COL"][2]} RD)\n' + f'LAD: {results["LAD"][0]} - {results["LAD"][1]} ({results["LAD"][2]} RD)\n' + f'SDP: {results["SDP"][0]} - {results["SDP"][1]} ({results["SDP"][2]} RD)\n' + f'SFG: {results["SFG"][0]} - {results["SFG"][1]} ({results["SFG"][2]} RD)\n', ) return embed @@ -304,15 +484,17 @@ class Players(commands.Cog): @tasks.loop(hours=1) async def weekly_loop(self): - current = await db_get('current') + current = await db_get("current") now = datetime.datetime.now() - logger.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 if now.weekday() == 0 and now.hour == 0: # Fall/Winter - current['week'] += 1 - await db_patch('current', object_id=current['id'], params=[('week', current['week'])]) + current["week"] += 1 + await db_patch( + "current", object_id=current["id"], params=[("week", current["week"])] + ) # End Freeze # elif now.weekday() == 5 and now.hour == 5 and current['freeze']: # Spring/Summer @@ -324,19 +506,28 @@ class Players(commands.Cog): await self.bot.wait_until_ready() async def cog_command_error(self, ctx, error): - await ctx.send(f'{error}') + await ctx.send(f"{error}") @tasks.loop(hours=18) async def build_player_list(self): - all_players = await db_get('players', params=[('flat', True), ('inc_dex', False)], timeout=25) - all_cardsets = await db_get('cardsets', params=[('flat', True)]) + all_players = await db_get( + "players", params=[("flat", True), ("inc_dex", False)], timeout=25 + ) + all_cardsets = await db_get("cardsets", params=[("flat", True)]) - [self.player_list.append(x['p_name'].lower()) for x in all_players['players'] if x['p_name'].lower() - not in self.player_list] - logger.info(f'There are now {len(self.player_list)} player names in the fuzzy search list.') + [ + self.player_list.append(x["p_name"].lower()) + for x in all_players["players"] + if x["p_name"].lower() not in self.player_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']] - logger.info(f'There are now {len(self.cardset_list)} cardsets in the fuzzy search list.') + self.cardset_list = [x["name"].lower() for x in all_cardsets["cardsets"]] + 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): @@ -413,109 +604,135 @@ class Players(commands.Cog): # db.close() # return return_embeds - @commands.command(name='build_list', help='Mod: Synchronize fuzzy player list') + @commands.command(name="build_list", help="Mod: Synchronize fuzzy player list") async def build_player_command(self, ctx): self.build_player_list.stop() self.build_player_list.start() - await ctx.send(f'Just kicked off the build...') + await ctx.send(f"Just kicked off the build...") await asyncio.sleep(10) - await ctx.send(f'There are now {len(self.player_list)} player names in the fuzzy search list.') + await ctx.send( + f"There are now {len(self.player_list)} player names in the fuzzy search list." + ) - @commands.command(name='player', help='For specific cardset, run /player', aliases=['show', 'card']) + @commands.command( + name="player", + help="For specific cardset, run /player", + aliases=["show", "card"], + ) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def player_card_command(self, ctx, *, player_name: str): this_player = fuzzy_search(player_name, self.player_list) if not this_player: - await ctx.send(f'No clue who that is.') + await ctx.send(f"No clue who that is.") return - all_players = await db_get('players', params=[('name', this_player)]) + all_players = await db_get("players", params=[("name", this_player)]) all_cards = [ - {'player': x, 'team': {'lname': 'Paper Dynasty', 'logo': IMAGES['logo'], 'season': PD_SEASON}} - for x in all_players['players'] + { + "player": x, + "team": { + "lname": "Paper Dynasty", + "logo": IMAGES["logo"], + "season": PD_SEASON, + }, + } + for x in all_players["players"] ] - all_cards.sort(key=lambda x: x['player']['rarity']['value'], reverse=True) + all_cards.sort(key=lambda x: x["player"]["rarity"]["value"], reverse=True) all_embeds = [] for x in all_cards: all_embeds.extend(await get_card_embeds(x)) await ctx.send(content=None, embeds=all_embeds) - @app_commands.command(name='player', description='Display one or more of the player\'s cards') + @app_commands.command( + name="player", description="Display one or more of the player's cards" + ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - @app_commands.autocomplete(player_name=player_autocomplete, cardset=cardset_autocomplete) + @app_commands.autocomplete( + player_name=player_autocomplete, cardset=cardset_autocomplete + ) async def player_slash_command( - self, interaction: discord.Interaction, player_name: str, - cardset: str = 'All'): + self, interaction: discord.Interaction, player_name: str, cardset: str = "All" + ): ephemeral = False - if interaction.channel.name in ['paper-dynasty-chat', 'pd-news-ticker']: + if interaction.channel.name in ["paper-dynasty-chat", "pd-news-ticker"]: ephemeral = True await interaction.response.defer(ephemeral=ephemeral) this_player = fuzzy_search(player_name, self.player_list) if not this_player: - await interaction.response.send_message(f'No clue who that is.') + await interaction.response.send_message(f"No clue who that is.") return - if cardset and cardset != 'All': + if cardset and cardset != "All": this_cardset = await cardset_search(cardset, self.cardset_list) if this_cardset: - all_params = [('name', this_player), ('cardset_id', this_cardset['id'])] + all_params = [("name", this_player), ("cardset_id", this_cardset["id"])] else: - await interaction.edit_original_response(content=f'I couldn\'t find {cardset} cardset.') + await interaction.edit_original_response( + content=f"I couldn't find {cardset} cardset." + ) return else: - all_params = [('name', this_player)] + all_params = [("name", this_player)] - all_players = await db_get('players', params=all_params) - if all_players['count'] == 0: - await interaction.edit_original_response(content='No players found') + all_players = await db_get("players", params=all_params) + if all_players["count"] == 0: + await interaction.edit_original_response(content="No players found") return - all_cards = [get_blank_team_card(x) for x in all_players['players']] - all_cards.sort(key=lambda x: x['player']['rarity']['value'], reverse=True) + all_cards = [get_blank_team_card(x) for x in all_players["players"]] + all_cards.sort(key=lambda x: x["player"]["rarity"]["value"], reverse=True) all_embeds = [] for x in all_cards: all_embeds.extend(await get_card_embeds(x, include_stats=True)) - logger.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"]}') + await interaction.edit_original_response( + content=f'# {all_players["players"][0]["p_name"]}' + ) await embed_pagination( all_embeds, interaction.channel, interaction.user, timeout=20, - start_page=0 + start_page=0, ) else: await interaction.edit_original_response(content=None, embed=all_embeds[0]) - @app_commands.command(name='update-player', description='Update a player\'s card to a specific MLB team') + @app_commands.command( + name="update-player", + description="Update a player's card to a specific MLB team", + ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - async def update_player_team(self, interaction: discord.Interaction, player_id: int): + async def update_player_team( + self, interaction: discord.Interaction, player_id: int + ): owner_team = await get_team_by_owner(interaction.user.id) if not owner_team: await interaction.response.send_message( - 'Thank you for offering to help - if you sign up for a team with /newteam I can let you post updates.', - ephemeral=True + "Thank you for offering to help - if you sign up for a team with /newteam I can let you post updates.", + ephemeral=True, ) return - if interaction.channel.name in ['paper-dynasty-chat', 'pd-news-ticker']: + if interaction.channel.name in ["paper-dynasty-chat", "pd-news-ticker"]: await interaction.response.send_message( - f'Slide on down to #pd-bot-hole to run updates - thanks!', - ephemeral=True + f"Slide on down to #pd-bot-hole to run updates - thanks!", + ephemeral=True, ) await interaction.response.defer() - this_player = await db_get('players', object_id=player_id) + this_player = await db_get("players", object_id=player_id) if not this_player: - await interaction.response.send_message(f'No clue who that is.') + await interaction.response.send_message(f"No clue who that is.") return embed = await get_card_embeds(get_blank_team_card(this_player)) @@ -523,536 +740,668 @@ class Players(commands.Cog): view = helpers.Confirm(responders=[interaction.user]) question = await interaction.channel.send( - content='Is this the player you want to update?', - view=view + content="Is this the player you want to update?", view=view ) await view.wait() if not view.value: - await question.edit(content='Okay, we\'ll leave it be.', view=None) + await question.edit(content="Okay, we'll leave it be.", view=None) return else: await question.delete() - view = SelectView([ - helpers.SelectUpdatePlayerTeam('AL', this_player, owner_team, self.bot), - helpers.SelectUpdatePlayerTeam('NL', this_player, owner_team, self.bot) - ]) + view = SelectView( + [ + helpers.SelectUpdatePlayerTeam("AL", this_player, owner_team, self.bot), + helpers.SelectUpdatePlayerTeam("NL", this_player, owner_team, self.bot), + ] + ) await interaction.channel.send(content=None, view=view) - @app_commands.command(name='record', description='Display team record against AI teams') + @app_commands.command( + name="record", description="Display team record against AI teams" + ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def record_slash_command( - self, interaction: discord.Interaction, - league: Literal['All', 'Minor League', 'Major League', 'Flashback', 'Hall of Fame'], - team_abbrev: Optional[str] = None): + self, + interaction: discord.Interaction, + league: Literal[ + "All", "Minor League", "Major League", "Flashback", "Hall of Fame" + ], + team_abbrev: Optional[str] = None, + ): ephemeral = False - if interaction.channel.name in ['paper-dynasty-chat', 'pd-news-ticker']: + if interaction.channel.name in ["paper-dynasty-chat", "pd-news-ticker"]: ephemeral = True if team_abbrev: - t_query = await db_get('teams', params=[('abbrev', team_abbrev)]) + t_query = await db_get("teams", params=[("abbrev", team_abbrev)]) else: - t_query = await db_get('teams', params=[('gm_id', interaction.user.id)]) + t_query = await db_get("teams", params=[("gm_id", interaction.user.id)]) - if t_query['count'] == 0: + if t_query["count"] == 0: await interaction.response.send_message( - f'Hmm...I can\'t find the team you looking for.', ephemeral=ephemeral + f"Hmm...I can't find the team you looking for.", ephemeral=ephemeral ) return - team = t_query['teams'][0] - current = await db_get('current') + team = t_query["teams"][0] + current = await db_get("current") await interaction.response.send_message( f'I\'m tallying the {team["lname"]} results now...', ephemeral=ephemeral ) - st_query = await db_get(f'teams/{team["id"]}/season-record', object_id=current["season"]) + st_query = await db_get( + f'teams/{team["id"]}/season-record', object_id=current["season"] + ) - minor_embed = get_record_embed(team, st_query['minor-league'], 'Minor League') - major_embed = get_record_embed(team, st_query['major-league'], 'Major League') - flashback_embed = get_record_embed(team, st_query['flashback'], 'Flashback') - hof_embed = get_record_embed(team, st_query['hall-of-fame'], 'Hall of Fame') + minor_embed = get_record_embed(team, st_query["minor-league"], "Minor League") + major_embed = get_record_embed(team, st_query["major-league"], "Major League") + flashback_embed = get_record_embed(team, st_query["flashback"], "Flashback") + hof_embed = get_record_embed(team, st_query["hall-of-fame"], "Hall of Fame") - if league == 'All': + if league == "All": start_page = 0 - elif league == 'Minor League': + elif league == "Minor League": start_page = 0 - elif league == 'Major League': + elif league == "Major League": start_page = 1 - elif league == 'Flashback': + elif league == "Flashback": start_page = 2 else: start_page = 3 - await interaction.edit_original_response(content=f'Here are the {team["lname"]} campaign records') + await interaction.edit_original_response( + content=f'Here are the {team["lname"]} campaign records' + ) await embed_pagination( [minor_embed, major_embed, flashback_embed, hof_embed], interaction.channel, interaction.user, timeout=20, - start_page=start_page + start_page=start_page, ) - @app_commands.command(name='team', description='Show team overview and rosters') + @app_commands.command(name="team", description="Show team overview and rosters") @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) @app_legal_channel() - async def team_command(self, interaction: discord.Interaction, team_abbrev: Optional[str] = None): + async def team_command( + self, interaction: discord.Interaction, team_abbrev: Optional[str] = None + ): await interaction.response.defer() if team_abbrev: - t_query = await db_get('teams', params=[('abbrev', team_abbrev)]) + t_query = await db_get("teams", params=[("abbrev", team_abbrev)]) else: - t_query = await db_get('teams', params=[('gm_id', interaction.user.id)]) + t_query = await db_get("teams", params=[("gm_id", interaction.user.id)]) - if t_query['count'] == 0: + if t_query["count"] == 0: await interaction.edit_original_response( - content=f'Hmm...I can\'t find the team you looking for.' + content=f"Hmm...I can't find the team you looking for." ) return - team = t_query['teams'][0] + team = t_query["teams"][0] embed = await team_summary_embed(team, interaction) await interaction.edit_original_response(content=None, embed=embed) - group_lookup = app_commands.Group(name='lookup', description='Search for cards or players by ID') + group_lookup = app_commands.Group( + name="lookup", description="Search for cards or players by ID" + ) - @group_lookup.command(name='card-id', description='Look up individual card by ID') + @group_lookup.command(name="card-id", description="Look up individual card by ID") @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def card_lookup_command(self, interaction: discord.Interaction, card_id: int): await interaction.response.defer() - c_query = await db_get('cards', object_id=card_id) + c_query = await db_get("cards", object_id=card_id) if c_query: - c_string = f'Card ID {card_id} is a {helpers.player_desc(c_query["player"])}' - if c_query['team'] is not None: + c_string = ( + f'Card ID {card_id} is a {helpers.player_desc(c_query["player"])}' + ) + if c_query["team"] is not None: c_string += f' owned by the {c_query["team"]["sname"]}' if c_query["pack"] is not None: - c_string += f' pulled from a {c_query["pack"]["pack_type"]["name"]} pack.' + c_string += ( + f' pulled from a {c_query["pack"]["pack_type"]["name"]} pack.' + ) else: - c_query['team'] = c_query["pack"]["team"] - c_string += f' used by the {c_query["pack"]["team"]["sname"]} in a gauntlet' + c_query["team"] = c_query["pack"]["team"] + c_string += ( + f' used by the {c_query["pack"]["team"]["sname"]} in a gauntlet' + ) await interaction.edit_original_response( - content=c_string, - embeds=await get_card_embeds(c_query) + content=c_string, embeds=await get_card_embeds(c_query) ) return - await interaction.edit_original_response(content=f'There is no card with ID {card_id}') + await interaction.edit_original_response( + content=f"There is no card with ID {card_id}" + ) - @group_lookup.command(name='player-id', description='Look up an individual player by ID') + @group_lookup.command( + name="player-id", description="Look up an individual player by ID" + ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - async def player_lookup_command(self, interaction: discord.Interaction, player_id: int): + async def player_lookup_command( + self, interaction: discord.Interaction, player_id: int + ): await interaction.response.defer() - p_query = await db_get('players', object_id=player_id) + p_query = await db_get("players", object_id=player_id) if p_query: p_card = get_blank_team_card(p_query) await interaction.edit_original_response( - content=None, - embeds=await get_card_embeds(p_card) + content=None, embeds=await get_card_embeds(p_card) ) return - await interaction.edit_original_response(content=f'There is no player with ID {player_id}.') + await interaction.edit_original_response( + content=f"There is no player with ID {player_id}." + ) - @commands.hybrid_command(name='branding-pd', help='Update your team branding') + @commands.hybrid_command(name="branding-pd", help="Update your team branding") @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def branding_command( - self, ctx, team_logo_url: str = None, color: str = None, short_name: str = None, full_name: str = None): + self, + ctx, + team_logo_url: str = None, + color: str = None, + short_name: str = None, + full_name: str = None, + ): owner_team = await get_team_by_owner(get_context_user(ctx).id) if not owner_team: - await ctx.send(f'Hmm...I don\'t see a team for you, yet. You can create one with `/newteam`!') + await ctx.send( + f"Hmm...I don't see a team for you, yet. You can create one with `/newteam`!" + ) return params = [] if team_logo_url is not None: - params.append(('logo', team_logo_url)) + params.append(("logo", team_logo_url)) if color is not None: - params.append(('color', color)) + params.append(("color", color)) if short_name is not None: - params.append(('sname', short_name)) + params.append(("sname", short_name)) if full_name is not None: - params.append(('lname', full_name)) + params.append(("lname", full_name)) if not params: - await ctx.send(f'You keep thinking on it - I can\'t make updates if you don\'t provide them.') + await ctx.send( + f"You keep thinking on it - I can't make updates if you don't provide them." + ) return - team = await db_patch('teams', object_id=owner_team['id'], params=params) + team = await db_patch("teams", object_id=owner_team["id"], params=params) embed = await team_summary_embed(team, ctx) await ctx.send(content=None, embed=embed) - @commands.hybrid_command(name='fuck', help='You know') + @commands.hybrid_command(name="fuck", help="You know") @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def fuck_command(self, ctx, gm: Member): - t_query = await db_get('teams', params=[('gm_id', gm.id)]) - if t_query['count'] == 0: - await ctx.send(f'Who?') + t_query = await db_get("teams", params=[("gm_id", gm.id)]) + if t_query["count"] == 0: + await ctx.send(f"Who?") return await ctx.send(f'{t_query["teams"][0]["sname"]} are a bunch of cuties!') - @commands.hybrid_command(name='random', help='Check out a random card') + @commands.hybrid_command(name="random", help="Check out a random card") @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def random_card_command(self, ctx: commands.Context): - p_query = await db_get('players/random', params=[('limit', 1)]) - this_player = p_query['players'][0] + p_query = await db_get("players/random", params=[("limit", 1)]) + this_player = p_query["players"][0] this_embed = await get_card_embeds( - {'player': this_player, 'team': {'lname': 'Paper Dynasty', 'logo': IMAGES['logo'], 'season': PD_SEASON}} + { + "player": this_player, + "team": { + "lname": "Paper Dynasty", + "logo": IMAGES["logo"], + "season": PD_SEASON, + }, + } ) await ctx.send(content=None, embeds=this_embed) - group_paperdex = app_commands.Group(name='paperdex', description='Check your collection counts') + group_paperdex = app_commands.Group( + name="paperdex", description="Check your collection counts" + ) - @group_paperdex.command(name='cardset', description='Check your collection of a specific cardset') + @group_paperdex.command( + name="cardset", description="Check your collection of a specific cardset" + ) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def paperdex_cardset_slash(self, interaction: discord.Interaction): team = await get_team_by_owner(interaction.user.id) if not team: - await interaction.response.send_message(f'Do you even have a team? I don\'t know you.', ephemeral=True) + await interaction.response.send_message( + f"Do you even have a team? I don't know you.", ephemeral=True + ) return view = SelectView([SelectPaperdexCardset()], timeout=15) await interaction.response.send_message( - content='You have 15 seconds to select a cardset.', + content="You have 15 seconds to select a cardset.", view=view, - ephemeral=True + ephemeral=True, ) await view.wait() await interaction.delete_original_response() - @group_paperdex.command(name='team', description='Check your collection of a specific MLB franchise') + @group_paperdex.command( + name="team", description="Check your collection of a specific MLB franchise" + ) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def paperdex_cardset_slash(self, interaction: discord.Interaction): team = await get_team_by_owner(interaction.user.id) if not team: - await interaction.response.send_message(f'Do you even have a team? I don\'t know you.', ephemeral=True) + await interaction.response.send_message( + f"Do you even have a team? I don't know you.", ephemeral=True + ) return - view = SelectView([SelectPaperdexTeam('AL'), SelectPaperdexTeam('NL')], timeout=30) + view = SelectView( + [SelectPaperdexTeam("AL"), SelectPaperdexTeam("NL")], timeout=30 + ) await interaction.response.send_message( - content='You have 30 seconds to select a team.', - view=view, - ephemeral=True + content="You have 30 seconds to select a team.", view=view, ephemeral=True ) await view.wait() await interaction.delete_original_response() - @commands.hybrid_command(name='ai-teams', help='Get list of AI teams and abbreviations') + @commands.hybrid_command( + name="ai-teams", help="Get list of AI teams and abbreviations" + ) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def ai_teams_command(self, ctx: commands.Context): - embed = get_team_embed(f'Paper Dynasty AI Teams') - embed.description = 'Teams Available for Solo Play' + embed = get_team_embed(f"Paper Dynasty AI Teams") + embed.description = "Teams Available for Solo Play" embed.add_field( - name='AL East', - value=f'BAL - Baltimore Orioles\nBOS - Boston Red Sox\nNYY - New York Yankees\nTBR - Tampa Bay Rays\nTOR - ' - f'Toronto Blue Jays' + name="AL East", + value=f"BAL - Baltimore Orioles\nBOS - Boston Red Sox\nNYY - New York Yankees\nTBR - Tampa Bay Rays\nTOR - " + f"Toronto Blue Jays", ) embed.add_field( - name='AL Central', - value=f'CLE - Cleveland Guardians\nCHW - Chicago White Sox\nDET - Detroit Tigers\nKCR - Kansas City ' - f'Royals\nMIN - Minnesota Twins' + name="AL Central", + value=f"CLE - Cleveland Guardians\nCHW - Chicago White Sox\nDET - Detroit Tigers\nKCR - Kansas City " + f"Royals\nMIN - Minnesota Twins", ) embed.add_field( - name='NL West', - value=f'HOU - Houston Astros\nLAA - Los Angeles Angels\nOAK - Oakland Athletics\nSEA - Seattle Mariners' - f'\nTEX - Texas Rangers' + name="NL West", + value=f"HOU - Houston Astros\nLAA - Los Angeles Angels\nOAK - Oakland Athletics\nSEA - Seattle Mariners" + f"\nTEX - Texas Rangers", ) embed.add_field( - name='NL East', - value=f'ATL - Atlanta Braves\nMIA - Miami Marlins\nNYM - New York Mets\nPHI - Philadelphia Phillies\n' - f'WSN - Washington Nationals' + name="NL East", + value=f"ATL - Atlanta Braves\nMIA - Miami Marlins\nNYM - New York Mets\nPHI - Philadelphia Phillies\n" + f"WSN - Washington Nationals", ) embed.add_field( - name='NL Central', - value=f'CHC - Chicago Cubs\nCIN - Cincinnati Reds\nMIL - Milwaukee Brewers\nPIT - Pittsburgh Pirates\n' - f'STL - St Louis Cardinals' + name="NL Central", + value=f"CHC - Chicago Cubs\nCIN - Cincinnati Reds\nMIL - Milwaukee Brewers\nPIT - Pittsburgh Pirates\n" + f"STL - St Louis Cardinals", ) embed.add_field( - name='NL West', - value=f'ARI - Arizona Diamondbacks\nCOL - Colorado Rockies\nLAD - Los Angeles Dodgers\nSDP - San Diego ' - f'Padres\nSFG - San Francisco Giants' + name="NL West", + value=f"ARI - Arizona Diamondbacks\nCOL - Colorado Rockies\nLAD - Los Angeles Dodgers\nSDP - San Diego " + f"Padres\nSFG - San Francisco Giants", ) await ctx.send(content=None, embed=embed) - @commands.hybrid_command(name='standings', help='Check weekly or season-long standings') + @commands.hybrid_command( + name="standings", help="Check weekly or season-long standings" + ) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) - async def standings_command(self, ctx: commands.Context, which: Literal['week', 'season']): - current = await db_get('current') - params = [('season', current['season']), ('ranked', True)] + async def standings_command( + self, ctx: commands.Context, which: Literal["week", "season"] + ): + current = await db_get("current") + params = [("season", current["season"]), ("ranked", True)] - if which == 'week': - params.append(('week', current['week'])) + if which == "week": + params.append(("week", current["week"])) - r_query = await db_get('results', params=params) - if not r_query['count']: - await ctx.send(f'There are no Ranked games on record this {"week" if which == "week" else "season"}.') + r_query = await db_get("results", params=params) + if not r_query["count"]: + await ctx.send( + f'There are no Ranked games on record this {"week" if which == "week" else "season"}.' + ) return all_records = {} - for line in r_query['results']: - home_win = True if line['home_score'] > line['away_score'] else False + for line in r_query["results"]: + home_win = True if line["home_score"] > line["away_score"] else False - if line['away_team']['id'] not in all_records: - all_records[line['away_team']['id']] = { - 'wins': 1 if not home_win else 0, - 'losses': 1 if home_win else 0, - 'points': 2 if not home_win else 1 + if line["away_team"]["id"] not in all_records: + all_records[line["away_team"]["id"]] = { + "wins": 1 if not home_win else 0, + "losses": 1 if home_win else 0, + "points": 2 if not home_win else 1, } else: - all_records[line['away_team']['id']]['wins'] += 1 if not home_win else 0 - all_records[line['away_team']['id']]['losses'] += 1 if home_win else 0 - all_records[line['away_team']['id']]['points'] += 2 if not home_win else 1 + all_records[line["away_team"]["id"]]["wins"] += 1 if not home_win else 0 + all_records[line["away_team"]["id"]]["losses"] += 1 if home_win else 0 + all_records[line["away_team"]["id"]]["points"] += ( + 2 if not home_win else 1 + ) - if line['home_team']['id'] not in all_records: - all_records[line['home_team']['id']] = { - 'wins': 1 if home_win else 0, - 'losses': 1 if not home_win else 0, - 'points': 2 if home_win else 1 + if line["home_team"]["id"] not in all_records: + all_records[line["home_team"]["id"]] = { + "wins": 1 if home_win else 0, + "losses": 1 if not home_win else 0, + "points": 2 if home_win else 1, } else: - all_records[line['home_team']['id']]['wins'] += 1 if home_win else 0 - all_records[line['home_team']['id']]['losses'] += 1 if not home_win else 0 - all_records[line['home_team']['id']]['points'] += 2 if home_win else 0 + all_records[line["home_team"]["id"]]["wins"] += 1 if home_win else 0 + all_records[line["home_team"]["id"]]["losses"] += ( + 1 if not home_win else 0 + ) + all_records[line["home_team"]["id"]]["points"] += 2 if home_win else 0 # logger.info(f'all_records:\n\n{all_records}') - sorted_records = sorted(all_records.items(), key=lambda k_v: k_v[1]['points'], reverse=True) + sorted_records = sorted( + all_records.items(), key=lambda k_v: k_v[1]["points"], reverse=True + ) # logger.info(f'sorted_records: {sorted_records}') # await ctx.send(f'sorted: {sorted_records}') embed = get_team_embed( title=f'{"Season" if which == "season" else "Week"} ' - f'{current["season"] if which == "season" else current["week"]} Standings' + f'{current["season"] if which == "season" else current["week"]} Standings' ) - chunk_string = '' + chunk_string = "" for index, record in enumerate(sorted_records): # logger.info(f'index: {index} / record: {record}') - team = await db_get('teams', object_id=record[0]) + team = await db_get("teams", object_id=record[0]) if team: - 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' + 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: - logger.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( - name=f'Group {math.ceil((index + 1) / 20)} / ' - f'{math.ceil(len(sorted_records) / 20)}', - value=chunk_string + name=f"Group {math.ceil((index + 1) / 20)} / " + f"{math.ceil(len(sorted_records) / 20)}", + value=chunk_string, ) elif (index + 1) % 20 == 0: embed.add_field( - name=f'Group {math.ceil((index + 1) / 20)} / ' - f'{math.floor(len(sorted_records) / 20)}', - value=chunk_string + name=f"Group {math.ceil((index + 1) / 20)} / " + f"{math.floor(len(sorted_records) / 20)}", + value=chunk_string, ) await ctx.send(content=None, embed=embed) - @commands.hybrid_command(name='pullroster', help='Pull saved rosters from your team Sheet', - aliases=['roster', 'rosters', 'pullrosters']) + @commands.hybrid_command( + name="pullroster", + help="Pull saved rosters from your team Sheet", + aliases=["roster", "rosters", "pullrosters"], + ) @app_commands.describe( - specific_roster_num='Enter 1, 2, or 3 to only pull one roster; leave blank to pull all 3', + specific_roster_num="Enter 1, 2, or 3 to only pull one roster; leave blank to pull all 3", ) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) - async def pull_roster_command(self, ctx: commands.Context, specific_roster_num: Optional[int] = None): + async def pull_roster_command( + self, ctx: commands.Context, specific_roster_num: Optional[int] = None + ): team = await get_team_by_owner(get_context_user(ctx).id) if not team: - await ctx.send(f'Do you even have a team? I don\'t know you.') + await ctx.send(f"Do you even have a team? I don't know you.") return # Pull data from Sheets async with ctx.typing(): roster_data = get_rosters(team, self.bot) - logger.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): - logger.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', + "rosters", payload={ - 'team_id': team['id'], 'name': roster['name'], - 'roster_num': roster['roster_num'], 'card_ids': roster['cards'] - } + "team_id": team["id"], + "name": roster["name"], + "roster_num": roster["roster_num"], + "card_ids": roster["cards"], + }, ) await ctx.send(random_conf_gif()) - group_gauntlet = app_commands.Group(name='gauntlets', description='Check your progress or start a new Gauntlet') + group_gauntlet = app_commands.Group( + name="gauntlets", description="Check your progress or start a new Gauntlet" + ) - @group_gauntlet.command(name='status', description='View status of current Gauntlet run') + @group_gauntlet.command( + name="status", description="View status of current Gauntlet run" + ) @app_commands.describe( - team_abbrev='To check the status of a team\'s active run, enter their abbreviation' + team_abbrev="To check the status of a team's active run, enter their abbreviation" ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_run_command( - self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL, # type: ignore - team_abbrev: str = None): + self, + interaction: discord.Interaction, + event_name: ACTIVE_EVENT_LITERAL, # type: ignore + team_abbrev: str = None, + ): await interaction.response.defer() - e_query = await db_get('events', params=[("name", event_name), ("active", True)]) - if e_query['count'] == 0: - await interaction.edit_original_response(content=f'Hmm...looks like that event is inactive.') + e_query = await db_get( + "events", params=[("name", event_name), ("active", True)] + ) + if e_query["count"] == 0: + await interaction.edit_original_response( + content=f"Hmm...looks like that event is inactive." + ) return else: - this_event = e_query['events'][0] + this_event = e_query["events"][0] this_run, this_team = None, None if team_abbrev: - if 'Gauntlet-' not in team_abbrev: - team_abbrev = f'Gauntlet-{team_abbrev}' - t_query = await db_get('teams', params=[('abbrev', team_abbrev)]) - if t_query['count'] != 0: - this_team = t_query['teams'][0] - r_query = await db_get('gauntletruns', params=[ - ('team_id', this_team['id']), ('is_active', True), ('gauntlet_id', this_event['id']) - ]) + if "Gauntlet-" not in team_abbrev: + team_abbrev = f"Gauntlet-{team_abbrev}" + t_query = await db_get("teams", params=[("abbrev", team_abbrev)]) + if t_query["count"] != 0: + this_team = t_query["teams"][0] + r_query = await db_get( + "gauntletruns", + params=[ + ("team_id", this_team["id"]), + ("is_active", True), + ("gauntlet_id", this_event["id"]), + ], + ) - if r_query['count'] != 0: - this_run = r_query['runs'][0] + if r_query["count"] != 0: + this_run = r_query["runs"][0] else: await interaction.channel.send( content=f'I do not see an active run for the {this_team["lname"]}.' ) else: await interaction.channel.send( - content=f'I do not see an active run for {team_abbrev.upper()}.' + content=f"I do not see an active run for {team_abbrev.upper()}." ) await interaction.edit_original_response( content=None, - embed=await gauntlets.get_embed(this_run, this_event, this_team) + embed=await gauntlets.get_embed(this_run, this_event, this_team), ) - @group_gauntlet.command(name='start', description='Start a new Gauntlet run') + @group_gauntlet.command(name="start", description="Start a new Gauntlet run") @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - async def gauntlet_start_command( - self, interaction: discord.Interaction): - if 'hello' not in interaction.channel.name: + async def gauntlet_start_command(self, interaction: discord.Interaction): + if "hello" not in interaction.channel.name: await interaction.response.send_message( - content='The draft will probably take you about 15 minutes. Why don\'t you head to your private ' - 'channel to run the draft?', - ephemeral=True + content="The draft will probably take you about 15 minutes. Why don't you head to your private " + "channel to run the draft?", + ephemeral=True, ) return - logger.info(f'Starting a gauntlet run for user {interaction.user.name}') + logger.info(f"Starting a gauntlet run for user {interaction.user.name}") await interaction.response.defer() with Session(engine) as session: - main_team = await get_team_or_none(session, gm_id=interaction.user.id, main_team=True) - draft_team = await get_team_or_none(session, gm_id=interaction.user.id, gauntlet_team=True) + main_team = await get_team_or_none( + session, gm_id=interaction.user.id, main_team=True + ) + draft_team = await get_team_or_none( + session, gm_id=interaction.user.id, gauntlet_team=True + ) - e_query = await db_get('events', params=[("active", True)]) - if e_query['count'] == 0: - await interaction.edit_original_response(content='Hmm...I don\'t see any active events.') + e_query = await db_get("events", params=[("active", True)]) + if e_query["count"] == 0: + await interaction.edit_original_response( + content="Hmm...I don't see any active events." + ) return - elif e_query['count'] == 1: - this_event = e_query['events'][0] + elif e_query["count"] == 1: + this_event = e_query["events"][0] else: event_choice = await ask_with_buttons( interaction, - button_options=[x['name'] for x in e_query['events']], - question='Which event would you like to take on?', + button_options=[x["name"] for x in e_query["events"]], + question="Which event would you like to take on?", # edit_original_interaction=True, timeout=3, - delete_question=False + delete_question=False, ) - this_event = [event for event in e_query['events'] if event['name'] == event_choice][0] + this_event = [ + event + for event in e_query["events"] + if event["name"] == event_choice + ][0] # await interaction.channel.send( # content=f'You chose the {event_choice} event!' # ) - logger.info(f'this_event: {this_event}') + logger.info(f"this_event: {this_event}") first_flag = draft_team is None if draft_team is not None: r_query = await db_get( - 'gauntletruns', - params=[('team_id', draft_team.id), ('gauntlet_id', this_event['id']), ('is_active', True)] + "gauntletruns", + params=[ + ("team_id", draft_team.id), + ("gauntlet_id", this_event["id"]), + ("is_active", True), + ], ) - if r_query['count'] != 0: + if r_query["count"] != 0: await interaction.edit_original_response( content=f'Looks like you already have a {r_query["runs"][0]["gauntlet"]["name"]} run active! ' - f'You can check it out with the `/gauntlets status` command.' + f"You can check it out with the `/gauntlets status` command." ) return try: - draft_embed = await gauntlets.run_draft(interaction, main_team, this_event, draft_team) + draft_embed = await gauntlets.run_draft( + interaction, main_team, this_event, draft_team + ) except ZeroDivisionError as e: - return - except Exception as e: - logger.error(f'Failed to run {this_event["name"]} draft for the {main_team.sname}: {e}') + logger.error( + f'ZeroDivisionError in {this_event["name"]} draft for the {main_team.sname}: {e}' + ) await gauntlets.wipe_team(draft_team, interaction) await interaction.channel.send( - content=f'Shoot - it looks like we ran into an issue running the draft. I had to clear it all out ' - f'for now. I let {get_cal_user(interaction).mention} know what happened so he better ' - f'fix it quick.' + content=f"Shoot - it looks like we ran into an issue running the draft. I had to clear it all out " + f"for now. I let {get_cal_user(interaction).mention} know what happened so he better " + f"fix it quick." + ) + return + except Exception as e: + logger.error( + f'Failed to run {this_event["name"]} draft for the {main_team.sname}: {e}' + ) + await gauntlets.wipe_team(draft_team, interaction) + await interaction.channel.send( + content=f"Shoot - it looks like we ran into an issue running the draft. I had to clear it all out " + f"for now. I let {get_cal_user(interaction).mention} know what happened so he better " + f"fix it quick." ) return if first_flag: await interaction.channel.send( - f'Good luck, champ in the making! To start playing, follow these steps:\n\n' - f'1) Make a copy of the Team Sheet Template found in `/help-pd links`\n' - f'2) Run `/newsheet` to link it to your Gauntlet team\n' + f"Good luck, champ in the making! To start playing, follow these steps:\n\n" + f"1) Make a copy of the Team Sheet Template found in `/help-pd links`\n" + f"2) Run `/newsheet` to link it to your Gauntlet team\n" f'3) Go play your first game with `/new-game gauntlet {this_event["name"]}`' ) else: await interaction.channel.send( - f'Good luck, champ in the making! In your team sheet, sync your cards with **Paper Dynasty** -> ' - f'**Data Imports** -> **My Cards** then you can set your lineup here and you\'ll be ready to go!\n\n' - f'{get_roster_sheet(draft_team)}' + f"Good luck, champ in the making! In your team sheet, sync your cards with **Paper Dynasty** -> " + f"**Data Imports** -> **My Cards** then you can set your lineup here and you'll be ready to go!\n\n" + f"{get_roster_sheet(draft_team)}" ) await helpers.send_to_channel( bot=self.bot, - channel_name='pd-news-ticker', + channel_name="pd-news-ticker", content=f'The {main_team.lname} have entered the {this_event["name"]} Gauntlet!', - embed=draft_embed + embed=draft_embed, ) - @group_gauntlet.command(name='reset', description='Wipe your current team so you can re-draft') + @group_gauntlet.command( + name="reset", description="Wipe your current team so you can re-draft" + ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_reset_command( - self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL): # type: ignore + self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL + ): # type: ignore await interaction.response.defer() main_team = await get_team_by_owner(interaction.user.id) draft_team = await get_team_by_abbrev(f'Gauntlet-{main_team["abbrev"]}') if draft_team is None: await interaction.edit_original_response( - content='Hmm, I can\'t find a gauntlet team for you. Have you signed up already?') + content="Hmm, I can't find a gauntlet team for you. Have you signed up already?" + ) return - e_query = await db_get('events', params=[("name", event_name), ("active", True)]) - if e_query['count'] == 0: - await interaction.edit_original_response(content='Hmm...looks like that event is inactive.') + e_query = await db_get( + "events", params=[("name", event_name), ("active", True)] + ) + if e_query["count"] == 0: + await interaction.edit_original_response( + content="Hmm...looks like that event is inactive." + ) return else: - this_event = e_query['events'][0] + this_event = e_query["events"][0] - r_query = await db_get('gauntletruns', params=[ - ('team_id', draft_team['id']), ('is_active', True), ('gauntlet_id', this_event['id']) - ]) + r_query = await db_get( + "gauntletruns", + params=[ + ("team_id", draft_team["id"]), + ("is_active", True), + ("gauntlet_id", this_event["id"]), + ], + ) - if r_query['count'] != 0: - this_run = r_query['runs'][0] + if r_query["count"] != 0: + this_run = r_query["runs"][0] else: await interaction.edit_original_response( content=f'I do not see an active run for the {draft_team["lname"]}.' @@ -1060,27 +1409,23 @@ class Players(commands.Cog): return view = helpers.Confirm(responders=[interaction.user], timeout=60) - conf_string = f'Are you sure you want to wipe your active run?' - await interaction.edit_original_response( - content=conf_string, - view=view - ) + conf_string = f"Are you sure you want to wipe your active run?" + await interaction.edit_original_response(content=conf_string, view=view) await view.wait() if view.value: await gauntlets.end_run(this_run, this_event, draft_team, force_end=True) await interaction.edit_original_response( - content=f'Your {event_name} run has been reset. Run `/gauntlets start {event_name}` to redraft!', - view=None + content=f"Your {event_name} run has been reset. Run `/gauntlets start {event_name}` to redraft!", + view=None, ) else: await interaction.edit_original_response( - content=f'~~{conf_string}~~\n\nNo worries, I will leave it active.', - view=None + content=f"~~{conf_string}~~\n\nNo worries, I will leave it active.", + view=None, ) - # @commands.command(name='standings', aliases=['leaders', 'points', 'weekly'], help='Weekly standings') # async def standings_command(self, ctx, *week_or_season): # if not await legal_channel(ctx): @@ -1104,17 +1449,25 @@ class Players(commands.Cog): # for embed in all_embeds: # await ctx.send(content=None, embed=embed) - @commands.command(name='in', help='Get Paper Dynasty Players role') + @commands.command(name="in", help="Get Paper Dynasty Players role") async def give_role(self, ctx, *args): - await ctx.author.add_roles(discord.utils.get(ctx.guild.roles, name='Paper Dynasty Players')) - await ctx.send('I got u, boo. ;)\n\nNow that you\'ve got the PD role, you can run all of the Paper Dynasty ' - 'bot commands. For help, check out `/help-pd`') + await ctx.author.add_roles( + discord.utils.get(ctx.guild.roles, name="Paper Dynasty Players") + ) + await ctx.send( + "I got u, boo. ;)\n\nNow that you've got the PD role, you can run all of the Paper Dynasty " + "bot commands. For help, check out `/help-pd`" + ) - @commands.command(name='out', help='Remove Paper Dynasty Players role') - @commands.has_any_role('Paper Dynasty Players') + @commands.command(name="out", help="Remove Paper Dynasty Players role") + @commands.has_any_role("Paper Dynasty Players") async def take_role(self, ctx, *args): - await ctx.author.remove_roles(discord.utils.get(ctx.guild.roles, name='Paper Dynasty Players')) - await ctx.send('Oh no! I\'m so sad to see you go! What are we going to do without you?') + await ctx.author.remove_roles( + discord.utils.get(ctx.guild.roles, name="Paper Dynasty Players") + ) + await ctx.send( + "Oh no! I'm so sad to see you go! What are we going to do without you?" + ) # @commands.command(name='teams', help='List all teams') # @commands.has_any_role('Paper Dynasty Players') @@ -1617,7 +1970,7 @@ class Players(commands.Cog): # all_embeds[x].add_field(name='Abbrev - Name - GM', value=team_strings[x], inline=False) # await ctx.send(content=None, embed=all_embeds[x]) - @commands.command(name='c', aliases=['chaos', 'choas'], help='c, chaos, or choas') + @commands.command(name="c", aliases=["chaos", "choas"], help="c, chaos, or choas") async def chaos_roll(self, ctx): """ Have the pitcher check for chaos with a runner on base. @@ -1627,35 +1980,37 @@ class Players(commands.Cog): flag = None if d_twenty == 1: - flag = 'wild pitch' + flag = "wild pitch" elif d_twenty == 2: if random.randint(1, 2) == 1: - flag = 'balk' + flag = "balk" else: - flag = 'passed ball' + flag = "passed ball" if not flag: - roll_message = f'Chaos roll for {ctx.author.name}\n```md\nNo Chaos```' + roll_message = f"Chaos roll for {ctx.author.name}\n```md\nNo Chaos```" else: - roll_message = f'Chaos roll for {ctx.author.name}\n```md\nCheck {flag}```\n'\ - f'{flag.title()} roll```md\n# {d_twenty_two}\nDetails: [1d20 ({d_twenty_two})]```' + roll_message = ( + f"Chaos roll for {ctx.author.name}\n```md\nCheck {flag}```\n" + f"{flag.title()} roll```md\n# {d_twenty_two}\nDetails: [1d20 ({d_twenty_two})]```" + ) await ctx.send(roll_message) - @commands.command(name='sba', hidden=True) + @commands.command(name="sba", hidden=True) async def sba_command(self, ctx, *, player_name): async def get_one_player(id_or_name): - req_url = f'http://database/api/v1/players/{id_or_name}' + req_url = f"http://database/api/v1/players/{id_or_name}" resp = requests.get(req_url, timeout=3) if resp.status_code == 200: return resp.json() else: logger.warning(resp.text) - raise ValueError(f'DB: {resp.text}') + raise ValueError(f"DB: {resp.text}") this_player = await get_one_player(player_name) - logger.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( diff --git a/cogs/players_new/gauntlet.py b/cogs/players_new/gauntlet.py index 1889c83..4f06911 100644 --- a/cogs/players_new/gauntlet.py +++ b/cogs/players_new/gauntlet.py @@ -12,65 +12,89 @@ import datetime from sqlmodel import Session from api_calls import db_get, db_post, db_patch, db_delete, get_team_by_abbrev from helpers import ( - ACTIVE_EVENT_LITERAL, PD_PLAYERS_ROLE_NAME, get_team_embed, get_team_by_owner, - legal_channel, Confirm, send_to_channel + ACTIVE_EVENT_LITERAL, + PD_PLAYERS_ROLE_NAME, + get_team_embed, + get_team_by_owner, + legal_channel, + Confirm, + send_to_channel, ) from helpers.utils import get_roster_sheet, get_cal_user from utilities.buttons import ask_with_buttons from in_game.gameplay_models import engine from in_game.gameplay_queries import get_team_or_none -logger = logging.getLogger('discord_app') +logger = logging.getLogger("discord_app") # Try to import gauntlets module, provide fallback if not available try: import gauntlets + GAUNTLETS_AVAILABLE = True except ImportError: - logger.warning("Gauntlets module not available - gauntlet commands will have limited functionality") + logger.warning( + "Gauntlets module not available - gauntlet commands will have limited functionality" + ) GAUNTLETS_AVAILABLE = False gauntlets = None class Gauntlet(commands.Cog): """Gauntlet game mode functionality for Paper Dynasty.""" - + def __init__(self, bot): self.bot = bot - group_gauntlet = app_commands.Group(name='gauntlets', description='Check your progress or start a new Gauntlet') + group_gauntlet = app_commands.Group( + name="gauntlets", description="Check your progress or start a new Gauntlet" + ) - @group_gauntlet.command(name='status', description='View status of current Gauntlet run') + @group_gauntlet.command( + name="status", description="View status of current Gauntlet run" + ) @app_commands.describe( - team_abbrev='To check the status of a team\'s active run, enter their abbreviation' + team_abbrev="To check the status of a team's active run, enter their abbreviation" ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_run_command( - self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL, # type: ignore - team_abbrev: Optional[str] = None): + self, + interaction: discord.Interaction, + event_name: ACTIVE_EVENT_LITERAL, # type: ignore + team_abbrev: Optional[str] = None, + ): """View status of current gauntlet run - corrected to match original business logic.""" await interaction.response.defer() - e_query = await db_get('events', params=[("name", event_name), ("active", True)]) - if not e_query or e_query.get('count', 0) == 0: - await interaction.edit_original_response(content=f'Hmm...looks like that event is inactive.') + e_query = await db_get( + "events", params=[("name", event_name), ("active", True)] + ) + if not e_query or e_query.get("count", 0) == 0: + await interaction.edit_original_response( + content=f"Hmm...looks like that event is inactive." + ) return else: - this_event = e_query['events'][0] + this_event = e_query["events"][0] this_run, this_team = None, None if team_abbrev: - if 'Gauntlet-' not in team_abbrev: - team_abbrev = f'Gauntlet-{team_abbrev}' - t_query = await db_get('teams', params=[('abbrev', team_abbrev)]) - if t_query and t_query.get('count', 0) != 0: - this_team = t_query['teams'][0] - r_query = await db_get('gauntletruns', params=[ - ('team_id', this_team['id']), ('is_active', True), ('gauntlet_id', this_event['id']) - ]) + if "Gauntlet-" not in team_abbrev: + team_abbrev = f"Gauntlet-{team_abbrev}" + t_query = await db_get("teams", params=[("abbrev", team_abbrev)]) + if t_query and t_query.get("count", 0) != 0: + this_team = t_query["teams"][0] + r_query = await db_get( + "gauntletruns", + params=[ + ("team_id", this_team["id"]), + ("is_active", True), + ("gauntlet_id", this_event["id"]), + ], + ) - if r_query and r_query.get('count', 0) != 0: - this_run = r_query['runs'][0] + if r_query and r_query.get("count", 0) != 0: + this_run = r_query["runs"][0] else: await interaction.edit_original_response( content=f'I do not see an active run for the {this_team["lname"]}.' @@ -78,7 +102,7 @@ class Gauntlet(commands.Cog): return else: await interaction.edit_original_response( - content=f'I do not see an active run for {team_abbrev.upper()}.' + content=f"I do not see an active run for {team_abbrev.upper()}." ) return @@ -86,127 +110,168 @@ class Gauntlet(commands.Cog): if GAUNTLETS_AVAILABLE and gauntlets: await interaction.edit_original_response( content=None, - embed=await gauntlets.get_embed(this_run, this_event, this_team) # type: ignore + embed=await gauntlets.get_embed(this_run, this_event, this_team), # type: ignore ) else: await interaction.edit_original_response( - content='Gauntlet status unavailable - gauntlets module not loaded.' + content="Gauntlet status unavailable - gauntlets module not loaded." ) - @group_gauntlet.command(name='start', description='Start a new Gauntlet run') + @group_gauntlet.command(name="start", description="Start a new Gauntlet run") @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_start_command(self, interaction: discord.Interaction): """Start a new gauntlet run.""" - + # Channel restriction - must be in a 'hello' channel (private channel) - if interaction.channel and hasattr(interaction.channel, 'name') and 'hello' not in str(interaction.channel.name): + if ( + interaction.channel + and hasattr(interaction.channel, "name") + and "hello" not in str(interaction.channel.name) + ): await interaction.response.send_message( - content='The draft will probably take you about 15 minutes. Why don\'t you head to your private ' - 'channel to run the draft?', - ephemeral=True + content="The draft will probably take you about 15 minutes. Why don't you head to your private " + "channel to run the draft?", + ephemeral=True, ) return - logger.info(f'Starting a gauntlet run for user {interaction.user.name}') + logger.info(f"Starting a gauntlet run for user {interaction.user.name}") await interaction.response.defer() with Session(engine) as session: - main_team = await get_team_or_none(session, gm_id=interaction.user.id, main_team=True) - draft_team = await get_team_or_none(session, gm_id=interaction.user.id, gauntlet_team=True) + main_team = await get_team_or_none( + session, gm_id=interaction.user.id, main_team=True + ) + draft_team = await get_team_or_none( + session, gm_id=interaction.user.id, gauntlet_team=True + ) # Get active events - e_query = await db_get('events', params=[("active", True)]) - if not e_query or e_query.get('count', 0) == 0: - await interaction.edit_original_response(content='Hmm...I don\'t see any active events.') + e_query = await db_get("events", params=[("active", True)]) + if not e_query or e_query.get("count", 0) == 0: + await interaction.edit_original_response( + content="Hmm...I don't see any active events." + ) return - elif e_query.get('count', 0) == 1: - this_event = e_query['events'][0] + elif e_query.get("count", 0) == 1: + this_event = e_query["events"][0] else: event_choice = await ask_with_buttons( interaction, - button_options=[x['name'] for x in e_query['events']], - question='Which event would you like to take on?', + button_options=[x["name"] for x in e_query["events"]], + question="Which event would you like to take on?", timeout=3, - delete_question=False + delete_question=False, ) - this_event = [event for event in e_query['events'] if event['name'] == event_choice][0] - - logger.info(f'this_event: {this_event}') + this_event = [ + event + for event in e_query["events"] + if event["name"] == event_choice + ][0] + + logger.info(f"this_event: {this_event}") first_flag = draft_team is None if draft_team is not None: r_query = await db_get( - 'gauntletruns', - params=[('team_id', draft_team.id), ('gauntlet_id', this_event['id']), ('is_active', True)] + "gauntletruns", + params=[ + ("team_id", draft_team.id), + ("gauntlet_id", this_event["id"]), + ("is_active", True), + ], ) - if r_query and r_query.get('count', 0) != 0: + if r_query and r_query.get("count", 0) != 0: await interaction.edit_original_response( content=f'Looks like you already have a {r_query["runs"][0]["gauntlet"]["name"]} run active! ' - f'You can check it out with the `/gauntlets status` command.' + f"You can check it out with the `/gauntlets status` command." ) return try: - draft_embed = await gauntlets.run_draft(interaction, main_team, this_event, draft_team) # type: ignore + draft_embed = await gauntlets.run_draft(interaction, main_team, this_event, draft_team) # type: ignore except ZeroDivisionError as e: + logger.error( + f'ZeroDivisionError in {this_event["name"]} draft for the {main_team.sname if main_team else "unknown"}: {e}' + ) + await gauntlets.wipe_team(draft_team, interaction) # type: ignore + await interaction.followup.send( + content=f"Shoot - it looks like we ran into an issue running the draft. I had to clear it all out " + f"for now. I let {get_cal_user(interaction).mention} know what happened so he better " + f"fix it quick." + ) return except Exception as e: - logger.error(f'Failed to run {this_event["name"]} draft for the {main_team.sname if main_team else "unknown"}: {e}') - await gauntlets.wipe_team(draft_team, interaction) # type: ignore + logger.error( + f'Failed to run {this_event["name"]} draft for the {main_team.sname if main_team else "unknown"}: {e}' + ) + await gauntlets.wipe_team(draft_team, interaction) # type: ignore await interaction.followup.send( - content=f'Shoot - it looks like we ran into an issue running the draft. I had to clear it all out ' - f'for now. I let {get_cal_user(interaction).mention} know what happened so he better ' - f'fix it quick.' + content=f"Shoot - it looks like we ran into an issue running the draft. I had to clear it all out " + f"for now. I let {get_cal_user(interaction).mention} know what happened so he better " + f"fix it quick." ) return if first_flag: await interaction.followup.send( - f'Good luck, champ in the making! To start playing, follow these steps:\n\n' - f'1) Make a copy of the Team Sheet Template found in `/help-pd links`\n' - f'2) Run `/newsheet` to link it to your Gauntlet team\n' + f"Good luck, champ in the making! To start playing, follow these steps:\n\n" + f"1) Make a copy of the Team Sheet Template found in `/help-pd links`\n" + f"2) Run `/newsheet` to link it to your Gauntlet team\n" f'3) Go play your first game with `/new-game gauntlet {this_event["name"]}`' ) else: await interaction.followup.send( - f'Good luck, champ in the making! In your team sheet, sync your cards with **Paper Dynasty** -> ' - f'**Data Imports** -> **My Cards** then you can set your lineup here and you\'ll be ready to go!\n\n' - f'{get_roster_sheet(draft_team)}' + f"Good luck, champ in the making! In your team sheet, sync your cards with **Paper Dynasty** -> " + f"**Data Imports** -> **My Cards** then you can set your lineup here and you'll be ready to go!\n\n" + f"{get_roster_sheet(draft_team)}" ) await send_to_channel( bot=self.bot, - channel_name='pd-news-ticker', + channel_name="pd-news-ticker", content=f'The {main_team.lname if main_team else "Unknown Team"} have entered the {this_event["name"]} Gauntlet!', - embed=draft_embed + embed=draft_embed, ) - @group_gauntlet.command(name='reset', description='Wipe your current team so you can re-draft') + @group_gauntlet.command( + name="reset", description="Wipe your current team so you can re-draft" + ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) - async def gauntlet_reset_command(self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL): # type: ignore + async def gauntlet_reset_command(self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL): # type: ignore """Reset current gauntlet run.""" await interaction.response.defer() main_team = await get_team_by_owner(interaction.user.id) draft_team = await get_team_by_abbrev(f'Gauntlet-{main_team["abbrev"]}') if draft_team is None: await interaction.edit_original_response( - content='Hmm, I can\'t find a gauntlet team for you. Have you signed up already?') + content="Hmm, I can't find a gauntlet team for you. Have you signed up already?" + ) return - e_query = await db_get('events', params=[("name", event_name), ("active", True)]) - if e_query['count'] == 0: - await interaction.edit_original_response(content='Hmm...looks like that event is inactive.') + e_query = await db_get( + "events", params=[("name", event_name), ("active", True)] + ) + if e_query["count"] == 0: + await interaction.edit_original_response( + content="Hmm...looks like that event is inactive." + ) return else: - this_event = e_query['events'][0] + this_event = e_query["events"][0] - r_query = await db_get('gauntletruns', params=[ - ('team_id', draft_team['id']), ('is_active', True), ('gauntlet_id', this_event['id']) - ]) + r_query = await db_get( + "gauntletruns", + params=[ + ("team_id", draft_team["id"]), + ("is_active", True), + ("gauntlet_id", this_event["id"]), + ], + ) - if r_query and r_query.get('count', 0) != 0: - this_run = r_query['runs'][0] + if r_query and r_query.get("count", 0) != 0: + this_run = r_query["runs"][0] else: await interaction.edit_original_response( content=f'I do not see an active run for the {draft_team["lname"]}.' @@ -214,27 +279,24 @@ class Gauntlet(commands.Cog): return view = Confirm(responders=[interaction.user], timeout=60) - conf_string = f'Are you sure you want to wipe your active run?' - await interaction.edit_original_response( - content=conf_string, - view=view - ) + conf_string = f"Are you sure you want to wipe your active run?" + await interaction.edit_original_response(content=conf_string, view=view) await view.wait() if view.value: - await gauntlets.end_run(this_run, this_event, draft_team, force_end=True) # type: ignore + await gauntlets.end_run(this_run, this_event, draft_team, force_end=True) # type: ignore await interaction.edit_original_response( - content=f'Your {event_name} run has been reset. Run `/gauntlets start` to redraft!', - view=None + content=f"Your {event_name} run has been reset. Run `/gauntlets start` to redraft!", + view=None, ) else: await interaction.edit_original_response( - content=f'~~{conf_string}~~\n\nNo worries, I will leave it active.', - view=None + content=f"~~{conf_string}~~\n\nNo worries, I will leave it active.", + view=None, ) async def setup(bot): """Setup function for the Gauntlet cog.""" - await bot.add_cog(Gauntlet(bot)) \ No newline at end of file + await bot.add_cog(Gauntlet(bot)) diff --git a/command_logic/logic_gameplay.py b/command_logic/logic_gameplay.py index 55f2532..0144133 100644 --- a/command_logic/logic_gameplay.py +++ b/command_logic/logic_gameplay.py @@ -4295,12 +4295,14 @@ async def complete_game( else this_game.away_team ) + db_game = None 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"]) + if db_game is not None: + await roll_back(db_game["id"]) log_exception(e, msg="Unable to post game to API, rolling back") # Post game stats to API diff --git a/discord_utils.py b/discord_utils.py index 3f9c2d5..5db691e 100644 --- a/discord_utils.py +++ b/discord_utils.py @@ -4,6 +4,7 @@ Discord Utilities This module contains Discord helper functions for channels, roles, embeds, and other Discord-specific operations. """ + import logging import os import asyncio @@ -13,19 +14,21 @@ import discord from discord.ext import commands from helpers.constants import SBA_COLOR, PD_SEASON, IMAGES -logger = logging.getLogger('discord_app') +logger = logging.getLogger("discord_app") async def send_to_bothole(ctx, content, embed): """Send a message to the pd-bot-hole channel.""" - await discord.utils.get(ctx.guild.text_channels, name='pd-bot-hole') \ - .send(content=content, embed=embed) + await discord.utils.get(ctx.guild.text_channels, name="pd-bot-hole").send( + content=content, embed=embed + ) async def send_to_news(ctx, content, embed): """Send a message to the pd-news-ticker channel.""" - await discord.utils.get(ctx.guild.text_channels, name='pd-news-ticker') \ - .send(content=content, embed=embed) + await discord.utils.get(ctx.guild.text_channels, name="pd-news-ticker").send( + content=content, embed=embed + ) async def typing_pause(ctx, seconds=1): @@ -43,23 +46,20 @@ async def pause_then_type(ctx, message): async def check_if_pdhole(ctx): """Check if the current channel is pd-bot-hole.""" - if ctx.message.channel.name != 'pd-bot-hole': - await ctx.send('Slide on down to my bot-hole for running commands.') - await ctx.message.add_reaction('❌') + if ctx.message.channel.name != "pd-bot-hole": + await ctx.send("Slide on down to my bot-hole for running commands.") + await ctx.message.add_reaction("❌") return False return True async def bad_channel(ctx): """Check if current channel is in the list of bad channels for commands.""" - bad_channels = ['paper-dynasty-chat', 'pd-news-ticker'] + bad_channels = ["paper-dynasty-chat", "pd-news-ticker"] if ctx.message.channel.name in bad_channels: - await ctx.message.add_reaction('❌') - bot_hole = discord.utils.get( - ctx.guild.text_channels, - name=f'pd-bot-hole' - ) - await ctx.send(f'Slide on down to the {bot_hole.mention} ;)') + await ctx.message.add_reaction("❌") + bot_hole = discord.utils.get(ctx.guild.text_channels, name=f"pd-bot-hole") + await ctx.send(f"Slide on down to the {bot_hole.mention} ;)") return True else: return False @@ -68,14 +68,11 @@ async def bad_channel(ctx): def get_channel(ctx, name) -> Optional[discord.TextChannel]: """Get a text channel by name.""" # Handle both Context and Interaction objects - guild = ctx.guild if hasattr(ctx, 'guild') else None + guild = ctx.guild if hasattr(ctx, "guild") else None if not guild: return None - - channel = discord.utils.get( - guild.text_channels, - name=name - ) + + channel = discord.utils.get(guild.text_channels, name=name) if channel: return channel return None @@ -87,7 +84,7 @@ async def get_emoji(ctx, name, return_empty=True): emoji = await commands.converter.EmojiConverter().convert(ctx, name) except: if return_empty: - emoji = '' + emoji = "" else: return name return emoji @@ -101,9 +98,13 @@ async def react_and_reply(ctx, reaction, message): async def send_to_channel(bot, channel_name, content=None, embed=None): """Send a message to a specific channel by name or ID.""" - guild = bot.get_guild(int(os.environ.get('GUILD_ID'))) + guild_id = os.environ.get("GUILD_ID") + if not guild_id: + logger.error("GUILD_ID env var is not set") + return + guild = bot.get_guild(int(guild_id)) if not guild: - logger.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) @@ -111,7 +112,7 @@ async def send_to_channel(bot, channel_name, content=None, embed=None): if not this_channel: this_channel = discord.utils.get(guild.text_channels, id=channel_name) if not this_channel: - raise NameError(f'**{channel_name}** channel not found') + raise NameError(f"**{channel_name}** channel not found") return await this_channel.send(content=content, embed=embed) @@ -128,14 +129,16 @@ async def get_or_create_role(ctx, role_name, mentionable=True): def get_special_embed(special): """Create an embed for a special item.""" - embed = discord.Embed(title=f'{special.name} - Special #{special.get_id()}', - color=discord.Color.random(), - description=f'{special.short_desc}') - embed.add_field(name='Description', value=f'{special.long_desc}', inline=False) - if special.thumbnail.lower() != 'none': - embed.set_thumbnail(url=f'{special.thumbnail}') - if special.url.lower() != 'none': - embed.set_image(url=f'{special.url}') + embed = discord.Embed( + title=f"{special.name} - Special #{special.get_id()}", + color=discord.Color.random(), + description=f"{special.short_desc}", + ) + embed.add_field(name="Description", value=f"{special.long_desc}", inline=False) + if special.thumbnail.lower() != "none": + embed.set_thumbnail(url=f"{special.thumbnail}") + if special.url.lower() != "none": + embed.set_image(url=f"{special.url}") return embed @@ -154,99 +157,125 @@ def get_team_embed(title, team=None, thumbnail: bool = True): if team: embed = discord.Embed( title=title, - color=int(team["color"], 16) if team["color"] else int(SBA_COLOR, 16) + color=int(team["color"], 16) if team["color"] else int(SBA_COLOR, 16), + ) + embed.set_footer( + text=f'Paper Dynasty Season {team["season"]}', icon_url=IMAGES["logo"] ) - embed.set_footer(text=f'Paper Dynasty Season {team["season"]}', icon_url=IMAGES['logo']) if thumbnail: - embed.set_thumbnail(url=team["logo"] if team["logo"] else IMAGES['logo']) + embed.set_thumbnail(url=team["logo"] if team["logo"] else IMAGES["logo"]) else: - embed = discord.Embed( - title=title, - color=int(SBA_COLOR, 16) + embed = discord.Embed(title=title, color=int(SBA_COLOR, 16)) + embed.set_footer( + text=f"Paper Dynasty Season {PD_SEASON}", icon_url=IMAGES["logo"] ) - embed.set_footer(text=f'Paper Dynasty Season {PD_SEASON}', icon_url=IMAGES['logo']) if thumbnail: - embed.set_thumbnail(url=IMAGES['logo']) + embed.set_thumbnail(url=IMAGES["logo"]) return embed async def create_channel_old( - ctx, channel_name: str, category_name: str, everyone_send=False, everyone_read=True, allowed_members=None, - allowed_roles=None): + ctx, + channel_name: str, + category_name: str, + everyone_send=False, + everyone_read=True, + allowed_members=None, + allowed_roles=None, +): """Create a text channel with specified permissions (legacy version).""" this_category = discord.utils.get(ctx.guild.categories, name=category_name) if not this_category: - raise ValueError(f'I couldn\'t find a category named **{category_name}**') + raise ValueError(f"I couldn't find a category named **{category_name}**") overwrites = { - ctx.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True), - ctx.guild.default_role: discord.PermissionOverwrite(read_messages=everyone_read, send_messages=everyone_send) + ctx.guild.me: discord.PermissionOverwrite( + read_messages=True, send_messages=True + ), + ctx.guild.default_role: discord.PermissionOverwrite( + read_messages=everyone_read, send_messages=everyone_send + ), } if allowed_members: if isinstance(allowed_members, list): for member in allowed_members: - overwrites[member] = discord.PermissionOverwrite(read_messages=True, send_messages=True) + overwrites[member] = discord.PermissionOverwrite( + read_messages=True, send_messages=True + ) if allowed_roles: if isinstance(allowed_roles, list): for role in allowed_roles: - overwrites[role] = discord.PermissionOverwrite(read_messages=True, send_messages=True) + overwrites[role] = discord.PermissionOverwrite( + read_messages=True, send_messages=True + ) this_channel = await ctx.guild.create_text_channel( - channel_name, - overwrites=overwrites, - category=this_category + channel_name, overwrites=overwrites, category=this_category ) - logger.info(f'Creating channel ({channel_name}) in ({category_name})') + logger.info(f"Creating channel ({channel_name}) in ({category_name})") return this_channel async def create_channel( - ctx, channel_name: str, category_name: str, everyone_send=False, everyone_read=True, - read_send_members: list = None, read_send_roles: list = None, read_only_roles: list = None): + ctx, + channel_name: str, + category_name: str, + everyone_send=False, + everyone_read=True, + read_send_members: list = None, + read_send_roles: list = None, + read_only_roles: list = None, +): """Create a text channel with specified permissions.""" # Handle both Context and Interaction objects - guild = ctx.guild if hasattr(ctx, 'guild') else None + guild = ctx.guild if hasattr(ctx, "guild") else None if not guild: - raise ValueError(f'Unable to access guild from context object') - + raise ValueError(f"Unable to access guild from context object") + # Get bot member - different for Context vs Interaction - if hasattr(ctx, 'me'): # Context object + if hasattr(ctx, "me"): # Context object bot_member = ctx.me - elif hasattr(ctx, 'client'): # Interaction object + elif hasattr(ctx, "client"): # Interaction object bot_member = guild.get_member(ctx.client.user.id) else: # Fallback - try to find bot member by getting the first member with bot=True bot_member = next((m for m in guild.members if m.bot), None) if not bot_member: - raise ValueError(f'Unable to find bot member in guild') - + raise ValueError(f"Unable to find bot member in guild") + this_category = discord.utils.get(guild.categories, name=category_name) if not this_category: - raise ValueError(f'I couldn\'t find a category named **{category_name}**') + raise ValueError(f"I couldn't find a category named **{category_name}**") overwrites = { bot_member: discord.PermissionOverwrite(read_messages=True, send_messages=True), - guild.default_role: discord.PermissionOverwrite(read_messages=everyone_read, send_messages=everyone_send) + guild.default_role: discord.PermissionOverwrite( + read_messages=everyone_read, send_messages=everyone_send + ), } if read_send_members: for member in read_send_members: - overwrites[member] = discord.PermissionOverwrite(read_messages=True, send_messages=True) + overwrites[member] = discord.PermissionOverwrite( + read_messages=True, send_messages=True + ) if read_send_roles: for role in read_send_roles: - overwrites[role] = discord.PermissionOverwrite(read_messages=True, send_messages=True) + overwrites[role] = discord.PermissionOverwrite( + read_messages=True, send_messages=True + ) if read_only_roles: for role in read_only_roles: - overwrites[role] = discord.PermissionOverwrite(read_messages=True, send_messages=False) + overwrites[role] = discord.PermissionOverwrite( + read_messages=True, send_messages=False + ) this_channel = await guild.create_text_channel( - channel_name, - overwrites=overwrites, - category=this_category + channel_name, overwrites=overwrites, category=this_category ) - logger.info(f'Creating channel ({channel_name}) in ({category_name})') + logger.info(f"Creating channel ({channel_name}) in ({category_name})") - return this_channel \ No newline at end of file + return this_channel diff --git a/helpers/discord_utils.py b/helpers/discord_utils.py index 3f9c2d5..5db691e 100644 --- a/helpers/discord_utils.py +++ b/helpers/discord_utils.py @@ -4,6 +4,7 @@ Discord Utilities This module contains Discord helper functions for channels, roles, embeds, and other Discord-specific operations. """ + import logging import os import asyncio @@ -13,19 +14,21 @@ import discord from discord.ext import commands from helpers.constants import SBA_COLOR, PD_SEASON, IMAGES -logger = logging.getLogger('discord_app') +logger = logging.getLogger("discord_app") async def send_to_bothole(ctx, content, embed): """Send a message to the pd-bot-hole channel.""" - await discord.utils.get(ctx.guild.text_channels, name='pd-bot-hole') \ - .send(content=content, embed=embed) + await discord.utils.get(ctx.guild.text_channels, name="pd-bot-hole").send( + content=content, embed=embed + ) async def send_to_news(ctx, content, embed): """Send a message to the pd-news-ticker channel.""" - await discord.utils.get(ctx.guild.text_channels, name='pd-news-ticker') \ - .send(content=content, embed=embed) + await discord.utils.get(ctx.guild.text_channels, name="pd-news-ticker").send( + content=content, embed=embed + ) async def typing_pause(ctx, seconds=1): @@ -43,23 +46,20 @@ async def pause_then_type(ctx, message): async def check_if_pdhole(ctx): """Check if the current channel is pd-bot-hole.""" - if ctx.message.channel.name != 'pd-bot-hole': - await ctx.send('Slide on down to my bot-hole for running commands.') - await ctx.message.add_reaction('❌') + if ctx.message.channel.name != "pd-bot-hole": + await ctx.send("Slide on down to my bot-hole for running commands.") + await ctx.message.add_reaction("❌") return False return True async def bad_channel(ctx): """Check if current channel is in the list of bad channels for commands.""" - bad_channels = ['paper-dynasty-chat', 'pd-news-ticker'] + bad_channels = ["paper-dynasty-chat", "pd-news-ticker"] if ctx.message.channel.name in bad_channels: - await ctx.message.add_reaction('❌') - bot_hole = discord.utils.get( - ctx.guild.text_channels, - name=f'pd-bot-hole' - ) - await ctx.send(f'Slide on down to the {bot_hole.mention} ;)') + await ctx.message.add_reaction("❌") + bot_hole = discord.utils.get(ctx.guild.text_channels, name=f"pd-bot-hole") + await ctx.send(f"Slide on down to the {bot_hole.mention} ;)") return True else: return False @@ -68,14 +68,11 @@ async def bad_channel(ctx): def get_channel(ctx, name) -> Optional[discord.TextChannel]: """Get a text channel by name.""" # Handle both Context and Interaction objects - guild = ctx.guild if hasattr(ctx, 'guild') else None + guild = ctx.guild if hasattr(ctx, "guild") else None if not guild: return None - - channel = discord.utils.get( - guild.text_channels, - name=name - ) + + channel = discord.utils.get(guild.text_channels, name=name) if channel: return channel return None @@ -87,7 +84,7 @@ async def get_emoji(ctx, name, return_empty=True): emoji = await commands.converter.EmojiConverter().convert(ctx, name) except: if return_empty: - emoji = '' + emoji = "" else: return name return emoji @@ -101,9 +98,13 @@ async def react_and_reply(ctx, reaction, message): async def send_to_channel(bot, channel_name, content=None, embed=None): """Send a message to a specific channel by name or ID.""" - guild = bot.get_guild(int(os.environ.get('GUILD_ID'))) + guild_id = os.environ.get("GUILD_ID") + if not guild_id: + logger.error("GUILD_ID env var is not set") + return + guild = bot.get_guild(int(guild_id)) if not guild: - logger.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) @@ -111,7 +112,7 @@ async def send_to_channel(bot, channel_name, content=None, embed=None): if not this_channel: this_channel = discord.utils.get(guild.text_channels, id=channel_name) if not this_channel: - raise NameError(f'**{channel_name}** channel not found') + raise NameError(f"**{channel_name}** channel not found") return await this_channel.send(content=content, embed=embed) @@ -128,14 +129,16 @@ async def get_or_create_role(ctx, role_name, mentionable=True): def get_special_embed(special): """Create an embed for a special item.""" - embed = discord.Embed(title=f'{special.name} - Special #{special.get_id()}', - color=discord.Color.random(), - description=f'{special.short_desc}') - embed.add_field(name='Description', value=f'{special.long_desc}', inline=False) - if special.thumbnail.lower() != 'none': - embed.set_thumbnail(url=f'{special.thumbnail}') - if special.url.lower() != 'none': - embed.set_image(url=f'{special.url}') + embed = discord.Embed( + title=f"{special.name} - Special #{special.get_id()}", + color=discord.Color.random(), + description=f"{special.short_desc}", + ) + embed.add_field(name="Description", value=f"{special.long_desc}", inline=False) + if special.thumbnail.lower() != "none": + embed.set_thumbnail(url=f"{special.thumbnail}") + if special.url.lower() != "none": + embed.set_image(url=f"{special.url}") return embed @@ -154,99 +157,125 @@ def get_team_embed(title, team=None, thumbnail: bool = True): if team: embed = discord.Embed( title=title, - color=int(team["color"], 16) if team["color"] else int(SBA_COLOR, 16) + color=int(team["color"], 16) if team["color"] else int(SBA_COLOR, 16), + ) + embed.set_footer( + text=f'Paper Dynasty Season {team["season"]}', icon_url=IMAGES["logo"] ) - embed.set_footer(text=f'Paper Dynasty Season {team["season"]}', icon_url=IMAGES['logo']) if thumbnail: - embed.set_thumbnail(url=team["logo"] if team["logo"] else IMAGES['logo']) + embed.set_thumbnail(url=team["logo"] if team["logo"] else IMAGES["logo"]) else: - embed = discord.Embed( - title=title, - color=int(SBA_COLOR, 16) + embed = discord.Embed(title=title, color=int(SBA_COLOR, 16)) + embed.set_footer( + text=f"Paper Dynasty Season {PD_SEASON}", icon_url=IMAGES["logo"] ) - embed.set_footer(text=f'Paper Dynasty Season {PD_SEASON}', icon_url=IMAGES['logo']) if thumbnail: - embed.set_thumbnail(url=IMAGES['logo']) + embed.set_thumbnail(url=IMAGES["logo"]) return embed async def create_channel_old( - ctx, channel_name: str, category_name: str, everyone_send=False, everyone_read=True, allowed_members=None, - allowed_roles=None): + ctx, + channel_name: str, + category_name: str, + everyone_send=False, + everyone_read=True, + allowed_members=None, + allowed_roles=None, +): """Create a text channel with specified permissions (legacy version).""" this_category = discord.utils.get(ctx.guild.categories, name=category_name) if not this_category: - raise ValueError(f'I couldn\'t find a category named **{category_name}**') + raise ValueError(f"I couldn't find a category named **{category_name}**") overwrites = { - ctx.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True), - ctx.guild.default_role: discord.PermissionOverwrite(read_messages=everyone_read, send_messages=everyone_send) + ctx.guild.me: discord.PermissionOverwrite( + read_messages=True, send_messages=True + ), + ctx.guild.default_role: discord.PermissionOverwrite( + read_messages=everyone_read, send_messages=everyone_send + ), } if allowed_members: if isinstance(allowed_members, list): for member in allowed_members: - overwrites[member] = discord.PermissionOverwrite(read_messages=True, send_messages=True) + overwrites[member] = discord.PermissionOverwrite( + read_messages=True, send_messages=True + ) if allowed_roles: if isinstance(allowed_roles, list): for role in allowed_roles: - overwrites[role] = discord.PermissionOverwrite(read_messages=True, send_messages=True) + overwrites[role] = discord.PermissionOverwrite( + read_messages=True, send_messages=True + ) this_channel = await ctx.guild.create_text_channel( - channel_name, - overwrites=overwrites, - category=this_category + channel_name, overwrites=overwrites, category=this_category ) - logger.info(f'Creating channel ({channel_name}) in ({category_name})') + logger.info(f"Creating channel ({channel_name}) in ({category_name})") return this_channel async def create_channel( - ctx, channel_name: str, category_name: str, everyone_send=False, everyone_read=True, - read_send_members: list = None, read_send_roles: list = None, read_only_roles: list = None): + ctx, + channel_name: str, + category_name: str, + everyone_send=False, + everyone_read=True, + read_send_members: list = None, + read_send_roles: list = None, + read_only_roles: list = None, +): """Create a text channel with specified permissions.""" # Handle both Context and Interaction objects - guild = ctx.guild if hasattr(ctx, 'guild') else None + guild = ctx.guild if hasattr(ctx, "guild") else None if not guild: - raise ValueError(f'Unable to access guild from context object') - + raise ValueError(f"Unable to access guild from context object") + # Get bot member - different for Context vs Interaction - if hasattr(ctx, 'me'): # Context object + if hasattr(ctx, "me"): # Context object bot_member = ctx.me - elif hasattr(ctx, 'client'): # Interaction object + elif hasattr(ctx, "client"): # Interaction object bot_member = guild.get_member(ctx.client.user.id) else: # Fallback - try to find bot member by getting the first member with bot=True bot_member = next((m for m in guild.members if m.bot), None) if not bot_member: - raise ValueError(f'Unable to find bot member in guild') - + raise ValueError(f"Unable to find bot member in guild") + this_category = discord.utils.get(guild.categories, name=category_name) if not this_category: - raise ValueError(f'I couldn\'t find a category named **{category_name}**') + raise ValueError(f"I couldn't find a category named **{category_name}**") overwrites = { bot_member: discord.PermissionOverwrite(read_messages=True, send_messages=True), - guild.default_role: discord.PermissionOverwrite(read_messages=everyone_read, send_messages=everyone_send) + guild.default_role: discord.PermissionOverwrite( + read_messages=everyone_read, send_messages=everyone_send + ), } if read_send_members: for member in read_send_members: - overwrites[member] = discord.PermissionOverwrite(read_messages=True, send_messages=True) + overwrites[member] = discord.PermissionOverwrite( + read_messages=True, send_messages=True + ) if read_send_roles: for role in read_send_roles: - overwrites[role] = discord.PermissionOverwrite(read_messages=True, send_messages=True) + overwrites[role] = discord.PermissionOverwrite( + read_messages=True, send_messages=True + ) if read_only_roles: for role in read_only_roles: - overwrites[role] = discord.PermissionOverwrite(read_messages=True, send_messages=False) + overwrites[role] = discord.PermissionOverwrite( + read_messages=True, send_messages=False + ) this_channel = await guild.create_text_channel( - channel_name, - overwrites=overwrites, - category=this_category + channel_name, overwrites=overwrites, category=this_category ) - logger.info(f'Creating channel ({channel_name}) in ({category_name})') + logger.info(f"Creating channel ({channel_name}) in ({category_name})") - return this_channel \ No newline at end of file + return this_channel