cogs refactoring, removing useless bloat, main.py refactor
This commit is contained in:
101
main.py
Normal file
101
main.py
Normal file
@@ -0,0 +1,101 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
from dotenv import load_dotenv
|
||||
|
||||
CONFIG_FILE = 'bot_config.json'
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def setup_logging() -> None:
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('bot.log', encoding='utf-8'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
|
||||
def load_config() -> dict:
|
||||
if not os.path.exists(CONFIG_FILE):
|
||||
raise FileNotFoundError(f"Main bot config not found at {CONFIG_FILE}")
|
||||
|
||||
with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# Apply fallbacks
|
||||
settings = config.get("settings", {})
|
||||
settings.setdefault("command_prefix", "!")
|
||||
settings.setdefault("sync_commands", True)
|
||||
config["settings"] = settings
|
||||
config.setdefault("cogs", [])
|
||||
|
||||
return config
|
||||
|
||||
class Bot(commands.Bot):
|
||||
def __init__(self, config: dict):
|
||||
self.config = config
|
||||
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
intents.reactions = True
|
||||
intents.members = True
|
||||
intents.guilds = True
|
||||
intents.messages = True
|
||||
|
||||
super().__init__(
|
||||
command_prefix=self.config["settings"]["command_prefix"],
|
||||
intents=intents,
|
||||
help_command=None,
|
||||
)
|
||||
|
||||
async def setup_hook(self) -> None:
|
||||
for cog in self.config["cogs"]:
|
||||
try:
|
||||
await self.load_extension(cog)
|
||||
logger.info("Loaded cog: %s", cog)
|
||||
except Exception as e:
|
||||
logger.error("Failed to load cog %s: %s", cog, e, exc_info=True)
|
||||
|
||||
if self.config["settings"]["sync_commands"]:
|
||||
try:
|
||||
await self.tree.sync()
|
||||
logger.info("Application commands synced successfully")
|
||||
except Exception as e:
|
||||
logger.error("Failed to sync application commands: %s", e)
|
||||
|
||||
async def on_ready(self) -> None:
|
||||
if not hasattr(self, '_ready_fired'):
|
||||
self._ready_fired = True
|
||||
logger.info("Bot ready: %s (id: %s)", self.user, self.user.id)
|
||||
|
||||
async def main() -> None:
|
||||
setup_logging()
|
||||
load_dotenv()
|
||||
|
||||
token = os.getenv('DISCORD_TOKEN')
|
||||
if not token:
|
||||
logger.critical("DISCORD_TOKEN environment variable is missing; Shutting down")
|
||||
return
|
||||
|
||||
try:
|
||||
config = load_config()
|
||||
except Exception as e:
|
||||
logger.critical("Failed to load configuration: %s", e)
|
||||
return
|
||||
|
||||
bot = Bot(config)
|
||||
|
||||
try:
|
||||
await bot.start(token)
|
||||
except discord.LoginFailure:
|
||||
logger.critical("Improper DISCORD_TOKEN passed; Shutting down")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Bot shutdown via keyboard interrupt")
|
||||
Reference in New Issue
Block a user