import html from datetime import datetime, timezone def _format_timestamp(dt: datetime) -> str: return dt.strftime("%d/%m/%Y %H:%M:%S") def _avatar_url(user) -> str: if user.avatar: return user.avatar.url return f"https://cdn.discordapp.com/embed/avatars/{user.discriminator % 5}.png" def generate_transcript(messages: list[dict], ticket_info: dict) -> str: """Génère un transcript HTML stylé. messages: [{"author": discord.User, "content": str, "timestamp": datetime, "attachments": list}] ticket_info: {"category": str, "user_id": int, "channel_id": int} """ now = datetime.now(timezone.utc) date_str = _format_timestamp(now) messages_html = "" for msg in messages: author = msg["author"] content = html.escape(msg["content"]) if msg["content"] else "" timestamp = _format_timestamp(msg["timestamp"]) avatar = _avatar_url(author) is_staff = msg.get("is_staff", False) staff_badge = 'STAFF' if is_staff else "" attachments_html = "" for att in msg.get("attachments", []): if att.url.lower().endswith((".png", ".jpg", ".jpeg", ".gif", ".webp")): attachments_html += ( f'
attachment
' ) else: attachments_html += ( f'
{html.escape(att.filename)}
' ) messages_html += f"""
{html.escape(str(author))} {html.escape(str(author))} {staff_badge} {timestamp}
{content}
{attachments_html}
""" if not messages_html: messages_html = '
Aucun message dans ce ticket.
' return f""" Transcript — Ticket #{ticket_info.get("channel_id", 0)}

Transcript — Ticket #{ticket_info.get("channel_id", 0)}

Catégorie: {html.escape(ticket_info.get("category", "N/A"))} Utilisateur: {ticket_info.get("user_id", "N/A")} Généré le: {date_str}
{messages_html}
""" def save_transcript(html_content: str, channel_id: int) -> str: from config import DATA_DIR transcripts_dir = DATA_DIR / "transcripts" transcripts_dir.mkdir(parents=True, exist_ok=True) path = transcripts_dir / f"ticket_{channel_id}_{int(datetime.now(timezone.utc).timestamp())}.html" with open(path, "w", encoding="utf-8") as f: f.write(html_content) return str(path)