mirror of
https://github.com/pacnpal/Pac-cogs.git
synced 2025-12-20 02:41:06 -05:00
fixed
This commit is contained in:
@@ -1,57 +1,116 @@
|
||||
"""Module for handling command responses"""
|
||||
|
||||
import logging
|
||||
from enum import Enum, auto
|
||||
from typing import Optional, Union, Dict, Any, TypedDict, ClassVar
|
||||
from datetime import datetime
|
||||
import discord
|
||||
from typing import Optional, Union, Dict, Any
|
||||
from redbot.core.commands import Context
|
||||
|
||||
from ..utils.exceptions import ErrorSeverity
|
||||
|
||||
logger = logging.getLogger("VideoArchiver")
|
||||
|
||||
class ResponseType(Enum):
|
||||
"""Types of responses"""
|
||||
NORMAL = auto()
|
||||
SUCCESS = auto()
|
||||
ERROR = auto()
|
||||
WARNING = auto()
|
||||
INFO = auto()
|
||||
DEBUG = auto()
|
||||
|
||||
class ResponseTheme(TypedDict):
|
||||
"""Type definition for response theme"""
|
||||
emoji: str
|
||||
color: discord.Color
|
||||
|
||||
class ResponseFormat(TypedDict):
|
||||
"""Type definition for formatted response"""
|
||||
content: str
|
||||
color: discord.Color
|
||||
timestamp: str
|
||||
|
||||
class ResponseFormatter:
|
||||
"""Formats responses for consistency"""
|
||||
|
||||
@staticmethod
|
||||
def format_success(message: str) -> Dict[str, Any]:
|
||||
"""Format a success message"""
|
||||
return {
|
||||
"content": f"✅ {message}",
|
||||
"color": discord.Color.green()
|
||||
}
|
||||
THEMES: ClassVar[Dict[ResponseType, ResponseTheme]] = {
|
||||
ResponseType.SUCCESS: ResponseTheme(emoji="✅", color=discord.Color.green()),
|
||||
ResponseType.ERROR: ResponseTheme(emoji="❌", color=discord.Color.red()),
|
||||
ResponseType.WARNING: ResponseTheme(emoji="⚠️", color=discord.Color.gold()),
|
||||
ResponseType.INFO: ResponseTheme(emoji="ℹ️", color=discord.Color.blue()),
|
||||
ResponseType.DEBUG: ResponseTheme(emoji="🔧", color=discord.Color.greyple())
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def format_error(message: str) -> Dict[str, Any]:
|
||||
"""Format an error message"""
|
||||
return {
|
||||
"content": f"❌ {message}",
|
||||
"color": discord.Color.red()
|
||||
}
|
||||
SEVERITY_MAPPING: ClassVar[Dict[ErrorSeverity, ResponseType]] = {
|
||||
ErrorSeverity.LOW: ResponseType.INFO,
|
||||
ErrorSeverity.MEDIUM: ResponseType.WARNING,
|
||||
ErrorSeverity.HIGH: ResponseType.ERROR,
|
||||
ErrorSeverity.CRITICAL: ResponseType.ERROR
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def format_warning(message: str) -> Dict[str, Any]:
|
||||
"""Format a warning message"""
|
||||
return {
|
||||
"content": f"⚠️ {message}",
|
||||
"color": discord.Color.yellow()
|
||||
}
|
||||
@classmethod
|
||||
def format_response(
|
||||
cls,
|
||||
message: str,
|
||||
response_type: ResponseType = ResponseType.NORMAL
|
||||
) -> ResponseFormat:
|
||||
"""
|
||||
Format a response message.
|
||||
|
||||
Args:
|
||||
message: Message to format
|
||||
response_type: Type of response
|
||||
|
||||
Returns:
|
||||
Formatted response dictionary
|
||||
"""
|
||||
theme = cls.THEMES.get(response_type)
|
||||
if theme:
|
||||
return ResponseFormat(
|
||||
content=f"{theme['emoji']} {message}",
|
||||
color=theme['color'],
|
||||
timestamp=datetime.utcnow().isoformat()
|
||||
)
|
||||
return ResponseFormat(
|
||||
content=message,
|
||||
color=discord.Color.default(),
|
||||
timestamp=datetime.utcnow().isoformat()
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def format_info(message: str) -> Dict[str, Any]:
|
||||
"""Format an info message"""
|
||||
return {
|
||||
"content": f"ℹ️ {message}",
|
||||
"color": discord.Color.blue()
|
||||
}
|
||||
@classmethod
|
||||
def get_response_type(cls, severity: ErrorSeverity) -> ResponseType:
|
||||
"""
|
||||
Get response type for error severity.
|
||||
|
||||
Args:
|
||||
severity: Error severity level
|
||||
|
||||
Returns:
|
||||
Appropriate response type
|
||||
"""
|
||||
return cls.SEVERITY_MAPPING.get(severity, ResponseType.ERROR)
|
||||
|
||||
class InteractionHandler:
|
||||
"""Handles slash command interactions"""
|
||||
|
||||
@staticmethod
|
||||
async def send_initial_response(
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
content: Optional[str] = None,
|
||||
embed: Optional[discord.Embed] = None
|
||||
) -> bool:
|
||||
"""Send initial interaction response"""
|
||||
"""
|
||||
Send initial interaction response.
|
||||
|
||||
Args:
|
||||
interaction: Discord interaction
|
||||
content: Optional message content
|
||||
embed: Optional embed
|
||||
|
||||
Returns:
|
||||
True if response was sent successfully
|
||||
"""
|
||||
try:
|
||||
if not interaction.response.is_done():
|
||||
if embed:
|
||||
@@ -61,16 +120,26 @@ class InteractionHandler:
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending initial interaction response: {e}")
|
||||
logger.error(f"Error sending initial interaction response: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
async def send_followup(
|
||||
self,
|
||||
interaction: discord.Interaction,
|
||||
content: Optional[str] = None,
|
||||
embed: Optional[discord.Embed] = None
|
||||
) -> bool:
|
||||
"""Send interaction followup"""
|
||||
"""
|
||||
Send interaction followup.
|
||||
|
||||
Args:
|
||||
interaction: Discord interaction
|
||||
content: Optional message content
|
||||
embed: Optional embed
|
||||
|
||||
Returns:
|
||||
True if followup was sent successfully
|
||||
"""
|
||||
try:
|
||||
if embed:
|
||||
await interaction.followup.send(content=content, embed=embed)
|
||||
@@ -78,13 +147,13 @@ class InteractionHandler:
|
||||
await interaction.followup.send(content=content)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending interaction followup: {e}")
|
||||
logger.error(f"Error sending interaction followup: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
class ResponseManager:
|
||||
"""Manages command responses"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self) -> None:
|
||||
self.formatter = ResponseFormatter()
|
||||
self.interaction_handler = InteractionHandler()
|
||||
|
||||
@@ -93,25 +162,37 @@ class ResponseManager:
|
||||
ctx: Context,
|
||||
content: Optional[str] = None,
|
||||
embed: Optional[discord.Embed] = None,
|
||||
response_type: str = "normal"
|
||||
response_type: Union[ResponseType, str, ErrorSeverity] = ResponseType.NORMAL
|
||||
) -> None:
|
||||
"""Send a response to a command
|
||||
"""
|
||||
Send a response to a command.
|
||||
|
||||
Args:
|
||||
ctx: Command context
|
||||
content: Optional message content
|
||||
embed: Optional embed
|
||||
response_type: Type of response (normal, success, error, warning, info)
|
||||
response_type: Type of response or error severity
|
||||
"""
|
||||
try:
|
||||
# Format response if type specified
|
||||
if response_type != "normal":
|
||||
format_method = getattr(self.formatter, f"format_{response_type}", None)
|
||||
if format_method and content:
|
||||
formatted = format_method(content)
|
||||
content = formatted["content"]
|
||||
if not embed:
|
||||
embed = discord.Embed(color=formatted["color"])
|
||||
# Convert string response type to enum
|
||||
if isinstance(response_type, str):
|
||||
try:
|
||||
response_type = ResponseType[response_type.upper()]
|
||||
except KeyError:
|
||||
response_type = ResponseType.NORMAL
|
||||
# Convert error severity to response type
|
||||
elif isinstance(response_type, ErrorSeverity):
|
||||
response_type = self.formatter.get_response_type(response_type)
|
||||
|
||||
# Format response
|
||||
if response_type != ResponseType.NORMAL and content:
|
||||
formatted = self.formatter.format_response(content, response_type)
|
||||
content = formatted["content"]
|
||||
if not embed:
|
||||
embed = discord.Embed(
|
||||
color=formatted["color"],
|
||||
timestamp=datetime.fromisoformat(formatted["timestamp"])
|
||||
)
|
||||
|
||||
# Handle response
|
||||
if self._is_interaction(ctx):
|
||||
@@ -120,7 +201,7 @@ class ResponseManager:
|
||||
await self._handle_regular_response(ctx, content, embed)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending response: {e}")
|
||||
logger.error(f"Error sending response: {e}", exc_info=True)
|
||||
await self._send_fallback_response(ctx, content, embed)
|
||||
|
||||
def _is_interaction(self, ctx: Context) -> bool:
|
||||
@@ -151,7 +232,7 @@ class ResponseManager:
|
||||
await self._handle_regular_response(ctx, content, embed)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error handling interaction response: {e}")
|
||||
logger.error(f"Error handling interaction response: {e}", exc_info=True)
|
||||
await self._send_fallback_response(ctx, content, embed)
|
||||
|
||||
async def _handle_regular_response(
|
||||
@@ -167,7 +248,7 @@ class ResponseManager:
|
||||
else:
|
||||
await ctx.send(content=content)
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending regular response: {e}")
|
||||
logger.error(f"Error sending regular response: {e}", exc_info=True)
|
||||
await self._send_fallback_response(ctx, content, embed)
|
||||
|
||||
async def _send_fallback_response(
|
||||
@@ -183,7 +264,7 @@ class ResponseManager:
|
||||
else:
|
||||
await ctx.send(content=content)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to send fallback response: {e}")
|
||||
logger.error(f"Failed to send fallback response: {e}", exc_info=True)
|
||||
|
||||
# Global response manager instance
|
||||
response_manager = ResponseManager()
|
||||
@@ -192,7 +273,15 @@ async def handle_response(
|
||||
ctx: Context,
|
||||
content: Optional[str] = None,
|
||||
embed: Optional[discord.Embed] = None,
|
||||
response_type: str = "normal"
|
||||
response_type: Union[ResponseType, str, ErrorSeverity] = ResponseType.NORMAL
|
||||
) -> None:
|
||||
"""Helper function to handle responses using the response manager"""
|
||||
"""
|
||||
Helper function to handle responses using the response manager.
|
||||
|
||||
Args:
|
||||
ctx: Command context
|
||||
content: Optional message content
|
||||
embed: Optional embed
|
||||
response_type: Type of response or error severity
|
||||
"""
|
||||
await response_manager.send_response(ctx, content, embed, response_type)
|
||||
|
||||
Reference in New Issue
Block a user