|
| 1 | +# import re |
| 2 | +# from datetime import datetime, timedelta |
| 3 | + |
| 4 | +# import discord |
| 5 | +# from discord import Member, app_commands |
| 6 | +# from discord.abc import Messageable, PrivateChannel |
| 7 | +# from discord.ext import commands |
| 8 | + |
| 9 | +# from bot.ui import EmbedX |
| 10 | + |
| 11 | + |
| 12 | +# # ---------------------------------------------------------------------------------------------------- |
| 13 | +# # * Purge Cog |
| 14 | +# # ---------------------------------------------------------------------------------------------------- |
| 15 | +# class PurgeCog(commands.Cog): |
| 16 | +# def __init__(self, bot): |
| 17 | +# self.bot = bot |
| 18 | + |
| 19 | +# @app_commands.command( |
| 20 | +# name="purge", |
| 21 | +# description="Delete messages based on count, time, or message range", |
| 22 | +# ) |
| 23 | +# @app_commands.describe( |
| 24 | +# value="Count (e.g., 10), time (e.g., 5m/2h/1d), or message URL/ID", |
| 25 | +# second_value="Second message URL/ID for range deletion (optional)", |
| 26 | +# user="Only delete messages from this user (optional)", |
| 27 | +# ) |
| 28 | +# @app_commands.checks.has_permissions(manage_messages=True) |
| 29 | +# async def purge( |
| 30 | +# self, |
| 31 | +# interaction: discord.Interaction, |
| 32 | +# value: str, |
| 33 | +# second_value: str | None = None, |
| 34 | +# user: Member | None = None, |
| 35 | +# ): |
| 36 | +# """ """ |
| 37 | +# if ( |
| 38 | +# not interaction.guild |
| 39 | +# or not interaction.channel |
| 40 | +# or not isinstance(interaction.channel, Messageable) |
| 41 | +# or isinstance(interaction.channel, PrivateChannel) |
| 42 | +# ): |
| 43 | +# await interaction.followup.send( |
| 44 | +# embed=EmbedX.warning("This command cannot be used in this context."), |
| 45 | +# ephemeral=True, |
| 46 | +# ) |
| 47 | +# return |
| 48 | + |
| 49 | +# await interaction.response.defer(ephemeral=True) |
| 50 | +# channel = interaction.channel |
| 51 | + |
| 52 | +# # Check bot permissions |
| 53 | +# if not channel.permissions_for(interaction.guild.me).manage_messages: |
| 54 | +# await interaction.followup.send( |
| 55 | +# embed=EmbedX.warning("You don't have permission to manage messages."), |
| 56 | +# ephemeral=True, |
| 57 | +# ) |
| 58 | +# return |
| 59 | + |
| 60 | +# try: |
| 61 | +# # Case 1: Purge by count |
| 62 | +# if value.isdigit(): |
| 63 | +# count = min( |
| 64 | +# int(value), 100 |
| 65 | +# ) # Discord limit is 100 messages per bulk delete |
| 66 | +# messages = [ |
| 67 | +# msg |
| 68 | +# async for msg in channel.history(limit=count + 1) |
| 69 | +# if not user or msg.author == user |
| 70 | +# ] |
| 71 | +# await channel.delete_messages(messages) |
| 72 | +# await interaction.followup.send( |
| 73 | +# embed=EmbedX.success(f"Deleted **{len(messages)}** messages."), |
| 74 | +# ephemeral=True, |
| 75 | +# ) |
| 76 | +# return |
| 77 | + |
| 78 | +# # Case 2: Purge by time |
| 79 | +# time_units = {"s": 1, "m": 60, "h": 3600, "d": 86400} |
| 80 | +# if value[-1] in time_units and value[:-1].isdigit(): |
| 81 | +# time_amount = int(value[:-1]) |
| 82 | +# time_unit = time_units[value[-1]] |
| 83 | +# time_delta = timedelta(seconds=time_amount * time_unit) |
| 84 | +# cutoff_time = datetime.utcnow() - time_delta |
| 85 | + |
| 86 | +# messages = [ |
| 87 | +# msg |
| 88 | +# async for msg in channel.history(limit=100) |
| 89 | +# if msg.created_at > cutoff_time and (not user or msg.author == user) |
| 90 | +# ] |
| 91 | +# await channel.delete_messages(messages) |
| 92 | +# await interaction.followup.send( |
| 93 | +# embed=EmbedX.warning( |
| 94 | +# f"Deleted **{len(messages)}** messages from last {value}." |
| 95 | +# ), |
| 96 | +# ephemeral=True, |
| 97 | +# ) |
| 98 | +# return |
| 99 | + |
| 100 | +# # Case 3 & 4: Purge by message or between messages |
| 101 | +# start_msg = await self.get_message_from_input(channel, value) |
| 102 | +# if not start_msg: |
| 103 | +# await interaction.followup.send( |
| 104 | +# embed=EmbedX.error("Invalid message ID or URL."), ephemeral=True |
| 105 | +# ) |
| 106 | +# return |
| 107 | + |
| 108 | +# if second_value: # Between two messages |
| 109 | +# end_msg = await self.get_message_from_input(channel, second_value) |
| 110 | +# if not end_msg: |
| 111 | +# await interaction.followup.send( |
| 112 | +# embed=EmbedX.error("Invalid second message ID or URL."), |
| 113 | +# ephemeral=True, |
| 114 | +# ) |
| 115 | +# return |
| 116 | + |
| 117 | +# # Ensure start_msg is older than end_msg |
| 118 | +# if start_msg.created_at > end_msg.created_at: |
| 119 | +# start_msg, end_msg = end_msg, start_msg |
| 120 | + |
| 121 | +# messages = [ |
| 122 | +# msg |
| 123 | +# async for msg in channel.history(limit=100, before=end_msg) |
| 124 | +# if msg.created_at >= start_msg.created_at |
| 125 | +# and (not user or msg.author == user) |
| 126 | +# ] |
| 127 | +# else: # Until one message |
| 128 | +# messages = [ |
| 129 | +# msg |
| 130 | +# async for msg in channel.history(limit=100, before=start_msg) |
| 131 | +# if not user or msg.author == user |
| 132 | +# ] |
| 133 | + |
| 134 | +# await channel.delete_messages(messages) |
| 135 | +# await interaction.followup.send( |
| 136 | +# embed=EmbedX.success(f"Deleted **{len(messages)}** messages"), |
| 137 | +# ephemeral=True, |
| 138 | +# ) |
| 139 | + |
| 140 | +# except discord.Forbidden: |
| 141 | +# await interaction.followup.send( |
| 142 | +# embed=EmbedX.error("You don't have permission to delete messages!"), |
| 143 | +# ephemeral=True, |
| 144 | +# ) |
| 145 | +# except Exception as e: |
| 146 | +# await interaction.followup.send(embed=EmbedX.error(str(e)), ephemeral=True) |
| 147 | + |
| 148 | +# @purge.error |
| 149 | +# async def purge_error(self, interaction: discord.Interaction, error): |
| 150 | +# if isinstance(error, app_commands.MissingPermissions): |
| 151 | +# await interaction.response.send_message( |
| 152 | +# embed=EmbedX.warning( |
| 153 | +# "You need Manage Messages permission to use this command!" |
| 154 | +# ), |
| 155 | +# ephemeral=True, |
| 156 | +# ) |
| 157 | + |
| 158 | +# # ---------------------------------------------------------------------------------------------------- |
| 159 | + |
| 160 | +# async def get_message_from_input(self, channel, input_str): |
| 161 | +# """Extract message ID from URL or plain ID.""" |
| 162 | +# url_pattern = r"https://discord\.com/channels/\d+/\d+/(\d+)" |
| 163 | +# match = re.match(url_pattern, input_str) |
| 164 | +# if match: |
| 165 | +# message_id = int(match.group(1)) |
| 166 | +# else: |
| 167 | +# try: |
| 168 | +# message_id = int(input_str) |
| 169 | +# except ValueError: |
| 170 | +# return None |
| 171 | +# try: |
| 172 | +# return await channel.fetch_message(message_id) |
| 173 | +# except discord.NotFound: |
| 174 | +# return None |
0 commit comments