aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/cogs/filtering.py48
1 files changed, 31 insertions, 17 deletions
diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py
index c57ab0688..eb587d781 100644
--- a/bot/cogs/filtering.py
+++ b/bot/cogs/filtering.py
@@ -2,10 +2,9 @@ import asyncio
import logging
import re
from datetime import datetime, timedelta
-from typing import Optional, Union
+from typing import List, Optional, Union
import discord.errors
-from dateutil import parser
from dateutil.relativedelta import relativedelta
from discord import Colour, Member, Message, TextChannel
from discord.ext.commands import Cog
@@ -44,6 +43,8 @@ TOKEN_WATCHLIST_PATTERNS = [
]
WATCHLIST_PATTERNS = WORD_WATCHLIST_PATTERNS + TOKEN_WATCHLIST_PATTERNS
+DAYS_BETWEEN_ALERTS = 3
+
def expand_spoilers(text: str) -> str:
"""Return a string containing all interpretations of a spoilered message."""
@@ -120,7 +121,7 @@ class Filtering(Cog):
async def on_message(self, msg: Message) -> None:
"""Invoke message filter for new messages."""
await self._filter_message(msg)
- await self.bad_words_in_name(msg)
+ await self.check_is_bad_words_in_name(msg.author)
@Cog.listener()
async def on_message_edit(self, before: Message, after: Message) -> None:
@@ -135,27 +136,40 @@ class Filtering(Cog):
delta = relativedelta(after.edited_at, before.edited_at).microseconds
await self._filter_message(after, delta)
- async def bad_words_in_name(self, msg: Message) -> None:
+ @staticmethod
+ def get_name_matches(name: str) -> List[re.Match]:
+ """Check bad words from passed string (name). Return list of matches."""
+ matches = []
+ for pattern in WATCHLIST_PATTERNS:
+ match = pattern.search(name)
+ if match:
+ matches.append(match)
+ return matches
+
+ async def check_send_alert(self, member: Member) -> bool:
+ """When there is less than 3 days after last alert, return `False`, otherwise `True`."""
+ last_alert = await self.name_alerts.get(member.id)
+ if last_alert:
+ last_alert = datetime.fromtimestamp(last_alert)
+ if datetime.now() - timedelta(days=DAYS_BETWEEN_ALERTS) < last_alert:
+ return False
+
+ return True
+
+ async def check_is_bad_words_in_name(self, member: Member) -> None:
"""Check bad words from user display name. When there is more than 3 days after last alert, send new alert."""
# Use lock to avoid race conditions
async with self.name_lock:
# Check does nickname have match in filters.
- matches = []
- for pattern in WATCHLIST_PATTERNS:
- match = pattern.search(msg.author.display_name)
- if match:
- matches.append(match)
+ matches = self.get_name_matches(member.display_name)
if matches:
- last_alert = await self.name_alerts.get(msg.author.id)
- if last_alert:
- last_alert = parser.isoparse(last_alert)
- if datetime.now() - timedelta(days=3) < last_alert:
- return
+ if not self.check_send_alert(member):
+ return
log_string = (
- f"**User:** {msg.author.mention} (`{msg.author.id}`)\n"
- f"**Display Name:** {msg.author.display_name}\n"
+ f"**User:** {member.mention} (`{member.id}`)\n"
+ f"**Display Name:** {member.display_name}\n"
f"**Bad Matches:** {', '.join(match.group() for match in matches)}"
)
await self.mod_log.send_log_message(
@@ -167,7 +181,7 @@ class Filtering(Cog):
)
# Update time when alert sent
- await self.name_alerts.set(msg.author.id, datetime.now().isoformat())
+ await self.name_alerts.set(member.id, datetime.now().timestamp())
async def _filter_message(self, msg: Message, delta: Optional[int] = None) -> None:
"""Filter the input message to see if it violates any of our rules, and then respond accordingly."""