aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/exts/filtering/_filter_context.py4
-rw-r--r--bot/exts/filtering/_filter_lists/antispam.py18
-rw-r--r--bot/exts/filtering/_settings_types/actions/remove_context.py2
-rw-r--r--bot/exts/filtering/_ui/ui.py17
4 files changed, 28 insertions, 13 deletions
diff --git a/bot/exts/filtering/_filter_context.py b/bot/exts/filtering/_filter_context.py
index 9faa16b53..f5f635f9c 100644
--- a/bot/exts/filtering/_filter_context.py
+++ b/bot/exts/filtering/_filter_context.py
@@ -44,11 +44,13 @@ class FilterContext:
matches: list[str] = field(default_factory=list) # What exactly was found
notification_domain: str = "" # A domain to send the user for context
filter_info: dict['Filter', str] = field(default_factory=dict) # Additional info from a filter.
+ messages_deletion: bool = False # Whether the messages were deleted. Can't upload deletion log otherwise.
# Additional actions to perform
additional_actions: list[Callable[[FilterContext], Coroutine]] = field(default_factory=list)
- related_messages: set[Message] = field(default_factory=set)
+ related_messages: set[Message] = field(default_factory=set) # Deletion will include these.
related_channels: set[TextChannel | Thread | DMChannel] = field(default_factory=set)
attachments: dict[int, list[str]] = field(default_factory=dict) # Message ID to attachment URLs.
+ upload_deletion_logs: bool = True # Whether it's allowed to upload deletion logs.
@classmethod
def from_message(
diff --git a/bot/exts/filtering/_filter_lists/antispam.py b/bot/exts/filtering/_filter_lists/antispam.py
index 147998c1c..c5ce292e3 100644
--- a/bot/exts/filtering/_filter_lists/antispam.py
+++ b/bot/exts/filtering/_filter_lists/antispam.py
@@ -77,17 +77,23 @@ class AntispamList(UniquesListBase):
self.message_deletion_queue[ctx.author] = DeletionContext()
ctx.additional_actions.append(self._create_deletion_context_handler(ctx.author))
ctx.related_channels |= {msg.channel for msg in ctx.related_messages}
- else: # The additional messages found are already part of the deletion context
+ else: # The additional messages found are already part of a deletion context
ctx.related_messages = set()
current_infraction = self.message_deletion_queue[ctx.author].current_infraction
+ # In case another filter wants an alert, prevent deleted messages from being uploaded now and also for
+ # the spam alert (upload happens during alerting).
+ # Deleted messages API doesn't accept duplicates and will error.
+ # Additional messages are necessarily part of the deletion.
+ ctx.upload_deletion_logs = False
self.message_deletion_queue[ctx.author].add(ctx, triggers)
- current_actions = sublist.merge_actions(triggers) if triggers else None
+ current_actions = sublist.merge_actions(triggers)
# Don't alert yet.
current_actions.pop("ping", None)
current_actions.pop("send_alert", None)
+
new_infraction = current_actions["infraction_and_notification"].copy()
- # Smaller infraction value = higher in hierarchy.
+ # Smaller infraction value => higher in hierarchy.
if not current_infraction or new_infraction.infraction_type.value < current_infraction.value:
# Pick the first triggered filter for the reason, there's no good way to decide between them.
new_infraction.infraction_reason = (
@@ -161,11 +167,13 @@ class DeletionContext:
new_ctx.action_descriptions[-1] += f" (+{descriptions_num - 20} other actions)"
new_ctx.related_messages = reduce(
or_, (other_ctx.related_messages for other_ctx in other_contexts), ctx.related_messages
- )
+ ) | {ctx.message for ctx in other_contexts}
new_ctx.related_channels = reduce(
or_, (other_ctx.related_channels for other_ctx in other_contexts), ctx.related_channels
- )
+ ) | {ctx.channel for ctx in other_contexts}
new_ctx.attachments = reduce(or_, (other_ctx.attachments for other_ctx in other_contexts), ctx.attachments)
+ new_ctx.upload_deletion_logs = True
+ new_ctx.messages_deletion = all(ctx.messages_deletion for ctx in self.contexts)
rules = list(self.rules)
actions = antispam_list[ListType.DENY].merge_actions(rules)
diff --git a/bot/exts/filtering/_settings_types/actions/remove_context.py b/bot/exts/filtering/_settings_types/actions/remove_context.py
index e030f06d2..a34822542 100644
--- a/bot/exts/filtering/_settings_types/actions/remove_context.py
+++ b/bot/exts/filtering/_settings_types/actions/remove_context.py
@@ -59,6 +59,8 @@ class RemoveContext(ActionEntry):
if not ctx.message or not ctx.message.guild:
return
+ # If deletion somehow fails at least this will allow scheduling for deletion.
+ ctx.messages_deletion = True
channel_messages = defaultdict(set) # Duplicates will cause batch deletion to fail.
for message in {ctx.message} | ctx.related_messages:
channel_messages[message.channel].add(message)
diff --git a/bot/exts/filtering/_ui/ui.py b/bot/exts/filtering/_ui/ui.py
index dc996faf7..24fb507e3 100644
--- a/bot/exts/filtering/_ui/ui.py
+++ b/bot/exts/filtering/_ui/ui.py
@@ -57,22 +57,25 @@ T = TypeVar('T')
async def _build_alert_message_content(ctx: FilterContext, current_message_length: int) -> str:
"""Build the content section of the alert."""
# For multiple messages and those with attachments or excessive newlines, use the logs API
- if any((
+ if ctx.messages_deletion and ctx.upload_deletion_logs and any((
ctx.related_messages,
len(ctx.attachments) > 0,
ctx.content.count('\n') > 15
)):
url = await upload_log(ctx.related_messages, bot.instance.user.id, ctx.attachments)
- alert_content = f"A complete log of the offending messages can be found [here]({url})"
- else:
- alert_content = escape_markdown(ctx.content)
- remaining_chars = MAX_EMBED_DESCRIPTION - current_message_length
+ return f"A complete log of the offending messages can be found [here]({url})"
+
+ alert_content = escape_markdown(ctx.content)
+ remaining_chars = MAX_EMBED_DESCRIPTION - current_message_length
- if len(alert_content) > remaining_chars:
+ if len(alert_content) > remaining_chars:
+ if ctx.messages_deletion and ctx.upload_deletion_logs:
url = await upload_log([ctx.message], bot.instance.user.id, ctx.attachments)
log_site_msg = f"The full message can be found [here]({url})"
# 7 because that's the length of "[...]\n\n"
- alert_content = alert_content[:remaining_chars - (7 + len(log_site_msg))] + "[...]\n\n" + log_site_msg
+ return alert_content[:remaining_chars - (7 + len(log_site_msg))] + "[...]\n\n" + log_site_msg
+ else:
+ return alert_content[:remaining_chars - 5] + "[...]"
return alert_content