Vicy_Publique/commandes/stats_commandes.py
2026-08-16 19:37:15 +02:00

144 lines
6 KiB
Python

import discord
from discord import app_commands
from discord.ext import commands
import matplotlib.pyplot as plt
import io
import datetime
from utils.stats_manager import get_stats_detailed # fonction fictive améliorée
class StatsCommandes(commands.Cog):
def __init__(self, bot):
self.bot = bot
def plot_barh(self, labels, values, title, xlabel, color='cornflowerblue'):
plt.figure(figsize=(8,4))
plt.barh(labels[::-1], values[::-1], color=color)
plt.title(title)
plt.xlabel(xlabel)
plt.tight_layout()
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close()
buf.seek(0)
return buf
def plot_line(self, dates, values, title, xlabel, ylabel, color='tab:blue'):
plt.figure(figsize=(10,5))
plt.plot(dates, values, marker='o', color=color)
plt.title(title)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.grid(True, linestyle='--', alpha=0.7)
plt.tight_layout()
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close()
buf.seek(0)
return buf
def plot_pie(self, labels, values, title):
plt.figure(figsize=(6,6))
plt.pie(values, labels=labels, autopct='%1.1f%%', startangle=140, colors=plt.cm.Paired.colors)
plt.title(title)
plt.tight_layout()
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close()
buf.seek(0)
return buf
@app_commands.command(name="stats_bot", description="Affiche toutes les statistiques d'utilisation du bot.")
async def stats_bot(self, interaction: discord.Interaction):
# get_stats_detailed() doit retourner un dict avec les clés suivantes (exemple) :
# {
# "total_commandes": int,
# "top_commandes": [(nom, nb), ...],
# "top_utilisateurs": [(user_id, nb), ...],
# "evolution_commandes": [(date, nb), ...], # list de tuples date (datetime), nb commandes
# "repartition_statuts": {statut: nb, ...},
# "commandes_par_jour": {jour_semaine: nb, ...} # ex: "Lundi": 123
# }
stats = get_stats_detailed()
embed = discord.Embed(
title="📊 Statistiques Complètes du Bot",
description=f"Total commandes utilisées : **{stats['total_commandes']}**",
color=discord.Color.blue()
)
# Top commandes en texte
if stats["top_commandes"]:
top_cmds_text = "\n".join([f"• `{nom}` : **{nb}** fois" for nom, nb in stats["top_commandes"][:5]])
else:
top_cmds_text = "Aucune commande utilisée."
embed.add_field(name="🏆 Top 5 des commandes", value=top_cmds_text, inline=False)
# Top utilisateurs en texte
if stats["top_utilisateurs"]:
top_users_text = "\n".join(
[f"• <@{uid}> : **{nb}** commandes" for uid, nb in stats["top_utilisateurs"][:5]]
)
else:
top_users_text = "Aucun utilisateur enregistré."
embed.add_field(name="👤 Top 5 utilisateurs", value=top_users_text, inline=False)
# Génération des graphiques
files = []
# Graphique 1 : Top commandes (barh)
if stats["top_commandes"]:
noms_cmds = [x[0] for x in stats["top_commandes"][:5]]
vals_cmds = [x[1] for x in stats["top_commandes"][:5]]
buf1 = self.plot_barh(noms_cmds, vals_cmds, "Top 5 Commandes les plus utilisées", "Nombre d'utilisations")
files.append(discord.File(fp=buf1, filename="top_commandes.png"))
embed.set_image(url="attachment://top_commandes.png")
# Graphique 2 : Top utilisateurs (barh)
if stats["top_utilisateurs"]:
noms_users = [f"User {uid}" for uid, _ in stats["top_utilisateurs"][:5]] # On peut remplacer par mention si on fetch
vals_users = [nb for _, nb in stats["top_utilisateurs"][:5]]
buf2 = self.plot_barh(noms_users, vals_users, "Top 5 Utilisateurs actifs", "Nombre de commandes", color='mediumseagreen')
files.append(discord.File(fp=buf2, filename="top_utilisateurs.png"))
# Graphique 3 : Évolution commandes dans le temps (line)
if stats.get("evolution_commandes"):
dates = [d for d, _ in stats["evolution_commandes"]]
vals = [v for _, v in stats["evolution_commandes"]]
# Convertir dates datetime en string format court
dates_str = [d.strftime("%d/%m") for d in dates]
buf3 = self.plot_line(dates_str, vals, "Évolution des commandes dans le temps", "Date", "Nombre de commandes")
files.append(discord.File(fp=buf3, filename="evolution_commandes.png"))
# Graphique 4 : Répartition statuts (pie)
if stats.get("repartition_statuts"):
labels = list(stats["repartition_statuts"].keys())
values = list(stats["repartition_statuts"].values())
buf4 = self.plot_pie(labels, values, "Répartition des statuts des tâches")
files.append(discord.File(fp=buf4, filename="repartition_statuts.png"))
# Graphique 5 : Commandes par jour de la semaine (bar)
if stats.get("commandes_par_jour"):
jours = list(stats["commandes_par_jour"].keys())
valeurs = list(stats["commandes_par_jour"].values())
plt.figure(figsize=(8,4))
plt.bar(jours, valeurs, color='salmon')
plt.title("Commandes par jour de la semaine")
plt.xlabel("Jour")
plt.ylabel("Nombre de commandes")
plt.tight_layout()
buf5 = io.BytesIO()
plt.savefig(buf5, format='png')
plt.close()
buf5.seek(0)
files.append(discord.File(fp=buf5, filename="commandes_par_jour.png"))
# Envoi embed + fichiers graphiques
if files:
await interaction.response.send_message(embed=embed, files=files)
else:
await interaction.response.send_message(embed=embed)
async def setup(bot: commands.Bot):
await bot.add_cog(StatsCommandes(bot))