async def eval(self, ctx, *, evalStr): """Evaluate a Python expression.""" evalStr = utils.removeCodeBlock(evalStr) logger.info(f"{ctx.author.display_name} tried to eval {evalStr!r}.") # Show user that bot is busy doing something waitMsg = None if isinstance(ctx.channel, discord.TextChannel): waitMsg = await ctx.send(f"{emojis.run_program} Running eval... {emojis.loading}") async with ctx.typing(): try: result = await runEval(ctx, evalStr) except Exception as err: logger.error("eval error:\n" + utils.formatTraceback(err)) await ctx.send(emojis.warning + f" ` {utils.formatError(err)} `") return finally: # Remove wait message when done if waitMsg: await waitMsg.delete(delay=0) if isinstance(result, Embed): await ctx.send(embed=result) else: strResult = str(result).replace("```", r"\`\`\`") for m in utils.chunkMsg(strResult): await ctx.send(m)
async def rainbower(self): try: for guild in self.bot.guilds: for role in guild.roles: if role.name.lower() == "rainbow": await role.edit(color=next(colorgen)) except Exception as err: logger.error(formatTraceback(err))
async def holidayTask(self): """Holiday checker""" try: logger.info("Checking for holidays") now = datetime.now() # Holiday checks. newnick = conf.name newactivityname = conf.activity if now.month == 1 and now.day == 1: # New Year's Day logger.debug("Happy new year!") newnick += f" {intToRoman(int(now.year))}" newactivityname = "Happy New Year!" elif now.month == 3 and now.day == 10: # Digi's birthday logger.debug("Happy birthday Digi!") newnick += " 🎉" newactivityname = "Happy Birthday, DigiDuncan!" elif now.month == 2 and now.day == 8: # Natalie's birthday logger.debug("Happy birthday Natalie!") newnick += " 🎉" newactivityname = "Happy Birthday, Natalie!" elif now.month == 10 and now.day == 31: # Halloween logger.debug("Happy Halloween!") newnick = "SpookBot 🎃" newactivityname = "OoOoOoOo" elif now.month == 12 and now.day == 25: # Christmas logger.debug("Merry Christmas!") newnick = "SizeSanta 🎄" newactivityname = "Merry Christmas!" else: logger.info("Just another boring non-holiday...") for guild in self.bot.guilds: if newnick != guild.me.display_name: logger.info( f"Updating bot nick to \"{newnick}\" in {guild.name}.") await guild.me.edit(nick=newnick) if newactivityname != self.bot.guilds[0].get_member( self.bot.user.id).activity: logger.info(f"Updating bot activity to \"{newactivityname}\".") newactivity = discord.Game(name=newactivityname) await self.bot.change_presence(activity=newactivity) midnight = datetime.combine(now, time(hour=0, minute=0, second=0)) next_midnight = midnight + timedelta(days=1) await sleep_until(next_midnight) except Exception as err: logger.error(formatTraceback(err))
async def evil(self, ctx, *, evalStr): """Evaluate a Python expression, but evilly.""" # PERMISSION: requires manage_messages await ctx.message.delete(delay = 0) evalStr = utils.removeCodeBlock(evalStr) logger.info(f"{ctx.author.display_name} tried to quietly eval {evalStr!r}.") async with ctx.typing(): try: await runEval(ctx, evalStr, returnValue = False) except Exception as err: logger.error("eval error:\n" + utils.formatTraceback(err)) await ctx.author.send(emojis.warning + f" ` {utils.formatError(err)} `")
async def on_error(event, *args, **kwargs): _, error, _ = sys.exc_info() # Get actual error err = getattr(error, "original", error) # DigiException handling if isinstance(err, errors.DigiException): message = err.formatMessage() if message is not None: logger.log(err.level, message) if isinstance(err, errors.DigiContextException): message = str(err) if message is not None: logger.log(err.level, message) else: logger.error(f"Ignoring exception in {event}") logger.error(utils.formatTraceback(error))
async def on_command_error(ctx, error): # Get actual error err = getattr(error, "original", error) # If we got some bad arguments, use a generic argument exception error if isinstance(err, commands.BadUnionArgument) or isinstance(err, commands.MissingRequiredArgument) or isinstance(err, commands.BadArgument): err = errors.ArgumentException() if isinstance(err, commands.NotOwner): err = errors.AdminPermissionException() if isinstance(err, errors.AdminPermissionException): # Log Admin Permission Exceptions to telemetry telem = Telemetry.load() telem.incrementPermissionError(str(ctx.invoked_with)) telem.save() if isinstance(err, errors.DigiContextException): # DigiContextException handling message = await err.formatMessage(ctx) if message is not None: logger.log(err.level, message) userMessage = await err.formatUserMessage(ctx) if userMessage is not None: await ctx.send(userMessage) elif isinstance(err, errors.DigiException): # DigiException handling message = err.formatMessage() if message is not None: logger.log(err.level, message) userMessage = err.formatUserMessage() if userMessage is not None: await ctx.send(userMessage) elif isinstance(err, commands.errors.CommandNotFound): # log unknown commmands to telemetry telem = Telemetry.load() telem.incrementUnknown(str(ctx.invoked_with)) telem.save() else: # Default command error handling await ctx.send("Something went wrong.") logger.error(f"Ignoring exception in command {ctx.command}:") logger.error(utils.formatTraceback(error))
async def holidayTask(self): """Holiday checker""" try: logger.info("Checking for holidays") now = arrow.now() # Holiday checks. newnick = conf.name newactivityname = conf.activity if now.month == 1 and now.day == 1: # New Year's Day logger.info("Happy new year!") newnick += f" {intToRoman(int(now.year))}" newactivityname = "Happy New Year!" elif now.month == 2 and now.day == 14: # Valentine's Day (and AWK's birthday) logger.info("Happy Valentine's Day!") newnick += " 💗" newactivityname = "Happy Valentine's Day!" elif now.month == 3 and now.day == 10: # Digi's birthday logger.info("Happy birthday Digi!") newnick += " 🎉" newactivityname = "Happy Birthday, DigiDuncan!" elif now.month == 2 and now.day == 8: # Natalie's birthday logger.info("Happy birthday Natalie!") newnick += " 🎉" newactivityname = "Happy Birthday, Natalie!" elif now.month == 5 and now.day == 5: # Cinco de Mayo logger.info("Happy Cinco de Mayo!") newnick += " 🇲🇽" newactivityname = "Happy Cinco De Mayo!" elif now.month == 6 and now.day == 6: # Swedish Independence Day logger.info("Happy Swedish Independence Day!") newactivityname = "🇸🇪 AGGA 🇸🇪" elif now.month == 7 and now.day == 1: #Canada Day logger.info("Happy Canada Day!") newnick += " 🍁" newactivityname = "Happy Canada Day!" elif now.month == 7 and now.day == 4: # Fourth of July logger.info("Happy Fourth of July!") newnick += " 🇺🇸" newactivityname = "Happy Fourth of July!" elif now.month == 10 and now.day == 31: # Halloween logger.info("Happy Halloween!") newnick = "SpookBot 🎃" newactivityname = "OoOoOoOo" elif now.month == 12 and now.day == 25: # Christmas logger.info("Merry Christmas!") newnick = newnick[0] + "izeSanta 🎄" newactivityname = "Merry Christmas!" else: logger.info("Just another boring non-holiday...") for guild in self.bot.guilds: if not guild.me.guild_permissions.change_nickname: logger.info( f"Skipping changing nick in {guild.name} due to missing permissions." ) continue if newnick != guild.me.display_name: logger.info( f"Updating bot nick to \"{newnick}\" in {guild.name}.") # PERMISSION: requires change_nickname await guild.me.edit(nick=newnick) if self.bot.activity and newactivityname != self.bot.activity.name: logger.info(f"Updating bot activity to \"{newactivityname}\".") newactivity = discord.Game(name=newactivityname) await self.bot.change_presence(activity=newactivity) next_midnight = arrow.get(now).replace(hour=0, minute=0, second=0).shift(days=1) await sleep_until(next_midnight.datetime) except Exception as err: logger.error(formatTraceback(err))
async def on_command_error(ctx, error): # Get actual error err = getattr(error, "original", error) # TODO: Check if command exists better if ctx.command is not None: telemetry.ErrorThrown(ctx.command.name, error.__class__.__name__).save() # If we got some bad arguments, use a generic argument exception error if isinstance(err, commands.BadUnionArgument) or isinstance( err, commands.MissingRequiredArgument) or isinstance( err, commands.BadArgument): err = errors.ArgumentException() if isinstance(err, commands.NotOwner): err = errors.AdminPermissionException() if isinstance(err, commands.BadMultilineCommand): err = errors.MultilineAsNonFirstCommandException() if isinstance(err, errors.AdminPermissionException): # Log Admin Permission Exceptions to telemetry telemetry.AdminCommand(ctx.author.id, ctx.command.name).save() if isinstance(err, errors.DigiContextException): # DigiContextException handling message = await err.formatMessage(ctx) if message is not None: logger.log(err.level, message) userMessage = await err.formatUserMessage(ctx) if userMessage is not None: await ctx.send(f"{emojis.warning} {userMessage}") elif isinstance(err, errors.DigiException): # DigiException handling message = err.formatMessage() if message is not None: logger.log(err.level, message) userMessage = err.formatUserMessage() if userMessage is not None: await ctx.send(f"{emojis.warning} {userMessage}") elif isinstance(err, commands.errors.CommandNotFound): # log unknown commmands to telemetry telemetry.UnknownCommand( ctx.message.content.split(" ")[0][1:]).save() elif isinstance(err, commands.errors.MissingRequiredArgument): await ctx.send( f"{emojis.warning} Missing required argument(s) for `{ctx.prefix}{ctx.command}`." ) elif isinstance(err, commands.errors.ExpectedClosingQuoteError): await ctx.send(f"{emojis.warning} Mismatched quotes in command.") elif isinstance(err, commands.errors.InvalidEndOfQuotedStringError): await ctx.send( f"{emojis.warning} No space after a quote in command. Are your arguments smushed together?" ) elif isinstance(err, commands.errors.UnexpectedQuoteError): await ctx.send( f"{emojis.warning} Why is there a quote here? I'm confused...") elif isinstance(err, commands.errors.CheckFailure): await ctx.send( f"{emojis.error} You do not have permission to run this command." ) elif isinstance(err, commands.CommandOnCooldown): await ctx.send( f"{emojis.info} You're using that command too fast! Try again in {prettyTimeDelta(err.retry_after)}." ) elif isinstance(err, InvalidOperation): await ctx.send(f"{emojis.warning} That's... not math I can do.") elif isinstance(err, OverflowError): await ctx.send( "*SizeBot attempts to comprehend a being of infinite height, and gives up before it explodes.*" ) else: # Default command error handling await ctx.send(f"{emojis.error} Something went wrong.") logger.error(f"Ignoring exception in command {ctx.command}:") logger.error(utils.formatTraceback(error))