mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-22 02:37:57 -05:00
[V3 Mod&Filter] add tempbans and filtering names/nicknames (#1123)
* [V3 Mod] add tempban command * [V3 Filter] add name filtering * [V3 Mod] Modify invite finding to have a max_age param * [V3 Mod and Filter] regen messages.pot * [V3 Mod] fill in formatting on tban invite * [V3 Filter] add on_member_join + refactor logic on_member_update
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from collections import deque, defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
from collections import deque, defaultdict, namedtuple
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
@@ -27,7 +27,8 @@ class Mod:
|
||||
"ignored": False,
|
||||
"respect_hierarchy": True,
|
||||
"delete_delay": -1,
|
||||
"reinvite_on_unban": False
|
||||
"reinvite_on_unban": False,
|
||||
"current_tempbans": []
|
||||
}
|
||||
|
||||
default_channel_settings = {
|
||||
@@ -56,10 +57,14 @@ class Mod:
|
||||
self.unban_queue = []
|
||||
self.cache = defaultdict(lambda: deque(maxlen=3))
|
||||
|
||||
self.bot.loop.create_task(self._casetype_registration())
|
||||
|
||||
self.registration_task = self.bot.loop.create_task(self._casetype_registration())
|
||||
self.tban_expiry_task = self.bot.loop.create_task(self.check_tempban_expirations())
|
||||
self.last_case = defaultdict(dict)
|
||||
|
||||
def __unload(self):
|
||||
self.registration_task.cancel()
|
||||
self.tban_expiry_task.cancel()
|
||||
|
||||
async def _casetype_registration(self):
|
||||
casetypes_to_register = [
|
||||
{
|
||||
@@ -83,6 +88,13 @@ class Mod:
|
||||
"case_str": "Hackban",
|
||||
"audit_type": "ban"
|
||||
},
|
||||
{
|
||||
"name": "tempban",
|
||||
"default_setting": True,
|
||||
"image": "\N{ALARM CLOCK}\N{HAMMER}",
|
||||
"case_str": "Tempban",
|
||||
"audit_type": "ban"
|
||||
},
|
||||
{
|
||||
"name": "softban",
|
||||
"default_setting": True,
|
||||
@@ -432,6 +444,54 @@ class Mod:
|
||||
except RuntimeError as e:
|
||||
await ctx.send(e)
|
||||
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(ban_members=True)
|
||||
async def tempban(self, ctx: RedContext, user: discord.Member, days: int=1, *, reason: str=None):
|
||||
"""Tempbans the user for the specified number of days"""
|
||||
guild = ctx.guild
|
||||
author = ctx.author
|
||||
days_delta = timedelta(days=int(days))
|
||||
unban_time = datetime.utcnow() + days_delta
|
||||
channel = ctx.channel
|
||||
can_ban = channel.permissions_for(guild.me).ban_members
|
||||
|
||||
invite = await self.get_invite_for_reinvite(ctx, int(days_delta.total_seconds() + 86400))
|
||||
if invite is None:
|
||||
invite = ""
|
||||
|
||||
if can_ban:
|
||||
queue_entry = (guild.id, user.id)
|
||||
await self.settings.member(user).banned_until.set(unban_time.timestamp())
|
||||
cur_tbans = await self.settings.guild(guild).current_tempbans()
|
||||
cur_tbans.append(user.id)
|
||||
await self.settings.guild(guild).current_tempbans.set(cur_tbans)
|
||||
|
||||
try: # We don't want blocked DMs preventing us from banning
|
||||
msg = await user.send(
|
||||
_("You have been temporarily banned from {} until {}. "
|
||||
"Here is an invite for when your ban expires: {}").format(
|
||||
guild.name, unban_time.strftime("%m-%d-%Y %H:%M:%S"), invite))
|
||||
except discord.HTTPException:
|
||||
msg = None
|
||||
self.ban_queue.append(queue_entry)
|
||||
try:
|
||||
await guild.ban(user)
|
||||
except discord.Forbidden:
|
||||
await ctx.send(_("I can't do that for some reason."))
|
||||
except discord.HTTPException:
|
||||
await ctx.send(_("Something went wrong while banning"))
|
||||
else:
|
||||
await ctx.send(_("Done. Enough chaos for now"))
|
||||
|
||||
try:
|
||||
await modlog.create_case(
|
||||
guild, ctx.message.created_at, "tempban",
|
||||
user, author, reason, unban_time
|
||||
)
|
||||
except RuntimeError as e:
|
||||
await ctx.send(e)
|
||||
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(ban_members=True)
|
||||
@@ -571,7 +631,7 @@ class Mod:
|
||||
.format(invite.url))
|
||||
|
||||
@staticmethod
|
||||
async def get_invite_for_reinvite(ctx: RedContext):
|
||||
async def get_invite_for_reinvite(ctx: RedContext, max_age: int=86400):
|
||||
"""Handles the reinvite logic for getting an invite
|
||||
to send the newly unbanned user
|
||||
:returns: :class:`Invite`"""
|
||||
@@ -597,8 +657,8 @@ class Mod:
|
||||
if channel is None:
|
||||
return
|
||||
try:
|
||||
# Create invite that expires after 1 day
|
||||
return await channel.create_invite(max_age=86400)
|
||||
# Create invite that expires after max_age
|
||||
return await channel.create_invite(max_age=max_age)
|
||||
except discord.HTTPException:
|
||||
return
|
||||
|
||||
@@ -1085,6 +1145,31 @@ class Mod:
|
||||
await ctx.send(_("That user doesn't have any recorded name or "
|
||||
"nickname change."))
|
||||
|
||||
async def check_tempban_expirations(self):
|
||||
member = namedtuple("Member", "id guild")
|
||||
while self == self.bot.get_cog("Mod"):
|
||||
for guild in self.bot.guilds:
|
||||
guild_tempbans = await self.settings.guild(guild).current_tempbans()
|
||||
for uid in guild_tempbans:
|
||||
unban_time = datetime.utcfromtimestamp(
|
||||
await self.settings.member(
|
||||
member(uid, guild)
|
||||
).banned_until()
|
||||
)
|
||||
now = datetime.utcnow()
|
||||
if now > unban_time: # Time to unban the user
|
||||
user = await self.bot.get_user_info(uid)
|
||||
queue_entry = (guild.id, user.id)
|
||||
self.unban_queue.append(queue_entry)
|
||||
try:
|
||||
await guild.unban(user, reason="Tempban finished")
|
||||
except discord.Forbidden:
|
||||
self.unban_queue.remove(queue_entry)
|
||||
log.info("Failed to unban member due to permissions")
|
||||
except discord.HTTPException:
|
||||
self.unban_queue.remove(queue_entry)
|
||||
await asyncio.sleep(60)
|
||||
|
||||
async def check_duplicates(self, message):
|
||||
guild = message.guild
|
||||
author = message.author
|
||||
|
||||
Reference in New Issue
Block a user