Added search functionality to /player command

This commit is contained in:
Cal Corum 2025-10-08 14:45:41 -05:00
parent b1d05309ef
commit 660c6ad904
27 changed files with 1898 additions and 12 deletions

1780
cogs/economy.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,7 @@ from helpers import ACTIVE_EVENT_LITERAL, PD_PLAYERS_ROLE_NAME, IMAGES, PD_SEASO
get_team_by_owner, get_rosters, get_roster_sheet, legal_channel, random_conf_word, embed_pagination, get_cal_user, \
team_summary_embed, SelectView, SelectPaperdexCardset, SelectPaperdexTeam
from utilities.buttons import ask_with_buttons
from utilities.autocomplete import cardset_autocomplete, player_autocomplete
logger = logging.getLogger('discord_app')
@ -443,9 +444,10 @@ class Players(commands.Cog):
@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)
async def player_slash_command(
self, interaction: discord.Interaction, player_name: str,
cardset: Literal['All', '2025 Live', '2024 Season', '2024 Promos', '2023 Season', '2023 Promos', '2022 Season', '2022 Promos', '2021 Season', '2019 Season', '2018 Season', '2018 Promos', '2016 Season', '2013 Season', '2012 Season', '2008 Season', '1998 Season', '1998 Promos', 'Backyard Baseball', 'Mario Super Sluggers', 'Sams Choice'] = 'All'):
cardset: str = 'All'):
ephemeral = False
if interaction.channel.name in ['paper-dynasty-chat', 'pd-news-ticker']:
ephemeral = True

View File

@ -74,7 +74,7 @@ PD_PLAYERS = 'Paper Dynasty Players'
SBA_PLAYERS_ROLE_NAME = f'Season {SBA_SEASON} Players'
PD_PLAYERS_ROLE_NAME = f'Paper Dynasty Players'
ALL_CARDSET_NAMES = Literal['All', '2025 Live', '2024 Season', '2024 Promos', '2023 Season', '2023 Promos', '2022 Season', '2022 Promos', '2021 Season', '2019 Season', '2018 Season', '2018 Promos', '2016 Season', '2013 Season', '2012 Season', '2008 Season', '1998 Season', '1998 Promos', 'Backyard Baseball', 'Mario Super Sluggers', 'Sams Choice']
ALL_CARDSET_NAMES = Literal['All', '2025 Season', '2024 Season', '2024 Promos', '2023 Season', '2023 Promos', '2022 Season', '2022 Promos', '2021 Season', '2019 Season', '2018 Season', '2018 Promos', '2016 Season', '2013 Season', '2012 Season', '2008 Season', '1998 Season', '1998 Promos', 'Backyard Baseball', 'Mario Super Sluggers', 'Sams Choice']
# External URLs and Resources
PD_IMAGE_BUCKET = 'https://paper-dynasty.s3.us-east-1.amazonaws.com/static-images'

View File

@ -5,11 +5,14 @@ This module contains standalone utility functions with minimal dependencies,
including timestamp conversion, position abbreviations, and simple helpers.
"""
import datetime
from typing import Optional
import discord
def int_timestamp():
def int_timestamp(datetime_obj: Optional[datetime.datetime] = None):
"""Convert current datetime to integer timestamp."""
if datetime_obj:
return int(datetime.datetime.timestamp(datetime_obj) * 1000)
return int(datetime.datetime.now().timestamp())

View File

@ -822,18 +822,18 @@ class PlayerBase(SQLModel):
@property
def batter_card_url(self):
if 'batting' in self.image:
if self.image and 'batting' in self.image:
return self.image
elif 'batting' in self.image2:
elif self.image2 and 'batting' in self.image2:
return self.image2
else:
return None
@property
def pitcher_card_url(self):
if 'pitching' in self.image:
if self.image and 'pitching' in self.image:
return self.image
elif 'pitching' in self.image2:
elif self.image2 and 'pitching' in self.image2:
return self.image2
else:
return None

View File

@ -18,7 +18,7 @@ import discord
# Import the module to test (this will need to be updated when modules are moved)
try:
from cogs.players.gauntlet import Gauntlet
from cogs.players_new.gauntlet import Gauntlet
except ImportError:
# Create a mock class for testing structure
class Gauntlet:

View File

@ -17,7 +17,7 @@ import discord
# Import the module to test (this will need to be updated when modules are moved)
try:
from cogs.players.paperdex import Paperdex
from cogs.players_new.paperdex import Paperdex
except ImportError:
# Create a mock class for testing structure
class Paperdex:

View File

@ -17,7 +17,7 @@ import discord
# Import the module to test (this will need to be updated when modules are moved)
try:
from cogs.players.standings_records import StandingsRecords
from cogs.players_new.standings_records import StandingsRecords
except ImportError:
# Create a mock class for testing structure
class StandingsRecords:

View File

@ -16,7 +16,7 @@ import discord
# Import the module to test (this will need to be updated when modules are moved)
try:
from cogs.players.team_management import TeamManagement
from cogs.players_new.team_management import TeamManagement
except ImportError:
# Create a mock class for testing structure
class TeamManagement:

View File

@ -19,7 +19,7 @@ import random
# Import the module to test (this will need to be updated when modules are moved)
try:
from cogs.players.utility_commands import UtilityCommands
from cogs.players_new.utility_commands import UtilityCommands
except ImportError:
# Create a mock class for testing structure
class UtilityCommands:

101
utilities/autocomplete.py Normal file
View File

@ -0,0 +1,101 @@
"""
Autocomplete Utilities
Shared autocomplete functions for Discord slash commands.
"""
from typing import List
import discord
from discord import app_commands
from api_calls import db_get
from helpers import player_desc
async def cardset_autocomplete(
interaction: discord.Interaction,
current: str
) -> List[app_commands.Choice[str]]:
"""
Autocomplete for cardset names using fuzzy search.
Args:
interaction: Discord interaction object
current: Current input from user
Returns:
List of cardset name choices matching the current input
"""
if len(current) < 1:
return []
try:
# Search for cardsets using the /cardsets/search endpoint
search_results = await db_get(
'cardsets/search',
params=[('q', current), ('limit', 25)],
timeout=5
)
if not search_results or search_results.get('count', 0) == 0:
return []
# Get cardsets from search results
cardsets = search_results.get('cardsets', [])
# Create choices with cardset names
choices = [
app_commands.Choice(name=cardset['name'], value=cardset['name'])
for cardset in cardsets
if cardset.get('name')
]
return choices
except Exception:
# Silently fail on autocomplete errors to avoid disrupting user experience
return []
async def player_autocomplete(
interaction: discord.Interaction,
current: str
) -> List[app_commands.Choice[str]]:
"""
Autocomplete for player names using fuzzy search.
Args:
interaction: Discord interaction object
current: Current input from user
Returns:
List of player name choices matching the current input
"""
if len(current) < 2:
return []
try:
# Search for players using the /players/search endpoint
search_results = await db_get(
'players/search',
params=[('q', current), ('limit', 25), ('short_output', True), ('unique_names', True)],
timeout=5
)
if not search_results or search_results.get('count', 0) == 0:
return []
# Get players from search results
players = search_results.get('players', [])
# Create choices with player names
choices = [
app_commands.Choice(name=player['p_name'], value=player['p_name'])
for player in players
if player.get('p_name')
]
return choices
except Exception:
# Silently fail on autocomplete errors to avoid disrupting user experience
return []