diff --git a/bot.py b/bot.py index fb9603e..54754d3 100644 --- a/bot.py +++ b/bot.py @@ -90,7 +90,7 @@ class DiscordBot(commands.Bot): if os.path.exists(init_file): try: await self.load_extension(f"cogs.{folder}") - if folder not in ["fun", "general"]: + if folder not in ["fun", "general", "idevice"]: self.logger.info(f"Loaded extension '{folder}'") except Exception as e: exception = f"{type(e).__name__}: {e}" diff --git a/cogs/help.py b/cogs/help.py index 1a687d0..ae4b4b2 100644 --- a/cogs/help.py +++ b/cogs/help.py @@ -38,17 +38,14 @@ class Help(commands.Cog, name="help"): category_mapping = { # General Commands - "help": "general", - "botinfo": "general", - "serverinfo": "general", - "ping": "general", - "feedback": "general", - "uptime": "general", - # "context_menus": "general", - + "general": "general", + # Fun Commands "fun": "fun", + # idevice Commands + "idevice": "idevice", + # Moderation Commands "kick": "moderation", "ban": "moderation", @@ -70,13 +67,6 @@ class Help(commands.Cog, name="help"): "afc": "sidestore", "udid": "sidestore", - # idevice Commands - "idevice": "idevice", - "noapps": "idevice", - "errorcodes": "idevice", - "developermode": "idevice", - "mountddi": "idevice", - # Owner Commands "sync": "owner", "cog_management": "owner", @@ -180,7 +170,7 @@ class Help(commands.Cog, name="help"): commands_in_category.append((app_command.name, description)) seen_names.add(app_command.name) - if hasattr(app_command, 'commands') and category == "fun": + if hasattr(app_command, 'commands') and category in ["fun", "general", "idevice"]: for subcommand in app_command.commands: if subcommand.name in seen_names: continue diff --git a/cogs/idevice/__init__.py b/cogs/idevice/__init__.py new file mode 100644 index 0000000..3bdda61 --- /dev/null +++ b/cogs/idevice/__init__.py @@ -0,0 +1,59 @@ +import discord +from discord.ext import commands +from discord.ext.commands import Context + +from .idevice import idevice_command +from .error_codes import errorcodes_command +from .developermode import developermode_command +from .noapps import noapps_command +from .mountddi import mountddi_command + +class Idevice(commands.GroupCog, name="idevice"): + def __init__(self, bot) -> None: + self.bot = bot + super().__init__() + + @commands.hybrid_command( + name="idevice", + description="Get help with idevice commands and troubleshooting." + ) + async def idevice(self, context): + return await idevice_command()(self, context) + + @commands.hybrid_command( + name="errorcodes", + description="Look up error codes and their meanings." + ) + async def errorcodes(self, context, *, error_code: str = None): + return await errorcodes_command()(self, context, error_code=error_code) + + @commands.hybrid_command( + name="developermode", + description="How to turn on developer mode" + ) + async def developermode(self, context): + return await developermode_command()(self, context) + + @commands.hybrid_command( + name="noapps", + description="Help when apps aren't showing in installed apps view" + ) + async def noapps(self, context): + return await noapps_command()(self, context) + + @commands.hybrid_command( + name="mountddi", + description="How to manually mount DDI" + ) + async def mountddi(self, context): + return await mountddi_command()(self, context) + +async def setup(bot) -> None: + cog = Idevice(bot) + await bot.add_cog(cog) + + bot.logger.info("Loaded extension 'idevice.idevice'") + bot.logger.info("Loaded extension 'idevice.errorcodes'") + bot.logger.info("Loaded extension 'idevice.developermode'") + bot.logger.info("Loaded extension 'idevice.noapps'") + bot.logger.info("Loaded extension 'idevice.mountddi'") diff --git a/cogs/idevice/developermode.py b/cogs/idevice/developermode.py index 1be3ba7..aad0595 100644 --- a/cogs/idevice/developermode.py +++ b/cogs/idevice/developermode.py @@ -5,14 +5,11 @@ from discord.ext.commands import Context import time -class Developermode(commands.Cog, name="developermode"): - def __init__(self, bot) -> None: - self.bot = bot - +def developermode_command(): @commands.hybrid_command( name="developermode", description="How to turn on developer mode" ) - async def developermode(self, context: Context) -> None: + async def developermode(self, context): embed = discord.Embed( color=0xfa8c4a, description=( @@ -40,7 +37,5 @@ class Developermode(commands.Cog, name="developermode"): await context.interaction.response.send_message(embed=embed, view=view) else: await context.send(embed=embed, view=view) - - -async def setup(bot) -> None: - await bot.add_cog(Developermode(bot)) + + return developermode diff --git a/cogs/idevice/error_codes.py b/cogs/idevice/error_codes.py index cc616f2..0a1560f 100644 --- a/cogs/idevice/error_codes.py +++ b/cogs/idevice/error_codes.py @@ -6,54 +6,41 @@ from discord.ext import commands from discord.ext.commands import Context -class ErrorCodes(commands.Cog, name="errorcodes"): - def __init__(self, bot) -> None: - self.bot = bot - self.errors = self.load_errors() - self.key_to_data = {error['name']: (error['description'], error['code']) for error in self.errors} - self.code_to_key = {error['code']: error['name'] for error in self.errors} - - def load_errors(self): - json_path = os.path.join(os.path.dirname(__file__), 'files/errorcodes.json') - try: - with open(json_path, 'r', encoding='utf-8') as f: - return json.load(f) - except FileNotFoundError: - self.bot.logger.error(f"Error codes JSON file not found: {json_path}") - return [] - except json.JSONDecodeError as e: - self.bot.logger.error(f"Error parsing error codes JSON: {e}") - return [] - - async def errorcode_autocomplete(self, interaction: discord.Interaction, current: str): - current_lower = current.lower() - items = [] - for key, (title, code) in self.key_to_data.items(): - if not current or current_lower in key.lower() or current_lower in title.lower() or current_lower in str(code): - items.append(app_commands.Choice(name=f"{key} ยป {title} ({code})", value=key)) - if len(items) >= 25: - break - return items - - @commands.hybrid_command(name="errorcode", description="Look up an idevice error code by name or number") +def errorcodes_command(): + @commands.hybrid_command(name="errorcodes", description="Look up an idevice error code by name or number") @app_commands.describe(name="Start typing to search all error names and codes") - @app_commands.autocomplete(name=errorcode_autocomplete) - async def errorcode(self, context: Context, name: str): + async def errorcodes(self, context, name: str): + def load_errors(): + json_path = os.path.join(os.path.dirname(__file__), 'files/errorcodes.json') + try: + with open(json_path, 'r', encoding='utf-8') as f: + return json.load(f) + except FileNotFoundError: + self.bot.logger.error(f"Error codes JSON file not found: {json_path}") + return [] + except json.JSONDecodeError as e: + self.bot.logger.error(f"Error parsing error codes JSON: {e}") + return [] + + errors = load_errors() + key_to_data = {error['name']: (error['description'], error['code']) for error in errors} + code_to_key = {error['code']: error['name'] for error in errors} + key = name - if key not in self.key_to_data: + if key not in key_to_data: try: num = int(name) - key = self.code_to_key.get(num) + key = code_to_key.get(num) except ValueError: key = None - if key is None or key not in self.key_to_data: + if key is None or key not in key_to_data: if context.interaction: await context.interaction.response.send_message("Error not found.", ephemeral=True) else: await context.send("Error not found.") return - title, code = self.key_to_data[key] + title, code = key_to_data[key] embed = discord.Embed( description=f"## Error Code: {code}\n\n**Name**: `{key}`\n**Description**: {title}", @@ -73,9 +60,7 @@ class ErrorCodes(commands.Cog, name="errorcodes"): await context.interaction.response.send_message(embed=embed, view=view) else: await context.send(embed=embed, view=view) - -async def setup(bot) -> None: - cog = ErrorCodes(bot) - await bot.add_cog(cog) + + return errorcodes diff --git a/cogs/idevice/idevice.py b/cogs/idevice/idevice.py index 75c8390..44caa79 100644 --- a/cogs/idevice/idevice.py +++ b/cogs/idevice/idevice.py @@ -253,14 +253,11 @@ class ideviceView(discord.ui.View): self.add_item(ideviceSelect(bot)) -class idevice(commands.Cog, name="idevice"): - def __init__(self, bot) -> None: - self.bot = bot - +def idevice_command(): @commands.hybrid_command( name="idevice", description="idevice troubleshooting and help" ) - async def idevice(self, context: Context) -> None: + async def idevice(self, context): embed = discord.Embed( title="idevice Commands", description="Choose a command from the dropdown below to get help with specific issues:", @@ -274,8 +271,5 @@ class idevice(commands.Cog, name="idevice"): await context.interaction.response.send_message(embed=embed, view=view, ephemeral=True) else: await context.send(embed=embed, view=view) - - - -async def setup(bot) -> None: - await bot.add_cog(idevice(bot)) \ No newline at end of file + + return idevice \ No newline at end of file diff --git a/cogs/idevice/mountddi.py b/cogs/idevice/mountddi.py index adebf13..505b808 100644 --- a/cogs/idevice/mountddi.py +++ b/cogs/idevice/mountddi.py @@ -4,16 +4,13 @@ from discord.ext.commands import Context import os -class Mountddi(commands.Cog, name="mountddi"): - def __init__(self, bot) -> None: - self.bot = bot - +def mountddi_command(): @commands.hybrid_command( name="mountddi", description="How to manually mount DDI" ) - async def mountddi(self, ctx: Context) -> None: - await ctx.defer() + async def mountddi(self, context): + await context.defer() embed = discord.Embed( color=0xfa8c4a, @@ -46,15 +43,12 @@ class Mountddi(commands.Cog, name="mountddi"): emoji="<:githubicon:1417717356846776340>" )) - ddi_file_path = os.path.join(os.path.dirname(__file__), 'files/DDI.zip') file = discord.File(ddi_file_path, filename='DDI.zip') if os.path.exists(ddi_file_path) else None if file: - await ctx.send(embed=embed, view=view, file=file) + await context.send(embed=embed, view=view, file=file) else: - await ctx.send(embed=embed, view=view) - - -async def setup(bot) -> None: - await bot.add_cog(Mountddi(bot)) + await context.send(embed=embed, view=view) + + return mountddi diff --git a/cogs/idevice/noapps.py b/cogs/idevice/noapps.py index 2e54b72..386c27b 100644 --- a/cogs/idevice/noapps.py +++ b/cogs/idevice/noapps.py @@ -5,14 +5,11 @@ from discord.ext.commands import Context import time -class Noapps(commands.Cog, name="noapps"): - def __init__(self, bot) -> None: - self.bot = bot - +def noapps_command(): @commands.hybrid_command( name="noapps", description="Help when apps aren't showing in installed apps view" ) - async def noapps(self, context: Context) -> None: + async def noapps(self, context): embed = discord.Embed( color=0xfa8c4a, description=( @@ -41,7 +38,5 @@ class Noapps(commands.Cog, name="noapps"): await context.interaction.response.send_message(embed=embed, view=view) else: await context.send(embed=embed, view=view) - - -async def setup(bot) -> None: - await bot.add_cog(Noapps(bot)) + + return noapps