diff --git a/cogs/mod.py b/cogs/mod.py index 3121fd1fc..325663251 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -152,55 +152,41 @@ class Mod: cleanup text \"test\" 5 Remember to use double quotes.""" - if number < 1: - number = 1 - author = ctx.message.author - message = ctx.message + channel = ctx.message.channel - logger.info("{}({}) deleted {} messages containing '{}' in channel {}".format(author.name, - author.id, str(number), text, message.channel.name)) - if self.bot.user.bot and self.discordpy_updated(): - def to_delete(m): - if m == ctx.message or text in m.content: - return True - else: - return False - try: - await self.bot.purge_from(channel, limit=number+1, check=to_delete) - except discord.errors.Forbidden: - await self.bot.say("I need permissions to manage messages " - "in this channel.") + server = channel.server + is_bot = self.bot.user.bot + has_permissions = channel.permissions_for(server.me).manage_messages + + def check(m): + if text in m.content: + return True + elif m == ctx.message: + return True + else: + return False + + to_delete = [ctx.message] + + if not has_permissions: + await self.bot.say("I'm not allowed to delete messages.") + return + + tries_left = 5 + tmp = ctx.message + + while tries_left and len(to_delete) - 1 < number: + async for message in self.bot.logs_from(channel, limit=100, + before=tmp): + if len(to_delete) - 1 < number and check(message): + to_delete.append(message) + tmp = message + tries_left -= 1 + + if is_bot: + await self.mass_purge(to_delete) else: - await self.legacy_cleanup_text_messages(ctx, text, number) - - - async def legacy_cleanup_text_messages(self, ctx, text, number): - message = ctx.message - cmdmsg = ctx.message - if self.bot.user.bot: - print("Your discord.py is outdated, defaulting to slow deletion.") - try: - if number > 0 and number < 10000: - while True: - new = False - async for x in self.bot.logs_from(message.channel, limit=100, before=message): - if number == 0: - await self._delete_message(cmdmsg) - await asyncio.sleep(0.25) - return - if text in x.content: - await self._delete_message(x) - await asyncio.sleep(0.25) - number -= 1 - new = True - message = x - if not new or number == 0: - await self._delete_message(cmdmsg) - await asyncio.sleep(0.25) - break - except discord.errors.Forbidden: - await self.bot.send_message(message.channel, "I need permissions" - " to manage messages in this channel.") + await self.slow_deletion(to_delete) @cleanup.command(pass_context=True, no_pm=True) async def user(self, ctx, user: discord.Member, number: int): @@ -209,26 +195,41 @@ class Mod: Examples: cleanup user @\u200bTwentysix 2 cleanup user Red 6""" - if number < 1: - number = 1 - author = ctx.message.author + channel = ctx.message.channel - message = ctx.message - logger.info("{}({}) deleted {} messages made by {}({}) in channel {}".format(author.name, - author.id, str(number), user.name, user.id, message.channel.name)) - if self.bot.user.bot and self.discordpy_updated(): - def is_user(m): - if m == ctx.message or m.author == user: - return True - else: - return False - try: - await self.bot.purge_from(channel, limit=number+1, check=is_user) - except discord.errors.Forbidden: - await self.bot.say("I need permissions to manage messages " - "in this channel.") + server = channel.server + is_bot = self.bot.user.bot + has_permissions = channel.permissions_for(server.me).manage_messages + + def check(m): + if m.author == user: + return True + elif m == ctx.message: + return True + else: + return False + + to_delete = [ctx.message] + + if not has_permissions: + await self.bot.say("I'm not allowed to delete messages.") + return + + tries_left = 5 + tmp = ctx.message + + while tries_left and len(to_delete) - 1 < number: + async for message in self.bot.logs_from(channel, limit=100, + before=tmp): + if len(to_delete) -1 < number and check(message): + to_delete.append(message) + tmp = message + tries_left -= 1 + + if is_bot: + await self.mass_purge(to_delete) else: - await self.legacy_cleanup_user_messages(ctx, user, number) + await self.slow_deletion(to_delete) @cleanup.command(pass_context=True, no_pm=True) async def after(self, ctx, message_id : int): @@ -238,57 +239,31 @@ class Mod: settings, 'appearance' tab. Then right click a message and copy its id. """ + channel = ctx.message.channel - try: - message = await self.bot.get_message(channel, str(message_id)) - except discord.errors.NotFound: + server = channel.server + is_bot = self.bot.user.bot + has_permissions = channel.permissions_for(server.me).manage_messages + + to_delete = [] + + after = await self.bot.get_message(channel, message_id) + + if not has_permissions: + await self.bot.say("I'm not allowed to delete messages.") + return + elif not after: await self.bot.say("Message not found.") return - except discord.errors.Forbidden: - if self.bot.user.bot: - await self.bot.say("I'm not authorized to get that message.") - else: - await self.bot.say("This function is limited to bot accounts.") - return - except discord.errors.HTTPException: - await self.bot.say("Couldn't retrieve the message.") - return - try: - await self.bot.purge_from(channel, limit=2500, after=message) - except discord.errors.Forbidden: - await self.bot.say("I need permissions to manage messages " - "in this channel.") - - async def legacy_cleanup_user_messages(self, ctx, user, number): - author = ctx.message.author - message = ctx.message - cmdmsg = ctx.message - if self.bot.user.bot: - print("Your discord.py is outdated, defaulting to slow deletion.") - try: - if number > 0 and number < 10000: - while True: - new = False - async for x in self.bot.logs_from(message.channel, limit=100, before=message): - if number == 0: - await self._delete_message(cmdmsg) - await asyncio.sleep(0.25) - return - if x.author.id == user.id: - await self._delete_message(x) - await asyncio.sleep(0.25) - number -= 1 - new = True - message = x - if not new or number == 0: - await self._delete_message(cmdmsg) - await asyncio.sleep(0.25) - break - except discord.errors.Forbidden: - await self.bot.send_message(ctx.channel, "I need permissions " - "to manage messages in this channel.") + async for message in self.bot.logs_from(channel, limit=2000, + after=after): + to_delete.append(message) + if is_bot: + await self.mass_purge(to_delete) + else: + await self.slow_deletion(to_delete) @cleanup.command(pass_context=True, no_pm=True) async def messages(self, ctx, number: int): @@ -296,32 +271,25 @@ class Mod: Example: cleanup messages 26""" - if number < 1: - number = 1 - author = ctx.message.author - channel = ctx.message.channel - logger.info("{}({}) deleted {} messages in channel {}".format(author.name, - author.id, str(number), channel.name)) - if self.bot.user.bot and self.discordpy_updated(): - try: - await self.bot.purge_from(channel, limit=number+1) - except discord.errors.Forbidden: - await self.bot.say("I need permissions to manage messages in this channel.") - else: - await self.legacy_cleanup_messages(ctx, number) - async def legacy_cleanup_messages(self, ctx, number): - author = ctx.message.author channel = ctx.message.channel - if self.bot.user.bot: - print("Your discord.py is outdated, defaulting to slow deletion.") - try: - if number > 0 and number < 10000: - async for x in self.bot.logs_from(channel, limit=number + 1): - await self._delete_message(x) - await asyncio.sleep(0.25) - except discord.errors.Forbidden: - await self.bot.send_message(channel, "I need permissions to manage messages in this channel.") + server = channel.server + is_bot = self.bot.user.bot + has_permissions = channel.permissions_for(server.me).manage_messages + + to_delete = [] + + if not has_permissions: + await self.bot.say("I'm not allowed to delete messages.") + return + + async for message in self.bot.logs_from(channel, limit=number+1): + to_delete.append(message) + + if is_bot: + await self.mass_purge(to_delete) + else: + await self.slow_deletion(to_delete) @commands.group(pass_context=True) @checks.is_owner() @@ -631,12 +599,22 @@ class Mod: await self.bot.say("That user doesn't have any recorded name or " "nickname change.") - def discordpy_updated(self): - try: - assert self.bot.purge_from - except: - return False - return True + async def mass_purge(self, messages): + while messages: + if len(messages) > 1: + await self.bot.delete_messages(messages[:100]) + messages = messages[100:] + else: + await self.delete_message(messages) + await asyncio.sleep(1.5) + + async def slow_deletion(self, messages): + for message in messages: + try: + await self.bot.delete_message(message) + except: + pass + await asyncio.sleep(1.5) async def _delete_message(self, message): try: