aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar S. Co1 <[email protected]>2019-10-25 08:54:26 -0400
committerGravatar GitHub <[email protected]>2019-10-25 08:54:26 -0400
commit571b4ecc96398b3889eb90d433904629b040c5e3 (patch)
tree5b38dbac8d2ee5071eff9ab9156f5353ce71e446
parentUse standart filter conditions even if DEBUG_MODE is on. (diff)
parentMerge pull request #529 from python-discord/show-trigger-word (diff)
Merge branch 'master' into ###-filtering-devtest
-rw-r--r--bot/cogs/filtering.py35
-rw-r--r--bot/cogs/moderation/infractions.py4
-rw-r--r--bot/cogs/snekbox.py13
-rw-r--r--bot/constants.py8
-rw-r--r--config-default.yml9
5 files changed, 54 insertions, 15 deletions
diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py
index fda58b83a..be9b95bc7 100644
--- a/bot/cogs/filtering.py
+++ b/bot/cogs/filtering.py
@@ -150,11 +150,11 @@ class Filtering(Cog):
# Does the filter only need the message content or the full message?
if _filter["content_only"]:
- triggered = await _filter["function"](msg.content)
+ match = await _filter["function"](msg.content)
else:
- triggered = await _filter["function"](msg)
+ match = await _filter["function"](msg)
- if triggered:
+ if match:
# If this is a filter (not a watchlist), we should delete the message.
if _filter["type"] == "filter":
try:
@@ -180,12 +180,23 @@ class Filtering(Cog):
else:
channel_str = f"in {msg.channel.mention}"
+ # Word and match stats for watch_words and watch_tokens
+ if filter_name in ("watch_words", "watch_tokens"):
+ surroundings = match.string[max(match.start() - 10, 0): match.end() + 10]
+ message_content = (
+ f"**Match:** '{match[0]}'\n"
+ f"**Location:** '...{surroundings}...'\n"
+ f"\n**Original Message:**\n{msg.content}"
+ )
+ else: # Use content of discord Message
+ message_content = msg.content
+
message = (
f"The {filter_name} {_filter['type']} was triggered "
f"by **{msg.author}** "
f"(`{msg.author.id}`) {channel_str} with [the "
f"following message]({msg.jump_url}):\n\n"
- f"{msg.content}"
+ f"{message_content}"
)
log.debug(message)
@@ -195,7 +206,7 @@ class Filtering(Cog):
if filter_name == "filter_invites":
additional_embeds = []
- for invite, data in triggered.items():
+ for invite, data in match.items():
embed = discord.Embed(description=(
f"**Members:**\n{data['members']}\n"
f"**Active:**\n{data['active']}"
@@ -226,31 +237,33 @@ class Filtering(Cog):
break # We don't want multiple filters to trigger
@staticmethod
- async def _has_watchlist_words(text: str) -> bool:
+ async def _has_watchlist_words(text: str) -> Union[bool, re.Match]:
"""
Returns True if the text contains one of the regular expressions from the word_watchlist in our filter config.
Only matches words with boundaries before and after the expression.
"""
for regex_pattern in WORD_WATCHLIST_PATTERNS:
- if regex_pattern.search(text):
- return True
+ match = regex_pattern.search(text)
+ if match:
+ return match # match objects always have a boolean value of True
return False
@staticmethod
- async def _has_watchlist_tokens(text: str) -> bool:
+ async def _has_watchlist_tokens(text: str) -> Union[bool, re.Match]:
"""
Returns True if the text contains one of the regular expressions from the token_watchlist in our filter config.
This will match the expression even if it does not have boundaries before and after.
"""
for regex_pattern in TOKEN_WATCHLIST_PATTERNS:
- if regex_pattern.search(text):
+ match = regex_pattern.search(text)
+ if match:
# Make sure it's not a URL
if not URL_RE.search(text):
- return True
+ return match # match objects always have a boolean value of True
return False
diff --git a/bot/cogs/moderation/infractions.py b/bot/cogs/moderation/infractions.py
index f2ae7b95d..997ffe524 100644
--- a/bot/cogs/moderation/infractions.py
+++ b/bot/cogs/moderation/infractions.py
@@ -12,7 +12,7 @@ from discord.ext.commands import Context, command
from bot import constants
from bot.api import ResponseCodeError
-from bot.constants import Colours, Event
+from bot.constants import Colours, Event, STAFF_CHANNELS
from bot.decorators import respect_role_hierarchy
from bot.utils import time
from bot.utils.checks import with_role_check
@@ -465,6 +465,8 @@ class Infractions(Scheduler, commands.Cog):
if infraction["actor"] == self.bot.user.id:
end_msg = f" (reason: {infraction['reason']})"
+ elif ctx.channel.id not in STAFF_CHANNELS:
+ end_msg = ''
else:
infractions = await self.bot.api_client.get(
"bot/infractions",
diff --git a/bot/cogs/snekbox.py b/bot/cogs/snekbox.py
index c0390cb1e..362968bd0 100644
--- a/bot/cogs/snekbox.py
+++ b/bot/cogs/snekbox.py
@@ -115,6 +115,16 @@ class Snekbox(Cog):
return msg, error
+ @staticmethod
+ def get_status_emoji(results: dict) -> str:
+ """Return an emoji corresponding to the status code or lack of output in result."""
+ if not results["stdout"].strip(): # No output
+ return ":warning:"
+ elif results["returncode"] == 0: # No error
+ return ":white_check_mark:"
+ else: # Exception
+ return ":x:"
+
async def format_output(self, output: str) -> Tuple[str, Optional[str]]:
"""
Format the output and return a tuple of the formatted output and a URL to the full output.
@@ -201,7 +211,8 @@ class Snekbox(Cog):
else:
output, paste_link = await self.format_output(results["stdout"])
- msg = f"{ctx.author.mention} {msg}.\n\n```py\n{output}\n```"
+ icon = self.get_status_emoji(results)
+ msg = f"{ctx.author.mention} {icon} {msg}.\n\n```py\n{output}\n```"
if paste_link:
msg = f"{msg}\nFull output: {paste_link}"
diff --git a/bot/constants.py b/bot/constants.py
index 4beae84e9..f341fb499 100644
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -328,6 +328,7 @@ class Channels(metaclass=YAMLGetter):
subsection = "channels"
admins: int
+ admin_spam: int
announcements: int
big_brother_logs: int
bot: int
@@ -346,11 +347,14 @@ class Channels(metaclass=YAMLGetter):
helpers: int
message_log: int
meta: int
+ mod_spam: int
+ mods: int
mod_alerts: int
modlog: int
off_topic_0: int
off_topic_1: int
off_topic_2: int
+ organisation: int
python: int
reddit: int
talent_pool: int
@@ -392,6 +396,7 @@ class Guild(metaclass=YAMLGetter):
id: int
ignored: List[int]
+ staff_channels: List[int]
class Keys(metaclass=YAMLGetter):
@@ -507,6 +512,9 @@ PROJECT_ROOT = os.path.abspath(os.path.join(BOT_DIR, os.pardir))
MODERATION_ROLES = Roles.moderator, Roles.admin, Roles.owner
STAFF_ROLES = Roles.helpers, Roles.moderator, Roles.admin, Roles.owner
+# Roles combinations
+STAFF_CHANNELS = Guild.staff_channels
+
# Bot replies
NEGATIVE_REPLIES = [
diff --git a/config-default.yml b/config-default.yml
index 197743296..23dcbd44c 100644
--- a/config-default.yml
+++ b/config-default.yml
@@ -90,11 +90,12 @@ guild:
channels:
admins: &ADMINS 365960823622991872
+ admin_spam: &ADMIN_SPAM 563594791770914816
announcements: 354619224620138496
big_brother_logs: &BBLOGS 468507907357409333
bot: 267659945086812160
checkpoint_test: 422077681434099723
- defcon: 464469101889454091
+ defcon: &DEFCON 464469101889454091
devlog: &DEVLOG 622895325144940554
devtest: &DEVTEST 414574275865870337
help_0: 303906576991780866
@@ -105,14 +106,17 @@ guild:
help_5: 454941769734422538
help_6: 587375753306570782
help_7: 587375768556797982
- helpers: 385474242440986624
+ helpers: &HELPERS 385474242440986624
message_log: &MESSAGE_LOG 467752170159079424
meta: 429409067623251969
+ mod_spam: &MOD_SPAM 620607373828030464
+ mods: &MODS 305126844661760000
mod_alerts: 473092532147060736
modlog: &MODLOG 282638479504965634
off_topic_0: 291284109232308226
off_topic_1: 463035241142026251
off_topic_2: 463035268514185226
+ organisation: &ORGANISATION 551789653284356126
python: 267624335836053506
reddit: 458224812528238616
staff_lounge: &STAFF_LOUNGE 464905259261755392
@@ -121,6 +125,7 @@ guild:
user_event_a: &USER_EVENT_A 592000283102674944
verification: 352442727016693763
+ staff_channels: [*ADMINS, *ADMIN_SPAM, *MOD_SPAM, *MODS, *HELPERS, *ORGANISATION, *DEFCON]
ignored: [*ADMINS, *MESSAGE_LOG, *MODLOG]
roles: