Files
Gwendolyn/utils/eventHandlers.py
NikolajDanger 06b5d881ea 🔀 Merging with master
2021-06-14 21:06:51 +02:00

177 lines
6.8 KiB
Python

"""
Classes used to handle bot events and errors.
*Classes*
---------
EventHandler
ErrorHandler
"""
import discord # Used to init discord.Game and discord.Status, as well
# as compare errors to discord errors and as typehints
import traceback # Used to get the traceback of errors
import sys # Used to get traceback when the specific error is not
# available
from discord.ext import commands # Used to compare errors with command
# errors
from discord_slash.context import SlashContext
from utils.utilFunctions import emojiToCommand
class EventHandler():
"""
Handles bot events.
*Methods*
---------
on_ready()
on_slash_command(ctx: discord_slash.context.SlashContext)
on_reaction_add(ctx: discord_slash.context.SlashContext)
"""
def __init__(self, bot):
"""Initialize the handler."""
self.bot = bot
async def on_ready(self):
"""Log and sets status when it logs in."""
await self.bot.databaseFuncs.syncCommands()
name = self.bot.user.name
userid = str(self.bot.user.id)
loggedInMessage = f"Logged in as {name}, {userid}"
self.bot.log(loggedInMessage, level=25)
game = discord.Game("Use /help for commands")
onlineStatus = discord.Status.online
await self.bot.change_presence(activity=game, status=onlineStatus)
async def on_slash_command(self, ctx: SlashContext):
"""Log when a slash command is given."""
if ctx.subcommand_name is not None:
subcommand = f" {ctx.subcommand_name} "
else:
subcommand = " "
if ctx.subcommand_group is not None:
subcommandGroup = f"{ctx.subcommand_group} "
else:
subcommandGroup = ""
args = " ".join([str(i) for i in ctx.args])
fullCommand = f"/{ctx.command}{subcommand}{subcommandGroup}{args}"
logMessage = f"{ctx.author.display_name} ran {fullCommand}"
self.bot.log(logMessage, str(ctx.channel_id), level=25)
async def on_reaction_add(self, reaction: discord.Reaction,
user: discord.User):
"""Take action if the reaction is on a command message."""
if not user.bot:
tests = self.bot.databaseFuncs
message = reaction.message
channel = message.channel
reactedMessage = f"{user.display_name} reacted to a message"
self.bot.log(reactedMessage, str(channel.id))
plexData = tests.bedreNetflixReactionTest(message)
# plexData is a list containing 3 elements: whether it was
# the addshow/addmovie command message the reaction was to
# (bool), whether it's a movie (bool) (if false, it's a
# show), and the imdb ids/names for the for the movies or
# shows listed in the message (list).
reactionTestParams = [message, f"#{str(user.id)}"]
if tests.connectFourReactionTest(*reactionTestParams):
column = emojiToCommand(reaction.emoji)
params = [message, f"#{user.id}", column-1]
await self.bot.games.connectFour.placePiece(*params)
if plexData[0]:
plexFuncs = self.bot.other.bedreNetflix
if plexData[1]:
moviePick = emojiToCommand(reaction.emoji)
if moviePick == "none":
imdbID = None
else:
imdbID = plexData[2][moviePick-1]
if isinstance(channel, discord.DMChannel):
await message.delete()
await plexFuncs.addMovie(message, imdbID, False)
else:
await message.clear_reactions()
await plexFuncs.addMovie(message, imdbID)
else:
showPick = emojiToCommand(reaction.emoji)
if showPick == "none":
imdbName = None
else:
imdbName = plexData[2][showPick-1]
if isinstance(channel, discord.DMChannel):
await message.delete()
await plexFuncs.addShow(message, imdbName, False)
else:
await message.clear_reactions()
await plexFuncs.addShow(message, imdbName)
elif tests.hangmanReactionTest(*reactionTestParams):
self.bot.log("They reacted to the hangman message")
if ord(reaction.emoji) in range(127462, 127488):
# The range is letter-emojis
guess = chr(ord(reaction.emoji)-127397)
# Converts emoji to letter
params = [message, f"#{user.id}", guess]
await self.bot.games.hangman.guess(*params)
else:
self.bot.log("Bot they didn't react with a valid guess")
class ErrorHandler():
"""
Handles errors.
*Methods*
---------
on_slash_command_error(ctx: discord_slash.context.SlashContext,
error: Exception)
on_error(method: str)
"""
def __init__(self, bot):
"""Initialize the handler."""
self.bot = bot
async def on_slash_command_error(self, ctx: SlashContext,
error: Exception):
"""Log when there's a slash command."""
if isinstance(error, commands.CommandNotFound):
await ctx.send("That's not a command")
elif isinstance(error, discord.errors.NotFound):
self.bot.log("Deleted message before I could add all reactions")
elif isinstance(error, commands.errors.MissingRequiredArgument):
self.bot.log(f"{error}", str(ctx.channel_id))
await ctx.send(self.bot.longStrings["missing parameters"])
else:
params = [type(error), error, error.__traceback__]
exception = traceback.format_exception(*params)
exceptionString = "".join(exception)
logMessages = [f"exception in /{ctx.name}", f"{exceptionString}"]
self.bot.log(logMessages, str(ctx.channel_id), 40)
if isinstance(error, discord.errors.NotFound):
self.bot.log("Context is non-existant", level=40)
else:
await ctx.send("Something went wrong (error code 000)")
async def on_error(self, method: str):
"""Log when there's an error."""
errorType = sys.exc_info()[0]
if errorType == discord.errors.NotFound:
self.bot.log("Deleted message before I could add all reactions")
else:
exception = traceback.format_exc()
exceptionString = "".join(exception)
logMessages = [f"exception in {method}", f"{exceptionString}"]
self.bot.log(logMessages, level=40)