jarvis-bot/jarvis/__init__.py

126 lines
4.2 KiB
Python

"""Main J.A.R.V.I.S. package."""
import json
import logging
import traceback
from datetime import datetime
from aiohttp import ClientSession
from dis_snek import Context, Intents, Snake, listen
from jarvis_core.db import connect
# from jarvis import logo # noqa: F401
from jarvis import utils
from jarvis.config import get_config
from jarvis.events import member, message
jconfig = get_config()
logger = logging.getLogger("discord")
logger.setLevel(logging.getLevelName(jconfig.log_level))
file_handler = logging.FileHandler(filename="jarvis.log", encoding="UTF-8", mode="w")
file_handler.setFormatter(logging.Formatter("[%(asctime)s][%(levelname)s][%(name)s] %(message)s"))
logger.addHandler(file_handler)
intents = Intents.DEFAULT | Intents.MESSAGES | Intents.GUILD_MEMBERS
restart_ctx = None
DEFAULT_GUILD = 862402786116763668
DEFAULT_ERROR_CHANNEL = 943395824560394250
DEFAULT_URL = "https://paste.zevs.me/documents"
ERROR_MSG = """
Command Information:
Name: {invoked_name}
Args:
{arg_str}
Callback:
Args:
{callback_args}
Kwargs:
{callback_kwargs}
"""
class Jarvis(Snake):
async def on_command_error(
self, ctx: Context, error: Exception, *args: list, **kwargs: dict
) -> None:
"""Lepton on_command_error override."""
guild = await jarvis.get_guild(DEFAULT_GUILD)
channel = guild.get_channel(DEFAULT_ERROR_CHANNEL)
error_time = datetime.utcnow().strftime("%d-%m-%Y %H:%M-%S.%f UTC")
timestamp = int(datetime.now().timestamp())
timestamp = f"<t:{timestamp}:T>"
arg_str = (
"\n".join(f" {k}: {v}" for k, v in ctx.kwargs.items()) if ctx.kwargs else " None"
)
callback_args = "\n".join(f" - {i}" for i in args) if args else " None"
callback_kwargs = (
"\n".join(f" {k}: {v}" for k, v in kwargs.items()) if kwargs else " None"
)
full_message = ERROR_MSG.format(
error_time=error_time,
invoked_name=ctx.invoked_name,
arg_str=arg_str,
callback_args=callback_args,
callback_kwargs=callback_kwargs,
)
if len(full_message) >= 1900:
error_message = " ".join(traceback.format_exception(error))
full_message += "Exception: |\n " + error_message
async with ClientSession() as session:
resp = await session.post(DEFAULT_URL, data=full_message)
data = await resp.read()
data = json.loads(data.decode("UTF8"))
await channel.send(
f"JARVIS encountered an error at {timestamp}. Log too big to send over Discord."
f"\nPlease see log at https://paste.zevs.me/{data['key']}"
)
else:
error_message = "".join(traceback.format_exception(error))
await channel.send(
f"JARVIS encountered an error at {timestamp}:"
f"\n```yaml\n{full_message}\n```"
f"\nException:\n```py\n{error_message}\n```"
)
await ctx.send("Whoops! Encountered an error. The error has been logged.", ephemeral=True)
return await super().on_command_error(ctx, error, *args, **kwargs)
jarvis = Jarvis(intents=intents, default_prefix="!", sync_interactions=jconfig.sync)
__version__ = "2.0.0a1"
@listen()
async def on_ready() -> None:
"""Lepton on_ready override."""
global restart_ctx
print(" Logged in as {0.user}".format(jarvis)) # noqa: T001
print(" Connected to {} guild(s)".format(len(jarvis.guilds))) # noqa: T001
def run() -> None:
"""Run J.A.R.V.I.S."""
connect(**jconfig.mongo["connect"], testing=jconfig.mongo["database"] == "jarvis")
jconfig.get_db_config()
for extension in utils.get_extensions():
jarvis.load_extension(extension)
print( # noqa: T001
" https://discord.com/api/oauth2/authorize?client_id="
"{}&permissions=8&scope=bot%20applications.commands".format(jconfig.client_id)
)
jarvis.max_messages = jconfig.max_messages
# Add event listeners
if jconfig.events:
_ = [
member.MemberEventHandler(jarvis),
message.MessageEventHandler(jarvis),
]
jarvis.start(jconfig.token)