From e90868072ecef170a21a3c6b2b6e00da6c4c744c Mon Sep 17 00:00:00 2001 From: FancyJesse Date: Thu, 26 Mar 2020 14:32:10 -0700 Subject: [PATCH] [Cleanup] Add `[p]cleanup spam` command (#3688) * Added `[p]cleanup spam` function * formatting * accepts number and considers command message to total counts * use existing kwarg instead Safer to use the before kwarg as other messages might get included accidentally between invoking and executing Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com> * safer way to compare embeds and skip attachment only msgs Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com> * keeps the original message before the spam starts * now asks if its ok to delete 100+ spam msgs if found * unnecessary calculations, just add after * code styling and reverted history oldest_first option * switched to recommended logging formatting, thank you jack1142 * now using `get_messages_for_deletion()`, added needed limit kwarg * ugh forgot to swap em * duh * small string clarification Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com> --- redbot/cogs/cleanup/cleanup.py | 46 +++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/redbot/cogs/cleanup/cleanup.py b/redbot/cogs/cleanup/cleanup.py index 74ff35790..a406e7e9e 100644 --- a/redbot/cogs/cleanup/cleanup.py +++ b/redbot/cogs/cleanup/cleanup.py @@ -63,6 +63,7 @@ class Cleanup(commands.Cog): channel: discord.TextChannel, number: int = None, check: Callable[[discord.Message], bool] = lambda x: True, + limit: int = None, before: Union[discord.Message, datetime] = None, after: Union[discord.Message, datetime] = None, delete_pinned: bool = False, @@ -99,7 +100,7 @@ class Cleanup(commands.Cog): collected = [] async for message in channel.history( - limit=None, before=before, after=after, oldest_first=False + limit=limit, before=before, after=after, oldest_first=False ): if message.created_at < two_weeks_ago: break @@ -541,3 +542,46 @@ class Cleanup(commands.Cog): await mass_purge(to_delete, channel) else: await slow_deletion(to_delete) + + @cleanup.command(name="spam") + @commands.guild_only() + @commands.bot_has_permissions(manage_messages=True) + async def cleanup_spam(self, ctx: commands.Context, number: int = 50): + """Deletes duplicate messages in the channel from the last X messages and keeps only one copy. + + Defaults to 50. + """ + msgs = [] + spam = [] + + def check(m): + if m.attachments: + return False + c = (m.author.id, m.content, [e.to_dict() for e in m.embeds]) + if c in msgs: + spam.append(m) + return True + else: + msgs.append(c) + return False + + to_delete = await self.get_messages_for_deletion( + channel=ctx.channel, limit=number, check=check, before=ctx.message, + ) + + if len(to_delete) > 100: + cont = await self.check_100_plus(ctx, len(to_delete)) + if not cont: + return + + log.info( + "%s (%s) deleted %s spam messages in channel %s (%s).", + ctx.author, + ctx.author.id, + len(to_delete), + ctx.channel, + ctx.channel.id, + ) + + to_delete.append(ctx.message) + await mass_purge(to_delete, ctx.channel)