Migration vers Disnake et ajout des components V2

This commit is contained in:
Mathis 2026-05-09 18:42:42 +02:00
parent c8c579eefe
commit 98f7501e07
47 changed files with 1196 additions and 722 deletions

View file

@ -1,6 +1,6 @@
import discord
from discord import app_commands
from discord.ext import commands
from disnake.ext import commands
import json
import os
@ -38,7 +38,7 @@ class Blacklist(commands.Cog):
# ---------- Slash Commands ----------
@app_commands.command(name="blacklist", description="Blacklist un utilisateur")
@app_commands.describe(user="Utilisateur à blacklister", reason="Raison")
async def blacklist_slash(self, interaction: discord.Interaction, user: discord.User, reason: str = "Aucune raison fournie"):
async def blacklist_slash(self, interaction: disnake.Interaction, user: disnake.User, reason: str = "Aucune raison fournie"):
if not self.is_agent(interaction.user.id):
return await interaction.response.send_message("⛔ Tu nas pas la permission.", ephemeral=True)
@ -55,7 +55,7 @@ class Blacklist(commands.Cog):
@app_commands.command(name="unblacklist", description="Retire un utilisateur de la blacklist")
@app_commands.describe(user="Utilisateur à retirer")
async def unblacklist_slash(self, interaction: discord.Interaction, user: discord.User):
async def unblacklist_slash(self, interaction: disnake.Interaction, user: disnake.User):
if not self.is_agent(interaction.user.id):
return await interaction.response.send_message("⛔ Tu nas pas la permission.", ephemeral=True)
@ -81,13 +81,13 @@ class Blacklist(commands.Cog):
pass
# --------- Boutons ----------
class TicketButton(discord.ui.View):
class TicketButton(disnake.ui.View):
def __init__(self, user_id: int):
super().__init__(timeout=None)
self.user_id = user_id
@discord.ui.button(label="📩 Ouvrir une demande de déblacklist", style=discord.ButtonStyle.danger)
async def open_ticket(self, interaction: discord.Interaction, button: discord.ui.Button):
@disnake.ui.button(label="📩 Ouvrir une demande de déblacklist", style=disnake.ButtonStyle.danger)
async def open_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
if interaction.user.id != self.user_id:
return await interaction.response.send_message("❌ Ce bouton ne tappartient pas.", ephemeral=True)
@ -110,13 +110,13 @@ class TicketButton(discord.ui.View):
await interaction.response.send_message("✅ Ton ticket a été créé en MP avec le bot.", ephemeral=True)
class CloseTicketView(discord.ui.View):
class CloseTicketView(disnake.ui.View):
def __init__(self, user_id: int):
super().__init__(timeout=None)
self.user_id = user_id
@discord.ui.button(label="❌ Fermer le ticket", style=discord.ButtonStyle.danger)
async def close_ticket(self, interaction: discord.Interaction, button: discord.ui.Button):
@disnake.ui.button(label="❌ Fermer le ticket", style=disnake.ButtonStyle.danger)
async def close_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
agents = load_json(AGENTS_FILE, {"agents": []})
if str(interaction.user.id) not in agents["agents"]:
return await interaction.response.send_message("⛔ Seuls les agents Omega Kube peuvent fermer un ticket.", ephemeral=True)
@ -124,13 +124,13 @@ class CloseTicketView(discord.ui.View):
view = ConfirmCloseView(self.user_id)
await interaction.response.send_message("⚠️ Veux-tu vraiment fermer ce ticket ?", view=view, ephemeral=True)
class ConfirmCloseView(discord.ui.View):
class ConfirmCloseView(disnake.ui.View):
def __init__(self, user_id: int):
super().__init__(timeout=30)
self.user_id = user_id
@discord.ui.button(label="✅ Oui", style=discord.ButtonStyle.success)
async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):
@disnake.ui.button(label="✅ Oui", style=disnake.ButtonStyle.success)
async def confirm(self, button: disnake.ui.Button, interaction: disnake.Interaction):
agents = load_json(AGENTS_FILE, {"agents": []})
if str(interaction.user.id) not in agents["agents"]:
return await interaction.response.send_message("⛔ Tu nas pas la permission.", ephemeral=True)
@ -142,12 +142,12 @@ class ConfirmCloseView(discord.ui.View):
await interaction.channel.send("✅ Ticket fermé.")
await interaction.channel.delete()
@discord.ui.button(label="❌ Non", style=discord.ButtonStyle.secondary)
async def cancel(self, interaction: discord.Interaction, button: discord.ui.Button):
@disnake.ui.button(label="❌ Non", style=disnake.ButtonStyle.secondary)
async def cancel(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_message("❌ Fermeture annulée.", ephemeral=True)
# --------- Setup Cog ----------
async def setup(bot: commands.Bot):
def setup(bot: commands.Bot):
cog = Blacklist(bot)
await bot.add_cog(cog)
await bot.tree.sync(guild=discord.Object(id=MAIN_GUILD_ID))
await bot.tree.sync(guild=disnake.Object(id=MAIN_GUILD_ID))

View file

@ -83,12 +83,12 @@ def parse_date(date_str: str):
class AbsenceModal(disnake.ui.Modal):
def __init__(self, superieur: Optional[disnake.Member] = None):
super().__init__(title="Déclarer une Absence Staff")
super().__init__(title="Déclarer une Absence Staff", components=[self.motif, self.date_debut, self.date_fin])
self.superieur = superieur
motif = disnake.ui.TextInput(
label="Motif de l'absence",
style=disnake.TextStyle.paragraph,
style=disnake.TextInputStyle.paragraph,
placeholder="Ex: Vacances, Raisons personnelles, Travail...",
required=True,
max_length=500
@ -187,7 +187,7 @@ class AbsenceConfigView(disnake.ui.View):
self.guild_id = guild_id
@disnake.ui.button(label="Définir le Salon", style=disnake.ButtonStyle.primary, emoji="📁")
async def set_channel(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def set_channel(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_message("Mentionne le salon ici (ou envoie son ID) :", ephemeral=True)
def check(m):
@ -214,7 +214,7 @@ class AbsenceConfigView(disnake.ui.View):
await interaction.followup.send("❌ Temps écoulé.", ephemeral=True)
@disnake.ui.button(label="Définir le Rôle", style=disnake.ButtonStyle.primary, emoji="🎭")
async def set_role(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def set_role(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_message("Mentionne le rôle ici (ou envoie son ID) :", ephemeral=True)
def check(m):
@ -499,7 +499,7 @@ class Absence(commands.Cog):
settings = load_settings(message.guild.id)
channel_id = settings.get("absence_channel_id")
absence_url = f"https://discord.com/channels/{message.guild.id}/{channel_id}/{msg_id}" if channel_id and msg_id else ""
absence_url = f"https://disnake.com/channels/{message.guild.id}/{channel_id}/{msg_id}" if channel_id and msg_id else ""
reply_text = f"⚠️ {message.author.mention}, cet utilisateur est actuellement absent."
if absence_url:
@ -507,5 +507,5 @@ class Absence(commands.Cog):
await message.reply(reply_text, delete_after=30)
async def setup(bot):
await bot.add_cog(Absence(bot))
def setup(bot):
bot.add_cog(Absence(bot))

View file

@ -268,5 +268,5 @@ class Backup(commands.Cog):
await interaction.followup.send(embed=embed,ephemeral=True)
async def setup(bot: commands.Bot):
await bot.add_cog(Backup(bot))
def setup(bot):
bot.add_cog(Backup(bot))

View file

@ -198,5 +198,5 @@ class BackupRestore(commands.Cog):
async def element_autocomplete_decorator(self, interaction: disnake.ApplicationCommandInteraction, current: str):
return await self.element_autocomplete(interaction, current)
async def setup(bot: commands.Bot):
await bot.add_cog(BackupRestore(bot))
def setup(bot):
bot.add_cog(BackupRestore(bot))

View file

@ -200,7 +200,7 @@ class TicketButton(disnake.ui.View):
self.user_id = user_id
@disnake.ui.button(label="📩 Ouvrir une demande de révision", style=disnake.ButtonStyle.primary, custom_id="blacklist_open_ticket")
async def open_ticket(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def open_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
if interaction.user.id != self.user_id:
return await interaction.response.send_message("❌ Ce bouton ne tappartient pas.", ephemeral=True)
@ -239,7 +239,7 @@ class CloseTicketView(disnake.ui.View):
self.user_id = user_id
@disnake.ui.button(label="❌ Fermer le ticket", style=disnake.ButtonStyle.danger, custom_id="blacklist_close_ticket")
async def close_ticket(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def close_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
if not interaction.bot.get_cog("Blacklist").is_agent(interaction.user.id):
return await interaction.response.send_message("⛔ Seuls les agents peuvent fermer ce ticket.", ephemeral=True)
@ -252,7 +252,7 @@ class ConfirmCloseView(disnake.ui.View):
self.user_id = user_id
@disnake.ui.button(label="✅ Oui", style=disnake.ButtonStyle.success, custom_id="blacklist_confirm_close")
async def confirm(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def confirm(self, button: disnake.ui.Button, interaction: disnake.Interaction):
if not interaction.bot.get_cog("Blacklist").is_agent(interaction.user.id):
return await interaction.response.send_message("⛔ Tu nas pas la permission.", ephemeral=True)
@ -290,9 +290,9 @@ class ConfirmCloseView(disnake.ui.View):
await interaction.response.send_message("✅ Ticket fermé avec succès.", ephemeral=True)
@disnake.ui.button(label="❌ Non", style=disnake.ButtonStyle.secondary, custom_id="blacklist_cancel_close")
async def cancel(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def cancel(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_message("❌ Fermeture annulée.", ephemeral=True)
# --------- Setup ---------
async def setup(bot: commands.Bot):
await bot.add_cog(Blacklist(bot))
def setup(bot):
bot.add_cog(Blacklist(bot))

View file

@ -34,7 +34,7 @@ def save_report(issue_iid, user_id):
class BugReportModal(disnake.ui.Modal):
def __init__(self, priority_choice):
super().__init__(title="Signaler un Bug")
super().__init__(title="Signaler un Bug", components=[self.bug_title, self.description])
self.priority_choice = priority_choice
bug_title = disnake.ui.TextInput(
@ -46,7 +46,7 @@ class BugReportModal(disnake.ui.Modal):
description = disnake.ui.TextInput(
label="Description détaillée",
style=disnake.TextStyle.paragraph,
style=disnake.TextInputStyle.paragraph,
placeholder="Que s'est-il passé ? Comment reproduire le bug ?",
required=True,
max_length=1000
@ -77,7 +77,7 @@ class BugReportModal(disnake.ui.Modal):
class FeatureSuggestionModal(disnake.ui.Modal):
def __init__(self):
super().__init__(title="Suggérer une fonctionnalité")
super().__init__(title="Suggérer une fonctionnalité", components=[self.suggestion_title, self.description])
suggestion_title = disnake.ui.TextInput(
label="Titre de la suggestion",
@ -88,7 +88,7 @@ class FeatureSuggestionModal(disnake.ui.Modal):
description = disnake.ui.TextInput(
label="Détails de la fonctionnalité",
style=disnake.TextStyle.paragraph,
style=disnake.TextInputStyle.paragraph,
placeholder="Décrivez comment cela devrait fonctionner...",
required=True,
max_length=1000
@ -334,5 +334,5 @@ class BugReport(commands.Cog):
async def suggerer_fonctionnalite(self, interaction: disnake.ApplicationCommandInteraction):
await interaction.response.send_modal(FeatureSuggestionModal())
async def setup(bot):
await bot.add_cog(BugReport(bot))
def setup(bot):
bot.add_cog(BugReport(bot))

View file

@ -274,5 +274,5 @@ class Convocation(commands.Cog):
await interaction.response.send_message(embed=embed, ephemeral=True)
async def setup(bot):
await bot.add_cog(Convocation(bot))
def setup(bot):
bot.add_cog(Convocation(bot))

View file

@ -218,5 +218,5 @@ class Goodbye(commands.Cog):
await interaction.response.send_message(msg, ephemeral=True)
async def setup(bot):
await bot.add_cog(Goodbye(bot))
def setup(bot):
bot.add_cog(Goodbye(bot))

View file

@ -7,7 +7,7 @@ import re
class ModReasonModal(disnake.ui.Modal):
def __init__(self, parent_view, action_type):
super().__init__(title=f"Raison pour {action_type}")
super().__init__(title=f"Raison pour {action_type}", components=[])
self.parent_view = parent_view
self.action_type = action_type
@ -17,7 +17,7 @@ class ModReasonModal(disnake.ui.Modal):
required=True,
max_length=500
)
self.add_item(self.reason)
self.append_component(self.reason)
if action_type == "TIMEOUT":
self.duration = disnake.ui.TextInput(
@ -26,7 +26,7 @@ class ModReasonModal(disnake.ui.Modal):
required=True,
max_length=10
)
self.add_item(self.duration)
self.append_component(self.duration)
async def callback(self, interaction: disnake.Interaction):
reason = self.reason.value
@ -78,43 +78,43 @@ class ModPanelView(disnake.ui.View):
await interaction.edit_original_response(embed=embed, view=self)
@disnake.ui.button(label="Avertir", style=disnake.ButtonStyle.secondary, emoji="⚠️")
async def warn_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def warn_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_modal(ModReasonModal(self, "WARN"))
@disnake.ui.button(label="Timeout", style=disnake.ButtonStyle.secondary, emoji="")
async def timeout_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def timeout_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_modal(ModReasonModal(self, "TIMEOUT"))
@disnake.ui.button(label="Expulser", style=disnake.ButtonStyle.secondary, emoji="👢")
async def kick_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def kick_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_modal(ModReasonModal(self, "KICK"))
@disnake.ui.button(label="Bannir", style=disnake.ButtonStyle.danger, emoji="🔨")
async def ban_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def ban_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_modal(ModReasonModal(self, "BAN"))
@disnake.ui.button(label="Historique", style=disnake.ButtonStyle.primary, emoji="📜")
async def history_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def history_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
cog = interaction.bot.get_cog("Moderation")
await cog.history(interaction, self.member)
@disnake.ui.button(label="Clear Warns", style=disnake.ButtonStyle.danger, emoji="🧹")
async def clear_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def clear_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
cog = interaction.bot.get_cog("Moderation")
await cog.clearwarns(interaction, self.member, reason="Nettoyage via Panel")
await self.update_panel(interaction)
class ModConfigModal(disnake.ui.Modal):
def __init__(self, field_name, current_value):
super().__init__(title=f"Modifier {field_name}")
super().__init__(components=[], title=f"Modifier {field_name}")
self.field_name = field_name
self.input = disnake.ui.TextInput(
label=field_name,
default=str(current_value),
value=str(current_value),
placeholder="Entrez une valeur numérique...",
required=True
)
self.add_item(self.input)
self.append_component(self.input)
async def callback(self, interaction: disnake.Interaction):
value = self.input.value
@ -146,7 +146,7 @@ class ModConfigView(disnake.ui.View):
self.db_path = db_path
@disnake.ui.button(label="Log Channel", style=disnake.ButtonStyle.primary, emoji="📁")
async def log_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def log_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
view = disnake.ui.View()
select = disnake.ui.ChannelSelect(
placeholder="Sélectionnez le salon de logs...",
@ -166,7 +166,7 @@ class ModConfigView(disnake.ui.View):
await interaction.response.send_message("Choisissez le salon de logs :", view=view, ephemeral=True)
@disnake.ui.button(label="Paliers Warns", style=disnake.ButtonStyle.secondary, emoji="⚖️")
async def limits_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def limits_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("SELECT warn_limit_timeout, warn_limit_kick, warn_limit_ban FROM mod_config WHERE guild_id = ?", (self.guild_id,))
@ -187,7 +187,7 @@ class ModConfigView(disnake.ui.View):
await interaction.response.send_message("Quelle limite modifier ?", view=view, ephemeral=True)
@disnake.ui.button(label="Durée Timeout", style=disnake.ButtonStyle.secondary, emoji="⏱️")
async def duration_btn(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def duration_btn(self, button: disnake.ui.Button, interaction: disnake.Interaction):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("SELECT timeout_duration FROM mod_config WHERE guild_id = ?", (self.guild_id,))
@ -320,5 +320,5 @@ class Moderation(commands.Cog):
if not interaction.response.is_done(): await interaction.response.send_message(f"✅ Warns de {member.name} effacés.", ephemeral=True)
else: await interaction.followup.send(f"✅ Warns de {member.name} effacés.", ephemeral=True)
async def setup(bot):
await bot.add_cog(Moderation(bot))
def setup(bot):
bot.add_cog(Moderation(bot))

View file

@ -56,5 +56,5 @@ class AntiRaid(commands.Cog):
embed = disnake.Embed(title="🚨 ALERTE RAID", description=f"Vague de {len(self.join_cache[guild.id])} membres !", color=0xFF0000)
await channel.send(embed=embed)
async def setup(bot):
await bot.add_cog(AntiRaid(bot))
def setup(bot):
bot.add_cog(AntiRaid(bot))

View file

@ -13,7 +13,7 @@ WHITELIST_FILE = "data/whitelist.json"
CACHE_TTL = 5
# Triggers pour détection de liens
LINK_TRIGGERS = ("discord.gg/", "http://", "https://", "www.")
LINK_TRIGGERS = ("disnake.gg/", "http://", "https://", "www.")
class AntiSpam(commands.Cog):
def __init__(self, bot):
@ -181,5 +181,5 @@ class AntiSpam(commands.Cog):
except Exception as e:
print(f"Erreur lors de la sanction : {e}")
async def setup(bot):
await bot.add_cog(AntiSpam(bot))
def setup(bot):
bot.add_cog(AntiSpam(bot))

View file

@ -58,5 +58,5 @@ class LogsManager(commands.Cog):
)
await log_chan.send(embed=embed)
async def setup(bot):
await bot.add_cog(LogsManager(bot))
def setup(bot):
bot.add_cog(LogsManager(bot))

View file

@ -38,7 +38,7 @@ def save_settings(guild_id: int, settings: dict) -> None:
# --- MODALS DE CONFIGURATION DU RÈGLEMENT (BACK-END) ---
class RulesTitleModal(disnake.ui.Modal, title="📜 Titre du Règlement"):
class RulesTitleModal(disnake.ui.Modal):
"""Modal pour configurer le titre du règlement"""
title_input = disnake.ui.TextInput(
label="Titre du règlement",
@ -49,12 +49,12 @@ class RulesTitleModal(disnake.ui.Modal, title="📜 Titre du Règlement"):
)
def __init__(self, guild_id: int, settings: dict, on_update_callback=None):
super().__init__()
super().__init__(title="📜 Titre du Règlement", components=[self.title_input])
self.guild_id = guild_id
self.settings = settings
self.on_update_callback = on_update_callback
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
self.settings["rules_title"] = self.title_input.value
save_settings(self.guild_id, self.settings)
@ -77,24 +77,24 @@ class RulesTitleModal(disnake.ui.Modal, title="📜 Titre du Règlement"):
return view
class RulesContentModal(disnake.ui.Modal, title="📝 Contenu du Règlement"):
class RulesContentModal(disnake.ui.Modal):
"""Modal pour configurer le contenu du règlement"""
content_input = disnake.ui.TextInput(
label="Contenu du règlement",
placeholder="Entrez les règles de votre serveur...",
style=disnake.TextStyle.paragraph,
style=disnake.TextInputStyle.paragraph,
min_length=10,
max_length=4000,
required=True
)
def __init__(self, guild_id: int, settings: dict, on_update_callback=None):
super().__init__()
super().__init__(title="📝 Contenu du Règlement", components=[self.content_input])
self.guild_id = guild_id
self.settings = settings
self.on_update_callback = on_update_callback
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
self.settings["rules_content"] = self.content_input.value
save_settings(self.guild_id, self.settings)
@ -117,7 +117,7 @@ class RulesContentModal(disnake.ui.Modal, title="📝 Contenu du Règlement"):
return view
class RulesChannelModal(disnake.ui.Modal, title="📌 Salon du Règlement"):
class RulesChannelModal(disnake.ui.Modal):
"""Modal pour sélectionner le salon du règlement"""
channel_input = disnake.ui.TextInput(
label="ID du salon",
@ -128,12 +128,12 @@ class RulesChannelModal(disnake.ui.Modal, title="📌 Salon du Règlement"):
)
def __init__(self, guild_id: int, settings: dict, on_update_callback=None):
super().__init__()
super().__init__(title="📌 Salon du Règlement", components=[self.channel_input])
self.guild_id = guild_id
self.settings = settings
self.on_update_callback = on_update_callback
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
if not self.channel_input.value.isdigit():
return await interaction.response.send_message(
"❌ Erreur : ID invalide.",
@ -171,7 +171,7 @@ class RulesChannelModal(disnake.ui.Modal, title="📌 Salon du Règlement"):
return view
class RulesRoleModal(disnake.ui.Modal, title="✅ Rôle d'Acceptation"):
class RulesRoleModal(disnake.ui.Modal):
"""Modal pour configurer le rôle attribué à l'acceptation"""
role_input = disnake.ui.TextInput(
label="ID du rôle",
@ -182,12 +182,12 @@ class RulesRoleModal(disnake.ui.Modal, title="✅ Rôle d'Acceptation"):
)
def __init__(self, guild_id: int, settings: dict, on_update_callback=None):
super().__init__()
super().__init__(title="✅ Rôle d'Acceptation", components=[self.role_input])
self.guild_id = guild_id
self.settings = settings
self.on_update_callback = on_update_callback
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
if not self.role_input.value.isdigit():
return await interaction.response.send_message(
"❌ Erreur : ID invalide.",
@ -225,7 +225,7 @@ class RulesRoleModal(disnake.ui.Modal, title="✅ Rôle d'Acceptation"):
return view
class RulesMessageTypeModal(disnake.ui.Modal, title="📝 Type de Message"):
class RulesMessageTypeModal(disnake.ui.Modal):
"""Modal pour choisir le type de message du règlement"""
message_type = disnake.ui.TextInput(
label="Type de message",
@ -236,12 +236,12 @@ class RulesMessageTypeModal(disnake.ui.Modal, title="📝 Type de Message"):
)
def __init__(self, guild_id: int, settings: dict, on_update_callback=None):
super().__init__()
super().__init__(title="📝 Type de Message", components=[self.message_type])
self.guild_id = guild_id
self.settings = settings
self.on_update_callback = on_update_callback
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
msg_type = self.message_type.value.lower().strip()
if msg_type not in ["embed", "simple"]:
@ -323,13 +323,13 @@ class RulesAcceptButton(disnake.ui.View):
self.guild_id = guild_id
self.accept_role_id = accept_role_id
@discord.ui.button(
@disnake.ui.button(
label="J'accepte le règlement",
emoji="",
style=disnake.ButtonStyle.green,
custom_id="rules_accept_button"
)
async def accept_rules(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def accept_rules(self, button: disnake.ui.Button, interaction: disnake.Interaction):
"""Gère le clic sur le bouton d'acceptation"""
guild = interaction.guild
@ -495,8 +495,8 @@ class RulesCog(commands.Cog):
return title, content
async def setup(bot):
def setup(bot):
"""Setup du cog de règlement"""
cog = RulesCog(bot)
await bot.add_cog(cog)
bot.add_cog(cog)

View file

@ -47,5 +47,5 @@ class NoLink(commands.Cog):
print(f"Erreur lors de la suppression du message : {exc}")
async def setup(bot: commands.Bot) -> None:
await bot.add_cog(NoLink(bot))
def setup(bot: commands.Bot) -> None:
bot.add_cog(NoLink(bot))

View file

@ -77,5 +77,5 @@ class Scan(commands.Cog):
await interaction.followup.send(f"✅ Fichier sain.\nHash : `{result['hash']}`")
async def setup(bot: commands.Bot):
await bot.add_cog(Scan(bot))
def setup(bot):
bot.add_cog(Scan(bot))

View file

@ -69,7 +69,7 @@ def is_immune(guild, user) -> bool:
# --- MODALS DE CONFIGURATION ---
class SpamThresholdModal(disnake.ui.Modal, title="🛡️ Seuil Anti-Spam"):
class SpamThresholdModal(disnake.ui.Modal):
"""Modal pour configurer le seuil anti-spam"""
threshold_input = disnake.ui.TextInput(
label="Messages max autorisés",
@ -80,12 +80,12 @@ class SpamThresholdModal(disnake.ui.Modal, title="🛡️ Seuil Anti-Spam"):
)
def __init__(self, guild_id: int, settings: dict, view: 'SecurityView'):
super().__init__()
super().__init__(title="🛡️ Seuil Anti-Spam", components=[self.threshold_input])
self.guild_id = guild_id
self.settings = settings
self.parent_view = view
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
if not self.threshold_input.value.isdigit():
return await interaction.response.send_message(
"❌ Erreur : Veuillez entrer un nombre entier.",
@ -110,7 +110,7 @@ class SpamThresholdModal(disnake.ui.Modal, title="🛡️ Seuil Anti-Spam"):
ephemeral=True
)
class RaidThresholdModal(disnake.ui.Modal, title="⚔️ Seuil Anti-Raid"):
class RaidThresholdModal(disnake.ui.Modal):
"""Modal pour configurer le seuil anti-raid"""
threshold_input = disnake.ui.TextInput(
label="Joins max en 10 secondes",
@ -121,12 +121,12 @@ class RaidThresholdModal(disnake.ui.Modal, title="⚔️ Seuil Anti-Raid"):
)
def __init__(self, guild_id: int, settings: dict, view: 'SecurityView'):
super().__init__()
super().__init__(title="⚔️ Seuil Anti-Raid", components=[self.threshold_input])
self.guild_id = guild_id
self.settings = settings
self.parent_view = view
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
if not self.threshold_input.value.isdigit():
return await interaction.response.send_message(
"❌ Erreur : Veuillez entrer un nombre entier.",
@ -153,7 +153,7 @@ class RaidThresholdModal(disnake.ui.Modal, title="⚔️ Seuil Anti-Raid"):
# --- MODALS DE CONFIGURATION WHITELIST ---
class WhitelistModal(disnake.ui.Modal, title="👤 Ajouter à la Whitelist"):
class WhitelistModal(disnake.ui.Modal):
"""Modal pour ajouter un utilisateur à la whitelist"""
user_input = disnake.ui.TextInput(
label="ID de l'utilisateur",
@ -164,11 +164,11 @@ class WhitelistModal(disnake.ui.Modal, title="👤 Ajouter à la Whitelist"):
)
def __init__(self, guild_id: int, view: 'SecurityView'):
super().__init__()
super().__init__(title="👤 Ajouter à la Whitelist", components=[self.user_input])
self.guild_id = guild_id
self.parent_view = view
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
if not self.user_input.value.isdigit():
return await interaction.response.send_message(
"❌ Erreur : ID invalide.",
@ -873,7 +873,7 @@ class MainCategorySelect(disnake.ui.Select):
class WhitelistSelect(disnake.ui.Select):
"""Menu dropdown pour voir et gérer les utilisateurs whitelistés"""
def __init__(self, guild: discord.Guild, view: 'SecurityView'):
def __init__(self, guild: disnake.Guild, view: 'SecurityView'):
self.guild = guild
self.parent_view = view
whitelist = load_whitelist(guild.id)
@ -950,11 +950,11 @@ class Security(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(
@commands.slash_command(
name="security",
description="🛡️ Ouvrir le panneau de sécurité Kuby"
)
async def security(self, interaction: disnake.Interaction):
async def security(self, interaction: disnake.ApplicationCommandInteraction):
"""
Commande principale pour ouvrir l'interface de sécurité.
Accessible uniquement aux administrateurs et propriétaires whitelistés.
@ -989,12 +989,12 @@ class Security(commands.Cog):
)
@security.error
async def security_error(self, interaction: disnake.Interaction, error: app_commands.AppCommandError):
async def security_error(self, interaction: disnake.Interaction, error: Exception):
"""Gestion des erreurs de la commande security"""
# Utilisation de followup si l'interaction est déjà différée ou répondue
send_method = interaction.followup.send if interaction.response.is_done() else interaction.response.send_message
if isinstance(error, app_commands.MissingPermissions):
if isinstance(error, commands.MissingPermissions):
await send_method(
"❌ Permissions insuffisantes.",
ephemeral=True
@ -1006,7 +1006,7 @@ class Security(commands.Cog):
)
async def setup(bot):
def setup(bot):
"""Setup du cog de sécurité"""
await bot.add_cog(Security(bot))
bot.add_cog(Security(bot))

View file

@ -20,6 +20,6 @@ class SentBotMessages(commands.Cog):
except Exception as e:
await interaction.response.send_message(f"❌ Une erreur est survenue : {e}", ephemeral=True)
async def setup(bot):
await bot.add_cog(SentBotMessages(bot))
def setup(bot):
bot.add_cog(SentBotMessages(bot))

View file

@ -109,5 +109,5 @@ class SnipeCommands(commands.Cog):
ephemeral=True
)
async def setup(bot):
await bot.add_cog(SnipeCommands(bot))
def setup(bot):
bot.add_cog(SnipeCommands(bot))

View file

@ -68,5 +68,5 @@ class StaffLeaderboard(commands.Cog):
await interaction.followup.send("Une erreur est survenue lors de la génération du classement.", ephemeral=True)
async def setup(bot):
await bot.add_cog(StaffLeaderboard(bot))
def setup(bot):
bot.add_cog(StaffLeaderboard(bot))

View file

@ -133,5 +133,5 @@ class StaffRatings(commands.Cog):
return buf
async def setup(bot):
await bot.add_cog(StaffRatings(bot))
def setup(bot):
bot.add_cog(StaffRatings(bot))

File diff suppressed because it is too large Load diff

View file

@ -490,6 +490,6 @@ class TicketAnalytics(commands.Cog):
await interaction.followup.send(embed=feedback_embed, ephemeral=True)
async def setup(bot):
def setup(bot):
"""Setup function for the analytics cog"""
await bot.add_cog(TicketAnalytics(bot))
bot.add_cog(TicketAnalytics(bot))

View file

@ -15,11 +15,11 @@ class FeedbackView(disnake.ui.View):
self.add_item(RatingSelect())
@disnake.ui.button(label="📝 Laisser un commentaire", style=disnake.ButtonStyle.secondary, custom_id="feedback_comment", row=1)
async def comment_button(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def comment_button(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await interaction.response.send_modal(FeedbackModal(self))
@disnake.ui.button(label="✅ Envoyer", style=disnake.ButtonStyle.green, custom_id="feedback_submit", row=1)
async def submit_button(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def submit_button(self, button: disnake.ui.Button, interaction: disnake.Interaction):
if self.rating == 0:
await interaction.response.send_message("❌ Veuillez sélectionner une note avant d'envoyer.", ephemeral=True)
return
@ -128,17 +128,17 @@ class RatingSelect(disnake.ui.Select):
class FeedbackModal(disnake.ui.Modal):
def __init__(self, view):
super().__init__(title="Votre avis")
super().__init__(components=[], title="Votre avis")
self.view = view
self.comment = disnake.ui.TextInput(
label="Commentaire",
style=disnake.TextStyle.paragraph,
style=disnake.TextInputStyle.paragraph,
placeholder="Dites-nous ce que vous avez pensé du support...",
required=True,
max_length=1000
)
self.add_item(self.comment)
self.append_component(self.comment)
async def on_submit(self, interaction: disnake.Interaction):
async def callback(self, interaction: disnake.Interaction):
self.view.comment = self.comment.value
await interaction.response.send_message("Commentaire enregistré ! N'oubliez pas de valider avec 'Envoyer'.", ephemeral=True)

View file

@ -195,7 +195,7 @@ class ContinueFormView(disnake.ui.View):
self.step2_part2_data = step2_part2_data
@disnake.ui.button(label="📋 Continuer le formulaire", style=disnake.ButtonStyle.green, custom_id="continue_form")
async def continue_form(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def continue_form(self, button: disnake.ui.Button, interaction: disnake.Interaction):
"""Passe à l'étape suivante du formulaire"""
if self.current_step == 1:
await interaction.response.send_modal(TicketStep2Part1(self.step1_data))
@ -414,7 +414,7 @@ class TicketManagementView(disnake.ui.View):
return None
@disnake.ui.button(label="🔒 Fermer le Ticket", style=disnake.ButtonStyle.red, custom_id="close_ticket")
async def close_ticket(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def close_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
"""Ferme le ticket en désactivant l'envoi de messages pour le membre"""
await interaction.response.defer(ephemeral=True)
@ -445,7 +445,7 @@ class TicketManagementView(disnake.ui.View):
await interaction.followup.send(f"❌ Erreur lors de la fermeture : {e}", ephemeral=True)
@disnake.ui.button(label="👤 Claim le Ticket", style=disnake.ButtonStyle.blurple, custom_id="claim_ticket")
async def claim_ticket(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def claim_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
"""Un staff prend en charge le ticket"""
await interaction.response.defer(ephemeral=False)
@ -490,7 +490,7 @@ class ClosedTicketView(disnake.ui.View):
return None
@disnake.ui.button(label="♻ Réouvrir le Ticket", style=disnake.ButtonStyle.green, custom_id="reopen_ticket")
async def reopen_ticket(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def reopen_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
"""Réouvre le ticket pour le membre"""
await interaction.response.defer(ephemeral=True)
@ -526,15 +526,15 @@ class ReopenStatusView(disnake.ui.View):
self.owner = owner
@disnake.ui.button(label="Écrit (Ouvert)", style=disnake.ButtonStyle.secondary)
async def set_written(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def set_written(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await self.apply_status(interaction, "ouvert")
@disnake.ui.button(label="Oral (À faire)", style=disnake.ButtonStyle.primary)
async def set_oral(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def set_oral(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await self.apply_status(interaction, "oral-à-faire")
@disnake.ui.button(label="Accepté", style=disnake.ButtonStyle.success)
async def set_accepted(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def set_accepted(self, button: disnake.ui.Button, interaction: disnake.Interaction):
await self.apply_status(interaction, "accepté")
async def apply_status(self, interaction: disnake.Interaction, prefix: str):
@ -585,7 +585,7 @@ class ReopenStatusView(disnake.ui.View):
await interaction.followup.send(f"❌ Erreur système : {e}", ephemeral=True)
@disnake.ui.button(label="❌ Supprimer le Ticket", style=disnake.ButtonStyle.danger, custom_id="delete_ticket")
async def delete_ticket(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def delete_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
"""Supprime le salon du ticket"""
await interaction.response.defer(ephemeral=True)
@ -611,7 +611,7 @@ class TicketView(disnake.ui.View):
super().__init__(timeout=None)
@disnake.ui.button(label="📑 Ouvrir un Ticket Whitelist", style=disnake.ButtonStyle.red, custom_id="open_ticket")
async def open_ticket(self, interaction: disnake.Interaction, button: disnake.ui.Button):
async def open_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
"""Affiche le premier formulaire"""
await interaction.response.send_modal(TicketStep1())
@ -799,8 +799,8 @@ class Ticket(commands.Cog):
kuby_logger.error(f"Erreur lors de la validation du ticket: {e}", exc_info=True)
await message.channel.send(f"❌ Une erreur système est survenue : {e}")
async def setup(bot):
await bot.add_cog(Ticket(bot))
def setup(bot):
bot.add_cog(Ticket(bot))
bot.add_view(TicketView())
bot.add_view(TicketManagementView())
bot.add_view(ClosedTicketView())

View file

@ -455,6 +455,6 @@ class WebsiteSync(commands.Cog, name="Website Sync"):
# ─── Setup ───────────────────────────────────────────────────────────────────
async def setup(bot: commands.Bot):
await bot.add_cog(WebsiteSync(bot))
def setup(bot):
bot.add_cog(WebsiteSync(bot))
logger.info("Cog WebsiteSync chargé.")

View file

@ -243,6 +243,6 @@ class Welcome(commands.Cog):
bg_used = "background_template.png" if not banner_path else (banner_path.split('/')[-1])
await interaction.response.send_message(f"✅ Configuration de bienvenida enregistrée !\nFond utilisé: {bg_used}", ephemeral=True)
async def setup(bot):
await bot.add_cog(Welcome(bot))
def setup(bot):
bot.add_cog(Welcome(bot))

View file

@ -95,5 +95,5 @@ class Whitelist(commands.Cog):
return self._get_guild_whitelist(guild_id).copy()
async def setup(bot):
await bot.add_cog(Whitelist(bot))
def setup(bot):
bot.add_cog(Whitelist(bot))

View file

@ -293,5 +293,5 @@ class WhitelistRemovalView(View):
ephemeral=True
)
async def setup(bot):
await bot.add_cog(WhitelistMonitor(bot))
def setup(bot):
bot.add_cog(WhitelistMonitor(bot))