migration vers new components V2, et ajout de diverse fonctions !

This commit is contained in:
Mathis 2026-05-16 18:05:04 +02:00
parent 3590cb748f
commit ba9e297cb8
14 changed files with 851 additions and 371 deletions

View file

@ -4,6 +4,10 @@ import json
import os
from typing import List, Optional, Dict
import datetime
import asyncio
import logging
kuby_logger = logging.getLogger("KubyBot")
# --- CONFIGURATION ---
CONV_SETTINGS_FILE = "data/convocation_settings.json"
@ -91,25 +95,33 @@ class Convocation(commands.Cog):
await interaction.followup.send("⚠️ Je n'ai pas pu retirer certains rôles (Permission refusée).", ephemeral=True)
# 2. Dynamic Lockdown: Loop through ALL channels
lockdown_count = 0
for channel in interaction.guild.channels:
# On ignore le salon d'attente et ses parents s'il y en a
if attente_id and (channel.id == attente_id or (hasattr(channel, 'category') and channel.category and channel.category.id == attente_id)):
continue
# Check existing override for the member
overwrites = channel.overwrites_for(membre)
if not overwrites.is_empty():
# Save existing override (as dict of pair of permission name and boolean/None)
backup_data["overrides"][str(channel.id)] = {k: v for k, v in dict(overwrites).items() if v is not None}
# Apply Lockdown override for the member
try:
# Specific override for this member: View Channel = False
await channel.set_permissions(membre, view_channel=False, reason="Convocation Lockdown")
lockdown_count += 1
except disnake.Forbidden:
pass # Skip if we can't touch this channel
semaphore = asyncio.Semaphore(10)
async def lock_channel(channel):
async with semaphore:
# On ignore le salon d'attente et ses parents s'il y en a
if attente_id and (channel.id == attente_id or (hasattr(channel, 'category') and channel.category and channel.category.id == attente_id)):
return False
# Check existing override for the member
overwrites = channel.overwrites_for(membre)
if not overwrites.is_empty():
# Save existing override
backup_data["overrides"][str(channel.id)] = {k: v for k, v in dict(overwrites).items() if v is not None}
# Apply Lockdown override for the member
try:
await channel.set_permissions(membre, view_channel=False, reason="Convocation Lockdown")
return True
except disnake.Forbidden:
return False
except Exception as e:
kuby_logger.warning(f"⚠️ [Convocation] Impossible de verrouiller {channel.name}: {e}")
return False
tasks = [lock_channel(c) for c in interaction.guild.channels]
results = await asyncio.gather(*tasks)
lockdown_count = sum(1 for r in results if r is True)
self.save_backup(guild_id, membre.id, backup_data)
@ -190,43 +202,59 @@ class Convocation(commands.Cog):
await interaction.followup.send("⚠️ Aucune donnée de convocation trouvée pour ce membre.", ephemeral=True)
return
# 1. Remove Convocation role
if role_conv_id:
role_conv = interaction.guild.get_role(role_conv_id)
if role_conv and role_conv in membre.roles:
await membre.remove_roles(role_conv, reason="Fin de convocation")
# 1. Remove Convocation role & Restore original roles FIRST
try:
if role_conv_id:
role_conv = interaction.guild.get_role(role_conv_id)
if role_conv and role_conv in membre.roles:
await membre.remove_roles(role_conv, reason="Fin de convocation")
# 2. Restore channel overrides
restore_count = 0
role_ids = backup_data.get("roles", [])
if role_ids:
restored_roles = []
for rid in role_ids:
role = interaction.guild.get_role(rid)
if role and role.position < interaction.guild.me.top_role.position:
restored_roles.append(role)
if restored_roles:
await membre.add_roles(*restored_roles, reason="Restauration fin de convocation")
except Exception as e:
kuby_logger.error(f"❌ [Convocation] Erreur lors de la restauration des rôles pour {membre}: {e}")
# 2. Restore channel overrides (Parallel)
semaphore = asyncio.Semaphore(10)
overrides = backup_data.get("overrides", {})
for channel in interaction.guild.channels:
chan_id_str = str(channel.id)
try:
if chan_id_str in overrides:
# Restore previous override
ov_data = overrides[chan_id_str]
overwrite = disnake.PermissionOverwrite(**ov_data)
await channel.set_permissions(membre, overwrite=overwrite, reason="Restauration fin de convocation")
restore_count += 1
else:
# Clear our lockdown override
# On ne vide que si un override membre existait (sinon on risque de supprimer des perms rôles ?)
# En fait set_permissions(member, overwrite=None) supprime l'entrée PERSONNELLE du membre.
await channel.set_permissions(membre, overwrite=None, reason="Fin de convocation - Cleanup")
except disnake.Forbidden:
pass
async def restore_channel(channel):
async with semaphore:
chan_id_str = str(channel.id)
try:
if chan_id_str in overrides:
# Restore previous override
ov_data = overrides[chan_id_str]
overwrite = disnake.PermissionOverwrite(**ov_data)
await channel.set_permissions(membre, overwrite=overwrite, reason="Restauration fin de convocation")
return "restored"
elif membre in channel.overwrites:
# Clear our lockdown override only if it exists
await channel.set_permissions(membre, overwrite=None, reason="Fin de convocation - Cleanup")
return "cleared"
except disnake.Forbidden:
return "forbidden"
except Exception as e:
kuby_logger.warning(f"⚠️ [Convocation] Erreur restauration {channel.name}: {e}")
return "error"
return "skipped"
# 3. Restore roles
role_ids = backup_data.get("roles", [])
restored_roles = []
if role_ids:
for rid in role_ids:
role = interaction.guild.get_role(rid)
if role and role.position < interaction.guild.me.top_role.position:
restored_roles.append(role)
if restored_roles:
await membre.add_roles(*restored_roles, reason="Restauration fin de convocation")
tasks = [restore_channel(c) for c in interaction.guild.channels]
results = await asyncio.gather(*tasks)
restore_count = sum(1 for r in results if r == "restored")
clear_count = sum(1 for r in results if r == "cleared")
forbidden_count = sum(1 for r in results if r == "forbidden")
kuby_logger.info(f"🔓 [Convocation] Restauration terminée pour {membre}: {restore_count} restaurés, {clear_count} nettoyés, {forbidden_count} échecs permissions.")
self.clear_backup(guild_id, membre.id)