Kuby/commandes/staff_ratings.py

137 lines
No EOL
5.6 KiB
Python

import disnake
from disnake.ext import commands
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import io
import numpy as np
from datetime import datetime, timedelta
from collections import defaultdict
from commandes.ticket.data.storage import get_storage
from commandes.ticket.data.models import TicketStatus
from commandes.ticket.staff_analytics import StaffAnalytics
class StaffRatings(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.slash_command(name="staff-ratings", description="Affiche les évaluations du staff")
async def staff_ratings(self, interaction: disnake.ApplicationCommandInteraction,
team: str = commands.Param(None, description="Filtrer par équipe (optionnel)")):
"""Commande pour afficher les évaluations du staff"""
await interaction.response.defer(ephemeral=False)
try:
storage = get_storage()
analytics = StaffAnalytics(self.bot)
# Get staff list
staff_list = await analytics.get_staff_list(interaction.guild_id)
if not staff_list:
await interaction.followup.send("Aucun membre du staff n'a été trouvé.", ephemeral=True)
return
# Filter by team if specified
if team:
# This would require a team mapping in the staff data
# For now, we'll show all staff
pass
# Create the rating chart using matplotlib
chart_buffer = self.create_staff_rating_chart_matplotlib(staff_list)
# Create embed
embed = disnake.Embed(
title="📊 Évaluations du Staff",
description="Performance globale du staff",
color=disnake.Color.blue(),
timestamp=datetime.now()
)
# Add stats
total_ratings = sum(s['total_ratings'] for s in staff_list)
avg_rating = sum(s['average_rating'] for s in staff_list if s['total_ratings'] > 0) / len([s for s in staff_list if s['total_ratings'] > 0]) if any(s['total_ratings'] > 0 for s in staff_list) else 0
embed.add_field(
name="📈 Statistiques",
value=f"**Membres du staff:** {len(staff_list)}\n"
f"**Évaluations totales:** {total_ratings}\n"
f"**Note moyenne globale:** {avg_rating:.1f}",
inline=False
)
# Send chart
file = disnake.File(chart_buffer, filename="staff_ratings.png")
await interaction.followup.send(embed=embed, file=file)
except Exception as e:
print(f"Error in staff_ratings command: {e}")
await interaction.followup.send("Une erreur est survenue lors de la génération des statistiques.", ephemeral=True)
def create_staff_rating_chart_matplotlib(self, staff_list):
"""Create staff rating chart using matplotlib"""
# Filter staff with ratings
rated_staff = [s for s in staff_list if s['total_ratings'] > 0]
if not rated_staff:
# Return empty chart
fig, ax = plt.subplots(figsize=(10, 6), facecolor='#2F3136')
ax.set_facecolor('#2F3136')
ax.text(0.5, 0.5, 'Aucune évaluation disponible', ha='center', va='center',
transform=ax.transAxes, color='white')
ax.set_title('Évaluations des Membres du Staff', color='white')
buf = io.BytesIO()
plt.savefig(buf, format='png', bbox_inches='tight', facecolor='#2F3136')
buf.seek(0)
plt.close()
return buf
# Sort by average rating
rated_staff.sort(key=lambda x: x['average_rating'], reverse=True)
# Prepare data
names = [s['name'][:15] + '...' if len(s['name']) > 15 else s['name'] for s in rated_staff]
ratings = [s['average_rating'] for s in rated_staff]
counts = [s['total_ratings'] for s in rated_staff]
# Create figure
fig, ax = plt.subplots(figsize=(12, 8), facecolor='#2F3136')
fig.patch.set_facecolor('#2F3136')
ax.set_facecolor('#2F3136')
# Create bars
bars = ax.bar(range(len(ratings)), ratings, color=['#57F287' if r >= 4.5 else '#FEE75C' if r >= 3.5 else '#FAA61A' if r >= 2.5 else '#ED4245' for r in ratings])
# Customize
ax.set_xticks(range(len(names)))
ax.set_xticklabels(names, rotation=45, ha='right', color='white')
ax.set_ylabel('Note moyenne', color='white')
ax.set_title('Évaluations des Membres du Staff', color='white', fontsize=16)
ax.tick_params(colors='white')
ax.grid(True, alpha=0.3, color='gray')
# Add value labels on bars
for i, (bar, rating, count) in enumerate(zip(bars, ratings, counts)):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.05,
f'{rating:.1f}\n({count})', ha='center', va='bottom', color='white', fontsize=8)
# Set y-axis limits
ax.set_ylim(0, 5.2)
# Adjust layout
plt.tight_layout()
# Save to buffer
buf = io.BytesIO()
plt.savefig(buf, format='png', bbox_inches='tight', facecolor='#2F3136')
buf.seek(0)
plt.close()
return buf
def setup(bot):
bot.add_cog(StaffRatings(bot))