Fixed issue where key plays were showing the score twice: - Before: "Top 3: Player (NYY) homers, NYY up 2-0, NYY up 2-0" - After: "Top 3: Player (NYY) homers, NYY up 2-0" Changes: - Simplified Play.descriptive_text() to use rbi for score calculation - Removed duplicate score logic in format_key_plays() helper - Now only shows score after the play is completed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
122 lines
2.9 KiB
Python
122 lines
2.9 KiB
Python
"""
|
|
Discord Helper Utilities
|
|
|
|
Common Discord-related helper functions for channel lookups,
|
|
message sending, and formatting.
|
|
"""
|
|
from typing import Optional, List
|
|
import discord
|
|
from discord.ext import commands
|
|
|
|
from models.play import Play
|
|
from models.team import Team
|
|
from utils.logging import get_contextual_logger
|
|
|
|
logger = get_contextual_logger(__name__)
|
|
|
|
|
|
async def get_channel_by_name(
|
|
bot: commands.Bot,
|
|
channel_name: str
|
|
) -> Optional[discord.TextChannel]:
|
|
"""
|
|
Get a text channel by name from the configured guild.
|
|
|
|
Args:
|
|
bot: Discord bot instance
|
|
channel_name: Name of the channel to find
|
|
|
|
Returns:
|
|
TextChannel if found, None otherwise
|
|
"""
|
|
from config import get_config
|
|
|
|
config = get_config()
|
|
guild_id = config.guild_id
|
|
|
|
if not guild_id:
|
|
logger.error("GUILD_ID not configured")
|
|
return None
|
|
|
|
guild = bot.get_guild(guild_id)
|
|
if not guild:
|
|
logger.error(f"Guild {guild_id} not found")
|
|
return None
|
|
|
|
channel = discord.utils.get(guild.text_channels, name=channel_name)
|
|
|
|
if not channel:
|
|
logger.warning(f"Channel '{channel_name}' not found in guild {guild_id}")
|
|
return None
|
|
|
|
return channel
|
|
|
|
|
|
async def send_to_channel(
|
|
bot: commands.Bot,
|
|
channel_name: str,
|
|
content: Optional[str] = None,
|
|
embed: Optional[discord.Embed] = None
|
|
) -> bool:
|
|
"""
|
|
Send a message to a channel by name.
|
|
|
|
Args:
|
|
bot: Discord bot instance
|
|
channel_name: Name of the channel
|
|
content: Text content to send
|
|
embed: Embed to send
|
|
|
|
Returns:
|
|
True if message sent successfully, False otherwise
|
|
"""
|
|
channel = await get_channel_by_name(bot, channel_name)
|
|
|
|
if not channel:
|
|
logger.error(f"Cannot send to channel '{channel_name}' - not found")
|
|
return False
|
|
|
|
try:
|
|
# Build kwargs to avoid passing None for embed
|
|
kwargs = {}
|
|
if content is not None:
|
|
kwargs['content'] = content
|
|
if embed is not None:
|
|
kwargs['embed'] = embed
|
|
|
|
await channel.send(**kwargs)
|
|
logger.info(f"Sent message to #{channel_name}")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Failed to send message to #{channel_name}: {e}")
|
|
return False
|
|
|
|
|
|
def format_key_plays(
|
|
plays: List[Play],
|
|
away_team: Team,
|
|
home_team: Team
|
|
) -> str:
|
|
"""
|
|
Format top plays into embed field text.
|
|
|
|
Args:
|
|
plays: List of Play objects (should be sorted by WPA)
|
|
away_team: Away team object
|
|
home_team: Home team object
|
|
|
|
Returns:
|
|
Formatted string for embed field, or empty string if no plays
|
|
"""
|
|
if not plays:
|
|
return ""
|
|
|
|
key_plays_text = ""
|
|
|
|
for play in plays:
|
|
# Use the Play.descriptive_text() method (already includes score)
|
|
play_description = play.descriptive_text(away_team, home_team)
|
|
key_plays_text += f"{play_description}\n"
|
|
|
|
return key_plays_text
|