diff options
| author | 2020-05-29 19:21:39 +0300 | |
|---|---|---|
| committer | 2020-05-29 19:21:39 +0300 | |
| commit | 9ee955454141d093f1cd71fc84a5340f803fa142 (patch) | |
| tree | 6704e3ec9dcb17a041aaa483f413a05829a496aa | |
| parent | Filtering: Implement bad words detection in nicknames (diff) | |
Filtering: Refactor bad names checking
- Make `bad_words_in_name` and attach it to current `on_message`.
- Implement `asyncio.Lock` to avoid race conditions.
- Made that this first check is there matches and when there is,
check for alert.
| -rw-r--r-- | bot/cogs/filtering.py | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py index d54beeabf..17113d551 100644 --- a/bot/cogs/filtering.py +++ b/bot/cogs/filtering.py @@ -1,3 +1,4 @@ +import asyncio import logging import re from datetime import datetime, timedelta @@ -60,6 +61,7 @@ class Filtering(Cog): def __init__(self, bot: Bot): self.bot = bot + self.name_lock: Optional[asyncio.Lock] = None staff_mistake_str = "If you believe this was a mistake, please let staff know!" self.filters = { @@ -118,6 +120,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) @Cog.listener() async def on_message_edit(self, before: Message, after: Message) -> None: @@ -132,40 +135,42 @@ class Filtering(Cog): delta = relativedelta(after.edited_at, before.edited_at).microseconds await self._filter_message(after, delta) - @Cog.listener('on_message') async def bad_words_in_name(self, msg: Message) -> None: """Check bad words from user display name. When there is more than 3 days after last alert, send new alert.""" - if await self.name_alerts.contains(msg.author.id): - last_alert = parser.isoparse(await self.name_alerts.get(msg.author.id)) - - # When there is less than 3 days after last alert, return - if datetime.now() - timedelta(days=3) < last_alert: - return - - # 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) - - # When there is any match, then send alert to mods. - if matches: - log_string = ( - f"**User:** {msg.author.mention} (`{msg.author.id}`)\n" - f"**Display Name:** {msg.author.display_name}\n" - f"**Bad Matches:** {', '.join(match.group() for match in matches)}" - ) - await self.mod_log.send_log_message( - icon_url=Icons.token_removed, - colour=Colours.soft_red, - title="Username filtering alert", - text=log_string, - channel_id=Channels.mod_alerts - ) + if not self.name_lock: + self.name_lock = asyncio.Lock() + + # 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) + + 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 + + log_string = ( + f"**User:** {msg.author.mention} (`{msg.author.id}`)\n" + f"**Display Name:** {msg.author.display_name}\n" + f"**Bad Matches:** {', '.join(match.group() for match in matches)}" + ) + await self.mod_log.send_log_message( + icon_url=Icons.token_removed, + colour=Colours.soft_red, + title="Username filtering alert", + text=log_string, + channel_id=Channels.mod_alerts + ) - # Update time when alert sent - await self.name_alerts.set(msg.author.id, datetime.now().isoformat()) + # Update time when alert sent + await self.name_alerts.set(msg.author.id, datetime.now().isoformat()) 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.""" |