major-domo-v2/commands/draft/admin.py
Cal Corum 1d6fef51ab Consolidate season config variables to single source (v2.21.0)
Remove redundant sba_current_season and pd_current_season config values.
All code now uses sba_season and pd_season, which properly read from
environment variables. Fixes /team command defaulting to Season 12.

- Remove duplicate *_current_season constants from config.py
- Update 100+ references across commands, services, and utils
- sba_season defaults to 13, pd_season defaults to 10
- Environment variables SBA_SEASON/PD_SEASON now work correctly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 16:12:16 -06:00

295 lines
10 KiB
Python

"""
Draft Admin Commands
Admin-only commands for draft management and configuration.
"""
from typing import Optional
import discord
from discord import app_commands
from discord.ext import commands
from config import get_config
from services.draft_service import draft_service
from services.draft_pick_service import draft_pick_service
from utils.logging import get_contextual_logger
from utils.decorators import logged_command
from utils.permissions import league_admin_only
from views.draft_views import create_admin_draft_info_embed
from views.embeds import EmbedTemplate
class DraftAdminGroup(app_commands.Group):
"""Draft administration command group."""
def __init__(self):
super().__init__(
name="draft-admin",
description="Admin commands for draft management"
)
self.logger = get_contextual_logger(f'{__name__}.DraftAdminGroup')
@app_commands.command(name="info", description="View current draft configuration")
@league_admin_only()
@logged_command("/draft-admin info")
async def draft_admin_info(self, interaction: discord.Interaction):
"""Display current draft configuration and state."""
await interaction.response.defer()
# Get draft data
draft_data = await draft_service.get_draft_data()
if not draft_data:
embed = EmbedTemplate.error(
"Draft Not Found",
"Could not retrieve draft configuration."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Get current pick
config = get_config()
current_pick = await draft_pick_service.get_pick(
config.sba_season,
draft_data.currentpick
)
# Create admin info embed
embed = await create_admin_draft_info_embed(draft_data, current_pick)
await interaction.followup.send(embed=embed)
@app_commands.command(name="timer", description="Enable or disable draft timer")
@app_commands.describe(
enabled="Turn timer on or off",
minutes="Minutes per pick (optional, default uses current setting)"
)
@league_admin_only()
@logged_command("/draft-admin timer")
async def draft_admin_timer(
self,
interaction: discord.Interaction,
enabled: bool,
minutes: Optional[int] = None
):
"""Enable or disable the draft timer."""
await interaction.response.defer()
# Get draft data
draft_data = await draft_service.get_draft_data()
if not draft_data:
embed = EmbedTemplate.error(
"Draft Not Found",
"Could not retrieve draft configuration."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Update timer
updated = await draft_service.set_timer(draft_data.id, enabled, minutes)
if not updated:
embed = EmbedTemplate.error(
"Update Failed",
"Failed to update draft timer."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Success message
status = "enabled" if enabled else "disabled"
description = f"Draft timer has been **{status}**."
if enabled and minutes:
description += f"\n\nPick duration: **{minutes} minutes**"
elif enabled:
description += f"\n\nPick duration: **{updated.pick_minutes} minutes**"
embed = EmbedTemplate.success("Timer Updated", description)
await interaction.followup.send(embed=embed)
@app_commands.command(name="set-pick", description="Set current pick number")
@app_commands.describe(
pick_number="Overall pick number to jump to (1-512)"
)
@league_admin_only()
@logged_command("/draft-admin set-pick")
async def draft_admin_set_pick(
self,
interaction: discord.Interaction,
pick_number: int
):
"""Set the current pick number (admin operation)."""
await interaction.response.defer()
config = get_config()
# Validate pick number
if pick_number < 1 or pick_number > config.draft_total_picks:
embed = EmbedTemplate.error(
"Invalid Pick Number",
f"Pick number must be between 1 and {config.draft_total_picks}."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Get draft data
draft_data = await draft_service.get_draft_data()
if not draft_data:
embed = EmbedTemplate.error(
"Draft Not Found",
"Could not retrieve draft configuration."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Verify pick exists
pick = await draft_pick_service.get_pick(config.sba_season, pick_number)
if not pick:
embed = EmbedTemplate.error(
"Pick Not Found",
f"Pick #{pick_number} does not exist in the database."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Update current pick
updated = await draft_service.set_current_pick(
draft_data.id,
pick_number,
reset_timer=True
)
if not updated:
embed = EmbedTemplate.error(
"Update Failed",
"Failed to update current pick."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Success message
from utils.draft_helpers import format_pick_display
description = f"Current pick set to **{format_pick_display(pick_number)}**."
if pick.owner:
description += f"\n\n{pick.owner.abbrev} {pick.owner.sname} is now on the clock."
embed = EmbedTemplate.success("Pick Updated", description)
await interaction.followup.send(embed=embed)
@app_commands.command(name="channels", description="Configure draft Discord channels")
@app_commands.describe(
ping_channel="Channel for 'on the clock' pings",
result_channel="Channel for draft results"
)
@league_admin_only()
@logged_command("/draft-admin channels")
async def draft_admin_channels(
self,
interaction: discord.Interaction,
ping_channel: Optional[discord.TextChannel] = None,
result_channel: Optional[discord.TextChannel] = None
):
"""Configure draft Discord channels."""
await interaction.response.defer()
if not ping_channel and not result_channel:
embed = EmbedTemplate.error(
"No Channels Provided",
"Please specify at least one channel to update."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Get draft data
draft_data = await draft_service.get_draft_data()
if not draft_data:
embed = EmbedTemplate.error(
"Draft Not Found",
"Could not retrieve draft configuration."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Update channels
updated = await draft_service.update_channels(
draft_data.id,
ping_channel_id=ping_channel.id if ping_channel else None,
result_channel_id=result_channel.id if result_channel else None
)
if not updated:
embed = EmbedTemplate.error(
"Update Failed",
"Failed to update draft channels."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Success message
description = "Draft channels updated:\n\n"
if ping_channel:
description += f"**Ping Channel:** {ping_channel.mention}\n"
if result_channel:
description += f"**Result Channel:** {result_channel.mention}\n"
embed = EmbedTemplate.success("Channels Updated", description)
await interaction.followup.send(embed=embed)
@app_commands.command(name="reset-deadline", description="Reset current pick deadline")
@app_commands.describe(
minutes="Minutes to add (uses default if not provided)"
)
@league_admin_only()
@logged_command("/draft-admin reset-deadline")
async def draft_admin_reset_deadline(
self,
interaction: discord.Interaction,
minutes: Optional[int] = None
):
"""Reset the current pick deadline."""
await interaction.response.defer()
# Get draft data
draft_data = await draft_service.get_draft_data()
if not draft_data:
embed = EmbedTemplate.error(
"Draft Not Found",
"Could not retrieve draft configuration."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
if not draft_data.timer:
embed = EmbedTemplate.warning(
"Timer Inactive",
"Draft timer is currently disabled. Enable it with `/draft-admin timer on` first."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Reset deadline
updated = await draft_service.reset_draft_deadline(draft_data.id, minutes)
if not updated:
embed = EmbedTemplate.error(
"Update Failed",
"Failed to reset draft deadline."
)
await interaction.followup.send(embed=embed, ephemeral=True)
return
# Success message
deadline_timestamp = int(updated.pick_deadline.timestamp())
minutes_used = minutes if minutes else updated.pick_minutes
description = f"Pick deadline reset: **{minutes_used} minutes** added.\n\n"
description += f"New deadline: <t:{deadline_timestamp}:F> (<t:{deadline_timestamp}:R>)"
embed = EmbedTemplate.success("Deadline Reset", description)
await interaction.followup.send(embed=embed)
async def setup(bot: commands.Bot):
"""Setup function for loading the draft admin commands."""
bot.tree.add_command(DraftAdminGroup())