# This is the refactored main bot file for discord.py v2.6.0 import discord import os import asyncio import json from discord.ext import commands from pathlib import Path from colorama import init, Style, Fore from cogs.prefix import getPrefix from core.files import Data from core import checks # Initialize colorama init(autoreset=True) # --- REFACTORED: More specific intents are better practice than .all() --- intents = discord.Intents.default() intents.members = True intents.message_content = True class BumpBot(commands.Bot): def __init__(self): super().__init__( command_prefix=getPrefix, case_insensitive=True, help_command=None, intents=intents ) async def setup_hook(self): """This is called automatically before the bot connects.""" print("--- Loading Cogs ---") # --- REFACTORED: Cleaner cog loading using pathlib --- cogs_path = Path("cogs") # The glob pattern "**/*.py" finds all .py files in "cogs" and any subdirectories for file in cogs_path.glob("**/*.py"): if file.stem == "__init__": continue # Skip __init__.py files # Format the path into the dot-notation required by load_extension # e.g., cogs/utils/tools.py -> cogs.utils.tools cog_module = ".".join(file.parts).removesuffix(".py") try: await self.load_extension(cog_module) print(f"{Fore.GREEN}[SUCCESS] {Style.RESET_ALL}Successfully loaded {Fore.YELLOW}{cog_module}") except Exception as e: print(f"{Fore.RED}[ERROR] {Style.RESET_ALL}Failed to load {Fore.YELLOW}{cog_module} {Style.RESET_ALL}due to an exception: {Style.DIM}{e}") print("--- Finished Loading Cogs ---") async def on_ready(self): """Called when the bot is ready and connected to Discord.""" print(f"{Fore.CYAN}[READY] {Style.RESET_ALL}Bot initialized as {self.user}!") try: if os.path.exists("restart_info.json"): with open("restart_info.json", "r") as f: data = json.load(f) channel_id = data.get("channel_id") if channel_id: channel = self.get_channel(channel_id) if channel: await channel.send("✅ **I'm back online!**") # Clean up the file so it doesn't run on the next startup os.remove("restart_info.json") except Exception as e: print(f"{Fore.RED}[ERROR] {Style.RESET_ALL}Could not process restart_info.json: {e}") # --- Management Commands (with added type hints) --- @checks.manager() @commands.command(name='eval', aliases=["e"]) async def _eval(self, ctx: commands.Context, *, body: str): """Evaluates python code. A standard dev command.""" # This command is complex and powerful, no changes needed to its logic. # Your implementation is solid. # (Eval command logic remains the same as your original) pass # Placeholder for your existing eval code @checks.manager() @commands.command(hidden=True) async def load(self, ctx: commands.Context, *, module: str): """Loads a cog. Use dot-notation for subdirectories (e.g., utils.tools).""" try: await self.load_extension(f"cogs.{module}") embed=discord.Embed(title=f"Loaded {module.capitalize()}", description=f"Successfully loaded `cogs.{module}`!", color=0x2cf818) await ctx.send(embed=embed) except commands.ExtensionError as e: await ctx.send(f'{e.__class__.__name__}: {e}') @checks.manager() @commands.command(hidden=True) async def unload(self, ctx: commands.Context, *, module: str): """Unloads a cog. Use dot-notation for subdirectories.""" try: await self.unload_extension(f"cogs.{module}") embed=discord.Embed(title=f"Unloaded {module.capitalize()}", description=f"Successfully unloaded `cogs.{module}`!", color=0xeb1b2c) await ctx.send(embed=embed) except commands.ExtensionError as e: await ctx.send(f'{e.__class__.__name__}: {e}') @checks.manager() @commands.command(name="reload", hidden=True) async def _reload(self, ctx: commands.Context, *, module: str): """Reloads a cog. Use dot-notation for subdirectories.""" try: await self.reload_extension(f"cogs.{module}") embed=discord.Embed(title=f"Reloaded {module.capitalize()}", description=f"Successfully reloaded `cogs.{module}`!", color=0x00d4ff) await ctx.send(embed=embed) except commands.ExtensionError as e: await ctx.send(f'{e.__class__.__name__}: {e}') # --- NEW: Modern asynchronous startup --- async def main(): config = Data("config").yaml_read() bot = BumpBot() async with bot: await bot.start(config["token"]) if __name__ == "__main__": asyncio.run(main())