""" General Utilities This module contains standalone utility functions with minimal dependencies, including timestamp conversion, position abbreviations, and simple helpers. """ import datetime import discord def int_timestamp(): """Convert current datetime to integer timestamp.""" return int(datetime.datetime.now().timestamp()) def get_pos_abbrev(field_pos: str) -> str: """Convert position name to standard abbreviation.""" if field_pos.lower() == 'catcher': return 'C' elif field_pos.lower() == 'first baseman': return '1B' elif field_pos.lower() == 'second baseman': return '2B' elif field_pos.lower() == 'third baseman': return '3B' elif field_pos.lower() == 'shortstop': return 'SS' elif field_pos.lower() == 'left fielder': return 'LF' elif field_pos.lower() == 'center fielder': return 'CF' elif field_pos.lower() == 'right fielder': return 'RF' else: return 'P' def position_name_to_abbrev(position_name): """Convert position name to abbreviation (alternate format).""" if position_name == 'Catcher': return 'C' elif position_name == 'First Base': return '1B' elif position_name == 'Second Base': return '2B' elif position_name == 'Third Base': return '3B' elif position_name == 'Shortstop': return 'SS' elif position_name == 'Left Field': return 'LF' elif position_name == 'Center Field': return 'CF' elif position_name == 'Right Field': return 'RF' elif position_name == 'Pitcher': return 'P' else: return position_name def user_has_role(user: discord.User | discord.Member, role_name: str) -> bool: """Check if a Discord user has a specific role.""" for x in user.roles: if x.name == role_name: return True return False def get_roster_sheet_legacy(team): """Get legacy roster sheet URL for a team.""" return f'https://docs.google.com/spreadsheets/d/{team.gsheet}/edit' def get_roster_sheet(team): """ Get roster sheet URL for a team. Handles both dict and Team object formats. """ # Handle both dict (team["gsheet"]) and object (team.gsheet) formats gsheet = team.get("gsheet") if isinstance(team, dict) else getattr(team, "gsheet", None) return f'https://docs.google.com/spreadsheets/d/{gsheet}/edit' def get_player_url(team, player) -> str: """Generate player URL for SBA or Baseball Reference.""" if team.get('league') == 'SBA': return f'https://statsplus.net/super-baseball-association/player/{player["player_id"]}' else: return f'https://www.baseball-reference.com/players/{player["bbref_id"][0]}/{player["bbref_id"]}.shtml' def owner_only(ctx) -> bool: """Check if user is the bot owner.""" # ID for discord User Cal owners = [287463767924137994, 1087936030899347516] # Handle both Context (has .author) and Interaction (has .user) objects user = getattr(ctx, 'user', None) or getattr(ctx, 'author', None) if user and user.id in owners: return True return False def get_context_user(ctx): """ Get the user from either a Context or Interaction object. Hybrid commands can receive either commands.Context (from prefix commands) or discord.Interaction (from slash commands). This helper safely extracts the user from either type. Returns: discord.User or discord.Member: The user who invoked the command """ # Handle both Context (has .author) and Interaction (has .user) objects return getattr(ctx, 'user', None) or getattr(ctx, 'author', None) def get_cal_user(ctx): """Get the Cal user from context. Always returns an object with .mention attribute.""" import logging logger = logging.getLogger('discord_app') # Define placeholder user class first class PlaceholderUser: def __init__(self): self.mention = "<@287463767924137994>" self.id = 287463767924137994 # Handle both Context and Interaction objects if hasattr(ctx, 'bot'): # Context object bot = ctx.bot logger.debug("get_cal_user: Using Context object") elif hasattr(ctx, 'client'): # Interaction object bot = ctx.client logger.debug("get_cal_user: Using Interaction object") else: logger.error("get_cal_user: No bot or client found in context") return PlaceholderUser() if not bot: logger.error("get_cal_user: bot is None") return PlaceholderUser() logger.debug(f"get_cal_user: Searching among members") try: for user in bot.get_all_members(): if user.id == 287463767924137994: logger.debug("get_cal_user: Found user in get_all_members") return user except Exception as e: logger.error(f"get_cal_user: Exception in get_all_members: {e}") # Fallback: try to get user directly by ID logger.debug("get_cal_user: User not found in get_all_members, trying get_user") try: user = bot.get_user(287463767924137994) if user: logger.debug("get_cal_user: Found user via get_user") return user else: logger.debug("get_cal_user: get_user returned None") except Exception as e: logger.error(f"get_cal_user: Exception in get_user: {e}") # Last resort: return a placeholder user object with mention logger.debug("get_cal_user: Using placeholder user") return PlaceholderUser()