Repository: Cog-Creators/Red-DiscordBot

Issue:
[Cleanup] Respect pinned mesages
Ohhh ye, we're adding more upon Cleanup's logic like it already wasn't hard enough! 😏 Cleanup should respect pinned messages when cleaning up in any setting used by not removing them when their detected in the list.


Discussion:
What if cleanup post a warning whether you want to delete pinned messages or not? and introduce a flag/subcommand to ignore pinned messages

Resolving patch:
diff --git a/redbot/cogs/cleanup/cleanup.py b/redbot/cogs/cleanup/cleanup.py
--- a/redbot/cogs/cleanup/cleanup.py
+++ b/redbot/cogs/cleanup/cleanup.py
@@ -40,7 +40,8 @@ def author_check(message):
     @staticmethod
     async def get_messages_for_deletion(
             ctx: commands.Context, channel: discord.TextChannel, number,
-            check=lambda x: True, limit=100, before=None, after=None
+            check=lambda x: True, limit=100, before=None, after=None,
+            delete_pinned=False
     ) -> list:
         """
         Gets a list of messages meeting the requirements to be deleted.
@@ -50,6 +51,7 @@ async def get_messages_for_deletion(
         - The message passes a provided check (if no check is provided,
           this is automatically true)
         - The message is less than 14 days old
+        - The message is not pinned
         """
         to_delete = []
         too_old = False
@@ -59,8 +61,12 @@ async def get_messages_for_deletion(
             async for message in channel.history(limit=limit,
                                                  before=before,
                                                  after=after):
-                if (not number or len(to_delete) - 1 < number) and check(message) \
-                        and (ctx.message.created_at - message.created_at).days < 14:
+                if (
+                    (not number or len(to_delete) - 1 < number)
+                    and check(message)
+                    and (ctx.message.created_at - message.created_at).days < 14
+                    and (delete_pinned or not message.pinned)
+                ):
                     to_delete.append(message)
                 elif (ctx.message.created_at - message.created_at).days >= 14:
                     too_old = True
@@ -83,7 +89,7 @@ async def cleanup(self, ctx: commands.Context):
     @cleanup.command()
     @commands.guild_only()
     @commands.bot_has_permissions(manage_messages=True)
-    async def text(self, ctx: commands.Context, text: str, number: int):
+    async def text(self, ctx: commands.Context, text: str, number: int, delete_pinned: bool=False):
         """Deletes last X messages matching the specified text.
 
         Example:
@@ -109,7 +115,8 @@ def check(m):
                 return False
 
         to_delete = await self.get_messages_for_deletion(
-            ctx, channel, number, check=check, limit=1000, before=ctx.message)
+            ctx, channel, number, check=check, limit=1000, before=ctx.message,
+            delete_pinned=delete_pinned)
 
         reason = "{}({}) deleted {} messages "\
                  " containing '{}' in channel {}.".format(author.name,
@@ -124,7 +131,7 @@ def check(m):
     @cleanup.command()
     @commands.guild_only()
     @commands.bot_has_permissions(manage_messages=True)
-    async def user(self, ctx: commands.Context, user: str, number: int):
+    async def user(self, ctx: commands.Context, user: str, number: int, delete_pinned: bool=False):
         """Deletes last X messages from specified user.
 
         Examples:
@@ -159,7 +166,8 @@ def check(m):
                 return False
 
         to_delete = await self.get_messages_for_deletion(
-            ctx, channel, number, check=check, limit=1000, before=ctx.message
+            ctx, channel, number, check=check, limit=1000, before=ctx.message,
+            delete_pinned=delete_pinned
         )
         reason = "{}({}) deleted {} messages "\
                  " made by {}({}) in channel {}."\
@@ -176,7 +184,7 @@ def check(m):
     @cleanup.command()
     @commands.guild_only()
     @commands.bot_has_permissions(manage_messages=True)
-    async def after(self, ctx: commands.Context, message_id: int):
+    async def after(self, ctx: commands.Context, message_id: int, delete_pinned: bool=False):
         """Deletes all messages after specified message.
 
         To get a message id, enable developer mode in Discord's
@@ -202,7 +210,7 @@ async def after(self, ctx: commands.Context, message_id: int):
             return
 
         to_delete = await self.get_messages_for_deletion(
-            ctx, channel, 0, limit=None, after=after
+            ctx, channel, 0, limit=None, after=after, delete_pinned=delete_pinned
         )
 
         reason = "{}({}) deleted {} messages in channel {}."\
@@ -215,7 +223,7 @@ async def after(self, ctx: commands.Context, message_id: int):
     @cleanup.command()
     @commands.guild_only()
     @commands.bot_has_permissions(manage_messages=True)
-    async def messages(self, ctx: commands.Context, number: int):
+    async def messages(self, ctx: commands.Context, number: int, delete_pinned: bool=False):
         """Deletes last X messages.
 
         Example:
@@ -232,7 +240,8 @@ async def messages(self, ctx: commands.Context, number: int):
                 return
 
         to_delete = await self.get_messages_for_deletion(
-            ctx, channel, number, limit=1000, before=ctx.message
+            ctx, channel, number, limit=1000, before=ctx.message,
+            delete_pinned=delete_pinned
         )
 
         reason = "{}({}) deleted {} messages in channel {}."\
@@ -248,7 +257,7 @@ async def messages(self, ctx: commands.Context, number: int):
     @cleanup.command(name='bot')
     @commands.guild_only()
     @commands.bot_has_permissions(manage_messages=True)
-    async def cleanup_bot(self, ctx: commands.Context, number: int):
+    async def cleanup_bot(self, ctx: commands.Context, number: int, delete_pinned: bool=False):
         """Cleans up command messages and messages from the bot."""
 
         channel = ctx.message.channel
@@ -280,7 +289,8 @@ def check(m):
             return False
 
         to_delete = await self.get_messages_for_deletion(
-            ctx, channel, number, check=check, limit=1000, before=ctx.message
+            ctx, channel, number, check=check, limit=1000, before=ctx.message,
+            delete_pinned=delete_pinned
         )
 
         reason = "{}({}) deleted {} "\
@@ -295,7 +305,9 @@ def check(m):
             await slow_deletion(to_delete)
 
     @cleanup.command(name='self')
-    async def cleanup_self(self, ctx: commands.Context, number: int, match_pattern: str = None):
+    async def cleanup_self(
+            self, ctx: commands.Context, number: int,
+            match_pattern: str = None, delete_pinned: bool=False):
         """Cleans up messages owned by the bot.
 
         By default, all messages are cleaned. If a third argument is specified,
@@ -345,7 +357,8 @@ def check(m):
             return False
 
         to_delete = await self.get_messages_for_deletion(
-            ctx, channel, number, check=check, limit=1000, before=ctx.message
+            ctx, channel, number, check=check, limit=1000, before=ctx.message,
+            delete_pinned=delete_pinned
         )
 
         # Selfbot convenience, delete trigger message


Test patch: