All checks were successful
ci / ci (push) Successful in 45s
- Boutons: Réclamer, Transférer, Verrouiller/Déverrouiller, Ajouter, Fermer - Accents français partout (catégorie, équipe, configuré, etc.) - Retiré PriorityButton et StatsButton (trop chargé) - Layout: Gestion (Réclamer/Transférer/Verrouiller) → Ajouter/Fermer
243 lines
9 KiB
Python
243 lines
9 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
import discord
|
|
from discord import app_commands
|
|
from discord.ext import commands
|
|
|
|
from tickets import storage
|
|
from tickets.data import TicketCategory
|
|
from tickets.ui import (
|
|
AddMemberButton,
|
|
ClaimButton,
|
|
CloseButton,
|
|
LockButton,
|
|
PanelCreateButton,
|
|
TransferButton,
|
|
_is_staff,
|
|
)
|
|
|
|
logger = logging.getLogger("vision")
|
|
|
|
|
|
class PanelView(discord.ui.LayoutView):
|
|
def __init__(self):
|
|
super().__init__(timeout=None)
|
|
container = discord.ui.Container()
|
|
container.add_item(
|
|
discord.ui.TextDisplay(
|
|
"## Système de tickets\n"
|
|
"Besoin d'aide ? Créez un ticket et notre équipe vous répondra.\n"
|
|
"Cliquez sur le bouton ci-dessous pour commencer."
|
|
)
|
|
)
|
|
container.add_item(discord.ui.Separator())
|
|
container.add_item(discord.ui.ActionRow(PanelCreateButton()))
|
|
self.add_item(container)
|
|
|
|
|
|
class ConfigView(discord.ui.LayoutView):
|
|
def __init__(self):
|
|
super().__init__(timeout=None)
|
|
container = discord.ui.Container()
|
|
container.add_item(discord.ui.TextDisplay("## Configuration Tickets\nModifications enregistrées."))
|
|
self.add_item(container)
|
|
|
|
|
|
class AddCategoryModal(discord.ui.Modal, title="Ajouter une catégorie"):
|
|
name = discord.ui.TextInput(label="Nom", max_length=50, required=True)
|
|
emoji = discord.ui.TextInput(label="Emoji", max_length=10, required=False)
|
|
description = discord.ui.TextInput(
|
|
label="Description",
|
|
max_length=100,
|
|
required=False,
|
|
style=discord.TextStyle.paragraph,
|
|
)
|
|
|
|
async def on_submit(self, interaction: discord.Interaction):
|
|
config = storage.get_config(interaction.guild_id)
|
|
cat_id = self.name.value.lower().replace(" ", "-")[:20]
|
|
cat = TicketCategory(
|
|
id=cat_id,
|
|
name=self.name.value,
|
|
emoji=self.emoji.value or "",
|
|
description=self.description.value or "",
|
|
)
|
|
config.categories.append(cat)
|
|
storage.save_config(config)
|
|
await interaction.response.send_message(f"Catégorie **{cat.name}** ajoutée.", ephemeral=True)
|
|
|
|
|
|
class ConfigToggleButton(discord.ui.Button):
|
|
def __init__(self, enabled: bool):
|
|
super().__init__(
|
|
label="Désactiver" if enabled else "Activer",
|
|
style=discord.ButtonStyle.danger if enabled else discord.ButtonStyle.success,
|
|
custom_id="ticket_cfg_toggle",
|
|
)
|
|
|
|
async def callback(self, interaction: discord.Interaction):
|
|
config = storage.get_config(interaction.guild_id)
|
|
config.enabled = not config.enabled
|
|
storage.save_config(config)
|
|
await interaction.response.edit_message(view=ConfigView())
|
|
|
|
|
|
class ConfigAddCatButton(discord.ui.Button):
|
|
def __init__(self):
|
|
super().__init__(label="Ajouter catégorie", style=discord.ButtonStyle.primary, custom_id="ticket_cfg_addcat")
|
|
|
|
async def callback(self, interaction: discord.Interaction):
|
|
await interaction.response.send_modal(AddCategoryModal())
|
|
|
|
|
|
class ConfigSetStaffButton(discord.ui.Button):
|
|
def __init__(self):
|
|
super().__init__(label="Role staff", style=discord.ButtonStyle.secondary, custom_id="ticket_cfg_staff")
|
|
|
|
async def callback(self, interaction: discord.Interaction):
|
|
view = discord.ui.View(timeout=300)
|
|
sel = discord.ui.RoleSelect(
|
|
placeholder="Role staff...", custom_id="ticket_staff_role_select", min_values=1, max_values=1
|
|
)
|
|
|
|
async def _cb(interaction: discord.Interaction):
|
|
config = storage.get_config(interaction.guild_id)
|
|
config.staff_role_id = sel.values[0].id
|
|
storage.save_config(config)
|
|
await interaction.response.edit_message(content=f"Role staff : {sel.values[0].mention}", view=None)
|
|
|
|
sel.callback = _cb
|
|
view.add_item(sel)
|
|
await interaction.response.send_message("Sélectionnez le rôle staff :", view=view, ephemeral=True)
|
|
|
|
|
|
class ConfigSetLogButton(discord.ui.Button):
|
|
def __init__(self):
|
|
super().__init__(label="Canal logs", style=discord.ButtonStyle.secondary, custom_id="ticket_cfg_log")
|
|
|
|
async def callback(self, interaction: discord.Interaction):
|
|
view = discord.ui.View(timeout=300)
|
|
sel = discord.ui.ChannelSelect(
|
|
placeholder="Canal de logs...",
|
|
custom_id="ticket_log_channel_select",
|
|
channel_types=[discord.ChannelType.text],
|
|
min_values=1,
|
|
max_values=1,
|
|
)
|
|
|
|
async def _cb(interaction: discord.Interaction):
|
|
config = storage.get_config(interaction.guild_id)
|
|
config.log_channel_id = sel.values[0].id
|
|
storage.save_config(config)
|
|
await interaction.response.edit_message(content=f"Canal de logs : {sel.values[0].mention}", view=None)
|
|
|
|
sel.callback = _cb
|
|
view.add_item(sel)
|
|
await interaction.response.send_message("Sélectionnez le canal de logs :", view=view, ephemeral=True)
|
|
|
|
|
|
class TicketManagementView(discord.ui.LayoutView):
|
|
def __init__(self):
|
|
super().__init__(timeout=None)
|
|
container = discord.ui.Container()
|
|
container.add_item(discord.ui.TextDisplay("### Gestion"))
|
|
container.add_item(discord.ui.ActionRow(ClaimButton(), TransferButton(), LockButton()))
|
|
container.add_item(discord.ui.Separator())
|
|
container.add_item(discord.ui.ActionRow(AddMemberButton(), CloseButton()))
|
|
self.add_item(container)
|
|
|
|
|
|
class TicketSystem(commands.Cog):
|
|
ticket = app_commands.Group(name="ticket", description="Systeme de tickets")
|
|
|
|
def __init__(self, bot: commands.Bot):
|
|
self.bot = bot
|
|
self.bot.add_view(PanelView())
|
|
self.bot.add_view(TicketManagementView())
|
|
|
|
@commands.Cog.listener()
|
|
async def on_ready(self):
|
|
logger.info("TicketSystem cog charge")
|
|
|
|
@commands.Cog.listener()
|
|
async def on_message(self, message: discord.Message):
|
|
if message.author.bot:
|
|
return
|
|
if not message.guild:
|
|
return
|
|
|
|
ticket = storage.get_ticket(message.channel.id)
|
|
if not ticket:
|
|
return
|
|
|
|
config = storage.get_config(message.guild.id)
|
|
member = message.guild.get_member(message.author.id)
|
|
if not member:
|
|
return
|
|
|
|
is_staff = _is_staff(member, config)
|
|
|
|
from tickets.data import TicketMessage
|
|
|
|
msg = TicketMessage(
|
|
author_id=message.author.id,
|
|
author_name=str(message.author),
|
|
content=message.content,
|
|
timestamp=message.created_at.isoformat(),
|
|
attachments=[a.url for a in message.attachments],
|
|
is_staff=is_staff,
|
|
)
|
|
ticket.messages.append(msg)
|
|
storage.save_ticket(ticket)
|
|
|
|
@ticket.command(name="setup", description="Envoyer le panneau de tickets")
|
|
@app_commands.describe(channel="Canal pour le panneau")
|
|
@app_commands.checks.has_permissions(manage_guild=True)
|
|
async def ticket_setup(self, interaction: discord.Interaction, channel: discord.TextChannel):
|
|
config = storage.get_config(interaction.guild_id)
|
|
config.enabled = True
|
|
config.panel_channel_id = channel.id
|
|
storage.save_config(config)
|
|
view = PanelView()
|
|
msg = await channel.send(view=view)
|
|
config.panel_message_id = msg.id
|
|
storage.save_config(config)
|
|
container = discord.ui.Container()
|
|
container.add_item(discord.ui.TextDisplay(f"## Panneau envoyé\nCanal : {channel.mention}\nStatut : Actif"))
|
|
resp_view = discord.ui.LayoutView()
|
|
resp_view.add_item(container)
|
|
await interaction.response.send_message(view=resp_view, ephemeral=True)
|
|
|
|
@ticket.command(name="config", description="Configuration du système de tickets")
|
|
@app_commands.checks.has_permissions(manage_guild=True)
|
|
async def ticket_config(self, interaction: discord.Interaction):
|
|
config = storage.get_config(interaction.guild_id)
|
|
cats = "\n".join(f"- {c.emoji} **{c.name}**" for c in config.categories) or "*Aucune*"
|
|
staff_line = f"**Rôle staff :** <@&{config.staff_role_id}>\n" if config.staff_role_id else ""
|
|
log_line = f"**Canal de logs :** <#{config.log_channel_id}>\n" if config.log_channel_id else ""
|
|
container = discord.ui.Container()
|
|
container.add_item(
|
|
discord.ui.TextDisplay(
|
|
f"## Configuration Tickets\n"
|
|
f"**Statut :** {'Actif' if config.enabled else 'Inactif'}\n"
|
|
f"{staff_line}{log_line}### Categories\n{cats}"
|
|
)
|
|
)
|
|
container.add_item(discord.ui.Separator())
|
|
container.add_item(
|
|
discord.ui.ActionRow(
|
|
ConfigToggleButton(config.enabled),
|
|
ConfigAddCatButton(),
|
|
ConfigSetStaffButton(),
|
|
ConfigSetLogButton(),
|
|
)
|
|
)
|
|
view = discord.ui.LayoutView()
|
|
view.add_item(container)
|
|
await interaction.response.send_message(view=view, ephemeral=True)
|
|
|
|
|
|
async def setup(bot: commands.Bot):
|
|
await bot.add_cog(TicketSystem(bot))
|