138 lines
5.6 KiB
Python
138 lines
5.6 KiB
Python
|
|
import discord
|
||
|
|
from discord import app_commands
|
||
|
|
from discord.ext import commands, tasks
|
||
|
|
from utils.gitlab_client import gitlab_client
|
||
|
|
import logging
|
||
|
|
import json
|
||
|
|
import os
|
||
|
|
import asyncio
|
||
|
|
|
||
|
|
kuby_logger = logging.getLogger("KubyBot")
|
||
|
|
REPORTS_FILE = "data/gitlab_reports.json"
|
||
|
|
|
||
|
|
def save_report(issue_iid, user_id):
|
||
|
|
os.makedirs("data", exist_ok=True)
|
||
|
|
try:
|
||
|
|
if os.path.exists(REPORTS_FILE):
|
||
|
|
with open(REPORTS_FILE, "r") as f:
|
||
|
|
data = json.load(f)
|
||
|
|
else:
|
||
|
|
data = {}
|
||
|
|
|
||
|
|
data[str(issue_iid)] = user_id
|
||
|
|
|
||
|
|
with open(REPORTS_FILE, "w") as f:
|
||
|
|
json.dump(data, f, indent=4)
|
||
|
|
except Exception as e:
|
||
|
|
kuby_logger.error(f"Error saving report to JSON: {e}")
|
||
|
|
|
||
|
|
class BugReportModal(discord.ui.Modal, title="Signaler un Bug"):
|
||
|
|
def __init__(self, priority_choice):
|
||
|
|
super().__init__()
|
||
|
|
self.priority_choice = priority_choice
|
||
|
|
|
||
|
|
bug_title = discord.ui.TextInput(
|
||
|
|
label="Titre du bug",
|
||
|
|
placeholder="Décrivez brièvement le problème...",
|
||
|
|
required=True,
|
||
|
|
max_length=100
|
||
|
|
)
|
||
|
|
|
||
|
|
description = discord.ui.TextInput(
|
||
|
|
label="Description détaillée",
|
||
|
|
style=discord.TextStyle.paragraph,
|
||
|
|
placeholder="Que s'est-il passé ? Comment reproduire le bug ?",
|
||
|
|
required=True,
|
||
|
|
max_length=1000
|
||
|
|
)
|
||
|
|
|
||
|
|
async def on_submit(self, interaction: discord.Interaction):
|
||
|
|
await interaction.response.send_message("Envoi de votre rapport de bug à GitLab...", ephemeral=True)
|
||
|
|
|
||
|
|
description_text = f"**Rapporté par:** {interaction.user} ({interaction.user.id})\n"
|
||
|
|
description_text += f"**Priorité:** {self.priority_choice.name}\n\n"
|
||
|
|
description_text += f"**Description:**\n{self.description.value}"
|
||
|
|
|
||
|
|
# Mapping des priorités vers des labels GitLab stylisés (Scoped Labels)
|
||
|
|
labels = ["bug", "manual-report", f"Priority::{self.priority_choice.value}"]
|
||
|
|
|
||
|
|
result = await gitlab_client.create_issue(
|
||
|
|
title=f"[MANUAL] {self.bug_title.value}",
|
||
|
|
description=description_text,
|
||
|
|
labels=labels
|
||
|
|
)
|
||
|
|
|
||
|
|
if result:
|
||
|
|
issue_iid = result.get("iid")
|
||
|
|
save_report(issue_iid, interaction.user.id)
|
||
|
|
await interaction.edit_original_response(content=f"✅ Votre bug a été signalé avec succès ! Gameur a bien été averti et le bug sera réglé dans la prochaine mise à jour. [Voir l'issue]({result.get('web_url')})")
|
||
|
|
else:
|
||
|
|
await interaction.edit_original_response(content="❌ Une erreur est survenue lors de l'envoi du rapport à GitLab. Veuillez contacter un administrateur.")
|
||
|
|
|
||
|
|
class BugReport(commands.Cog):
|
||
|
|
def __init__(self, bot):
|
||
|
|
self.bot = bot
|
||
|
|
self.check_gitlab_issues.start()
|
||
|
|
|
||
|
|
def cog_unload(self):
|
||
|
|
self.check_gitlab_issues.cancel()
|
||
|
|
|
||
|
|
@tasks.loop(minutes=30)
|
||
|
|
async def check_gitlab_issues(self):
|
||
|
|
"""Vérifie périodiquement si des issues suivies ont été fermées"""
|
||
|
|
if not os.path.exists(REPORTS_FILE):
|
||
|
|
return
|
||
|
|
|
||
|
|
try:
|
||
|
|
with open(REPORTS_FILE, "r") as f:
|
||
|
|
reports = json.load(f)
|
||
|
|
|
||
|
|
if not reports:
|
||
|
|
return
|
||
|
|
|
||
|
|
issues_to_remove = []
|
||
|
|
for issue_iid, user_id in reports.items():
|
||
|
|
issue = await gitlab_client.get_issue(int(issue_iid))
|
||
|
|
if issue and issue.get("state") == "closed":
|
||
|
|
# L'issue est fermée ! On prévient l'utilisateur
|
||
|
|
user = self.bot.get_user(user_id)
|
||
|
|
if user:
|
||
|
|
try:
|
||
|
|
embed = discord.Embed(
|
||
|
|
title="🛠️ Bug Résolu !",
|
||
|
|
description=f"Bonne nouvelle ! Le bug que vous avez signalé (**{issue.get('title')}**) a été marqué comme terminé sur GitLab.",
|
||
|
|
color=discord.Color.green()
|
||
|
|
)
|
||
|
|
embed.add_field(name="Statut", value="Terminé / Résolu")
|
||
|
|
embed.add_field(name="Prochaine étape", value="La mise à jour arrive prochainement !")
|
||
|
|
embed.set_footer(text="Merci de votre aide pour améliorer le bot.")
|
||
|
|
await user.send(embed=embed)
|
||
|
|
issues_to_remove.append(issue_iid)
|
||
|
|
except Exception as e:
|
||
|
|
kuby_logger.error(f"Impossible d'envoyer un MP à {user_id}: {e}")
|
||
|
|
else:
|
||
|
|
# On ne peut pas trouver l'user, on retire quand même pour ne pas boucler
|
||
|
|
issues_to_remove.append(issue_iid)
|
||
|
|
|
||
|
|
if issues_to_remove:
|
||
|
|
for iid in issues_to_remove:
|
||
|
|
del reports[iid]
|
||
|
|
with open(REPORTS_FILE, "w") as f:
|
||
|
|
json.dump(reports, f, indent=4)
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
kuby_logger.error(f"Erreur lors du cycle de vérification GitLab: {e}")
|
||
|
|
|
||
|
|
@app_commands.command(name="signaler_bug", description="Signaler un bug aux développeurs")
|
||
|
|
@app_commands.choices(priority=[
|
||
|
|
app_commands.Choice(name="Basse", value="Low"),
|
||
|
|
app_commands.Choice(name="Normale", value="Normal"),
|
||
|
|
app_commands.Choice(name="Haute", value="High"),
|
||
|
|
app_commands.Choice(name="Urgente", value="Urgent"),
|
||
|
|
])
|
||
|
|
async def signaler_bug(self, interaction: discord.Interaction, priority: app_commands.Choice[str]):
|
||
|
|
await interaction.response.send_modal(BugReportModal(priority))
|
||
|
|
|
||
|
|
async def setup(bot):
|
||
|
|
await bot.add_cog(BugReport(bot))
|