Skip to content

Commit 80d189d

Browse files
committed
Prioritize certain channels
1 parent 54a72d9 commit 80d189d

1 file changed

Lines changed: 37 additions & 27 deletions

File tree

bot/exts/moderation/clean.py

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import itertools
44
import re
55
import time
6-
from collections import defaultdict
76
from collections.abc import Callable, Collection
87
from datetime import datetime
98
from itertools import takewhile
@@ -40,6 +39,8 @@
4039

4140
BULK_DELETE_LIMIT = 100
4241

42+
PRIORITY_CHANNELS = [Channels.python_general]
43+
4344

4445
class CleanChannels(Converter):
4546
"""A converter to turn the string into a list of channels to clean, or the literal `*` for all public channels."""
@@ -125,31 +126,37 @@ async def _send_expiring_message(ctx: Context, content: str) -> None:
125126
await ctx.send(content, delete_after=delete_after)
126127

127128
@staticmethod
128-
def _channels_set(
129-
channels: CleanChannels, ctx: Context, first_limit: CleanLimit, second_limit: CleanLimit
130-
) -> set[TextChannel]:
131-
"""Standardize the input `channels` argument to a usable set of text channels."""
129+
def _get_channels(
130+
channels: CleanChannels, ctx: Context, first_limit: CleanLimit, second_limit: CleanLimit
131+
) -> list[TextChannel]:
132+
"""Standardize the input `channels` argument to a usable list of text channels, arranged by priority."""
133+
def channel_rank(channel: TextChannel) -> int:
134+
if channel == ctx.channel: # Clean the invocation channel first if it's listed.
135+
return -1
136+
try:
137+
return PRIORITY_CHANNELS.index(channel.id)
138+
except ValueError:
139+
return len(PRIORITY_CHANNELS)
140+
132141
# Default to using the invoking context's channel or the channel of the message limit(s).
133142
if not channels:
134143
# Input was validated - if first_limit is a message, second_limit won't point at a different channel.
135144
if isinstance(first_limit, Message):
136-
channels = {first_limit.channel}
145+
channels = [first_limit.channel]
137146
elif isinstance(second_limit, Message):
138-
channels = {second_limit.channel}
147+
channels = [second_limit.channel]
139148
else:
140-
channels = {ctx.channel}
141-
else:
142-
if channels == "*":
143-
channels = {
144-
channel for channel in itertools.chain(ctx.guild.channels, ctx.guild.threads)
145-
if isinstance(channel, TextChannel | Thread)
146-
# Ignore non-public channels or ones that can't be written in to optimize for speed.
147-
and channel.permissions_for(ctx.guild.default_role).view_channel
148-
and channel.permissions_for(ctx.guild.default_role).send_messages
149-
}
150-
else:
151-
channels = set(channels)
152-
149+
channels = [ctx.channel]
150+
elif channels == "*":
151+
channels = [
152+
channel for channel in itertools.chain(ctx.guild.channels, ctx.guild.threads)
153+
if isinstance(channel, TextChannel | Thread)
154+
# Ignore non-public channels or ones that can't be written in to optimize for speed.
155+
and channel.permissions_for(ctx.guild.default_role).view_channel
156+
and channel.permissions_for(ctx.guild.default_role).send_messages
157+
]
158+
159+
channels.sort(key=channel_rank)
153160
return channels
154161

155162
@staticmethod
@@ -239,18 +246,19 @@ def _use_api(self, oldest_limit: datetime) -> bool:
239246

240247
def _get_messages_from_cache(
241248
self,
242-
channels: set[TextChannel],
249+
channels: list[TextChannel],
243250
to_delete: Predicate,
244251
lower_limit: datetime
245-
) -> defaultdict[TextChannel, list]:
252+
) -> dict[TextChannel, list[Message]]:
246253
"""Helper function for getting messages from the cache."""
247-
message_mappings = defaultdict(list)
254+
message_mappings = {channel: [] for channel in channels}
255+
channels_set = set(channels)
248256
for message in takewhile(lambda m: m.created_at > lower_limit, reversed(self.bot.cached_messages)):
249257
if not self.cleaning:
250258
# Cleaning was canceled
251259
return message_mappings
252260

253-
if message.channel in channels and to_delete(message):
261+
if message.channel in channels_set and to_delete(message):
254262
message_mappings[message.channel].append(message)
255263

256264
return message_mappings
@@ -344,7 +352,7 @@ async def _delete_bulk(
344352
If cleaning was cancelled in the middle, return messages already deleted.
345353
"""
346354
deleted = []
347-
old_messages = {channel: [] for channel in messages_per_channel}
355+
old_messages = {}
348356

349357
for channel, messages in messages_per_channel.items():
350358
to_delete = []
@@ -442,7 +450,7 @@ async def _clean_messages(
442450
return None
443451
self.cleaning = True
444452

445-
deletion_channels = self._channels_set(channels, ctx, first_limit, second_limit)
453+
deletion_channels = self._get_channels(channels, ctx, first_limit, second_limit)
446454

447455
if isinstance(first_limit, Message):
448456
first_limit = first_limit.created_at
@@ -468,7 +476,9 @@ async def _clean_messages(
468476
messages_per_channel = self._get_messages_from_cache(
469477
channels=deletion_channels, to_delete=predicate, lower_limit=first_limit
470478
)
471-
deleted_messages, old_messages = await self._delete_bulk(messages_per_channel, executor)
479+
deleted_messages, cache_old_messages = await self._delete_bulk(messages_per_channel, executor)
480+
for channel, messages in cache_old_messages.items():
481+
old_messages[channel].extend(messages)
472482
second_limit = self._earliest_cache_datetime()
473483

474484
if self._use_api(first_limit):

0 commit comments

Comments
 (0)