aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar mbaruh <[email protected]>2021-08-28 17:12:34 +0300
committerGravatar mbaruh <[email protected]>2021-08-28 17:12:34 +0300
commitd81b550594d02f25fcc310eb22cda5bd930fd197 (patch)
tree0c377d7c19406fbe3b77068063a9036b30b5ad5e
parentDon't delete clean cancel embed in mod channel (diff)
Change cache usage
The cache is used only when all channels are used, as before. Unlike before, using all channels requires using "*" in the channels argument. Before all channels would be used if use_cache was set to True. Using all channels uses the cache by default. To traverse every single text channel in the server, setting use_cache to False is required in the command.
-rw-r--r--bot/exts/moderation/clean.py64
1 files changed, 46 insertions, 18 deletions
diff --git a/bot/exts/moderation/clean.py b/bot/exts/moderation/clean.py
index 504ecccd1..15a48ea75 100644
--- a/bot/exts/moderation/clean.py
+++ b/bot/exts/moderation/clean.py
@@ -3,11 +3,11 @@ import re
import time
from collections import defaultdict
from itertools import chain
-from typing import Any, Callable, DefaultDict, Iterable, List, Optional, Tuple
+from typing import Any, Callable, DefaultDict, Iterable, List, Literal, Optional, TYPE_CHECKING, Tuple, Union
from discord import Colour, Embed, Message, NotFound, TextChannel, User, errors
-from discord.ext import commands
-from discord.ext.commands import Cog, Context, group, has_any_role
+from discord.ext.commands import Cog, Context, Converter, group, has_any_role
+from discord.ext.commands.converter import TextChannelConverter
from discord.ext.commands.errors import BadArgument, MaxConcurrencyReached, MissingRequiredArgument
from bot.bot import Bot
@@ -23,6 +23,22 @@ log = logging.getLogger(__name__)
Predicate = Callable[[Message], bool]
+class CleanChannels(Converter):
+ """A converter that turns the given string to a list of channels to clean, or the literal `*` for all channels."""
+
+ _channel_converter = TextChannelConverter()
+
+ async def convert(self, ctx: Context, argument: str) -> Union[Literal["*"], list[TextChannel]]:
+ """Converts a string to a list of channels to clean, or the literal `*` for all channels."""
+ if argument == "*":
+ return "*"
+ return [await self._channel_converter.convert(ctx, channel) for channel in argument.split()]
+
+
+if TYPE_CHECKING:
+ CleanChannels = Union[Literal["*"], list[TextChannel]] # noqa: F811
+
+
class Clean(Cog):
"""
A cog that allows messages to be deleted in bulk, while applying various filters.
@@ -122,13 +138,13 @@ class Clean(Cog):
self,
amount: int,
ctx: Context,
- channels: Iterable[TextChannel],
+ channels: CleanChannels,
bots_only: bool = False,
- use_cache: bool = False,
user: User = None,
regex: Optional[str] = None,
until_message: Optional[Message] = None,
after_message: Optional[Message] = None,
+ use_cache: Optional[bool] = True
) -> None:
"""A helper function that does the actual message cleaning."""
def predicate_bots_only(message: Message) -> bool:
@@ -215,12 +231,15 @@ class Clean(Cog):
# Invocation message has already been deleted
log.info("Tried to delete invocation message, but it was already deleted.")
- if use_cache:
+ if channels == "*" and use_cache:
message_mappings, message_ids = self._get_messages_from_cache(amount=amount, to_delete=predicate)
else:
+ deletion_channels = channels
+ if channels == "*":
+ deletion_channels = [channel for channel in ctx.guild.channels if isinstance(channel, TextChannel)]
message_mappings, message_ids = await self._get_messages_from_channels(
amount=amount,
- channels=channels,
+ channels=deletion_channels,
to_delete=predicate,
until_message=until_message
)
@@ -265,7 +284,7 @@ class Clean(Cog):
await self._log_clean(list(chain.from_iterable(message_mappings.values())), channels, ctx.author)
- async def _log_clean(self, messages: list[Message], channels: Iterable[TextChannel], invoker: User) -> None:
+ async def _log_clean(self, messages: list[Message], channels: CleanChannels, invoker: User) -> None:
"""Log the deleted messages to the modlog."""
if not messages:
# Can't build an embed, nothing to clean!
@@ -276,7 +295,10 @@ class Clean(Cog):
log_url = await self.mod_log.upload_log(log_messages, invoker.id)
# Build the embed and send it
- target_channels = ", ".join(channel.mention for channel in channels)
+ if channels == "*":
+ target_channels = "all channels"
+ else:
+ target_channels = ", ".join(channel.mention for channel in channels)
message = (
f"**{len(messages)}** messages deleted in {target_channels} by "
@@ -305,10 +327,11 @@ class Clean(Cog):
ctx: Context,
user: User,
amount: Optional[int] = 10,
- channels: commands.Greedy[TextChannel] = None
+ use_cache: Optional[bool] = True,
+ *,
+ channels: Optional[CleanChannels] = None
) -> None:
"""Delete messages posted by the provided user, stop cleaning after traversing `amount` messages."""
- use_cache = not channels
await self._clean_messages(amount, ctx, user=user, channels=channels, use_cache=use_cache)
@clean_group.command(name="all", aliases=["everything"])
@@ -317,10 +340,12 @@ class Clean(Cog):
self,
ctx: Context,
amount: Optional[int] = 10,
- channels: commands.Greedy[TextChannel] = None
+ use_cache: Optional[bool] = True,
+ *,
+ channels: Optional[CleanChannels] = None
) -> None:
"""Delete all messages, regardless of poster, stop cleaning after traversing `amount` messages."""
- await self._clean_messages(amount, ctx, channels=channels)
+ await self._clean_messages(amount, ctx, channels=channels, use_cache=use_cache)
@clean_group.command(name="bots", aliases=["bot"])
@has_any_role(*MODERATION_ROLES)
@@ -328,22 +353,25 @@ class Clean(Cog):
self,
ctx: Context,
amount: Optional[int] = 10,
- channels: commands.Greedy[TextChannel] = None
+ use_cache: Optional[bool] = True,
+ *,
+ channels: Optional[CleanChannels] = None
) -> None:
"""Delete all messages posted by a bot, stop cleaning after traversing `amount` messages."""
- await self._clean_messages(amount, ctx, bots_only=True, channels=channels)
+ await self._clean_messages(amount, ctx, bots_only=True, channels=channels, use_cache=use_cache)
- @clean_group.command(name="regex", aliases=["word", "expression"])
+ @clean_group.command(name="regex", aliases=["word", "expression", "pattern"])
@has_any_role(*MODERATION_ROLES)
async def clean_regex(
self,
ctx: Context,
regex: str,
amount: Optional[int] = 10,
- channels: commands.Greedy[TextChannel] = None
+ use_cache: Optional[bool] = True,
+ *,
+ channels: Optional[CleanChannels] = None
) -> None:
"""Delete all messages that match a certain regex, stop cleaning after traversing `amount` messages."""
- use_cache = not channels
await self._clean_messages(amount, ctx, regex=regex, channels=channels, use_cache=use_cache)
@clean_group.command(name="until")