mirror of
https://github.com/skylanix/MamieHenriette.git
synced 2026-02-06 06:40:35 +01:00
Refonte du systeme d'avertissement et devient un moderation_event
Ajout de la commande !ban !kick !unban !listevent Ajout du role ID dans le panel , et possibilité d'activé les commandes via le panel
This commit is contained in:
@@ -40,12 +40,14 @@ class Commande(db.Model):
|
|||||||
trigger = db.Column(db.String(32), unique=True)
|
trigger = db.Column(db.String(32), unique=True)
|
||||||
response = db.Column(db.String(2000))
|
response = db.Column(db.String(2000))
|
||||||
|
|
||||||
class Warning(db.Model):
|
class ModerationEvent(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
type = db.Column(db.String(32))
|
||||||
username = db.Column(db.String(256))
|
username = db.Column(db.String(256))
|
||||||
discord_id = db.Column(db.String(64))
|
discord_id = db.Column(db.String(64))
|
||||||
created_at = db.Column(db.DateTime)
|
created_at = db.Column(db.DateTime)
|
||||||
reason = db.Column(db.String(1024))
|
reason = db.Column(db.String(1024))
|
||||||
staff_id = db.Column(db.String(64))
|
staff_id = db.Column(db.String(64))
|
||||||
staff_name = db.Column(db.String(256))
|
staff_name = db.Column(db.String(256))
|
||||||
|
duration = db.Column(db.Integer)
|
||||||
|
|
||||||
|
|||||||
@@ -46,12 +46,14 @@ CREATE TABLE IF NOT EXISTS `commande` (
|
|||||||
`response` VARCHAR(2000) NOT NULL
|
`response` VARCHAR(2000) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `warning` (
|
CREATE TABLE IF NOT EXISTS `moderation_event` (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
`type` VARCHAR(32) NOT NULL,
|
||||||
`username` VARCHAR(256) NOT NULL,
|
`username` VARCHAR(256) NOT NULL,
|
||||||
`discord_id` VARCHAR(64) NOT NULL,
|
`discord_id` VARCHAR(64) NOT NULL,
|
||||||
`created_at` DATETIME NOT NULL,
|
`created_at` DATETIME NOT NULL,
|
||||||
`reason` VARCHAR(1024) NOT NULL,
|
`reason` VARCHAR(1024) NOT NULL,
|
||||||
`staff_id` VARCHAR(64) NOT NULL,
|
`staff_id` VARCHAR(64) NOT NULL,
|
||||||
`staff_name` VARCHAR(256) NOT NULL
|
`staff_name` VARCHAR(256) NOT NULL,
|
||||||
|
`duration` INTEGER NULL
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from database.helpers import ConfigurationHelper
|
|||||||
from database.models import Configuration, Humeur, Commande
|
from database.models import Configuration, Humeur, Commande
|
||||||
from discord import Message, TextChannel
|
from discord import Message, TextChannel
|
||||||
from discordbot.humblebundle import checkHumbleBundleAndNotify
|
from discordbot.humblebundle import checkHumbleBundleAndNotify
|
||||||
from discordbot.command import handle_warning_command
|
from discordbot.command import handle_warning_command, handle_remove_warning_command, handle_list_warnings_command, handle_ban_command, handle_kick_command, handle_unban_command
|
||||||
from protondb import searhProtonDb
|
from protondb import searhProtonDb
|
||||||
|
|
||||||
class DiscordBot(discord.Client):
|
class DiscordBot(discord.Client):
|
||||||
@@ -65,10 +65,32 @@ async def on_message(message: Message):
|
|||||||
return
|
return
|
||||||
command_name = message.content.split()[0]
|
command_name = message.content.split()[0]
|
||||||
|
|
||||||
if command_name in ['!averto', '!av', '!avertissement', '!warn']:
|
if ConfigurationHelper().getValue('moderation_enable'):
|
||||||
await handle_warning_command(message, bot)
|
if command_name in ['!averto', '!av', '!avertissement', '!warn']:
|
||||||
return
|
await handle_warning_command(message, bot)
|
||||||
|
return
|
||||||
|
|
||||||
|
if command_name in ['!delaverto', '!removewarn', '!unwarn']:
|
||||||
|
await handle_remove_warning_command(message, bot)
|
||||||
|
return
|
||||||
|
|
||||||
|
if command_name in ['!listevent', '!listwarn', '!warnings']:
|
||||||
|
await handle_list_warnings_command(message, bot)
|
||||||
|
return
|
||||||
|
|
||||||
|
if ConfigurationHelper().getValue('moderation_ban_enable'):
|
||||||
|
if command_name == '!ban':
|
||||||
|
await handle_ban_command(message, bot)
|
||||||
|
return
|
||||||
|
|
||||||
|
if command_name == '!unban':
|
||||||
|
await handle_unban_command(message, bot)
|
||||||
|
return
|
||||||
|
|
||||||
|
if ConfigurationHelper().getValue('moderation_kick_enable'):
|
||||||
|
if command_name == '!kick':
|
||||||
|
await handle_kick_command(message, bot)
|
||||||
|
return
|
||||||
|
|
||||||
commande = Commande.query.filter_by(discord_enable=True, trigger=command_name).first()
|
commande = Commande.query.filter_by(discord_enable=True, trigger=command_name).first()
|
||||||
if commande:
|
if commande:
|
||||||
|
|||||||
@@ -1,24 +1,80 @@
|
|||||||
import discord
|
import discord
|
||||||
|
import asyncio
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from database import db
|
from database import db
|
||||||
from database.models import Warning
|
from database.helpers import ConfigurationHelper
|
||||||
|
from database.models import ModerationEvent
|
||||||
from discord import Message
|
from discord import Message
|
||||||
|
|
||||||
STAFF_ROLE_ID = 581990740431732738
|
def get_staff_role_id():
|
||||||
|
staff_role = ConfigurationHelper().getValue('moderation_staff_role_id')
|
||||||
|
return int(staff_role) if staff_role else 581990740431732738
|
||||||
|
|
||||||
|
def get_embed_delete_delay():
|
||||||
|
delay = ConfigurationHelper().getValue('moderation_embed_delete_delay')
|
||||||
|
return int(delay) if delay else 0
|
||||||
|
|
||||||
|
async def delete_after_delay(message):
|
||||||
|
delay = get_embed_delete_delay()
|
||||||
|
if delay > 0:
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
try:
|
||||||
|
await message.delete()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
async def handle_warning_command(message: Message, bot):
|
async def handle_warning_command(message: Message, bot):
|
||||||
if not any(role.id == STAFF_ROLE_ID for role in message.author.roles):
|
if not any(role.id == get_staff_role_id() for role in message.author.roles):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Accès refusé",
|
||||||
|
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
return
|
return
|
||||||
|
|
||||||
parts = message.content.split(maxsplit=2)
|
parts = message.content.split(maxsplit=2)
|
||||||
|
|
||||||
if len(parts) < 2 or not message.mentions:
|
if len(parts) < 2:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="📋 Utilisation de la commande",
|
||||||
|
description="**Syntaxe :** `!averto @utilisateur [raison]` ou `!averto <id> [raison]`",
|
||||||
|
color=discord.Color.blue()
|
||||||
|
)
|
||||||
|
embed.add_field(name="Exemples", value="• `!averto @User Spam dans le chat`\n• `!warn 123456789012345678 Comportement inapproprié`\n• `!av @User`", inline=False)
|
||||||
|
embed.add_field(name="Aliases", value="`!averto`, `!av`, `!avertissement`, `!warn`", inline=False)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
return
|
return
|
||||||
|
|
||||||
target_user = message.mentions[0]
|
target_user = None
|
||||||
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
if message.mentions:
|
||||||
|
target_user = message.mentions[0]
|
||||||
|
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
user_id = int(parts[1])
|
||||||
|
target_user = await bot.fetch_user(user_id)
|
||||||
|
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
||||||
|
except (ValueError, discord.NotFound):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="Utilisateur introuvable. Vérifiez la mention ou l'ID Discord.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
warning = Warning(
|
if not target_user:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="Impossible de trouver l'utilisateur.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
event = ModerationEvent(
|
||||||
|
type='warning',
|
||||||
username=target_user.name,
|
username=target_user.name,
|
||||||
discord_id=str(target_user.id),
|
discord_id=str(target_user.id),
|
||||||
created_at=datetime.utcnow(),
|
created_at=datetime.utcnow(),
|
||||||
@@ -26,19 +82,452 @@ async def handle_warning_command(message: Message, bot):
|
|||||||
staff_id=str(message.author.id),
|
staff_id=str(message.author.id),
|
||||||
staff_name=message.author.name
|
staff_name=message.author.name
|
||||||
)
|
)
|
||||||
db.session.add(warning)
|
db.session.add(event)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title="⚠️ Avertissement",
|
title="⚠️ Sanction",
|
||||||
description=f"{target_user.mention} a reçu un avertissement de la part de l'équipe de modération",
|
description=f"L'utilisateur **{target_user.name}** (`@{target_user.name}`) a été **averti**.",
|
||||||
color=discord.Color.red(),
|
color=discord.Color.orange()
|
||||||
|
)
|
||||||
|
if reason != "Sans raison":
|
||||||
|
embed.add_field(name="Raison", value=reason, inline=False)
|
||||||
|
|
||||||
|
sent_message = await message.channel.send(embed=embed)
|
||||||
|
await message.delete()
|
||||||
|
asyncio.create_task(delete_after_delay(sent_message))
|
||||||
|
|
||||||
|
async def handle_remove_warning_command(message: Message, bot):
|
||||||
|
if not any(role.id == get_staff_role_id() for role in message.author.roles):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Accès refusé",
|
||||||
|
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
parts = message.content.split(maxsplit=1)
|
||||||
|
|
||||||
|
if len(parts) < 2:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="📋 Utilisation de la commande",
|
||||||
|
description="**Syntaxe :** `!delaverto <id>`",
|
||||||
|
color=discord.Color.blue()
|
||||||
|
)
|
||||||
|
embed.add_field(name="Exemples", value="• `!delaverto 5`\n• `!removewarn 12`", inline=False)
|
||||||
|
embed.add_field(name="Aliases", value="`!delaverto`, `!removewarn`, `!delwarn`", inline=False)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
event_id = int(parts[1])
|
||||||
|
except ValueError:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="L'ID doit être un nombre entier.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
event = ModerationEvent.query.filter_by(id=event_id).first()
|
||||||
|
|
||||||
|
if not event:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description=f"Aucun événement de modération trouvé avec l'ID `{event_id}`.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
username = event.username
|
||||||
|
event_type = event.type
|
||||||
|
|
||||||
|
db.session.delete(event)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="✅ Événement supprimé",
|
||||||
|
description=f"L'événement de type **{event_type}** pour **{username}** (ID: {event_id}) a été supprimé.",
|
||||||
|
color=discord.Color.green(),
|
||||||
timestamp=datetime.utcnow()
|
timestamp=datetime.utcnow()
|
||||||
)
|
)
|
||||||
embed.add_field(name="👤 Utilisateur", value=f"{target_user.name}\n`{target_user.id}`", inline=True)
|
embed.add_field(name="🛡️ Modérateur", value=f"{message.author.name}\n`{message.author.id}`", inline=True)
|
||||||
#embed.add_field(name="🛡️ Modérateur", value=f"{message.author.name}\n`{message.author.id}`", inline=True)
|
|
||||||
embed.add_field(name="📝 Raison", value=reason, inline=False)
|
|
||||||
embed.set_footer(text="Mamie Henriette")
|
embed.set_footer(text="Mamie Henriette")
|
||||||
|
|
||||||
await message.channel.send(embed=embed)
|
await message.channel.send(embed=embed)
|
||||||
await message.delete()
|
await message.delete()
|
||||||
|
|
||||||
|
async def handle_list_warnings_command(message: Message, bot):
|
||||||
|
if not any(role.id == get_staff_role_id() for role in message.author.roles):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Accès refusé",
|
||||||
|
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
parts = message.content.split(maxsplit=1)
|
||||||
|
user_filter = None
|
||||||
|
|
||||||
|
if len(parts) > 1 and message.mentions:
|
||||||
|
user_filter = str(message.mentions[0].id)
|
||||||
|
|
||||||
|
if user_filter:
|
||||||
|
events = ModerationEvent.query.filter_by(discord_id=user_filter).order_by(ModerationEvent.created_at.desc()).all()
|
||||||
|
else:
|
||||||
|
events = ModerationEvent.query.order_by(ModerationEvent.created_at.desc()).all()
|
||||||
|
|
||||||
|
if not events:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="📋 Liste des événements",
|
||||||
|
description="Aucun événement de modération trouvé.",
|
||||||
|
color=discord.Color.blue()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
page = 0
|
||||||
|
per_page = 5
|
||||||
|
max_page = (len(events) - 1) // per_page
|
||||||
|
|
||||||
|
def create_embed(page_num):
|
||||||
|
start = page_num * per_page
|
||||||
|
end = start + per_page
|
||||||
|
page_events = events[start:end]
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="📋 Liste des événements de modération",
|
||||||
|
description=f"Total : {len(events)} événement(s)",
|
||||||
|
color=discord.Color.blue(),
|
||||||
|
timestamp=datetime.utcnow()
|
||||||
|
)
|
||||||
|
|
||||||
|
for event in page_events:
|
||||||
|
date_str = event.created_at.strftime('%d/%m/%Y %H:%M') if event.created_at else 'N/A'
|
||||||
|
embed.add_field(
|
||||||
|
name=f"ID {event.id} - {event.type.upper()} - {event.username}",
|
||||||
|
value=f"**Discord ID:** `{event.discord_id}`\n**Date:** {date_str}\n**Raison:** {event.reason}\n**Staff:** {event.staff_name}",
|
||||||
|
inline=False
|
||||||
|
)
|
||||||
|
|
||||||
|
embed.set_footer(text=f"Page {page_num + 1}/{max_page + 1}")
|
||||||
|
return embed
|
||||||
|
|
||||||
|
msg = await message.channel.send(embed=create_embed(page))
|
||||||
|
|
||||||
|
if max_page > 0:
|
||||||
|
await msg.add_reaction('⬅️')
|
||||||
|
await msg.add_reaction('➡️')
|
||||||
|
await msg.add_reaction('❌')
|
||||||
|
|
||||||
|
def check(reaction, user):
|
||||||
|
return user == message.author and str(reaction.emoji) in ['⬅️', '➡️', '❌'] and reaction.message.id == msg.id
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
reaction, user = await bot.wait_for('reaction_add', timeout=60.0, check=check)
|
||||||
|
|
||||||
|
if str(reaction.emoji) == '❌':
|
||||||
|
await msg.delete()
|
||||||
|
break
|
||||||
|
elif str(reaction.emoji) == '➡️' and page < max_page:
|
||||||
|
page += 1
|
||||||
|
await msg.edit(embed=create_embed(page))
|
||||||
|
elif str(reaction.emoji) == '⬅️' and page > 0:
|
||||||
|
page -= 1
|
||||||
|
await msg.edit(embed=create_embed(page))
|
||||||
|
|
||||||
|
await msg.remove_reaction(reaction, user)
|
||||||
|
except:
|
||||||
|
break
|
||||||
|
|
||||||
|
if msg:
|
||||||
|
try:
|
||||||
|
await msg.clear_reactions()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
await message.delete()
|
||||||
|
|
||||||
|
async def handle_ban_command(message: Message, bot):
|
||||||
|
if not any(role.id == get_staff_role_id() for role in message.author.roles):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Accès refusé",
|
||||||
|
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
parts = message.content.split(maxsplit=2)
|
||||||
|
|
||||||
|
if len(parts) < 2:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="📋 Utilisation de la commande",
|
||||||
|
description="**Syntaxe :** `!ban @utilisateur [raison]` ou `!ban <id> [raison]`",
|
||||||
|
color=discord.Color.blue()
|
||||||
|
)
|
||||||
|
embed.add_field(name="Exemples", value="• `!ban @User Spam répété`\n• `!ban 123456789012345678 Comportement toxique`", inline=False)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
target_user = None
|
||||||
|
if message.mentions:
|
||||||
|
target_user = message.mentions[0]
|
||||||
|
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
user_id = int(parts[1])
|
||||||
|
target_user = await bot.fetch_user(user_id)
|
||||||
|
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
||||||
|
except (ValueError, discord.NotFound):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="Utilisateur introuvable. Vérifiez la mention ou l'ID Discord.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not target_user:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="Impossible de trouver l'utilisateur.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
member = message.guild.get_member(target_user.id)
|
||||||
|
joined_days = None
|
||||||
|
if member and member.joined_at:
|
||||||
|
delta = datetime.utcnow() - member.joined_at.replace(tzinfo=None)
|
||||||
|
joined_days = delta.days
|
||||||
|
|
||||||
|
try:
|
||||||
|
await message.guild.ban(target_user, reason=reason)
|
||||||
|
except discord.Forbidden:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="Je n'ai pas les permissions nécessaires pour bannir cet utilisateur.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
event = ModerationEvent(
|
||||||
|
type='ban',
|
||||||
|
username=target_user.name,
|
||||||
|
discord_id=str(target_user.id),
|
||||||
|
created_at=datetime.utcnow(),
|
||||||
|
reason=reason,
|
||||||
|
staff_id=str(message.author.id),
|
||||||
|
staff_name=message.author.name
|
||||||
|
)
|
||||||
|
db.session.add(event)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="⚠️ Sanction",
|
||||||
|
description=f"L'utilisateur **{target_user.name}** (`@{target_user.name}`) a été **banni**.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
embed.add_field(name="ID Discord", value=f"`{target_user.id}`", inline=False)
|
||||||
|
if joined_days is not None:
|
||||||
|
embed.add_field(name="Membre depuis", value=f"{joined_days} jour{'s' if joined_days > 1 else ''}", inline=False)
|
||||||
|
if reason != "Sans raison":
|
||||||
|
embed.add_field(name="Raison", value=reason, inline=False)
|
||||||
|
|
||||||
|
sent_message = await message.channel.send(embed=embed)
|
||||||
|
await message.delete()
|
||||||
|
asyncio.create_task(delete_after_delay(sent_message))
|
||||||
|
|
||||||
|
async def handle_kick_command(message: Message, bot):
|
||||||
|
if not any(role.id == get_staff_role_id() for role in message.author.roles):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Accès refusé",
|
||||||
|
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
parts = message.content.split(maxsplit=2)
|
||||||
|
|
||||||
|
if len(parts) < 2 or not message.mentions:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="📋 Utilisation de la commande",
|
||||||
|
description="**Syntaxe :** `!kick @utilisateur [raison]`",
|
||||||
|
color=discord.Color.blue()
|
||||||
|
)
|
||||||
|
embed.add_field(name="Exemples", value="• `!kick @User Spam dans le chat`\n• `!kick @User Comportement inapproprié`", inline=False)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
target_member = message.mentions[0]
|
||||||
|
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
||||||
|
|
||||||
|
member_obj = message.guild.get_member(target_member.id)
|
||||||
|
if not member_obj:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="L'utilisateur n'est pas membre du serveur.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
joined_days = None
|
||||||
|
if member_obj.joined_at:
|
||||||
|
delta = datetime.utcnow() - member_obj.joined_at.replace(tzinfo=None)
|
||||||
|
joined_days = delta.days
|
||||||
|
|
||||||
|
try:
|
||||||
|
await message.guild.kick(member_obj, reason=reason)
|
||||||
|
except discord.Forbidden:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="Je n'ai pas les permissions nécessaires pour expulser cet utilisateur.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
event = ModerationEvent(
|
||||||
|
type='kick',
|
||||||
|
username=target_member.name,
|
||||||
|
discord_id=str(target_member.id),
|
||||||
|
created_at=datetime.utcnow(),
|
||||||
|
reason=reason,
|
||||||
|
staff_id=str(message.author.id),
|
||||||
|
staff_name=message.author.name
|
||||||
|
)
|
||||||
|
db.session.add(event)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="⚠️ Sanction",
|
||||||
|
description=f"L'utilisateur **{target_member.name}** (`@{target_member.name}`) a été **expulsé**.",
|
||||||
|
color=discord.Color.orange()
|
||||||
|
)
|
||||||
|
if joined_days is not None:
|
||||||
|
embed.add_field(name="Membre depuis", value=f"{joined_days} jour{'s' if joined_days > 1 else ''}", inline=False)
|
||||||
|
if reason != "Sans raison":
|
||||||
|
embed.add_field(name="Raison", value=reason, inline=False)
|
||||||
|
|
||||||
|
sent_message = await message.channel.send(embed=embed)
|
||||||
|
await message.delete()
|
||||||
|
asyncio.create_task(delete_after_delay(sent_message))
|
||||||
|
|
||||||
|
async def handle_unban_command(message: Message, bot):
|
||||||
|
if not any(role.id == get_staff_role_id() for role in message.author.roles):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Accès refusé",
|
||||||
|
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
parts = message.content.split(maxsplit=2)
|
||||||
|
|
||||||
|
if len(parts) < 2:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="📋 Utilisation de la commande",
|
||||||
|
description="**Syntaxe :** `!unban <discord_id>` ou `!unban #<sanction_id> [raison]`",
|
||||||
|
color=discord.Color.blue()
|
||||||
|
)
|
||||||
|
embed.add_field(name="Exemples", value="• `!unban 123456789012345678`\n• `!unban #5 Appel accepté`", inline=False)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
||||||
|
target_user = None
|
||||||
|
discord_id = None
|
||||||
|
|
||||||
|
if parts[1].startswith('#'):
|
||||||
|
try:
|
||||||
|
sanction_id = int(parts[1][1:])
|
||||||
|
event = ModerationEvent.query.filter_by(id=sanction_id, type='ban').first()
|
||||||
|
if not event:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description=f"Aucune sanction de ban trouvée avec l'ID #{sanction_id}.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
discord_id = event.discord_id
|
||||||
|
try:
|
||||||
|
target_user = await bot.fetch_user(int(discord_id))
|
||||||
|
except discord.NotFound:
|
||||||
|
pass
|
||||||
|
except ValueError:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="ID de sanction invalide.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
discord_id = parts[1]
|
||||||
|
target_user = await bot.fetch_user(int(discord_id))
|
||||||
|
except (ValueError, discord.NotFound):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="ID Discord invalide ou utilisateur introuvable.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
await message.guild.unban(discord.Object(id=int(discord_id)), reason=reason)
|
||||||
|
except discord.NotFound:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="Cet utilisateur n'est pas banni.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
except discord.Forbidden:
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="❌ Erreur",
|
||||||
|
description="Je n'ai pas les permissions nécessaires pour débannir cet utilisateur.",
|
||||||
|
color=discord.Color.red()
|
||||||
|
)
|
||||||
|
await message.channel.send(embed=embed)
|
||||||
|
return
|
||||||
|
|
||||||
|
username = target_user.name if target_user else f"ID: {discord_id}"
|
||||||
|
|
||||||
|
event = ModerationEvent(
|
||||||
|
type='unban',
|
||||||
|
username=username,
|
||||||
|
discord_id=discord_id,
|
||||||
|
created_at=datetime.utcnow(),
|
||||||
|
reason=reason,
|
||||||
|
staff_id=str(message.author.id),
|
||||||
|
staff_name=message.author.name
|
||||||
|
)
|
||||||
|
db.session.add(event)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="⚠️ Sanction",
|
||||||
|
description=f"L'utilisateur **{username}** (`@{username}`) a été **débanni**.",
|
||||||
|
color=discord.Color.green()
|
||||||
|
)
|
||||||
|
if reason != "Sans raison":
|
||||||
|
embed.add_field(name="Raison", value=reason, inline=False)
|
||||||
|
|
||||||
|
sent_message = await message.channel.send(embed=embed)
|
||||||
|
await message.delete()
|
||||||
|
asyncio.create_task(delete_after_delay(sent_message))
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ def updateConfiguration():
|
|||||||
ConfigurationHelper().createOrUpdate('humble_bundle_enable', False)
|
ConfigurationHelper().createOrUpdate('humble_bundle_enable', False)
|
||||||
if (request.form.get("proton_db_api_id") != None and request.form.get("proton_db_enable_enable") == None) :
|
if (request.form.get("proton_db_api_id") != None and request.form.get("proton_db_enable_enable") == None) :
|
||||||
ConfigurationHelper().createOrUpdate('proton_db_enable_enable', False)
|
ConfigurationHelper().createOrUpdate('proton_db_enable_enable', False)
|
||||||
|
if (request.form.get("moderation_staff_role_id") != None and request.form.get("moderation_enable") == None) :
|
||||||
|
ConfigurationHelper().createOrUpdate('moderation_enable', False)
|
||||||
|
if (request.form.get("moderation_staff_role_id") != None and request.form.get("moderation_ban_enable") == None) :
|
||||||
|
ConfigurationHelper().createOrUpdate('moderation_ban_enable', False)
|
||||||
|
if (request.form.get("moderation_staff_role_id") != None and request.form.get("moderation_kick_enable") == None) :
|
||||||
|
ConfigurationHelper().createOrUpdate('moderation_kick_enable', False)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,24 @@
|
|||||||
from flask import render_template
|
from flask import render_template, request, redirect, url_for
|
||||||
from webapp import webapp
|
from webapp import webapp
|
||||||
from database.models import Warning
|
from database import db
|
||||||
|
from database.models import ModerationEvent
|
||||||
|
|
||||||
@webapp.route("/moderation")
|
@webapp.route("/moderation")
|
||||||
def moderation():
|
def moderation():
|
||||||
warnings = Warning.query.order_by(Warning.created_at.desc()).all()
|
events = ModerationEvent.query.order_by(ModerationEvent.created_at.desc()).all()
|
||||||
return render_template("moderation.html", warnings=warnings)
|
return render_template("moderation.html", events=events)
|
||||||
|
|
||||||
|
@webapp.route("/moderation/update/<int:event_id>", methods=['POST'])
|
||||||
|
def update_moderation_event(event_id):
|
||||||
|
event = ModerationEvent.query.get_or_404(event_id)
|
||||||
|
event.reason = request.form.get('reason')
|
||||||
|
db.session.commit()
|
||||||
|
return redirect(url_for('moderation'))
|
||||||
|
|
||||||
|
@webapp.route("/moderation/delete/<int:event_id>")
|
||||||
|
def delete_moderation_event(event_id):
|
||||||
|
event = ModerationEvent.query.get_or_404(event_id)
|
||||||
|
db.session.delete(event)
|
||||||
|
db.session.commit()
|
||||||
|
return redirect(url_for('moderation'))
|
||||||
|
|
||||||
|
|||||||
@@ -55,4 +55,32 @@
|
|||||||
</select>
|
</select>
|
||||||
<input type="Submit" value="Définir">
|
<input type="Submit" value="Définir">
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<h2>Modération Discord</h2>
|
||||||
|
<form action="{{ url_for('updateConfiguration') }}" method="POST">
|
||||||
|
<label for="moderation_enable">Activer les avertissements</label>
|
||||||
|
<input type="checkbox" name="moderation_enable" {% if configuration.getValue('moderation_enable') %}
|
||||||
|
checked="checked" {% endif %}>
|
||||||
|
<label>Activer les commandes d'avertissement (!averto, !delaverto, !listaverto)</label>
|
||||||
|
|
||||||
|
<label for="moderation_ban_enable">Activer le ban</label>
|
||||||
|
<input type="checkbox" name="moderation_ban_enable" {% if configuration.getValue('moderation_ban_enable') %}
|
||||||
|
checked="checked" {% endif %}>
|
||||||
|
<label>Activer les commandes de bannissement (!ban, !unban)</label>
|
||||||
|
|
||||||
|
<label for="moderation_kick_enable">Activer le kick</label>
|
||||||
|
<input type="checkbox" name="moderation_kick_enable" {% if configuration.getValue('moderation_kick_enable') %}
|
||||||
|
checked="checked" {% endif %}>
|
||||||
|
<label>Activer la commande d'expulsion (!kick)</label>
|
||||||
|
|
||||||
|
<label for="moderation_staff_role_id">ID du rôle Staff</label>
|
||||||
|
<input name="moderation_staff_role_id" type="text" value="{{ configuration.getValue('moderation_staff_role_id') }}"
|
||||||
|
placeholder="581990740431732738" />
|
||||||
|
|
||||||
|
<label for="moderation_embed_delete_delay">Délai de suppression des embeds (en secondes, 0 = ne pas supprimer)</label>
|
||||||
|
<input name="moderation_embed_delete_delay" type="number" value="{{ configuration.getValue('moderation_embed_delete_delay') or '0' }}"
|
||||||
|
placeholder="0" min="0" />
|
||||||
|
|
||||||
|
<input type="Submit" value="Définir">
|
||||||
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -2,25 +2,39 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Modération Discord</h1>
|
<h1>Modération Discord</h1>
|
||||||
<p>Liste des avertissements émis sur le serveur Discord.</p>
|
<p>Historique des actions de modération sur le serveur Discord.</p>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Type</th>
|
||||||
<th>Utilisateur</th>
|
<th>Utilisateur</th>
|
||||||
<th>Discord ID</th>
|
<th>Discord ID</th>
|
||||||
<th>Date & Heure</th>
|
<th>Date & Heure</th>
|
||||||
<th>Raison</th>
|
<th>Raison</th>
|
||||||
<th>Staff</th>
|
<th>Staff</th>
|
||||||
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for warning in warnings %}
|
{% for event in events %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ warning.username }}</td>
|
<td>{{ event.id }}</td>
|
||||||
<td>{{ warning.discord_id }}</td>
|
<td>{{ event.type }}</td>
|
||||||
<td>{{ warning.created_at.strftime('%d/%m/%Y %H:%M') if warning.created_at else 'N/A' }}</td>
|
<td>{{ event.username }}</td>
|
||||||
<td>{{ warning.reason }}</td>
|
<td>{{ event.discord_id }}</td>
|
||||||
<td>{{ warning.staff_name }}</td>
|
<td>{{ event.created_at.strftime('%d/%m/%Y %H:%M') if event.created_at else 'N/A' }}</td>
|
||||||
|
<td>
|
||||||
|
<form action="{{ url_for('update_moderation_event', event_id = event.id) }}" method="POST" style="margin: 0;">
|
||||||
|
<input name="reason" type="text" value="{{ event.reason }}" style="width: 100%;" />
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td>{{ event.staff_name }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="javascript:void(0)" onclick="this.parentElement.parentElement.querySelector('form').submit()">Modifier</a>
|
||||||
|
|
|
||||||
|
<a href="{{ url_for('delete_moderation_event', event_id = event.id) }}" onclick="return confirm('Êtes-vous sûr de vouloir supprimer cet événement ?')">🗑️ Supprimer</a>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user