mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[Filter] implement exempting channels from the filter (#2064)
This commit is contained in:
parent
3cb2b95121
commit
93a0e45c34
@ -1,4 +1,5 @@
|
||||
import discord
|
||||
from typing import Union
|
||||
|
||||
from redbot.core import checks, Config, modlog, commands
|
||||
from redbot.core.bot import Red
|
||||
@ -25,8 +26,10 @@ class Filter(commands.Cog):
|
||||
"filter_default_name": "John Doe",
|
||||
}
|
||||
default_member_settings = {"filter_count": 0, "next_reset_time": 0}
|
||||
default_channel_settings = {"filter": []}
|
||||
self.settings.register_guild(**default_guild_settings)
|
||||
self.settings.register_member(**default_member_settings)
|
||||
self.settings.register_channel(**default_channel_settings)
|
||||
self.register_task = self.bot.loop.create_task(self.register_filterban())
|
||||
|
||||
def __unload(self):
|
||||
@ -40,11 +43,55 @@ class Filter(commands.Cog):
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def filterset(self, ctx: commands.Context):
|
||||
"""
|
||||
Filter settings
|
||||
"""
|
||||
pass
|
||||
|
||||
@filterset.command(name="defaultname")
|
||||
async def filter_default_name(self, ctx: commands.Context, name: str):
|
||||
"""Sets the default name to use if filtering names is enabled
|
||||
|
||||
Note that this has no effect if filtering names is disabled
|
||||
|
||||
The default name used is John Doe
|
||||
"""
|
||||
guild = ctx.guild
|
||||
await self.settings.guild(guild).filter_default_name.set(name)
|
||||
await ctx.send(_("The name to use on filtered names has been set."))
|
||||
|
||||
@filterset.command(name="ban")
|
||||
async def filter_ban(self, ctx: commands.Context, count: int, timeframe: int):
|
||||
"""Autobans if the specified number of messages are filtered in the timeframe
|
||||
|
||||
The timeframe is represented by seconds.
|
||||
"""
|
||||
if (count <= 0) != (timeframe <= 0):
|
||||
await ctx.send(
|
||||
_(
|
||||
"Count and timeframe either both need to be 0 "
|
||||
"or both need to be greater than 0!"
|
||||
)
|
||||
)
|
||||
return
|
||||
elif count == 0 and timeframe == 0:
|
||||
await self.settings.guild(ctx.guild).filterban_count.set(0)
|
||||
await self.settings.guild(ctx.guild).filterban_time.set(0)
|
||||
await ctx.send(_("Autoban disabled."))
|
||||
else:
|
||||
await self.settings.guild(ctx.guild).filterban_count.set(count)
|
||||
await self.settings.guild(ctx.guild).filterban_time.set(timeframe)
|
||||
await ctx.send(_("Count and time have been set."))
|
||||
|
||||
@commands.group(name="filter")
|
||||
@commands.guild_only()
|
||||
@checks.mod_or_permissions(manage_messages=True)
|
||||
async def _filter(self, ctx: commands.Context):
|
||||
"""Adds/removes words from filter
|
||||
"""Adds/removes words from server filter
|
||||
|
||||
Use double quotes to add/remove sentences
|
||||
Using this command with no subcommands will send
|
||||
@ -62,6 +109,86 @@ class Filter(commands.Cog):
|
||||
except discord.Forbidden:
|
||||
await ctx.send(_("I can't send direct messages to you."))
|
||||
|
||||
@_filter.group(name="channel")
|
||||
async def _filter_channel(self, ctx: commands.Context):
|
||||
"""Adds/removes words from channel filter
|
||||
|
||||
Use double quotes to add/remove sentences
|
||||
Using this command with no subcommands will send
|
||||
the list of the channel's filtered words."""
|
||||
if ctx.invoked_subcommand is None:
|
||||
channel = ctx.channel
|
||||
author = ctx.author
|
||||
word_list = await self.settings.channel(channel).filter()
|
||||
if word_list:
|
||||
words = ", ".join(word_list)
|
||||
words = _("Filtered in this channel:") + "\n\n" + words
|
||||
try:
|
||||
for page in pagify(words, delims=[" ", "\n"], shorten_by=8):
|
||||
await author.send(page)
|
||||
except discord.Forbidden:
|
||||
await ctx.send(_("I can't send direct messages to you."))
|
||||
|
||||
@_filter_channel.command("add")
|
||||
async def filter_channel_add(self, ctx: commands.Context, *, words: str):
|
||||
"""Adds words to the filter
|
||||
|
||||
Use double quotes to add sentences
|
||||
Examples:
|
||||
filter add word1 word2 word3
|
||||
filter add \"This is a sentence\""""
|
||||
channel = ctx.channel
|
||||
split_words = words.split()
|
||||
word_list = []
|
||||
tmp = ""
|
||||
for word in split_words:
|
||||
if not word.startswith('"') and not word.endswith('"') and not tmp:
|
||||
word_list.append(word)
|
||||
else:
|
||||
if word.startswith('"'):
|
||||
tmp += word[1:] + " "
|
||||
elif word.endswith('"'):
|
||||
tmp += word[:-1]
|
||||
word_list.append(tmp)
|
||||
tmp = ""
|
||||
else:
|
||||
tmp += word + " "
|
||||
added = await self.add_to_filter(channel, word_list)
|
||||
if added:
|
||||
await ctx.send(_("Words added to filter."))
|
||||
else:
|
||||
await ctx.send(_("Words already in the filter."))
|
||||
|
||||
@_filter_channel.command("remove")
|
||||
async def filter_channel_remove(self, ctx: commands.Context, *, words: str):
|
||||
"""Remove words from the filter
|
||||
|
||||
Use double quotes to remove sentences
|
||||
Examples:
|
||||
filter remove word1 word2 word3
|
||||
filter remove \"This is a sentence\""""
|
||||
channel = ctx.channel
|
||||
split_words = words.split()
|
||||
word_list = []
|
||||
tmp = ""
|
||||
for word in split_words:
|
||||
if not word.startswith('"') and not word.endswith('"') and not tmp:
|
||||
word_list.append(word)
|
||||
else:
|
||||
if word.startswith('"'):
|
||||
tmp += word[1:] + " "
|
||||
elif word.endswith('"'):
|
||||
tmp += word[:-1]
|
||||
word_list.append(tmp)
|
||||
tmp = ""
|
||||
else:
|
||||
tmp += word + " "
|
||||
removed = await self.remove_from_filter(channel, word_list)
|
||||
if removed:
|
||||
await ctx.send(_("Words removed from filter."))
|
||||
else:
|
||||
await ctx.send(_("Those words weren't in the filter."))
|
||||
|
||||
@_filter.command(name="add")
|
||||
async def filter_add(self, ctx: commands.Context, *, words: str):
|
||||
"""Adds words to the filter
|
||||
@ -136,54 +263,39 @@ class Filter(commands.Cog):
|
||||
else:
|
||||
await ctx.send(_("Names and nicknames will now be checked against the filter."))
|
||||
|
||||
@_filter.command(name="defaultname")
|
||||
async def filter_default_name(self, ctx: commands.Context, name: str):
|
||||
"""Sets the default name to use if filtering names is enabled
|
||||
|
||||
Note that this has no effect if filtering names is disabled
|
||||
|
||||
The default name used is John Doe
|
||||
"""
|
||||
guild = ctx.guild
|
||||
await self.settings.guild(guild).filter_default_name.set(name)
|
||||
await ctx.send(_("The name to use on filtered names has been set."))
|
||||
|
||||
@_filter.command(name="ban")
|
||||
async def filter_ban(self, ctx: commands.Context, count: int, timeframe: int):
|
||||
"""Autobans if the specified number of messages are filtered in the timeframe
|
||||
|
||||
The timeframe is represented by seconds.
|
||||
"""
|
||||
if (count <= 0) != (timeframe <= 0):
|
||||
await ctx.send(
|
||||
_(
|
||||
"Count and timeframe either both need to be 0 "
|
||||
"or both need to be greater than 0!"
|
||||
)
|
||||
)
|
||||
return
|
||||
elif count == 0 and timeframe == 0:
|
||||
await self.settings.guild(ctx.guild).filterban_count.set(0)
|
||||
await self.settings.guild(ctx.guild).filterban_time.set(0)
|
||||
await ctx.send(_("Autoban disabled."))
|
||||
else:
|
||||
await self.settings.guild(ctx.guild).filterban_count.set(count)
|
||||
await self.settings.guild(ctx.guild).filterban_time.set(timeframe)
|
||||
await ctx.send(_("Count and time have been set."))
|
||||
|
||||
async def add_to_filter(self, server: discord.Guild, words: list) -> bool:
|
||||
async def add_to_filter(
|
||||
self, server_or_channel: Union[discord.Guild, discord.TextChannel], words: list
|
||||
) -> bool:
|
||||
added = False
|
||||
async with self.settings.guild(server).filter() as cur_list:
|
||||
if isinstance(server_or_channel, discord.Guild):
|
||||
async with self.settings.guild(server_or_channel).filter() as cur_list:
|
||||
for w in words:
|
||||
if w.lower() not in cur_list and w:
|
||||
cur_list.append(w.lower())
|
||||
added = True
|
||||
|
||||
elif isinstance(server_or_channel, discord.TextChannel):
|
||||
async with self.settings.channel(server_or_channel).filter() as cur_list:
|
||||
for w in words:
|
||||
if w.lower not in cur_list and w:
|
||||
cur_list.append(w.lower())
|
||||
added = True
|
||||
|
||||
return added
|
||||
|
||||
async def remove_from_filter(self, server: discord.Guild, words: list) -> bool:
|
||||
async def remove_from_filter(
|
||||
self, server_or_channel: Union[discord.Guild, discord.TextChannel], words: list
|
||||
) -> bool:
|
||||
removed = False
|
||||
async with self.settings.guild(server).filter() as cur_list:
|
||||
if isinstance(server_or_channel, discord.Guild):
|
||||
async with self.settings.guild(server_or_channel).filter() as cur_list:
|
||||
for w in words:
|
||||
if w.lower() in cur_list:
|
||||
cur_list.remove(w.lower())
|
||||
removed = True
|
||||
|
||||
elif isinstance(server_or_channel, discord.TextChannel):
|
||||
async with self.settings.channel(server_or_channel).filter() as cur_list:
|
||||
for w in words:
|
||||
if w.lower() in cur_list:
|
||||
cur_list.remove(w.lower())
|
||||
@ -194,7 +306,10 @@ class Filter(commands.Cog):
|
||||
async def check_filter(self, message: discord.Message):
|
||||
server = message.guild
|
||||
author = message.author
|
||||
word_list = await self.settings.guild(server).filter()
|
||||
word_list = set(
|
||||
await self.settings.guild(server).filter()
|
||||
+ await self.settings.channel(message.channel).filter()
|
||||
)
|
||||
filter_count = await self.settings.guild(server).filterban_count()
|
||||
filter_time = await self.settings.guild(server).filterban_time()
|
||||
user_count = await self.settings.member(author).filter_count()
|
||||
@ -246,10 +361,19 @@ class Filter(commands.Cog):
|
||||
if not valid_user:
|
||||
return
|
||||
|
||||
# Bots and mods or superior are ignored from the filter
|
||||
mod_or_superior = await is_mod_or_superior(self.bot, obj=author)
|
||||
if mod_or_superior:
|
||||
if await self.bot.is_automod_immune(message):
|
||||
return
|
||||
|
||||
await self.check_filter(message)
|
||||
|
||||
async def on_message_edit(self, _, message):
|
||||
author = message.author
|
||||
if message.guild is None or self.bot.user == author:
|
||||
return
|
||||
valid_user = isinstance(author, discord.Member) and not author.bot
|
||||
if not valid_user:
|
||||
return
|
||||
|
||||
# As is anyone configured to be
|
||||
if await self.bot.is_automod_immune(message):
|
||||
return
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user