emojis.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. """Emojis du serveur : Claude les écrit par leur nom (:hap:), Discord les reçoit sous forme de code."""
  2. from __future__ import annotations
  3. import re
  4. import discord
  5. # Code Discord d'un emoji personnalisé : <:nom:123…>, ou <a:nom:123…> s'il est animé.
  6. DISCORD_EMOJI = re.compile(r"<a?:(\w+):\d+>")
  7. # Nom d'emoji entre deux-points ; le code est repris tel quel, comme les blocs de code.
  8. _SHORT_EMOJI = re.compile(r"```.*?```|`[^`\n]*`|<a?:\w+:\d+>|:([A-Za-z0-9_]{2,32}):", re.S)
  9. SHORT_EMOJI = re.compile(r":[A-Za-z0-9_]{2,32}:")
  10. def usable_emojis(guild: discord.Guild | None) -> list[discord.Emoji]:
  11. """Emojis que le bot peut envoyer, triés par nom (la liste du prompt reste ainsi en cache).
  12. Animés compris : un bot n'a pas besoin de Nitro. Ceux réservés à des rôles que le bot
  13. n'a pas sont exclus."""
  14. if guild is None:
  15. return []
  16. roles = set(guild.me.roles) if guild.me else set()
  17. emojis = [e for e in guild.emojis if e.available and (not e.roles or roles.intersection(e.roles))]
  18. return sorted(emojis, key=lambda e: (e.name.lower(), e.id))
  19. def emoji_names(guild: discord.Guild | None) -> list[str]:
  20. return [e.name for e in usable_emojis(guild)]
  21. def short_emojis(text: str) -> str:
  22. """Remplace les codes des emojis (<:hap:123…>) par leur nom (:hap:), plus court à lire pour Claude."""
  23. return DISCORD_EMOJI.sub(r":\1:", text)
  24. def discord_emojis(text: str, guild: discord.Guild | None) -> str:
  25. """Remplace les noms d'emojis écrits par Claude (:hap:) par leur code Discord.
  26. Un nom inconnu reste tel quel ; la casse est tolérée (:Hap: pour :hap:)."""
  27. emojis = usable_emojis(guild)
  28. if not emojis:
  29. return text
  30. exact = {e.name: e for e in emojis}
  31. loose = {e.name.lower(): e for e in reversed(emojis)}
  32. def replace(match: re.Match) -> str:
  33. name = match.group(1)
  34. emoji = name and (exact.get(name) or loose.get(name.lower()))
  35. return str(emoji) if emoji else match.group(0)
  36. return _SHORT_EMOJI.sub(replace, text)