Code improvements

This commit is contained in:
2025-05-25 16:42:08 +02:00
parent 4281aafc61
commit fe567952b4
5 changed files with 435 additions and 82 deletions

View File

@@ -16,6 +16,17 @@ import sys
jellyseerr_api = None
def get_api():
"""Get the Jellyseerr API client instance.
This function retrieves the API client instance that was initialized in main.py.
It handles the potential circular import issue by accessing the instance through sys.modules.
Returns:
JellyseerrAPI: The initialized API client instance
Raises:
RuntimeError: If the API client hasn't been initialized
"""
global jellyseerr_api
if jellyseerr_api is None:
# Get the API client instance from the main module
@@ -25,10 +36,19 @@ def get_api():
else:
# This should not happen, but just in case
logger.error("Could not find jellyseerr_api instance")
raise RuntimeError("API client not initialized. This is likely a bug.")
return jellyseerr_api
def safe_int_convert(value, default=None):
"""Safely convert a value to integer, returning default if conversion fails"""
"""Safely convert a value to integer, returning default if conversion fails.
Args:
value: The value to convert to an integer
default: The default value to return if conversion fails
Returns:
int or default: The converted integer or the default value
"""
if value is None:
return default
try:
@@ -37,13 +57,25 @@ def safe_int_convert(value, default=None):
return default
class MediaCommands(commands.Cog):
"""Commands for searching and displaying media information."""
def __init__(self, bot):
"""Initialize the MediaCommands cog.
Args:
bot: The Discord bot instance
"""
self.bot = bot
self.embed_color = config.EMBED_COLOR
@commands.command(name="info", aliases=["i"])
async def get_media_info(self, ctx, media_id = None):
"""Get detailed information about a movie or TV show by ID (auto-detects type)"""
"""Get detailed information about a movie or TV show by ID (auto-detects type).
Args:
ctx: The command context
media_id: The TMDB ID of the movie or TV show
"""
if not media_id:
await ctx.send("Please provide a media ID. Example: `!info 550` (for Fight Club)")
return
@@ -219,13 +251,24 @@ class MediaCommands(commands.Cog):
f"2. Your Jellyseerr account doesn't have permission to view this media\n\n"
f"Try using `{config.BOT_PREFIX}testmedia {media_id}` for more information.")
except aiohttp.ClientConnectorError as e:
logger.error(f"Connection error retrieving media details for ID {media_id}: {str(e)}", exc_info=True)
await ctx.send(f"Error connecting to Jellyseerr server. Please check if the server is running and try again later.")
except asyncio.TimeoutError:
logger.error(f"Request timed out for media ID {media_id}", exc_info=True)
await ctx.send(f"Request timed out. The Jellyseerr server might be slow or overloaded. Please try again later.")
except Exception as e:
logger.error(f"Error retrieving media details for ID {media_id}: {str(e)}", exc_info=True)
await ctx.send(f"Error retrieving media details: {str(e)}")
@commands.command(name="search", aliases=["s"])
async def search_media(self, ctx, *, query: str = None):
"""Search for movies and TV shows by title"""
"""Search for movies and TV shows by title.
Args:
ctx: The command context
query: The search query/term
"""
if not query:
await ctx.send("Please provide a search term. Example: `!search Stranger Things`")
return
@@ -282,14 +325,25 @@ class MediaCommands(commands.Cog):
await ctx.send(embed=embed)
except aiohttp.ClientConnectorError:
logger.error(f"Connection error while searching for '{query}'", exc_info=True)
await ctx.send(f"Error connecting to Jellyseerr server. Please check if the server is running and try again later.")
except asyncio.TimeoutError:
logger.error(f"Search request timed out for '{query}'", exc_info=True)
await ctx.send(f"Search request timed out. The Jellyseerr server might be slow or overloaded. Please try again later.")
except Exception as e:
logger.error(f"Error searching for '{query}': {str(e)}", exc_info=True)
await ctx.send(f"Error searching for media: {str(e)}")
# Movie and TV commands removed - replaced by the unified info command
@commands.command(name="trending")
async def get_trending(self, ctx):
"""Get trending movies and TV shows"""
"""Get trending movies and TV shows.
Args:
ctx: The command context
"""
async with ctx.typing():
try:
api = get_api()
@@ -333,11 +387,25 @@ class MediaCommands(commands.Cog):
await ctx.send(embed=embed)
except aiohttp.ClientConnectorError:
logger.error("Connection error while retrieving trending media", exc_info=True)
await ctx.send(f"Error connecting to Jellyseerr server. Please check if the server is running and try again later.")
except asyncio.TimeoutError:
logger.error("Trending request timed out", exc_info=True)
await ctx.send(f"Request timed out. The Jellyseerr server might be slow or overloaded. Please try again later.")
except Exception as e:
logger.error(f"Error retrieving trending media: {str(e)}", exc_info=True)
await ctx.send(f"Error retrieving trending media: {str(e)}")
class RequestCommands(commands.Cog):
"""Commands for managing media requests."""
def __init__(self, bot):
"""Initialize the RequestCommands cog.
Args:
bot: The Discord bot instance
"""
self.bot = bot
self.embed_color = config.EMBED_COLOR
@@ -481,7 +549,13 @@ class RequestCommands(commands.Cog):
elif "401" in error_message or "403" in error_message:
await ctx.send(f"Error creating request: Authentication error. The bot account may not have permission to make requests.")
else:
await ctx.send(f"Error creating request: {str(e)}")
# Provide more specific error messages for common issues
if "already exists" in str(e).lower():
await ctx.send(f"This media has already been requested or is already available in your library.")
elif "not found" in str(e).lower():
await ctx.send(f"Media not found. Please check the ID and try again.")
else:
await ctx.send(f"Error creating request: {str(e)}")
@commands.command(name="requests", aliases=["reqs"])
async def list_requests(self, ctx, status: str = "pending", page = 1):
@@ -571,7 +645,14 @@ class RequestCommands(commands.Cog):
await ctx.send(embed=embed)
except aiohttp.ClientConnectorError:
logger.error(f"Connection error while retrieving {status} requests", exc_info=True)
await ctx.send(f"Error connecting to Jellyseerr server. Please check if the server is running and try again later.")
except asyncio.TimeoutError:
logger.error(f"Request timed out while retrieving {status} requests", exc_info=True)
await ctx.send(f"Request timed out. The Jellyseerr server might be slow or overloaded. Please try again later.")
except Exception as e:
logger.error(f"Error retrieving {status} requests: {str(e)}", exc_info=True)
await ctx.send(f"Error retrieving requests: {str(e)}")
# Approve and decline commands have been removed
@@ -579,6 +660,11 @@ class RequestCommands(commands.Cog):
# UtilityCommands have been moved to utility_commands.py
def setup(bot):
"""Set up the command cogs.
Args:
bot: The Discord bot instance
"""
bot.add_cog(MediaCommands(bot))
bot.add_cog(RequestCommands(bot))
bot.add_cog(UtilityCommands(bot))