"""
Ticket Transcript Generator
===========================
Generates beautiful transcript files from ticket conversations.
"""
import json
import os
from datetime import datetime
from typing import Optional, List, Dict, Any
from discord import User, Member
from ..data.models import TicketData, TicketMessage
class TranscriptGenerator:
"""
Generates formatted transcripts from ticket data.
Features:
- Multiple output formats (TXT, JSON, HTML)
- Customizable templates
- Attachment handling
- Statistics inclusion
"""
TRANSCRIPT_DIR = "data/tickets/transcripts"
def __init__(self):
os.makedirs(self.TRANSCRIPT_DIR, exist_ok=True)
def generate_txt(
self,
ticket: TicketData,
messages: Optional[List[Dict[str, Any]]] = None,
include_stats: bool = True
) -> str:
"""Generate a plain text transcript"""
lines = []
# Header
lines.append("=" * 60)
lines.append("TRANSCRIPT DE TICKET")
lines.append("=" * 60)
lines.append("")
lines.append(f"ID du salon: {ticket.channel_id}")
lines.append(f"ID du serveur: {ticket.guild_id}")
lines.append(f"Créé par: {ticket.user_id}")
lines.append(f"Catégorie: {ticket.category_id}")
lines.append(f"Statut: {ticket.status.value}")
lines.append(f"Priorité: {ticket.priority.value}")
lines.append(f"Créé le: {ticket.created_at.strftime('%Y-%m-%d %H:%M:%S')}")
if ticket.closed_at:
lines.append(f"Fermé le: {ticket.closed_at.strftime('%Y-%m-%d %H:%M:%S')}")
if ticket.claimed_by:
lines.append(f"Réclamé par: {ticket.claimed_by}")
if ticket.reason:
lines.append(f"Raison: {ticket.reason}")
lines.append("")
lines.append("-" * 60)
lines.append("HISTORIQUE DES MESSAGES")
lines.append("-" * 60)
lines.append("")
# Messages
if messages:
for msg in messages:
timestamp = msg.get("timestamp", "")
if isinstance(timestamp, str):
try:
dt = datetime.fromisoformat(timestamp)
timestamp = dt.strftime("%Y-%m-%d %H:%M:%S")
except ValueError:
pass
author = msg.get("author_name", "Inconnu")
content = msg.get("content", "")
is_staff = msg.get("is_staff", False)
staff_marker = " [STAFF]" if is_staff else ""
lines.append(f"[{timestamp}] {author}{staff_marker}")
if content:
lines.append(f" {content}")
lines.append("")
# Statistics
if include_stats and ticket.duration_minutes:
lines.append("-" * 60)
lines.append("STATISTIQUES")
lines.append("-" * 60)
lines.append(f"Durée: {ticket.duration_minutes:.1f} minutes")
lines.append(f"Nombre de messages: {len(messages) if messages else len(ticket.messages)}")
if ticket.rating:
stars = "⭐" * ticket.rating
lines.append(f"Note: {stars} ({ticket.rating}/5)")
if ticket.feedback:
lines.append(f"Feedback: {ticket.feedback}")
lines.append("")
lines.append("=" * 60)
lines.append(f"Généré le: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
lines.append("=" * 60)
return "\n".join(lines)
def generate_json(
self,
ticket: TicketData,
messages: Optional[List[Dict[str, Any]]] = None,
include_stats: bool = True
) -> Dict[str, Any]:
"""Generate a JSON transcript"""
data = {
"version": "1.0",
"generated_at": datetime.now().isoformat(),
"ticket": {
"channel_id": ticket.channel_id,
"guild_id": ticket.guild_id,
"user_id": ticket.user_id,
"category_id": ticket.category_id,
"status": ticket.status.value,
"priority": ticket.priority.value,
"created_at": ticket.created_at.isoformat(),
"closed_at": ticket.closed_at.isoformat() if ticket.closed_at else None,
"claimed_by": ticket.claimed_by,
"reason": ticket.reason,
"rating": ticket.rating,
"feedback": ticket.feedback
},
"messages": messages or [m.to_dict() for m in ticket.messages]
}
if include_stats:
data["statistics"] = {
"duration_minutes": ticket.duration_minutes,
"message_count": len(messages) if messages else len(ticket.messages),
"duration_formatted": self._format_duration(ticket.duration_minutes) if ticket.duration_minutes else None
}
return data
def generate_html(
self,
ticket: TicketData,
messages: Optional[List[Dict[str, Any]]] = None,
include_stats: bool = True,
guild_name: str = "Serveur Discord"
) -> str:
"""Generate an HTML transcript with styling"""
# Get priority color
priority_colors = {
"low": "#2ecc71",
"normal": "#3498db",
"high": "#e67e22",
"urgent": "#e74c3c"
}
priority_color = priority_colors.get(ticket.priority.value, "#3498db")
html_messages = ""
if messages:
for msg in messages:
timestamp = msg.get("timestamp", "")
if isinstance(timestamp, str):
try:
dt = datetime.fromisoformat(timestamp)
timestamp = dt.strftime("%d/%m/%Y %H:%M:%S")
except ValueError:
pass
author = msg.get("author_name", "Inconnu")
content = msg.get("content", "").replace("\n", "
")
is_staff = msg.get("is_staff", False)
staff_class = " staff-message" if is_staff else ""
staff_badge = 'STAFF' if is_staff else ""
html_messages += f"""