Migration vers Disnake et ajout des components V2
This commit is contained in:
parent
c8c579eefe
commit
98f7501e07
47 changed files with 1196 additions and 722 deletions
30
backups/scratch/check_button_sig.py
Normal file
30
backups/scratch/check_button_sig.py
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import disnake
|
||||||
|
from disnake.ui import View, Button
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
class MyView(View):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(timeout=None)
|
||||||
|
|
||||||
|
@disnake.ui.button(label="Test")
|
||||||
|
async def my_btn(self, arg1, arg2):
|
||||||
|
print(f"Arg1 type: {type(arg1)}")
|
||||||
|
print(f"Arg2 type: {type(arg2)}")
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
view = MyView()
|
||||||
|
btn = view.children[0]
|
||||||
|
print(f"Button: {btn}")
|
||||||
|
# Mock an interaction
|
||||||
|
class MockInteraction:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
await btn.callback(MockInteraction())
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error during callback: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
4
backups/scratch/check_checks.py
Normal file
4
backups/scratch/check_checks.py
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
import disnake
|
||||||
|
import disnake.ext.commands as commands
|
||||||
|
bot = commands.Bot(command_prefix="!")
|
||||||
|
print(f"Check methods: {[m for m in dir(bot) if 'check' in m]}")
|
||||||
19
backups/scratch/check_disnake.py
Normal file
19
backups/scratch/check_disnake.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import disnake
|
||||||
|
import disnake.ext.commands as commands
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
print(f"Disnake version: {disnake.__version__}")
|
||||||
|
bot = commands.Bot(command_prefix="!")
|
||||||
|
print(f"Bot has setup_hook: {hasattr(bot, 'setup_hook')}")
|
||||||
|
|
||||||
|
async def test():
|
||||||
|
print("Testing setup_hook call...")
|
||||||
|
class TestBot(commands.Bot):
|
||||||
|
async def setup_hook(self):
|
||||||
|
print("setup_hook CALLED!")
|
||||||
|
|
||||||
|
tbot = TestBot(command_prefix="!")
|
||||||
|
# We won't start it because we don't have a token here,
|
||||||
|
# but we can check if the library expects it.
|
||||||
|
|
||||||
|
asyncio.run(test())
|
||||||
7
backups/scratch/check_disnake_2.py
Normal file
7
backups/scratch/check_disnake_2.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import disnake
|
||||||
|
import disnake.ext.commands as commands
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
bot = commands.Bot(command_prefix="!")
|
||||||
|
print(f"Bot methods: {[m for m in dir(bot) if 'setup' in m or 'load' in m]}")
|
||||||
|
print(f"Is context manager: {hasattr(bot, '__aenter__')}")
|
||||||
6
backups/scratch/check_disnake_3.py
Normal file
6
backups/scratch/check_disnake_3.py
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import disnake
|
||||||
|
import disnake.ext.commands as commands
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
bot = commands.Bot(command_prefix="!")
|
||||||
|
print(f"load_extension is coroutine: {inspect.iscoroutinefunction(bot.load_extension)}")
|
||||||
8
backups/scratch/check_textstyle.py
Normal file
8
backups/scratch/check_textstyle.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import disnake
|
||||||
|
print(f"disnake.TextStyle: {hasattr(disnake, 'TextStyle')}")
|
||||||
|
print(f"disnake.TextInputStyle: {hasattr(disnake, 'TextInputStyle')}")
|
||||||
|
try:
|
||||||
|
import disnake.ui
|
||||||
|
print(f"disnake.ui.TextInputStyle: {hasattr(disnake.ui, 'TextInputStyle')}")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
52
backups/scratch/fix_modal_view_mixup.py
Normal file
52
backups/scratch/fix_modal_view_mixup.py
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
def fix_file(filepath):
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Split by class to be surgical
|
||||||
|
classes = re.split(r'^(class\s+.*)$', content, flags=re.MULTILINE)
|
||||||
|
|
||||||
|
new_content = []
|
||||||
|
if len(classes) > 0:
|
||||||
|
new_content.append(classes[0]) # Header
|
||||||
|
|
||||||
|
for i in range(1, len(classes), 2):
|
||||||
|
class_header = classes[i]
|
||||||
|
class_body = classes[i+1] if i+1 < len(classes) else ""
|
||||||
|
|
||||||
|
# Determine if it's a View or a Modal
|
||||||
|
is_view = "disnake.ui.View" in class_header or "(disnake.ui.View)" in class_header or "super().__init__(timeout=" in class_body
|
||||||
|
is_modal = "disnake.ui.Modal" in class_header or "(disnake.ui.Modal)" in class_header or "super().__init__(title=" in class_body
|
||||||
|
|
||||||
|
if is_view:
|
||||||
|
# Views use add_item
|
||||||
|
class_body = class_body.replace("self.append_component(", "self.add_item(")
|
||||||
|
# Ensure super().__init__ doesn't have components=[] if it's a view
|
||||||
|
class_body = class_body.replace("super().__init__(components=[],", "super().__init__(")
|
||||||
|
class_body = class_body.replace("super().__init__(components=[], ", "super().__init__(")
|
||||||
|
|
||||||
|
if is_modal:
|
||||||
|
# Modals use append_component
|
||||||
|
class_body = class_body.replace("self.add_item(", "self.append_component(")
|
||||||
|
# Modals MUST have components=[] in super().__init__ if not already there
|
||||||
|
# (My previous sed might have added it correctly)
|
||||||
|
pass
|
||||||
|
|
||||||
|
new_content.append(class_header)
|
||||||
|
new_content.append(class_body)
|
||||||
|
|
||||||
|
final_content = "".join(new_content)
|
||||||
|
if final_content != content:
|
||||||
|
with open(filepath, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(final_content)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk('commandes'):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith('.py'):
|
||||||
|
path = os.path.join(root, file)
|
||||||
|
if fix_file(path):
|
||||||
|
print(f"Fixed {path}")
|
||||||
36
backups/scratch/fix_text_input_default.py
Normal file
36
backups/scratch/fix_text_input_default.py
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
def fix_text_input_default(filepath):
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Match TextInput( followed by anything including newlines, until )
|
||||||
|
# This is a bit risky but we can refine it.
|
||||||
|
# We look for default= inside the arguments of TextInput
|
||||||
|
|
||||||
|
def replace_default(match):
|
||||||
|
args = match.group(2)
|
||||||
|
new_args = args.replace("default=", "value=")
|
||||||
|
return f"{match.group(1)}{new_args})"
|
||||||
|
|
||||||
|
# Regex: (disnake\.ui\.TextInput\(|ui\.TextInput\(|TextInput\() (.*? \))
|
||||||
|
# We need to handle nested parentheses if any, but TextInput usually doesn't have them in args.
|
||||||
|
|
||||||
|
new_content = re.sub(r'((?:disnake\.ui\.|ui\.|)TextInput\()(.*?\))', replace_default, content, flags=re.DOTALL)
|
||||||
|
|
||||||
|
if new_content != content:
|
||||||
|
with open(filepath, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(new_content)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
files_to_check = [
|
||||||
|
"commandes/moderation.py",
|
||||||
|
"commandes/ticket/__init__.py"
|
||||||
|
]
|
||||||
|
|
||||||
|
for path in files_to_check:
|
||||||
|
if os.path.exists(path):
|
||||||
|
if fix_text_input_default(path):
|
||||||
|
print(f"Fixed {path}")
|
||||||
7
backups/scratch/inspect_modal.py
Normal file
7
backups/scratch/inspect_modal.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import disnake
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f"Modal init signature: {inspect.signature(disnake.ui.Modal.__init__)}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error inspecting Modal: {e}")
|
||||||
7
backups/scratch/inspect_section.py
Normal file
7
backups/scratch/inspect_section.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import disnake
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f"Section init signature: {inspect.signature(disnake.ui.Section.__init__)}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error inspecting Section: {e}")
|
||||||
3
backups/scratch/test_container.py
Normal file
3
backups/scratch/test_container.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import disnake
|
||||||
|
print(disnake.ui.Container)
|
||||||
|
print(disnake.ui.TextDisplay)
|
||||||
17
backups/scratch/test_edit_message.py
Normal file
17
backups/scratch/test_edit_message.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import disnake
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
class DummyResponse:
|
||||||
|
async def edit_message(self, *args, **kwargs):
|
||||||
|
print(kwargs)
|
||||||
|
|
||||||
|
inter = type('DummyInter', (), {'response': DummyResponse()})()
|
||||||
|
container = disnake.ui.Container()
|
||||||
|
try:
|
||||||
|
await inter.response.edit_message(components=[container])
|
||||||
|
print("Success")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
|
||||||
|
asyncio.run(main())
|
||||||
88
bot.py
88
bot.py
|
|
@ -1,4 +1,5 @@
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
# Charger les variables d'environnement AVANT tout le reste
|
# Charger les variables d'environnement AVANT tout le reste
|
||||||
|
|
@ -13,7 +14,6 @@ from src.logger import kuby_logger, log_performance
|
||||||
import logging
|
import logging
|
||||||
from src.advanced_logger import AdvancedLogger
|
from src.advanced_logger import AdvancedLogger
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
|
|
||||||
# Récupération et validation de l'ID d'application
|
# Récupération et validation de l'ID d'application
|
||||||
application_id_raw = os.getenv("APPLICATION_ID")
|
application_id_raw = os.getenv("APPLICATION_ID")
|
||||||
|
|
@ -42,9 +42,6 @@ class MyBot(commands.Bot):
|
||||||
)
|
)
|
||||||
kuby_logger.info("MyBot instance created successfully")
|
kuby_logger.info("MyBot instance created successfully")
|
||||||
|
|
||||||
async def setup_hook(self):
|
|
||||||
kuby_logger.info("🚀 Démarrage du bot Kuby...")
|
|
||||||
|
|
||||||
# Initialize advanced logger
|
# Initialize advanced logger
|
||||||
self.advanced_logger = AdvancedLogger(self)
|
self.advanced_logger = AdvancedLogger(self)
|
||||||
kuby_logger.info("✅ Advanced logger initialized")
|
kuby_logger.info("✅ Advanced logger initialized")
|
||||||
|
|
@ -54,8 +51,6 @@ class MyBot(commands.Bot):
|
||||||
try:
|
try:
|
||||||
flask_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "serveur_flask.py")
|
flask_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "serveur_flask.py")
|
||||||
if os.path.exists(flask_path):
|
if os.path.exists(flask_path):
|
||||||
# On utilise DEVNULL car PM2 ou Nohup gèrent déjà les logs globaux
|
|
||||||
# et ça évite que le pipe se remplisse et bloque le serveur Flask
|
|
||||||
self.flask_process = subprocess.Popen(
|
self.flask_process = subprocess.Popen(
|
||||||
[sys.executable, flask_path],
|
[sys.executable, flask_path],
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
|
|
@ -68,6 +63,11 @@ class MyBot(commands.Bot):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
kuby_logger.error(f"❌ Impossible de démarrer le serveur Flask: {e}")
|
kuby_logger.error(f"❌ Impossible de démarrer le serveur Flask: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
async def do_async_setup(self):
|
||||||
|
# --- INITIALIZATION LOGIC (Called before start() in kuby.py) ---
|
||||||
|
kuby_logger.info("🚀 Configuration initiale du bot Kuby...")
|
||||||
|
|
||||||
# Charger les extensions
|
# Charger les extensions
|
||||||
extensions = [
|
extensions = [
|
||||||
"commandes.whitelist",
|
"commandes.whitelist",
|
||||||
|
|
@ -95,62 +95,43 @@ class MyBot(commands.Bot):
|
||||||
|
|
||||||
for extension in extensions:
|
for extension in extensions:
|
||||||
try:
|
try:
|
||||||
await self.load_extension(extension)
|
self.load_extension(extension)
|
||||||
kuby_logger.info(f"✅ Extension chargée : {extension}")
|
kuby_logger.info(f"✅ Extension chargée : {extension}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
kuby_logger.error(f"❌ Erreur lors du chargement de {extension} : {e}", exc_info=True)
|
kuby_logger.error(f"❌ Erreur lors du chargement de {extension} : {e}", exc_info=True)
|
||||||
|
|
||||||
# --- SYSTÈME DE WHITELIST (CORRIGÉ POUR ÉVITER LES ERREURS) ---
|
# --- SYSTÈME DE WHITELIST (DÉDIÉ SLASH COMMANDS) ---
|
||||||
@self.check
|
async def global_slash_whitelist_check(inter: disnake.ApplicationCommandInteraction):
|
||||||
async def whitelist_check(ctx):
|
|
||||||
try:
|
try:
|
||||||
# 1. Bypass pour le propriétaire (Owner)
|
if await self.is_owner(inter.author):
|
||||||
if await self.is_owner(ctx.author):
|
return True
|
||||||
|
command_name = inter.data.name
|
||||||
|
if command_name in ["ticketconfig", "ticketpanel", "ticket_config", "ticket_panel", "ticket_whitelist_config"]:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# 1b. Bypass pour les commandes de config tickets
|
|
||||||
# Si la commande est une commande ticket et l'utilisateur a les perms ticket
|
|
||||||
if ctx.command and (ctx.command.name in ["ticketconfig", "ticketsetup", "configticket"]):
|
|
||||||
try:
|
|
||||||
storage = get_storage()
|
|
||||||
config = storage.load_config(ctx.guild.id)
|
|
||||||
if can_access_config(ctx, config):
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
kuby_logger.error(f"Error checking ticket permissions in global whitelist: {e}")
|
|
||||||
# Fallthrough to normal whitelist check if error
|
|
||||||
|
|
||||||
|
|
||||||
# 2. Récupération du Cog
|
|
||||||
whitelist_cog = self.get_cog("WhitelistMonitor")
|
whitelist_cog = self.get_cog("WhitelistMonitor")
|
||||||
if not whitelist_cog:
|
if not whitelist_cog:
|
||||||
kuby_logger.warning("WhitelistMonitor cog not found, allowing all commands")
|
|
||||||
return True
|
return True
|
||||||
|
is_whitelisted = whitelist_cog.is_whitelisted(inter.guild.id, inter.author.id)
|
||||||
is_whitelisted = whitelist_cog.is_whitelisted(ctx.guild.id, ctx.author.id)
|
|
||||||
|
|
||||||
if not is_whitelisted:
|
if not is_whitelisted:
|
||||||
kuby_logger.info(f"User {ctx.author} (ID: {ctx.author.id}) attempted to use command but is not whitelisted")
|
kuby_logger.info(f"🚫 [Check] Accès refusé : {inter.author} sur /{command_name}")
|
||||||
|
|
||||||
# Réponse adaptée (Slash vs Message)
|
|
||||||
msg = "❌ Vous n'êtes pas autorisé à utiliser cette commande. Veuillez demander à être ajouté à la whitelist."
|
msg = "❌ Vous n'êtes pas autorisé à utiliser cette commande. Veuillez demander à être ajouté à la whitelist."
|
||||||
if ctx.interaction:
|
if not inter.response.is_done():
|
||||||
await ctx.send(msg, ephemeral=True)
|
await inter.response.send_message(msg, ephemeral=True)
|
||||||
else:
|
|
||||||
await ctx.send(msg)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
kuby_logger.error(f"Error in whitelist check: {e}")
|
kuby_logger.error(f"⚠️ [Check] Erreur critique: {e}", exc_info=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Sync slash commands
|
self.add_app_command_check(global_slash_whitelist_check)
|
||||||
try:
|
|
||||||
# Disnake handles syncing automatically by default
|
# --- LOGGING DES INTERACTIONS ---
|
||||||
kuby_logger.info("✅ Commandes slash prêtes avec Disnake")
|
@self.listen("on_interaction")
|
||||||
except Exception as e:
|
async def log_interaction(inter: disnake.Interaction):
|
||||||
kuby_logger.error(f"❌ Erreur lors de la synchronisation des commandes slash : {e}", exc_info=True)
|
if inter.type == disnake.InteractionType.application_command:
|
||||||
|
kuby_logger.info(f"⚡ Interaction reçue : /{inter.data.name} par {inter.user}")
|
||||||
|
|
||||||
|
kuby_logger.info("✅ Configuration terminée")
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
if hasattr(self, 'flask_process') and self.flask_process:
|
if hasattr(self, 'flask_process') and self.flask_process:
|
||||||
|
|
@ -163,22 +144,12 @@ class MyBot(commands.Bot):
|
||||||
await super().close()
|
await super().close()
|
||||||
|
|
||||||
# --- ÉVÉNEMENTS RESTAURÉS ---
|
# --- ÉVÉNEMENTS RESTAURÉS ---
|
||||||
|
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
kuby_logger.info(f"🤖 Bot connecté : {self.user} (ID : {self.user.id})")
|
kuby_logger.info(f"🤖 Bot connecté : {self.user} (ID : {self.user.id})")
|
||||||
kuby_logger.info(f"📊 Serveurs : {len(self.guilds)}")
|
kuby_logger.info(f"📊 Serveurs : {len(self.guilds)}")
|
||||||
|
|
||||||
# Log intents status
|
|
||||||
kuby_logger.info(f"🔍 Intents Status - Members: {self.intents.members}, Presences: {self.intents.presences}, Core: {self.intents.message_content}")
|
kuby_logger.info(f"🔍 Intents Status - Members: {self.intents.members}, Presences: {self.intents.presences}, Core: {self.intents.message_content}")
|
||||||
|
|
||||||
if not self.intents.members:
|
if not self.intents.members:
|
||||||
kuby_logger.warning("⚠️ L'intent MEMBERS est désactivé ! Les événements de join/leave et les DMs pourraient ne pas fonctionner correctement.")
|
kuby_logger.warning("⚠️ L'intent MEMBERS est désactivé !")
|
||||||
|
|
||||||
for guild in self.guilds:
|
|
||||||
kuby_logger.debug(f"Guild: {guild.name} (ID: {guild.id}) - Members: {guild.member_count}")
|
|
||||||
|
|
||||||
total_members = sum(guild.member_count for guild in self.guilds)
|
|
||||||
kuby_logger.info(f"📊 Total members across all guilds: {total_members}")
|
|
||||||
kuby_logger.info("✅ Bot prêt et opérationnel !")
|
kuby_logger.info("✅ Bot prêt et opérationnel !")
|
||||||
|
|
||||||
async def on_guild_join(self, guild):
|
async def on_guild_join(self, guild):
|
||||||
|
|
@ -209,7 +180,6 @@ class MyBot(commands.Bot):
|
||||||
kuby_logger.info(f"👋 {member} left {member.guild.name}")
|
kuby_logger.info(f"👋 {member} left {member.guild.name}")
|
||||||
if hasattr(self, 'advanced_logger'):
|
if hasattr(self, 'advanced_logger'):
|
||||||
self.advanced_logger.log_member_leave(member)
|
self.advanced_logger.log_member_leave(member)
|
||||||
# Notification de départ
|
|
||||||
try:
|
try:
|
||||||
from commandes.security import load_settings
|
from commandes.security import load_settings
|
||||||
settings = load_settings(member.guild.id)
|
settings = load_settings(member.guild.id)
|
||||||
|
|
@ -246,7 +216,7 @@ class MyBot(commands.Bot):
|
||||||
|
|
||||||
async def on_command_error(self, ctx, error):
|
async def on_command_error(self, ctx, error):
|
||||||
if isinstance(error, commands.CheckFailure):
|
if isinstance(error, commands.CheckFailure):
|
||||||
return # Déjà géré dans le whitelist_check
|
return
|
||||||
kuby_logger.error(f"Command error in {ctx.command}: {str(error)}", exc_info=True)
|
kuby_logger.error(f"Command error in {ctx.command}: {str(error)}", exc_info=True)
|
||||||
|
|
||||||
bot = MyBot()
|
bot = MyBot()
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import discord
|
import discord
|
||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
from discord.ext import commands
|
from disnake.ext import commands
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ class Blacklist(commands.Cog):
|
||||||
# ---------- Slash Commands ----------
|
# ---------- Slash Commands ----------
|
||||||
@app_commands.command(name="blacklist", description="Blacklist un utilisateur")
|
@app_commands.command(name="blacklist", description="Blacklist un utilisateur")
|
||||||
@app_commands.describe(user="Utilisateur à blacklister", reason="Raison")
|
@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):
|
if not self.is_agent(interaction.user.id):
|
||||||
return await interaction.response.send_message("⛔ Tu n’as pas la permission.", ephemeral=True)
|
return await interaction.response.send_message("⛔ Tu n’as 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.command(name="unblacklist", description="Retire un utilisateur de la blacklist")
|
||||||
@app_commands.describe(user="Utilisateur à retirer")
|
@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):
|
if not self.is_agent(interaction.user.id):
|
||||||
return await interaction.response.send_message("⛔ Tu n’as pas la permission.", ephemeral=True)
|
return await interaction.response.send_message("⛔ Tu n’as pas la permission.", ephemeral=True)
|
||||||
|
|
||||||
|
|
@ -81,13 +81,13 @@ class Blacklist(commands.Cog):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# --------- Boutons ----------
|
# --------- Boutons ----------
|
||||||
class TicketButton(discord.ui.View):
|
class TicketButton(disnake.ui.View):
|
||||||
def __init__(self, user_id: int):
|
def __init__(self, user_id: int):
|
||||||
super().__init__(timeout=None)
|
super().__init__(timeout=None)
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
|
||||||
@discord.ui.button(label="📩 Ouvrir une demande de déblacklist", style=discord.ButtonStyle.danger)
|
@disnake.ui.button(label="📩 Ouvrir une demande de déblacklist", style=disnake.ButtonStyle.danger)
|
||||||
async def open_ticket(self, interaction: discord.Interaction, button: discord.ui.Button):
|
async def open_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
|
||||||
if interaction.user.id != self.user_id:
|
if interaction.user.id != self.user_id:
|
||||||
return await interaction.response.send_message("❌ Ce bouton ne t’appartient pas.", ephemeral=True)
|
return await interaction.response.send_message("❌ Ce bouton ne t’appartient 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)
|
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):
|
def __init__(self, user_id: int):
|
||||||
super().__init__(timeout=None)
|
super().__init__(timeout=None)
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
|
||||||
@discord.ui.button(label="❌ Fermer le ticket", style=discord.ButtonStyle.danger)
|
@disnake.ui.button(label="❌ Fermer le ticket", style=disnake.ButtonStyle.danger)
|
||||||
async def close_ticket(self, interaction: discord.Interaction, button: discord.ui.Button):
|
async def close_ticket(self, button: disnake.ui.Button, interaction: disnake.Interaction):
|
||||||
agents = load_json(AGENTS_FILE, {"agents": []})
|
agents = load_json(AGENTS_FILE, {"agents": []})
|
||||||
if str(interaction.user.id) not in agents["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)
|
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)
|
view = ConfirmCloseView(self.user_id)
|
||||||
await interaction.response.send_message("⚠️ Veux-tu vraiment fermer ce ticket ?", view=view, ephemeral=True)
|
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):
|
def __init__(self, user_id: int):
|
||||||
super().__init__(timeout=30)
|
super().__init__(timeout=30)
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
|
||||||
@discord.ui.button(label="✅ Oui", style=discord.ButtonStyle.success)
|
@disnake.ui.button(label="✅ Oui", style=disnake.ButtonStyle.success)
|
||||||
async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):
|
async def confirm(self, button: disnake.ui.Button, interaction: disnake.Interaction):
|
||||||
agents = load_json(AGENTS_FILE, {"agents": []})
|
agents = load_json(AGENTS_FILE, {"agents": []})
|
||||||
if str(interaction.user.id) not in agents["agents"]:
|
if str(interaction.user.id) not in agents["agents"]:
|
||||||
return await interaction.response.send_message("⛔ Tu n’as pas la permission.", ephemeral=True)
|
return await interaction.response.send_message("⛔ Tu n’as pas la permission.", ephemeral=True)
|
||||||
|
|
@ -142,12 +142,12 @@ class ConfirmCloseView(discord.ui.View):
|
||||||
await interaction.channel.send("✅ Ticket fermé.")
|
await interaction.channel.send("✅ Ticket fermé.")
|
||||||
await interaction.channel.delete()
|
await interaction.channel.delete()
|
||||||
|
|
||||||
@discord.ui.button(label="❌ Non", style=discord.ButtonStyle.secondary)
|
@disnake.ui.button(label="❌ Non", style=disnake.ButtonStyle.secondary)
|
||||||
async def cancel(self, interaction: discord.Interaction, button: discord.ui.Button):
|
async def cancel(self, button: disnake.ui.Button, interaction: disnake.Interaction):
|
||||||
await interaction.response.send_message("❌ Fermeture annulée.", ephemeral=True)
|
await interaction.response.send_message("❌ Fermeture annulée.", ephemeral=True)
|
||||||
|
|
||||||
# --------- Setup Cog ----------
|
# --------- Setup Cog ----------
|
||||||
async def setup(bot: commands.Bot):
|
def setup(bot: commands.Bot):
|
||||||
cog = Blacklist(bot)
|
cog = Blacklist(bot)
|
||||||
await bot.add_cog(cog)
|
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))
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,12 @@ def parse_date(date_str: str):
|
||||||
|
|
||||||
class AbsenceModal(disnake.ui.Modal):
|
class AbsenceModal(disnake.ui.Modal):
|
||||||
def __init__(self, superieur: Optional[disnake.Member] = None):
|
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
|
self.superieur = superieur
|
||||||
|
|
||||||
motif = disnake.ui.TextInput(
|
motif = disnake.ui.TextInput(
|
||||||
label="Motif de l'absence",
|
label="Motif de l'absence",
|
||||||
style=disnake.TextStyle.paragraph,
|
style=disnake.TextInputStyle.paragraph,
|
||||||
placeholder="Ex: Vacances, Raisons personnelles, Travail...",
|
placeholder="Ex: Vacances, Raisons personnelles, Travail...",
|
||||||
required=True,
|
required=True,
|
||||||
max_length=500
|
max_length=500
|
||||||
|
|
@ -187,7 +187,7 @@ class AbsenceConfigView(disnake.ui.View):
|
||||||
self.guild_id = guild_id
|
self.guild_id = guild_id
|
||||||
|
|
||||||
@disnake.ui.button(label="Définir le Salon", style=disnake.ButtonStyle.primary, emoji="📁")
|
@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)
|
await interaction.response.send_message("Mentionne le salon ici (ou envoie son ID) :", ephemeral=True)
|
||||||
|
|
||||||
def check(m):
|
def check(m):
|
||||||
|
|
@ -214,7 +214,7 @@ class AbsenceConfigView(disnake.ui.View):
|
||||||
await interaction.followup.send("❌ Temps écoulé.", ephemeral=True)
|
await interaction.followup.send("❌ Temps écoulé.", ephemeral=True)
|
||||||
|
|
||||||
@disnake.ui.button(label="Définir le Rôle", style=disnake.ButtonStyle.primary, emoji="🎭")
|
@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)
|
await interaction.response.send_message("Mentionne le rôle ici (ou envoie son ID) :", ephemeral=True)
|
||||||
|
|
||||||
def check(m):
|
def check(m):
|
||||||
|
|
@ -499,7 +499,7 @@ class Absence(commands.Cog):
|
||||||
settings = load_settings(message.guild.id)
|
settings = load_settings(message.guild.id)
|
||||||
channel_id = settings.get("absence_channel_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."
|
reply_text = f"⚠️ {message.author.mention}, cet utilisateur est actuellement absent."
|
||||||
if absence_url:
|
if absence_url:
|
||||||
|
|
@ -507,5 +507,5 @@ class Absence(commands.Cog):
|
||||||
|
|
||||||
await message.reply(reply_text, delete_after=30)
|
await message.reply(reply_text, delete_after=30)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Absence(bot))
|
bot.add_cog(Absence(bot))
|
||||||
|
|
|
||||||
|
|
@ -268,5 +268,5 @@ class Backup(commands.Cog):
|
||||||
await interaction.followup.send(embed=embed,ephemeral=True)
|
await interaction.followup.send(embed=embed,ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot: commands.Bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Backup(bot))
|
bot.add_cog(Backup(bot))
|
||||||
|
|
|
||||||
|
|
@ -198,5 +198,5 @@ class BackupRestore(commands.Cog):
|
||||||
async def element_autocomplete_decorator(self, interaction: disnake.ApplicationCommandInteraction, current: str):
|
async def element_autocomplete_decorator(self, interaction: disnake.ApplicationCommandInteraction, current: str):
|
||||||
return await self.element_autocomplete(interaction, current)
|
return await self.element_autocomplete(interaction, current)
|
||||||
|
|
||||||
async def setup(bot: commands.Bot):
|
def setup(bot):
|
||||||
await bot.add_cog(BackupRestore(bot))
|
bot.add_cog(BackupRestore(bot))
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ class TicketButton(disnake.ui.View):
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
|
||||||
@disnake.ui.button(label="📩 Ouvrir une demande de révision", style=disnake.ButtonStyle.primary, custom_id="blacklist_open_ticket")
|
@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:
|
if interaction.user.id != self.user_id:
|
||||||
return await interaction.response.send_message("❌ Ce bouton ne t’appartient pas.", ephemeral=True)
|
return await interaction.response.send_message("❌ Ce bouton ne t’appartient pas.", ephemeral=True)
|
||||||
|
|
||||||
|
|
@ -239,7 +239,7 @@ class CloseTicketView(disnake.ui.View):
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
|
||||||
@disnake.ui.button(label="❌ Fermer le ticket", style=disnake.ButtonStyle.danger, custom_id="blacklist_close_ticket")
|
@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):
|
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)
|
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
|
self.user_id = user_id
|
||||||
|
|
||||||
@disnake.ui.button(label="✅ Oui", style=disnake.ButtonStyle.success, custom_id="blacklist_confirm_close")
|
@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):
|
if not interaction.bot.get_cog("Blacklist").is_agent(interaction.user.id):
|
||||||
return await interaction.response.send_message("⛔ Tu n’as pas la permission.", ephemeral=True)
|
return await interaction.response.send_message("⛔ Tu n’as 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)
|
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")
|
@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)
|
await interaction.response.send_message("❌ Fermeture annulée.", ephemeral=True)
|
||||||
|
|
||||||
# --------- Setup ---------
|
# --------- Setup ---------
|
||||||
async def setup(bot: commands.Bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Blacklist(bot))
|
bot.add_cog(Blacklist(bot))
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ def save_report(issue_iid, user_id):
|
||||||
|
|
||||||
class BugReportModal(disnake.ui.Modal):
|
class BugReportModal(disnake.ui.Modal):
|
||||||
def __init__(self, priority_choice):
|
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
|
self.priority_choice = priority_choice
|
||||||
|
|
||||||
bug_title = disnake.ui.TextInput(
|
bug_title = disnake.ui.TextInput(
|
||||||
|
|
@ -46,7 +46,7 @@ class BugReportModal(disnake.ui.Modal):
|
||||||
|
|
||||||
description = disnake.ui.TextInput(
|
description = disnake.ui.TextInput(
|
||||||
label="Description détaillée",
|
label="Description détaillée",
|
||||||
style=disnake.TextStyle.paragraph,
|
style=disnake.TextInputStyle.paragraph,
|
||||||
placeholder="Que s'est-il passé ? Comment reproduire le bug ?",
|
placeholder="Que s'est-il passé ? Comment reproduire le bug ?",
|
||||||
required=True,
|
required=True,
|
||||||
max_length=1000
|
max_length=1000
|
||||||
|
|
@ -77,7 +77,7 @@ class BugReportModal(disnake.ui.Modal):
|
||||||
|
|
||||||
class FeatureSuggestionModal(disnake.ui.Modal):
|
class FeatureSuggestionModal(disnake.ui.Modal):
|
||||||
def __init__(self):
|
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(
|
suggestion_title = disnake.ui.TextInput(
|
||||||
label="Titre de la suggestion",
|
label="Titre de la suggestion",
|
||||||
|
|
@ -88,7 +88,7 @@ class FeatureSuggestionModal(disnake.ui.Modal):
|
||||||
|
|
||||||
description = disnake.ui.TextInput(
|
description = disnake.ui.TextInput(
|
||||||
label="Détails de la fonctionnalité",
|
label="Détails de la fonctionnalité",
|
||||||
style=disnake.TextStyle.paragraph,
|
style=disnake.TextInputStyle.paragraph,
|
||||||
placeholder="Décrivez comment cela devrait fonctionner...",
|
placeholder="Décrivez comment cela devrait fonctionner...",
|
||||||
required=True,
|
required=True,
|
||||||
max_length=1000
|
max_length=1000
|
||||||
|
|
@ -334,5 +334,5 @@ class BugReport(commands.Cog):
|
||||||
async def suggerer_fonctionnalite(self, interaction: disnake.ApplicationCommandInteraction):
|
async def suggerer_fonctionnalite(self, interaction: disnake.ApplicationCommandInteraction):
|
||||||
await interaction.response.send_modal(FeatureSuggestionModal())
|
await interaction.response.send_modal(FeatureSuggestionModal())
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(BugReport(bot))
|
bot.add_cog(BugReport(bot))
|
||||||
|
|
|
||||||
|
|
@ -274,5 +274,5 @@ class Convocation(commands.Cog):
|
||||||
|
|
||||||
await interaction.response.send_message(embed=embed, ephemeral=True)
|
await interaction.response.send_message(embed=embed, ephemeral=True)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Convocation(bot))
|
bot.add_cog(Convocation(bot))
|
||||||
|
|
|
||||||
|
|
@ -218,5 +218,5 @@ class Goodbye(commands.Cog):
|
||||||
|
|
||||||
await interaction.response.send_message(msg, ephemeral=True)
|
await interaction.response.send_message(msg, ephemeral=True)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Goodbye(bot))
|
bot.add_cog(Goodbye(bot))
|
||||||
|
|
@ -7,7 +7,7 @@ import re
|
||||||
|
|
||||||
class ModReasonModal(disnake.ui.Modal):
|
class ModReasonModal(disnake.ui.Modal):
|
||||||
def __init__(self, parent_view, action_type):
|
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.parent_view = parent_view
|
||||||
self.action_type = action_type
|
self.action_type = action_type
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ class ModReasonModal(disnake.ui.Modal):
|
||||||
required=True,
|
required=True,
|
||||||
max_length=500
|
max_length=500
|
||||||
)
|
)
|
||||||
self.add_item(self.reason)
|
self.append_component(self.reason)
|
||||||
|
|
||||||
if action_type == "TIMEOUT":
|
if action_type == "TIMEOUT":
|
||||||
self.duration = disnake.ui.TextInput(
|
self.duration = disnake.ui.TextInput(
|
||||||
|
|
@ -26,7 +26,7 @@ class ModReasonModal(disnake.ui.Modal):
|
||||||
required=True,
|
required=True,
|
||||||
max_length=10
|
max_length=10
|
||||||
)
|
)
|
||||||
self.add_item(self.duration)
|
self.append_component(self.duration)
|
||||||
|
|
||||||
async def callback(self, interaction: disnake.Interaction):
|
async def callback(self, interaction: disnake.Interaction):
|
||||||
reason = self.reason.value
|
reason = self.reason.value
|
||||||
|
|
@ -78,43 +78,43 @@ class ModPanelView(disnake.ui.View):
|
||||||
await interaction.edit_original_response(embed=embed, view=self)
|
await interaction.edit_original_response(embed=embed, view=self)
|
||||||
|
|
||||||
@disnake.ui.button(label="Avertir", style=disnake.ButtonStyle.secondary, emoji="⚠️")
|
@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"))
|
await interaction.response.send_modal(ModReasonModal(self, "WARN"))
|
||||||
|
|
||||||
@disnake.ui.button(label="Timeout", style=disnake.ButtonStyle.secondary, emoji="⏳")
|
@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"))
|
await interaction.response.send_modal(ModReasonModal(self, "TIMEOUT"))
|
||||||
|
|
||||||
@disnake.ui.button(label="Expulser", style=disnake.ButtonStyle.secondary, emoji="👢")
|
@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"))
|
await interaction.response.send_modal(ModReasonModal(self, "KICK"))
|
||||||
|
|
||||||
@disnake.ui.button(label="Bannir", style=disnake.ButtonStyle.danger, emoji="🔨")
|
@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"))
|
await interaction.response.send_modal(ModReasonModal(self, "BAN"))
|
||||||
|
|
||||||
@disnake.ui.button(label="Historique", style=disnake.ButtonStyle.primary, emoji="📜")
|
@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")
|
cog = interaction.bot.get_cog("Moderation")
|
||||||
await cog.history(interaction, self.member)
|
await cog.history(interaction, self.member)
|
||||||
|
|
||||||
@disnake.ui.button(label="Clear Warns", style=disnake.ButtonStyle.danger, emoji="🧹")
|
@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")
|
cog = interaction.bot.get_cog("Moderation")
|
||||||
await cog.clearwarns(interaction, self.member, reason="Nettoyage via Panel")
|
await cog.clearwarns(interaction, self.member, reason="Nettoyage via Panel")
|
||||||
await self.update_panel(interaction)
|
await self.update_panel(interaction)
|
||||||
|
|
||||||
class ModConfigModal(disnake.ui.Modal):
|
class ModConfigModal(disnake.ui.Modal):
|
||||||
def __init__(self, field_name, current_value):
|
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.field_name = field_name
|
||||||
self.input = disnake.ui.TextInput(
|
self.input = disnake.ui.TextInput(
|
||||||
label=field_name,
|
label=field_name,
|
||||||
default=str(current_value),
|
value=str(current_value),
|
||||||
placeholder="Entrez une valeur numérique...",
|
placeholder="Entrez une valeur numérique...",
|
||||||
required=True
|
required=True
|
||||||
)
|
)
|
||||||
self.add_item(self.input)
|
self.append_component(self.input)
|
||||||
|
|
||||||
async def callback(self, interaction: disnake.Interaction):
|
async def callback(self, interaction: disnake.Interaction):
|
||||||
value = self.input.value
|
value = self.input.value
|
||||||
|
|
@ -146,7 +146,7 @@ class ModConfigView(disnake.ui.View):
|
||||||
self.db_path = db_path
|
self.db_path = db_path
|
||||||
|
|
||||||
@disnake.ui.button(label="Log Channel", style=disnake.ButtonStyle.primary, emoji="📁")
|
@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()
|
view = disnake.ui.View()
|
||||||
select = disnake.ui.ChannelSelect(
|
select = disnake.ui.ChannelSelect(
|
||||||
placeholder="Sélectionnez le salon de logs...",
|
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)
|
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="⚖️")
|
@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)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute("SELECT warn_limit_timeout, warn_limit_kick, warn_limit_ban FROM mod_config WHERE guild_id = ?", (self.guild_id,))
|
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)
|
await interaction.response.send_message("Quelle limite modifier ?", view=view, ephemeral=True)
|
||||||
|
|
||||||
@disnake.ui.button(label="Durée Timeout", style=disnake.ButtonStyle.secondary, emoji="⏱️")
|
@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)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute("SELECT timeout_duration FROM mod_config WHERE guild_id = ?", (self.guild_id,))
|
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)
|
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)
|
else: await interaction.followup.send(f"✅ Warns de {member.name} effacés.", ephemeral=True)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Moderation(bot))
|
bot.add_cog(Moderation(bot))
|
||||||
|
|
|
||||||
|
|
@ -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)
|
embed = disnake.Embed(title="🚨 ALERTE RAID", description=f"Vague de {len(self.join_cache[guild.id])} membres !", color=0xFF0000)
|
||||||
await channel.send(embed=embed)
|
await channel.send(embed=embed)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(AntiRaid(bot))
|
bot.add_cog(AntiRaid(bot))
|
||||||
|
|
@ -13,7 +13,7 @@ WHITELIST_FILE = "data/whitelist.json"
|
||||||
CACHE_TTL = 5
|
CACHE_TTL = 5
|
||||||
|
|
||||||
# Triggers pour détection de liens
|
# Triggers pour détection de liens
|
||||||
LINK_TRIGGERS = ("discord.gg/", "http://", "https://", "www.")
|
LINK_TRIGGERS = ("disnake.gg/", "http://", "https://", "www.")
|
||||||
|
|
||||||
class AntiSpam(commands.Cog):
|
class AntiSpam(commands.Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
|
@ -181,5 +181,5 @@ class AntiSpam(commands.Cog):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Erreur lors de la sanction : {e}")
|
print(f"Erreur lors de la sanction : {e}")
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(AntiSpam(bot))
|
bot.add_cog(AntiSpam(bot))
|
||||||
|
|
@ -58,5 +58,5 @@ class LogsManager(commands.Cog):
|
||||||
)
|
)
|
||||||
await log_chan.send(embed=embed)
|
await log_chan.send(embed=embed)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(LogsManager(bot))
|
bot.add_cog(LogsManager(bot))
|
||||||
|
|
@ -38,7 +38,7 @@ def save_settings(guild_id: int, settings: dict) -> None:
|
||||||
|
|
||||||
# --- MODALS DE CONFIGURATION DU RÈGLEMENT (BACK-END) ---
|
# --- 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"""
|
"""Modal pour configurer le titre du règlement"""
|
||||||
title_input = disnake.ui.TextInput(
|
title_input = disnake.ui.TextInput(
|
||||||
label="Titre du règlement",
|
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):
|
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.guild_id = guild_id
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.on_update_callback = on_update_callback
|
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
|
self.settings["rules_title"] = self.title_input.value
|
||||||
save_settings(self.guild_id, self.settings)
|
save_settings(self.guild_id, self.settings)
|
||||||
|
|
||||||
|
|
@ -77,24 +77,24 @@ class RulesTitleModal(disnake.ui.Modal, title="📜 Titre du Règlement"):
|
||||||
return view
|
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"""
|
"""Modal pour configurer le contenu du règlement"""
|
||||||
content_input = disnake.ui.TextInput(
|
content_input = disnake.ui.TextInput(
|
||||||
label="Contenu du règlement",
|
label="Contenu du règlement",
|
||||||
placeholder="Entrez les règles de votre serveur...",
|
placeholder="Entrez les règles de votre serveur...",
|
||||||
style=disnake.TextStyle.paragraph,
|
style=disnake.TextInputStyle.paragraph,
|
||||||
min_length=10,
|
min_length=10,
|
||||||
max_length=4000,
|
max_length=4000,
|
||||||
required=True
|
required=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, guild_id: int, settings: dict, on_update_callback=None):
|
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.guild_id = guild_id
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.on_update_callback = on_update_callback
|
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
|
self.settings["rules_content"] = self.content_input.value
|
||||||
save_settings(self.guild_id, self.settings)
|
save_settings(self.guild_id, self.settings)
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ class RulesContentModal(disnake.ui.Modal, title="📝 Contenu du Règlement"):
|
||||||
return view
|
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"""
|
"""Modal pour sélectionner le salon du règlement"""
|
||||||
channel_input = disnake.ui.TextInput(
|
channel_input = disnake.ui.TextInput(
|
||||||
label="ID du salon",
|
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):
|
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.guild_id = guild_id
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.on_update_callback = on_update_callback
|
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():
|
if not self.channel_input.value.isdigit():
|
||||||
return await interaction.response.send_message(
|
return await interaction.response.send_message(
|
||||||
"❌ Erreur : ID invalide.",
|
"❌ Erreur : ID invalide.",
|
||||||
|
|
@ -171,7 +171,7 @@ class RulesChannelModal(disnake.ui.Modal, title="📌 Salon du Règlement"):
|
||||||
return view
|
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"""
|
"""Modal pour configurer le rôle attribué à l'acceptation"""
|
||||||
role_input = disnake.ui.TextInput(
|
role_input = disnake.ui.TextInput(
|
||||||
label="ID du rôle",
|
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):
|
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.guild_id = guild_id
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.on_update_callback = on_update_callback
|
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():
|
if not self.role_input.value.isdigit():
|
||||||
return await interaction.response.send_message(
|
return await interaction.response.send_message(
|
||||||
"❌ Erreur : ID invalide.",
|
"❌ Erreur : ID invalide.",
|
||||||
|
|
@ -225,7 +225,7 @@ class RulesRoleModal(disnake.ui.Modal, title="✅ Rôle d'Acceptation"):
|
||||||
return view
|
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"""
|
"""Modal pour choisir le type de message du règlement"""
|
||||||
message_type = disnake.ui.TextInput(
|
message_type = disnake.ui.TextInput(
|
||||||
label="Type de message",
|
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):
|
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.guild_id = guild_id
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.on_update_callback = on_update_callback
|
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()
|
msg_type = self.message_type.value.lower().strip()
|
||||||
|
|
||||||
if msg_type not in ["embed", "simple"]:
|
if msg_type not in ["embed", "simple"]:
|
||||||
|
|
@ -323,13 +323,13 @@ class RulesAcceptButton(disnake.ui.View):
|
||||||
self.guild_id = guild_id
|
self.guild_id = guild_id
|
||||||
self.accept_role_id = accept_role_id
|
self.accept_role_id = accept_role_id
|
||||||
|
|
||||||
@discord.ui.button(
|
@disnake.ui.button(
|
||||||
label="J'accepte le règlement",
|
label="J'accepte le règlement",
|
||||||
emoji="✅",
|
emoji="✅",
|
||||||
style=disnake.ButtonStyle.green,
|
style=disnake.ButtonStyle.green,
|
||||||
custom_id="rules_accept_button"
|
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"""
|
"""Gère le clic sur le bouton d'acceptation"""
|
||||||
guild = interaction.guild
|
guild = interaction.guild
|
||||||
|
|
||||||
|
|
@ -495,8 +495,8 @@ class RulesCog(commands.Cog):
|
||||||
return title, content
|
return title, content
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
"""Setup du cog de règlement"""
|
"""Setup du cog de règlement"""
|
||||||
cog = RulesCog(bot)
|
cog = RulesCog(bot)
|
||||||
await bot.add_cog(cog)
|
bot.add_cog(cog)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,5 +47,5 @@ class NoLink(commands.Cog):
|
||||||
print(f"Erreur lors de la suppression du message : {exc}")
|
print(f"Erreur lors de la suppression du message : {exc}")
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot: commands.Bot) -> None:
|
def setup(bot: commands.Bot) -> None:
|
||||||
await bot.add_cog(NoLink(bot))
|
bot.add_cog(NoLink(bot))
|
||||||
|
|
|
||||||
|
|
@ -77,5 +77,5 @@ class Scan(commands.Cog):
|
||||||
await interaction.followup.send(f"✅ Fichier sain.\nHash : `{result['hash']}`")
|
await interaction.followup.send(f"✅ Fichier sain.\nHash : `{result['hash']}`")
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot: commands.Bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Scan(bot))
|
bot.add_cog(Scan(bot))
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ def is_immune(guild, user) -> bool:
|
||||||
|
|
||||||
# --- MODALS DE CONFIGURATION ---
|
# --- MODALS DE CONFIGURATION ---
|
||||||
|
|
||||||
class SpamThresholdModal(disnake.ui.Modal, title="🛡️ Seuil Anti-Spam"):
|
class SpamThresholdModal(disnake.ui.Modal):
|
||||||
"""Modal pour configurer le seuil anti-spam"""
|
"""Modal pour configurer le seuil anti-spam"""
|
||||||
threshold_input = disnake.ui.TextInput(
|
threshold_input = disnake.ui.TextInput(
|
||||||
label="Messages max autorisés",
|
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'):
|
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.guild_id = guild_id
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.parent_view = view
|
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():
|
if not self.threshold_input.value.isdigit():
|
||||||
return await interaction.response.send_message(
|
return await interaction.response.send_message(
|
||||||
"❌ Erreur : Veuillez entrer un nombre entier.",
|
"❌ Erreur : Veuillez entrer un nombre entier.",
|
||||||
|
|
@ -110,7 +110,7 @@ class SpamThresholdModal(disnake.ui.Modal, title="🛡️ Seuil Anti-Spam"):
|
||||||
ephemeral=True
|
ephemeral=True
|
||||||
)
|
)
|
||||||
|
|
||||||
class RaidThresholdModal(disnake.ui.Modal, title="⚔️ Seuil Anti-Raid"):
|
class RaidThresholdModal(disnake.ui.Modal):
|
||||||
"""Modal pour configurer le seuil anti-raid"""
|
"""Modal pour configurer le seuil anti-raid"""
|
||||||
threshold_input = disnake.ui.TextInput(
|
threshold_input = disnake.ui.TextInput(
|
||||||
label="Joins max en 10 secondes",
|
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'):
|
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.guild_id = guild_id
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.parent_view = view
|
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():
|
if not self.threshold_input.value.isdigit():
|
||||||
return await interaction.response.send_message(
|
return await interaction.response.send_message(
|
||||||
"❌ Erreur : Veuillez entrer un nombre entier.",
|
"❌ Erreur : Veuillez entrer un nombre entier.",
|
||||||
|
|
@ -153,7 +153,7 @@ class RaidThresholdModal(disnake.ui.Modal, title="⚔️ Seuil Anti-Raid"):
|
||||||
|
|
||||||
# --- MODALS DE CONFIGURATION WHITELIST ---
|
# --- 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"""
|
"""Modal pour ajouter un utilisateur à la whitelist"""
|
||||||
user_input = disnake.ui.TextInput(
|
user_input = disnake.ui.TextInput(
|
||||||
label="ID de l'utilisateur",
|
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'):
|
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.guild_id = guild_id
|
||||||
self.parent_view = view
|
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():
|
if not self.user_input.value.isdigit():
|
||||||
return await interaction.response.send_message(
|
return await interaction.response.send_message(
|
||||||
"❌ Erreur : ID invalide.",
|
"❌ Erreur : ID invalide.",
|
||||||
|
|
@ -873,7 +873,7 @@ class MainCategorySelect(disnake.ui.Select):
|
||||||
class WhitelistSelect(disnake.ui.Select):
|
class WhitelistSelect(disnake.ui.Select):
|
||||||
"""Menu dropdown pour voir et gérer les utilisateurs whitelistés"""
|
"""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.guild = guild
|
||||||
self.parent_view = view
|
self.parent_view = view
|
||||||
whitelist = load_whitelist(guild.id)
|
whitelist = load_whitelist(guild.id)
|
||||||
|
|
@ -950,11 +950,11 @@ class Security(commands.Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
@app_commands.command(
|
@commands.slash_command(
|
||||||
name="security",
|
name="security",
|
||||||
description="🛡️ Ouvrir le panneau de sécurité Kuby"
|
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é.
|
Commande principale pour ouvrir l'interface de sécurité.
|
||||||
Accessible uniquement aux administrateurs et propriétaires whitelistés.
|
Accessible uniquement aux administrateurs et propriétaires whitelistés.
|
||||||
|
|
@ -989,12 +989,12 @@ class Security(commands.Cog):
|
||||||
)
|
)
|
||||||
|
|
||||||
@security.error
|
@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"""
|
"""Gestion des erreurs de la commande security"""
|
||||||
# Utilisation de followup si l'interaction est déjà différée ou répondue
|
# 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
|
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(
|
await send_method(
|
||||||
"❌ Permissions insuffisantes.",
|
"❌ Permissions insuffisantes.",
|
||||||
ephemeral=True
|
ephemeral=True
|
||||||
|
|
@ -1006,7 +1006,7 @@ class Security(commands.Cog):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
"""Setup du cog de sécurité"""
|
"""Setup du cog de sécurité"""
|
||||||
await bot.add_cog(Security(bot))
|
bot.add_cog(Security(bot))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,6 @@ class SentBotMessages(commands.Cog):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await interaction.response.send_message(f"❌ Une erreur est survenue : {e}", ephemeral=True)
|
await interaction.response.send_message(f"❌ Une erreur est survenue : {e}", ephemeral=True)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(SentBotMessages(bot))
|
bot.add_cog(SentBotMessages(bot))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,5 +109,5 @@ class SnipeCommands(commands.Cog):
|
||||||
ephemeral=True
|
ephemeral=True
|
||||||
)
|
)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(SnipeCommands(bot))
|
bot.add_cog(SnipeCommands(bot))
|
||||||
|
|
|
||||||
|
|
@ -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)
|
await interaction.followup.send("Une erreur est survenue lors de la génération du classement.", ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(StaffLeaderboard(bot))
|
bot.add_cog(StaffLeaderboard(bot))
|
||||||
|
|
@ -133,5 +133,5 @@ class StaffRatings(commands.Cog):
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(StaffRatings(bot))
|
bot.add_cog(StaffRatings(bot))
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -490,6 +490,6 @@ class TicketAnalytics(commands.Cog):
|
||||||
await interaction.followup.send(embed=feedback_embed, ephemeral=True)
|
await interaction.followup.send(embed=feedback_embed, ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
"""Setup function for the analytics cog"""
|
"""Setup function for the analytics cog"""
|
||||||
await bot.add_cog(TicketAnalytics(bot))
|
bot.add_cog(TicketAnalytics(bot))
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ class FeedbackView(disnake.ui.View):
|
||||||
self.add_item(RatingSelect())
|
self.add_item(RatingSelect())
|
||||||
|
|
||||||
@disnake.ui.button(label="📝 Laisser un commentaire", style=disnake.ButtonStyle.secondary, custom_id="feedback_comment", row=1)
|
@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))
|
await interaction.response.send_modal(FeedbackModal(self))
|
||||||
|
|
||||||
@disnake.ui.button(label="✅ Envoyer", style=disnake.ButtonStyle.green, custom_id="feedback_submit", row=1)
|
@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:
|
if self.rating == 0:
|
||||||
await interaction.response.send_message("❌ Veuillez sélectionner une note avant d'envoyer.", ephemeral=True)
|
await interaction.response.send_message("❌ Veuillez sélectionner une note avant d'envoyer.", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
@ -128,17 +128,17 @@ class RatingSelect(disnake.ui.Select):
|
||||||
|
|
||||||
class FeedbackModal(disnake.ui.Modal):
|
class FeedbackModal(disnake.ui.Modal):
|
||||||
def __init__(self, view):
|
def __init__(self, view):
|
||||||
super().__init__(title="Votre avis")
|
super().__init__(components=[], title="Votre avis")
|
||||||
self.view = view
|
self.view = view
|
||||||
self.comment = disnake.ui.TextInput(
|
self.comment = disnake.ui.TextInput(
|
||||||
label="Commentaire",
|
label="Commentaire",
|
||||||
style=disnake.TextStyle.paragraph,
|
style=disnake.TextInputStyle.paragraph,
|
||||||
placeholder="Dites-nous ce que vous avez pensé du support...",
|
placeholder="Dites-nous ce que vous avez pensé du support...",
|
||||||
required=True,
|
required=True,
|
||||||
max_length=1000
|
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
|
self.view.comment = self.comment.value
|
||||||
await interaction.response.send_message("Commentaire enregistré ! N'oubliez pas de valider avec 'Envoyer'.", ephemeral=True)
|
await interaction.response.send_message("Commentaire enregistré ! N'oubliez pas de valider avec 'Envoyer'.", ephemeral=True)
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ class ContinueFormView(disnake.ui.View):
|
||||||
self.step2_part2_data = step2_part2_data
|
self.step2_part2_data = step2_part2_data
|
||||||
|
|
||||||
@disnake.ui.button(label="📋 Continuer le formulaire", style=disnake.ButtonStyle.green, custom_id="continue_form")
|
@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"""
|
"""Passe à l'étape suivante du formulaire"""
|
||||||
if self.current_step == 1:
|
if self.current_step == 1:
|
||||||
await interaction.response.send_modal(TicketStep2Part1(self.step1_data))
|
await interaction.response.send_modal(TicketStep2Part1(self.step1_data))
|
||||||
|
|
@ -414,7 +414,7 @@ class TicketManagementView(disnake.ui.View):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@disnake.ui.button(label="🔒 Fermer le Ticket", style=disnake.ButtonStyle.red, custom_id="close_ticket")
|
@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"""
|
"""Ferme le ticket en désactivant l'envoi de messages pour le membre"""
|
||||||
await interaction.response.defer(ephemeral=True)
|
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)
|
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")
|
@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"""
|
"""Un staff prend en charge le ticket"""
|
||||||
await interaction.response.defer(ephemeral=False)
|
await interaction.response.defer(ephemeral=False)
|
||||||
|
|
||||||
|
|
@ -490,7 +490,7 @@ class ClosedTicketView(disnake.ui.View):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@disnake.ui.button(label="♻ Réouvrir le Ticket", style=disnake.ButtonStyle.green, custom_id="reopen_ticket")
|
@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"""
|
"""Réouvre le ticket pour le membre"""
|
||||||
await interaction.response.defer(ephemeral=True)
|
await interaction.response.defer(ephemeral=True)
|
||||||
|
|
||||||
|
|
@ -526,15 +526,15 @@ class ReopenStatusView(disnake.ui.View):
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
|
|
||||||
@disnake.ui.button(label="Écrit (Ouvert)", style=disnake.ButtonStyle.secondary)
|
@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")
|
await self.apply_status(interaction, "ouvert")
|
||||||
|
|
||||||
@disnake.ui.button(label="Oral (À faire)", style=disnake.ButtonStyle.primary)
|
@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")
|
await self.apply_status(interaction, "oral-à-faire")
|
||||||
|
|
||||||
@disnake.ui.button(label="Accepté", style=disnake.ButtonStyle.success)
|
@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é")
|
await self.apply_status(interaction, "accepté")
|
||||||
|
|
||||||
async def apply_status(self, interaction: disnake.Interaction, prefix: str):
|
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)
|
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")
|
@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"""
|
"""Supprime le salon du ticket"""
|
||||||
await interaction.response.defer(ephemeral=True)
|
await interaction.response.defer(ephemeral=True)
|
||||||
|
|
||||||
|
|
@ -611,7 +611,7 @@ class TicketView(disnake.ui.View):
|
||||||
super().__init__(timeout=None)
|
super().__init__(timeout=None)
|
||||||
|
|
||||||
@disnake.ui.button(label="📑 Ouvrir un Ticket Whitelist", style=disnake.ButtonStyle.red, custom_id="open_ticket")
|
@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"""
|
"""Affiche le premier formulaire"""
|
||||||
await interaction.response.send_modal(TicketStep1())
|
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)
|
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}")
|
await message.channel.send(f"❌ Une erreur système est survenue : {e}")
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Ticket(bot))
|
bot.add_cog(Ticket(bot))
|
||||||
bot.add_view(TicketView())
|
bot.add_view(TicketView())
|
||||||
bot.add_view(TicketManagementView())
|
bot.add_view(TicketManagementView())
|
||||||
bot.add_view(ClosedTicketView())
|
bot.add_view(ClosedTicketView())
|
||||||
|
|
@ -455,6 +455,6 @@ class WebsiteSync(commands.Cog, name="Website Sync"):
|
||||||
|
|
||||||
|
|
||||||
# ─── Setup ───────────────────────────────────────────────────────────────────
|
# ─── Setup ───────────────────────────────────────────────────────────────────
|
||||||
async def setup(bot: commands.Bot):
|
def setup(bot):
|
||||||
await bot.add_cog(WebsiteSync(bot))
|
bot.add_cog(WebsiteSync(bot))
|
||||||
logger.info("Cog WebsiteSync chargé.")
|
logger.info("Cog WebsiteSync chargé.")
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,6 @@ class Welcome(commands.Cog):
|
||||||
bg_used = "background_template.png" if not banner_path else (banner_path.split('/')[-1])
|
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)
|
await interaction.response.send_message(f"✅ Configuration de bienvenida enregistrée !\nFond utilisé: {bg_used}", ephemeral=True)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Welcome(bot))
|
bot.add_cog(Welcome(bot))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,5 +95,5 @@ class Whitelist(commands.Cog):
|
||||||
return self._get_guild_whitelist(guild_id).copy()
|
return self._get_guild_whitelist(guild_id).copy()
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(Whitelist(bot))
|
bot.add_cog(Whitelist(bot))
|
||||||
|
|
@ -293,5 +293,5 @@ class WhitelistRemovalView(View):
|
||||||
ephemeral=True
|
ephemeral=True
|
||||||
)
|
)
|
||||||
|
|
||||||
async def setup(bot):
|
def setup(bot):
|
||||||
await bot.add_cog(WhitelistMonitor(bot))
|
bot.add_cog(WhitelistMonitor(bot))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"date": "2026-05-01T14:42:53.534230+00:00",
|
"date": "2026-05-09T16:29:01.039153+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-05-01T14:34:33.777534+00:00",
|
"date": "2026-05-09T16:24:58.475866+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-05-01T14:31:01.918316+00:00",
|
"date": "2026-05-09T16:21:25.813131+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-05-01T14:11:08.947818+00:00",
|
"date": "2026-05-09T16:18:53.874797+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-05-01T13:48:18.180388+00:00",
|
"date": "2026-05-09T16:15:46.234991+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-05-01T13:36:45.397039+00:00",
|
"date": "2026-05-09T16:11:35.632086+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-05-01T13:20:32.058899+00:00",
|
"date": "2026-05-09T16:07:40.809724+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-23T14:35:15.364216+00:00",
|
"date": "2026-05-09T16:05:50.275892+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-23T13:35:15.351819+00:00",
|
"date": "2026-05-09T16:03:53.916964+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-23T12:35:15.324906+00:00",
|
"date": "2026-05-09T16:02:51.029940+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -90,7 +90,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-23T11:35:15.210303+00:00",
|
"date": "2026-05-09T15:51:13.568534+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-23T10:35:15.338465+00:00",
|
"date": "2026-05-09T15:38:58.554617+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -108,7 +108,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-23T10:28:55.984163+00:00",
|
"date": "2026-05-09T15:30:32.050849+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -117,7 +117,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-02T17:03:30.870748+00:00",
|
"date": "2026-05-09T15:28:00.677254+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-01T14:00:13.276907+00:00",
|
"date": "2026-05-09T15:27:08.221370+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -135,7 +135,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-01T13:19:44.954622+00:00",
|
"date": "2026-05-09T15:25:53.264798+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -144,7 +144,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-01T13:17:23.537128+00:00",
|
"date": "2026-05-09T15:19:10.836829+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -153,7 +153,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-01T13:15:14.389369+00:00",
|
"date": "2026-05-09T15:15:08.978927+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -162,7 +162,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-01T13:08:00.124432+00:00",
|
"date": "2026-05-09T15:12:59.706120+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
@ -171,7 +171,7 @@
|
||||||
"success": true
|
"success": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-04-01T13:03:42.601666+00:00",
|
"date": "2026-05-09T14:59:44.423282+00:00",
|
||||||
"trigger": "auto",
|
"trigger": "auto",
|
||||||
"serversCount": 1,
|
"serversCount": 1,
|
||||||
"membersCount": 12,
|
"membersCount": 12,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"guild_id": 1369669999345537145,
|
"guild_id": 1369669999345537145,
|
||||||
"user_id": 971446412690722826,
|
"user_id": 971446412690722826,
|
||||||
"category_id": "3b0b9bc1",
|
"category_id": "3b0b9bc1",
|
||||||
"status": "open",
|
"status": "closed",
|
||||||
"priority": "normal",
|
"priority": "normal",
|
||||||
"created_at": "2026-01-10T15:57:24.973539",
|
"created_at": "2026-01-10T15:57:24.973539",
|
||||||
"closed_at": null,
|
"closed_at": null,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"guild_id": 1369669999345537145,
|
"guild_id": 1369669999345537145,
|
||||||
"user_id": 971446412690722826,
|
"user_id": 971446412690722826,
|
||||||
"category_id": "91522e2c",
|
"category_id": "91522e2c",
|
||||||
"status": "open",
|
"status": "closed",
|
||||||
"priority": "normal",
|
"priority": "normal",
|
||||||
"created_at": "2026-01-16T18:43:42.737852",
|
"created_at": "2026-01-16T18:43:42.737852",
|
||||||
"closed_at": null,
|
"closed_at": null,
|
||||||
|
|
|
||||||
1
kuby.py
1
kuby.py
|
|
@ -28,6 +28,7 @@ kuby_logger.info("✅ Token Discord chargé avec succès")
|
||||||
async def main():
|
async def main():
|
||||||
kuby_logger.info("🔄 Démarrage de la connexion Discord...")
|
kuby_logger.info("🔄 Démarrage de la connexion Discord...")
|
||||||
try:
|
try:
|
||||||
|
await bot.do_async_setup()
|
||||||
kuby_logger.info("🔗 Connexion établie avec Discord...")
|
kuby_logger.info("🔗 Connexion établie avec Discord...")
|
||||||
await bot.start(TOKEN)
|
await bot.start(TOKEN)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue