1
Fork 0
mirror of https://github.com/wlinator/luminara.git synced 2024-10-02 20:23:12 +00:00
Lumi/main.py

196 lines
6.3 KiB
Python
Raw Normal View History

2023-06-19 14:20:17 +00:00
import os
2023-07-02 15:33:25 +00:00
import platform
2024-02-27 17:23:59 +00:00
import sys
2024-03-14 20:13:54 +00:00
import traceback
2023-06-19 14:20:17 +00:00
import discord
2024-03-16 14:05:40 +00:00
from discord.ext import commands, bridge
2023-06-19 14:20:17 +00:00
from dotenv import load_dotenv
2024-03-07 19:26:11 +00:00
from lib import embeds
from config import json_loader
2023-06-29 11:35:12 +00:00
from handlers.ReactionHandler import ReactionHandler
2023-06-29 11:21:17 +00:00
from handlers.XPHandler import XPHandler
2024-02-28 13:01:20 +00:00
from handlers import LoggingHandler
2024-03-07 19:26:11 +00:00
from services.GuildConfig import GuildConfig
2023-06-19 14:20:17 +00:00
2024-02-27 17:23:59 +00:00
load_dotenv('.env')
instance = os.getenv("INSTANCE")
2024-03-16 14:05:40 +00:00
def get_prefix(bot, message):
return GuildConfig.get_prefix(message.guild.id)
client = bridge.Bot(
2023-07-02 13:50:21 +00:00
owner_id=os.getenv('OWNER_ID'),
2024-03-16 14:05:40 +00:00
command_prefix='!',
2023-07-02 13:50:21 +00:00
intents=discord.Intents.all(),
2023-07-13 18:43:25 +00:00
status=discord.Status.online
2023-07-02 13:50:21 +00:00
)
2024-02-28 13:01:20 +00:00
logs = LoggingHandler.setup_logger()
2023-07-02 13:50:21 +00:00
2024-02-28 13:01:20 +00:00
@client.event
2023-06-19 14:20:17 +00:00
async def on_ready():
2024-02-28 13:01:20 +00:00
logs.info(f"[INFO] Logged in as {client.user.name}")
logs.info(f"[INFO] discord.py API version: {discord.__version__}")
logs.info(f"[INFO] Python version: {platform.python_version()}")
logs.info(f"[INFO] Running on: {platform.system()} {platform.release()} ({os.name})")
logs.info("-------------------------------------------------------")
2023-06-29 09:33:00 +00:00
2023-06-19 14:20:17 +00:00
"""
https://docs.pycord.dev/en/stable/api/events.html#discord.on_ready
This function isn't guaranteed to only be called once.
Event is called when RESUME request fails.
"""
@client.listen()
2023-06-29 11:21:17 +00:00
async def on_message(message):
2024-02-28 13:01:20 +00:00
if message.author.bot or instance.lower() != "main":
2024-02-28 11:09:04 +00:00
return
2024-02-27 17:23:59 +00:00
2023-07-02 15:33:25 +00:00
try:
xp_handler = XPHandler()
await xp_handler.process_xp(message)
reaction_handler = ReactionHandler(reactions)
await reaction_handler.handle_message(message)
2023-06-29 11:21:17 +00:00
2023-07-02 15:33:25 +00:00
except Exception as error:
2024-02-28 13:01:20 +00:00
logs.error(f"[EventHandler] on_message (check debug log): {error}", exc_info=False)
logs.debug(f"[EventHandler] on_message (w/ stacktrace): {error}", exc_info=True)
2023-06-29 11:35:12 +00:00
2023-06-29 11:21:17 +00:00
2024-02-28 13:01:20 +00:00
@client.event
2023-06-29 12:48:52 +00:00
async def on_member_join(member):
2024-03-07 19:26:11 +00:00
config = GuildConfig(member.guild.id)
2023-06-29 12:48:52 +00:00
2024-03-07 19:26:11 +00:00
if (not config.welcome_channel_id
2023-06-29 12:48:52 +00:00
2024-03-07 19:26:11 +00:00
# comment next line if debugging greetings
or instance.lower() != "main"
):
2024-02-27 18:20:21 +00:00
return
2024-03-07 19:26:11 +00:00
embed = embeds.welcome_message(member, config.welcome_message)
2024-03-07 19:26:11 +00:00
try:
await member.guild.get_channel(config.welcome_channel_id).send(embed=embed, content=member.mention)
except Exception as e:
logs.info(f"[GreetingHandler] Message not sent in '{member.guild.name}'. Channel ID may be invalid. {e}")
2023-06-29 12:48:52 +00:00
2024-02-28 13:01:20 +00:00
@client.event
2023-07-02 15:33:25 +00:00
async def on_application_command_completion(ctx) -> None:
"""
This code is executed when a slash_command has been successfully executed.
2024-02-27 18:20:21 +00:00
This technically serves as a CommandHandler function
2023-07-02 15:33:25 +00:00
:param ctx:
:return:
"""
full_command_name = ctx.command.qualified_name
split = full_command_name.split(" ")
executed_command = str(split[0])
if ctx.guild is not None:
2024-02-28 13:01:20 +00:00
# logs.info(
2024-02-27 18:20:21 +00:00
# f"Executed {executed_command} command in {ctx.guild.name} (ID: {ctx.guild.id}) "
# f"by {ctx.author} (ID: {ctx.author.id})"
# )
2024-02-28 13:01:20 +00:00
logs.info(f"[CommandHandler] {ctx.author.name} successfully did \"/{executed_command}\". "
2024-03-07 19:26:11 +00:00
f"| guild: {ctx.guild.name} ")
2023-07-02 15:33:25 +00:00
else:
2024-02-28 13:01:20 +00:00
# logs.info(
2024-02-27 18:20:21 +00:00
# f"Executed {executed_command} command by {ctx.author} (ID: {ctx.author.id}) in DMs."
# )
2024-02-28 13:01:20 +00:00
logs.info(f"[CommandHandler] {ctx.author.name} successfully did \"/{executed_command}\". | direct message")
2023-07-02 15:33:25 +00:00
2024-02-28 13:01:20 +00:00
@client.event
2024-01-02 13:32:02 +00:00
async def on_application_command_error(ctx, error) -> None:
if isinstance(error, commands.CommandOnCooldown):
2023-07-12 15:36:00 +00:00
2024-01-02 13:32:02 +00:00
seconds = error.retry_after
minutes = seconds // 60
seconds %= 60
cooldown = "{:02d}:{:02d}".format(int(minutes), int(seconds))
2023-07-12 15:36:00 +00:00
2024-01-02 13:32:02 +00:00
await ctx.respond(
f"⏳ | **{ctx.author.name}** you are on cooldown. "
f"You can use this command again in **{cooldown}**.",
ephemeral=True)
2023-07-12 15:36:00 +00:00
2024-02-28 13:01:20 +00:00
logs.info(f"[CommandHandler] {ctx.author.name} tried to do a command on cooldown.")
2023-07-12 15:36:00 +00:00
2024-01-02 13:32:02 +00:00
elif isinstance(error, commands.MissingPermissions):
await ctx.respond(strings["error_missing_permissions"].format(ctx.author.name), ephemeral=True)
2024-02-28 13:01:20 +00:00
logs.info(f"[CommandHandler] {ctx.author.name} has missing permissions to do a command: "
2024-03-07 19:26:11 +00:00
f"{ctx.command.qualified_name}")
2023-08-08 10:53:06 +00:00
2024-01-02 13:32:02 +00:00
elif isinstance(error, commands.BotMissingPermissions):
await ctx.respond(strings["error_bot_missing_permissions"].format(ctx.author.name), ephemeral=True)
2024-02-28 13:01:20 +00:00
logs.info(f"[CommandHandler] Racu is missing permissions: {ctx.command.qualified_name}")
2024-03-07 19:26:11 +00:00
2024-03-04 10:25:00 +00:00
elif isinstance(error, discord.CheckFailure) or isinstance(error, commands.CheckFailure):
2024-03-07 19:26:11 +00:00
logs.info(
2024-03-14 20:13:54 +00:00
f"[CommandHandler] {ctx.author.name} tried to do \"/{ctx.command.qualified_name}\" "
f"but a check returned False.")
2023-08-08 10:53:06 +00:00
2024-01-02 13:32:02 +00:00
else:
2024-03-14 20:13:54 +00:00
logs.error(f"[CommandHandler] on_application_command_error: {error}")
traceback.print_tb(error.original.__traceback__)
2024-02-27 17:23:59 +00:00
2023-07-02 15:43:13 +00:00
2024-02-28 13:01:20 +00:00
@client.event
2024-01-02 13:32:02 +00:00
async def on_error(event: str, *args, **kwargs) -> None:
2024-02-28 13:01:20 +00:00
logs.error(f"[EventHandler] on_error INFO: errors.event.{event} | '*args': {args} | '**kwargs': {kwargs}")
logs.error(f"[EventHandler] on_error EXCEPTION: {sys.exc_info()}")
2023-07-02 15:33:25 +00:00
2023-07-02 13:50:21 +00:00
# load all json
strings = json_loader.load_strings()
economy_config = json_loader.load_economy_config()
reactions = json_loader.load_reactions()
# Keep track of loaded module filenames
loaded_modules = set()
def load_cogs():
# sort modules alphabetically purely for an easier overview in logs
for filename in sorted(os.listdir('./modules')):
if filename in loaded_modules:
continue # module is already loaded
2023-07-02 13:50:21 +00:00
if filename.endswith('.py'):
module_name = f'modules.{filename[:-3]}'
try:
2024-02-28 13:01:20 +00:00
client.load_extension(module_name)
2023-07-02 13:50:21 +00:00
loaded_modules.add(filename)
2024-02-28 13:01:20 +00:00
logs.info(f"[MODULE] {filename[:-3].upper()} loaded.")
2023-07-02 13:50:21 +00:00
except Exception as e:
2024-02-28 13:01:20 +00:00
logs.error(f"[MODULE] Failed to load module {filename}: {e}")
2023-07-02 13:50:21 +00:00
if __name__ == '__main__':
"""
This code is only ran when main.py is the primary module,
thus NOT when main is imported from a cog. (sys.modules)
"""
2024-02-28 13:01:20 +00:00
logs.info("RACU IS BOOTING")
logs.info("\n")
2024-02-27 14:09:59 +00:00
load_cogs()
2024-02-27 14:09:59 +00:00
# empty line to separate modules from system info in logs
2024-02-28 13:01:20 +00:00
logs.info("\n")
2024-02-27 17:23:59 +00:00
2024-02-28 13:01:20 +00:00
client.run(os.getenv('TOKEN'))