1
0
Fork 0

Switch warn to slash commands

This commit is contained in:
Ethanell 2021-02-04 10:37:23 +01:00
parent 6f79c6b040
commit 35a5fec694
3 changed files with 88 additions and 81 deletions

View file

@ -1,6 +1,6 @@
from discord.ext import commands from discord.ext import commands
from discord import Member, VoiceState, Embed, Reaction, Guild from discord import Member, VoiceState, Embed, Reaction, Guild
from discord.ext.commands import CommandNotFound, BadArgument from discord.ext.commands import BadArgument
from discord_slash import SlashContext, cog_ext, SlashCommandOptionType from discord_slash import SlashContext, cog_ext, SlashCommandOptionType
from discord_slash.utils import manage_commands from discord_slash.utils import manage_commands

View file

@ -1,6 +1,5 @@
from urllib.parse import urlencode from urllib.parse import urlencode
from discord import Embed
from discord.ext import commands from discord.ext import commands
from discord_slash import cog_ext, SlashContext, SlashCommandOptionType from discord_slash import cog_ext, SlashContext, SlashCommandOptionType
from discord_slash.utils import manage_commands from discord_slash.utils import manage_commands

View file

@ -1,9 +1,11 @@
from discord import Embed, Forbidden, Member, Guild from discord import Embed, Forbidden, Member, Guild
from discord.ext import commands from discord.ext import commands
from discord.ext.commands import BadArgument from discord.ext.commands import BadArgument
from discord_slash import cog_ext, SlashCommandOptionType, SlashContext
from discord_slash.utils import manage_commands
from administrator import db from administrator import db, slash
from administrator.check import is_enabled from administrator.check import is_enabled, guild_only, has_permissions
from administrator.logger import logger from administrator.logger import logger
from administrator.utils import time_pars, seconds_to_time_string from administrator.utils import time_pars, seconds_to_time_string
@ -14,12 +16,13 @@ logger = logger.getChild(extension_name)
class Warn(commands.Cog): class Warn(commands.Cog):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot self.bot = bot
slash.get_cog_commands(self)
def description(self): def description(self):
return "Send warning to user and make custom action after a number of warn" return "Send warning to user and make custom action after a number of warn"
@staticmethod @staticmethod
async def check_warn(ctx: commands.Context, target: Member): async def check_warn(ctx: SlashContext, target: Member):
s = db.Session() s = db.Session()
c = s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id, db.Warn.user == target.id).count() c = s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id, db.Warn.user == target.id).count()
a = s.query(db.WarnAction).filter(db.WarnAction.guild == ctx.guild.id, db.WarnAction.count == c).first() a = s.query(db.WarnAction).filter(db.WarnAction.guild == ctx.guild.id, db.WarnAction.count == c).first()
@ -32,96 +35,72 @@ class Warn(commands.Cog):
elif a.action == "mute": elif a.action == "mute":
pass # Integration with upcoming ban & mute extension pass # Integration with upcoming ban & mute extension
@staticmethod @cog_ext.cog_subcommand(base="warn", name="add", description="Send a warn to a user", options=[
def get_target(ctx: commands.Context, user: str) -> Member: manage_commands.create_option("user", "The user", SlashCommandOptionType.USER, True),
users = {str(m): m for m in ctx.guild.members} manage_commands.create_option("description", "The description", SlashCommandOptionType.STRING, True)
if user not in users: ])
raise BadArgument()
return users[user]
@commands.group("warn", pass_context=True)
@is_enabled() @is_enabled()
@commands.guild_only() @guild_only()
#@commands.has_permissions(manage_roles=True, kick_members=True, ban_members=True, mute_members=True) @has_permissions(kick_members=True, ban_members=True, mute_members=True)
async def warn(self, ctx: commands.Context): async def warn_add(self, ctx: SlashContext, user: Member, description: str):
if ctx.invoked_subcommand is None:
await ctx.invoke(self.warn_help)
@warn.group("help", pass_context=True)
async def warn_help(self, ctx: commands.Context):
embed = Embed(title="Warn help")
embed.add_field(name="add <user> <description>", value="Send a warn to a user", inline=False)
embed.add_field(name="remove <user> <number>", value="Remove a number of warn to a user", inline=False)
embed.add_field(name="purge <user>", value="Remove all warn of a user", inline=False)
embed.add_field(name="list [user#discriminator|actions]", value="List warn of the guild or a specified user\n"
"If you specify `actions` instead of a user, "
"all the actions of the guild will be listed",
inline=False)
embed.add_field(name="action <count> <action>", value="Set an action for a count of warn\n"
"Actions: `mute<time>`, `kick`, `ban[time]`, `nothing`\n"
"Time: `?D?H?M?S`\n"
"Example: `action 1 mute1H` to mute someone for one hour "
"after only one war\n"
"or `action 3 ban1D` to ban someone for one day after 3 "
"warns", inline=False)
await ctx.send(embed=embed)
@warn.group("add", pass_context=True)
async def warn_add(self, ctx: commands.Context, user: str, description: str):
target = self.get_target(ctx, user)
s = db.Session() s = db.Session()
s.add(db.Warn(target.id, ctx.author.id, ctx.guild.id, description)) s.add(db.Warn(user.id, ctx.author.id, ctx.guild.id, description))
s.commit() s.commit()
s.close() s.close()
try: try:
embed = Embed(title="You get warned !", description="A moderator send you a warn", color=0xff0000) embed = Embed(title="You get warned !", description="A moderator send you a warn", color=0xff0000)
embed.add_field(name="Description:", value=description) embed.add_field(name="Description:", value=description)
await target.send(embed=embed) await user.send(embed=embed)
except Forbidden: except Forbidden:
await ctx.send("Fail to send warn notification to the user, DM close :warning:") await ctx.send(content="Fail to send warn notification to the user, DM close :warning:")
else: else:
await ctx.message.add_reaction("\U0001f44d") await ctx.send(content="\U0001f44d")
await self.check_warn(ctx, target) await self.check_warn(ctx, user)
@warn.group("remove", pass_context=True) @cog_ext.cog_subcommand(base="warn", name="remove", description="Remove a number of warn to a user", options=[
async def warn_remove(self, ctx: commands.Context, user: str, number: int): manage_commands.create_option("user", "The user", SlashCommandOptionType.USER, True),
target = self.get_target(ctx, user) manage_commands.create_option("number", "The warn to remove", SlashCommandOptionType.INTEGER, True)
])
@is_enabled()
@guild_only()
@has_permissions(kick_members=True, ban_members=True, mute_members=True)
async def warn_remove(self, ctx: SlashContext, user: Member, number: int):
s = db.Session() s = db.Session()
ws = s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id, db.Warn.user == target.id).all() ws = s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id, db.Warn.user == user.id).all()
if number <= 0 or number > len(ws): if number <= 0 or number > len(ws):
raise BadArgument() raise BadArgument()
s.delete(ws[number-1]) s.delete(ws[number-1])
s.commit() s.commit()
s.close() s.close()
await ctx.message.add_reaction("\U0001f44d") await ctx.send(content="\U0001f44d")
@warn.group("purge", pass_context=True) @cog_ext.cog_subcommand(base="warn", name="purge", description="Remove all warn of a user", options=[
async def warn_purge(self, ctx: commands.Context, user: str): manage_commands.create_option("user", "The user", SlashCommandOptionType.USER, True)])
target = self.get_target(ctx, user) @is_enabled()
@guild_only()
@has_permissions(kick_members=True, ban_members=True, mute_members=True)
async def warn_purge(self, ctx: SlashContext, user: Member):
s = db.Session() s = db.Session()
for w in s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id, db.Warn.user == target.id).all(): for w in s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id, db.Warn.user == user.id).all():
s.delete(w) s.delete(w)
s.commit() s.commit()
s.close() s.close()
await ctx.message.add_reaction("\U0001f44d") await ctx.send(content="\U0001f44d")
@warn.group("list", pass_context=True) @cog_ext.cog_subcommand(base="warn", name="list", description="List warn of the guild or a specified user",
async def warn_list(self, ctx: commands.Context, user: str = None): options=[
manage_commands.create_option("user", "The user", SlashCommandOptionType.USER, False)
])
@is_enabled()
@guild_only()
@has_permissions(kick_members=True, ban_members=True, mute_members=True)
async def warn_list(self, ctx: SlashContext, user: Member = None):
s = db.Session() s = db.Session()
embed = Embed(title="Warn list") embed = Embed(title="Warn list")
ws = {} ws = {}
if user:
if user == "actions": ws[user.id] = s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id, db.Warn.user == user.id).all()
embed.title = "Actions list"
for a in s.query(db.WarnAction).filter(db.WarnAction.guild == ctx.guild.id).order_by(db.WarnAction.count)\
.all():
action = f"{a.action} for {seconds_to_time_string(a.duration)}" if a.duration else a.action
embed.add_field(name=f"{a.count} warn(s)", value=action, inline=False)
elif user:
target = self.get_target(ctx, user)
ws[target.id] = s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id, db.Warn.user == target.id).all()
else: else:
for w in s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id).all(): for w in s.query(db.Warn).filter(db.Warn.guild == ctx.guild.id).all():
if w.user not in ws: if w.user not in ws:
@ -134,10 +113,45 @@ class Warn(commands.Cog):
for w in ws[u]] for w in ws[u]]
embed.add_field(name=self.bot.get_user(u), value="\n".join(warns), inline=False) embed.add_field(name=self.bot.get_user(u), value="\n".join(warns), inline=False)
await ctx.send(embed=embed) await ctx.send(embeds=[embed])
@warn.group("action", pass_context=True) @cog_ext.cog_subcommand(base="warn", name="actions", description="List all the actions of the guild")
async def warn_action(self, ctx: commands.Context, count: int, action: str): @is_enabled()
@guild_only()
@has_permissions(kick_members=True, ban_members=True, mute_members=True)
async def warn_actions(self, ctx: SlashContext):
s = db.Session()
embed = Embed(title="Warn list")
ws = {}
embed.title = "Actions list"
for a in s.query(db.WarnAction).filter(db.WarnAction.guild == ctx.guild.id).order_by(db.WarnAction.count) \
.all():
action = f"{a.action} for {seconds_to_time_string(a.duration)}" if a.duration else a.action
embed.add_field(name=f"{a.count} warn(s)", value=action, inline=False)
s.close()
for u in ws:
warns = [f"{self.bot.get_user(w.author).mention} - {w.date.strftime('%d/%m/%Y %H:%M')}```{w.description}```"
for w in ws[u]]
embed.add_field(name=self.bot.get_user(u), value="\n".join(warns), inline=False)
await ctx.send(embeds=[embed])
@cog_ext.cog_subcommand(base="warn", name="action", description="Set an action for a count of warn", options=[
manage_commands.create_option("count", "The number of warns", SlashCommandOptionType.INTEGER, True),
manage_commands.create_option("action", "The action", SlashCommandOptionType.STRING, True, [
manage_commands.create_choice("mute", "mute"),
manage_commands.create_choice("kick", "kick"),
manage_commands.create_choice("ban", "ban"),
manage_commands.create_choice("nothing", "nothing")
]),
manage_commands.create_option("time", "The duration of the action, ?D?H?M?S",
SlashCommandOptionType.STRING, False)
])
@is_enabled()
@guild_only()
@has_permissions(administrator=True)
async def warn_action(self, ctx: SlashContext, count: int, action: str, time: str = None):
if count <= 0 or\ if count <= 0 or\
(action not in ["kick", "nothing"] and not action.startswith("mute") and not action.startswith("ban")): (action not in ["kick", "nothing"] and not action.startswith("mute") and not action.startswith("ban")):
raise BadArgument() raise BadArgument()
@ -151,14 +165,8 @@ class Warn(commands.Cog):
else: else:
raise BadArgument() raise BadArgument()
else: else:
time = None if time:
if action.startswith("mute"): time = time_pars(time).total_seconds()
time = time_pars(action.replace("mute", "")).total_seconds()
action = "mute"
elif action.startswith("ban"):
if action[3:]:
time = time_pars(action.replace("ban", "")).total_seconds()
action = "ban"
if a: if a:
a.action = action a.action = action
a.duration = time a.duration = time
@ -167,7 +175,7 @@ class Warn(commands.Cog):
s.commit() s.commit()
s.close() s.close()
await ctx.message.add_reaction("\U0001f44d") await ctx.send(content="\U0001f44d")
@commands.Cog.listener() @commands.Cog.listener()
async def on_guild_remove(self, guild: Guild): async def on_guild_remove(self, guild: Guild):