Mise à jour du système d'absence staff
This commit is contained in:
parent
ae2347c7ce
commit
d8b2f06f86
3 changed files with 108 additions and 105 deletions
|
|
@ -152,23 +152,30 @@ class AbsenceModal(disnake.ui.Modal):
|
||||||
now = get_paris_now()
|
now = get_paris_now()
|
||||||
etat = "à venir" if debut > now else "en cours"
|
etat = "à venir" if debut > now else "en cours"
|
||||||
|
|
||||||
# Message dans le salon
|
# Message dans le salon avec V2 Components
|
||||||
absence_message = await channel.send(
|
components = [
|
||||||
f"# ABSENCE STAFF :\n"
|
disnake.ui.Container(
|
||||||
f"- **Pseudo Discord** : {interaction.user.mention}\n"
|
disnake.ui.Section(
|
||||||
f"- **Durée prévue** : {duree_str}\n"
|
f"# ABSENCE STAFF\n**👤 Membre** : {interaction.user.mention}",
|
||||||
f"- **Débute le** : {self.date_debut.value} (Paris)\n"
|
accessory=disnake.ui.Thumbnail(interaction.user.display_avatar.url)
|
||||||
f"- **Termine le** : {self.date_fin.value} (Paris)\n"
|
),
|
||||||
f"- **Motif** : {self.motif.value}\n"
|
disnake.ui.Separator(),
|
||||||
f"- **Mention du supérieur hiérarchique** : {self.superieur.mention if self.superieur else 'Aucun'}"
|
disnake.ui.TextDisplay(f"**⏳ Durée** : {duree_str}"),
|
||||||
)
|
disnake.ui.TextDisplay(f"**📅 Période** : `{val_debut}` ➔ `{val_fin}`"),
|
||||||
|
disnake.ui.TextDisplay(f"**📝 Motif** : {motif}"),
|
||||||
|
disnake.ui.TextDisplay(f"**🛡️ Supérieur** : {self.superieur.mention if self.superieur else 'Aucun'}")
|
||||||
|
)
|
||||||
|
]
|
||||||
|
absence_message = await channel.send(components=components)
|
||||||
|
|
||||||
# Enregistrement
|
# Enregistrement
|
||||||
guild_abs[str(interaction.user.id)] = {
|
guild_abs[str(interaction.user.id)] = {
|
||||||
"pseudo": interaction.user.name,
|
"pseudo": interaction.user.name,
|
||||||
"debut": self.date_debut.value,
|
"avatar_url": interaction.user.display_avatar.url,
|
||||||
"fin": self.date_fin.value,
|
"debut": val_debut,
|
||||||
"motif": self.motif.value,
|
"fin": val_fin,
|
||||||
|
"duree": duree_str,
|
||||||
|
"motif": motif,
|
||||||
"superieur": self.superieur.mention if self.superieur else "Aucun",
|
"superieur": self.superieur.mention if self.superieur else "Aucun",
|
||||||
"message_id": absence_message.id,
|
"message_id": absence_message.id,
|
||||||
"etat": etat
|
"etat": etat
|
||||||
|
|
@ -190,63 +197,55 @@ class AbsenceModal(disnake.ui.Modal):
|
||||||
await interaction.response.send_message("✅ Absence enregistrée avec succès !", ephemeral=True)
|
await interaction.response.send_message("✅ Absence enregistrée avec succès !", ephemeral=True)
|
||||||
|
|
||||||
class AbsenceConfigView(disnake.ui.View):
|
class AbsenceConfigView(disnake.ui.View):
|
||||||
def __init__(self, guild_id: int):
|
def __init__(self, guild_id: int, bot):
|
||||||
super().__init__(timeout=60)
|
super().__init__(timeout=300)
|
||||||
self.guild_id = guild_id
|
self.guild_id = guild_id
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
@disnake.ui.button(label="Définir le Salon", style=disnake.ButtonStyle.primary, emoji="📁")
|
@disnake.ui.channel_select(placeholder="Sélectionnez le salon d'affichage", min_values=1, max_values=1)
|
||||||
async def set_channel(self, button: disnake.ui.Button, interaction: disnake.Interaction):
|
async def select_channel(self, select: disnake.ui.ChannelSelect, interaction: disnake.MessageInteraction):
|
||||||
await interaction.response.send_message("Mentionne le salon ici (ou envoie son ID) :", ephemeral=True)
|
channel = select.values[0]
|
||||||
|
settings = load_settings(self.guild_id)
|
||||||
|
settings["absence_channel_id"] = channel.id
|
||||||
|
save_settings(self.guild_id, settings)
|
||||||
|
|
||||||
def check(m):
|
# Update the original message with new settings
|
||||||
return m.author == interaction.user and m.channel == interaction.channel
|
embed = self._get_updated_embed(settings, interaction.guild)
|
||||||
|
await interaction.response.edit_message(embed=embed, view=self)
|
||||||
|
await interaction.followup.send(f"✅ Salon d'absence configuré sur {channel.mention}", ephemeral=True)
|
||||||
|
|
||||||
try:
|
@disnake.ui.role_select(placeholder="Sélectionnez le rôle d'absence", min_values=1, max_values=1)
|
||||||
msg = await interaction.bot.wait_for('message', check=check, timeout=30)
|
async def select_role(self, select: disnake.ui.RoleSelect, interaction: disnake.MessageInteraction):
|
||||||
channel = None
|
role = select.values[0]
|
||||||
if msg.channel_mentions:
|
settings = load_settings(self.guild_id)
|
||||||
channel = msg.channel_mentions[0]
|
settings["absence_role_id"] = role.id
|
||||||
elif msg.content.isdigit():
|
save_settings(self.guild_id, settings)
|
||||||
channel = interaction.guild.get_channel(int(msg.content))
|
|
||||||
|
|
||||||
if not channel:
|
# Update the original message with new settings
|
||||||
return await interaction.followup.send("❌ Salon invalide.", ephemeral=True)
|
embed = self._get_updated_embed(settings, interaction.guild)
|
||||||
|
await interaction.response.edit_message(embed=embed, view=self)
|
||||||
|
await interaction.followup.send(f"✅ Rôle d'absence configuré sur **{role.name}**", ephemeral=True)
|
||||||
|
|
||||||
settings = load_settings(self.guild_id)
|
def _get_updated_embed(self, settings, guild):
|
||||||
settings["absence_channel_id"] = channel.id
|
channel_id = settings.get("absence_channel_id")
|
||||||
save_settings(self.guild_id, settings)
|
role_id = settings.get("absence_role_id")
|
||||||
await interaction.followup.send(f"✅ Salon d'absence configuré sur {channel.mention}", ephemeral=True)
|
|
||||||
try: await msg.delete()
|
|
||||||
except: pass
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
await interaction.followup.send("❌ Temps écoulé.", ephemeral=True)
|
|
||||||
|
|
||||||
@disnake.ui.button(label="Définir le Rôle", style=disnake.ButtonStyle.primary, emoji="🎭")
|
embed = disnake.Embed(
|
||||||
async def set_role(self, button: disnake.ui.Button, interaction: disnake.Interaction):
|
title="⚙️ Configuration des Absences Staff",
|
||||||
await interaction.response.send_message("Mentionne le rôle ici (ou envoie son ID) :", ephemeral=True)
|
description="Utilisez les menus déroulants ci-dessous pour configurer le système.",
|
||||||
|
color=disnake.Color.blue()
|
||||||
def check(m):
|
)
|
||||||
return m.author == interaction.user and m.channel == interaction.channel
|
embed.add_field(
|
||||||
|
name="📁 Salon d'affichage",
|
||||||
try:
|
value=f"<#{channel_id}>" if channel_id else "❌ Non configuré",
|
||||||
msg = await interaction.bot.wait_for('message', check=check, timeout=30)
|
inline=True
|
||||||
role = None
|
)
|
||||||
if msg.role_mentions:
|
embed.add_field(
|
||||||
role = msg.role_mentions[0]
|
name="🎭 Rôle d'absence",
|
||||||
elif msg.content.isdigit():
|
value=f"<@&{role_id}>" if role_id else "❌ Non configuré",
|
||||||
role = interaction.guild.get_role(int(msg.content))
|
inline=True
|
||||||
|
)
|
||||||
if not role:
|
return embed
|
||||||
return await interaction.followup.send("❌ Rôle invalide.", ephemeral=True)
|
|
||||||
|
|
||||||
settings = load_settings(self.guild_id)
|
|
||||||
settings["absence_role_id"] = role.id
|
|
||||||
save_settings(self.guild_id, settings)
|
|
||||||
await interaction.followup.send(f"✅ Rôle d'absence configuré sur **{role.name}**", ephemeral=True)
|
|
||||||
try: await msg.delete()
|
|
||||||
except: pass
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
await interaction.followup.send("❌ Temps écoulé.", ephemeral=True)
|
|
||||||
|
|
||||||
class Absence(commands.Cog):
|
class Absence(commands.Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
|
|
@ -285,29 +284,55 @@ class Absence(commands.Cog):
|
||||||
inline=True
|
inline=True
|
||||||
)
|
)
|
||||||
|
|
||||||
await interaction.response.send_message(embed=embed, view=AbsenceConfigView(interaction.guild.id), ephemeral=True)
|
await interaction.response.send_message(embed=embed, view=AbsenceConfigView(interaction.guild.id, self.bot), ephemeral=True)
|
||||||
|
|
||||||
async def strike_absence_message(self, guild: disnake.Guild, channel_id: int, message_id: int):
|
async def strike_absence_message(self, guild: disnake.Guild, channel_id: int, message_id: int, info: dict = None):
|
||||||
"""Modifie le message d'absence pour le barrer au lieu de le supprimer"""
|
"""Modifie le message d'absence pour le barrer au lieu de le supprimer"""
|
||||||
channel = guild.get_channel(channel_id)
|
channel = guild.get_channel(channel_id)
|
||||||
if not channel:
|
if not channel:
|
||||||
try:
|
try: channel = await guild.fetch_channel(channel_id)
|
||||||
channel = await guild.fetch_channel(channel_id)
|
except: return
|
||||||
except:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
msg = await channel.fetch_message(message_id)
|
msg = await channel.fetch_message(message_id)
|
||||||
content = msg.content
|
|
||||||
|
|
||||||
if "~~" in content: # Déjà barré
|
# Gestion des Rich Components V2
|
||||||
|
if info:
|
||||||
|
avatar_url = info.get("avatar_url")
|
||||||
|
if avatar_url:
|
||||||
|
header_component = disnake.ui.Section(
|
||||||
|
f"## ~~ABSENCE STAFF [TERMINÉ]~~\n~~**👤 Membre** : {info.get('pseudo', 'Inconnu')}~~",
|
||||||
|
accessory=disnake.ui.Thumbnail(avatar_url)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
header_component = disnake.ui.TextDisplay(f"## ~~ABSENCE STAFF [TERMINÉ]~~\n~~**👤 Membre** : {info.get('pseudo', 'Inconnu')}~~")
|
||||||
|
|
||||||
|
components = [
|
||||||
|
disnake.ui.Container(
|
||||||
|
header_component,
|
||||||
|
disnake.ui.Separator(),
|
||||||
|
disnake.ui.TextDisplay(f"~~**⏳ Durée** : {info.get('duree', 'N/A')}~~"),
|
||||||
|
disnake.ui.TextDisplay(f"~~**📅 Période** : {info.get('debut')} ➔ {info.get('fin')}~~"),
|
||||||
|
disnake.ui.TextDisplay(f"~~**📝 Motif** : {info.get('motif')}~~"),
|
||||||
|
disnake.ui.TextDisplay(f"~~**🛡️ Supérieur** : {info.get('superieur', 'Aucun')}~~")
|
||||||
|
)
|
||||||
|
]
|
||||||
|
print(f"[DEBUG] Tentative d'édition du message V2 {message_id}")
|
||||||
|
try:
|
||||||
|
await msg.edit(components=components)
|
||||||
|
print(f"[DEBUG] Succès édition V2")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[DEBUG] Erreur édition V2: {e}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Ancien format (Texte simple) - fallback
|
||||||
|
content = msg.content
|
||||||
|
if not content or "~~" in content: return
|
||||||
|
|
||||||
lines = content.split("\n")
|
lines = content.split("\n")
|
||||||
new_lines = []
|
new_lines = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if line.startswith("# "):
|
if line.startswith("# "):
|
||||||
# Conserver le style header mais barrer le texte
|
|
||||||
new_lines.append(f"# ~~{line[2:].strip()}~~ [TERMINÉ]")
|
new_lines.append(f"# ~~{line[2:].strip()}~~ [TERMINÉ]")
|
||||||
elif line.strip():
|
elif line.strip():
|
||||||
new_lines.append(f"~~{line}~~")
|
new_lines.append(f"~~{line}~~")
|
||||||
|
|
@ -335,7 +360,7 @@ class Absence(commands.Cog):
|
||||||
channel_id = settings.get("absence_channel_id")
|
channel_id = settings.get("absence_channel_id")
|
||||||
|
|
||||||
if channel_id and message_id:
|
if channel_id and message_id:
|
||||||
await self.strike_absence_message(interaction.guild, int(channel_id), int(message_id))
|
await self.strike_absence_message(interaction.guild, int(channel_id), int(message_id), info)
|
||||||
|
|
||||||
# Retrait du rôle
|
# Retrait du rôle
|
||||||
role_id = settings.get("absence_role_id")
|
role_id = settings.get("absence_role_id")
|
||||||
|
|
@ -470,7 +495,7 @@ class Absence(commands.Cog):
|
||||||
message_id = info.get("message_id")
|
message_id = info.get("message_id")
|
||||||
channel_id = settings.get("absence_channel_id")
|
channel_id = settings.get("absence_channel_id")
|
||||||
if channel_id and message_id:
|
if channel_id and message_id:
|
||||||
await self.strike_absence_message(guild, int(channel_id), int(message_id))
|
await self.strike_absence_message(guild, int(channel_id), int(message_id), info)
|
||||||
|
|
||||||
to_remove.append(user_id_str)
|
to_remove.append(user_id_str)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
@ -507,7 +532,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://disnake.com/channels/{message.guild.id}/{channel_id}/{msg_id}" if channel_id and msg_id else ""
|
absence_url = f"https://discord.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:
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,9 @@ class WhitelistMonitor(commands.Cog):
|
||||||
self.whitelist_file = "data/whitelist.json"
|
self.whitelist_file = "data/whitelist.json"
|
||||||
self.persistent_views_added = False
|
self.persistent_views_added = False
|
||||||
self.big_permissions = [
|
self.big_permissions = [
|
||||||
disnake.Permissions.administrator,
|
"administrator", "manage_guild", "manage_roles", "manage_channels",
|
||||||
disnake.Permissions.manage_guild,
|
"kick_members", "ban_members", "manage_messages", "moderate_members",
|
||||||
disnake.Permissions.manage_roles,
|
"manage_nicknames", "manage_emojis", "manage_webhooks", "view_audit_log"
|
||||||
disnake.Permissions.manage_channels,
|
|
||||||
disnake.Permissions.kick_members,
|
|
||||||
disnake.Permissions.ban_members,
|
|
||||||
disnake.Permissions.manage_messages,
|
|
||||||
disnake.Permissions.moderate_members,
|
|
||||||
disnake.Permissions.manage_nicknames,
|
|
||||||
disnake.Permissions.manage_emojis,
|
|
||||||
disnake.Permissions.manage_webhooks,
|
|
||||||
disnake.Permissions.view_audit_log
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def load_whitelist(self) -> Dict[str, List[str]]:
|
def load_whitelist(self) -> Dict[str, List[str]]:
|
||||||
|
|
@ -72,11 +63,8 @@ class WhitelistMonitor(commands.Cog):
|
||||||
|
|
||||||
def has_big_permissions(self, role: disnake.Role) -> bool:
|
def has_big_permissions(self, role: disnake.Role) -> bool:
|
||||||
"""Check if role has significant permissions."""
|
"""Check if role has significant permissions."""
|
||||||
permissions = role.permissions
|
perms = role.permissions
|
||||||
for perm in self.big_permissions:
|
return any(getattr(perms, p, False) for p in self.big_permissions)
|
||||||
if permissions.administrator or getattr(permissions, perm.name, False):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def send_whitelist_notification(self, member: disnake.Member, removed_roles: List[disnake.Role]):
|
async def send_whitelist_notification(self, member: disnake.Member, removed_roles: List[disnake.Role]):
|
||||||
"""Send DM notification to user about whitelist member losing roles."""
|
"""Send DM notification to user about whitelist member losing roles."""
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,3 @@
|
||||||
{
|
{
|
||||||
"1369669999345537145": {
|
"1369669999345537145": {}
|
||||||
"971446412690722826": {
|
|
||||||
"pseudo": "gameurpro12",
|
|
||||||
"debut": null,
|
|
||||||
"fin": null,
|
|
||||||
"motif": null,
|
|
||||||
"superieur": "<@353942721997832195>",
|
|
||||||
"message_id": 1505246281935618138,
|
|
||||||
"etat": "à venir"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue