2020-04-29 23:04:54 +00:00
|
|
|
import datetime
|
2020-04-28 23:36:42 +00:00
|
|
|
import itertools
|
2020-04-28 18:25:27 +00:00
|
|
|
import random
|
2020-04-28 23:36:42 +00:00
|
|
|
from operator import attrgetter
|
2020-04-29 14:27:40 +00:00
|
|
|
from time import time
|
2020-04-28 18:25:27 +00:00
|
|
|
|
2020-04-28 19:03:35 +00:00
|
|
|
import discord
|
2020-04-29 23:04:54 +00:00
|
|
|
from discord import Guild
|
2020-04-29 16:43:07 +00:00
|
|
|
from discord.ext import commands
|
2020-04-28 23:36:42 +00:00
|
|
|
from discord.ext.commands import (
|
|
|
|
Cog,
|
|
|
|
command,
|
|
|
|
Context,
|
|
|
|
Bot,
|
|
|
|
Command,
|
|
|
|
CommandError,
|
|
|
|
Group,
|
|
|
|
)
|
2020-04-28 18:25:27 +00:00
|
|
|
|
|
|
|
from src.constants import *
|
2020-04-29 23:04:54 +00:00
|
|
|
from src.constants import Emoji
|
2020-04-29 14:27:40 +00:00
|
|
|
from src.utils import has_role
|
2020-04-28 18:25:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
class MiscCog(Cog, name="Divers"):
|
2020-04-28 19:03:35 +00:00
|
|
|
def __init__(self, bot: Bot):
|
|
|
|
self.bot = bot
|
2020-04-28 23:36:42 +00:00
|
|
|
self.show_hidden = False
|
|
|
|
self.verify_checks = True
|
2020-04-28 19:03:35 +00:00
|
|
|
|
2020-04-28 18:25:27 +00:00
|
|
|
@command(
|
|
|
|
name="choose",
|
|
|
|
usage='choix1 choix2 "choix 3"...',
|
|
|
|
aliases=["choice", "choix", "ch"],
|
|
|
|
)
|
|
|
|
async def choose(self, ctx: Context, *args):
|
|
|
|
"""
|
|
|
|
Choisit une option parmi tous les arguments.
|
|
|
|
|
|
|
|
Pour les options qui contiennent une espace,
|
|
|
|
il suffit de mettre des guillemets (`"`) autour.
|
|
|
|
"""
|
|
|
|
|
|
|
|
choice = random.choice(args)
|
|
|
|
await ctx.send(f"J'ai choisi... **{choice}**")
|
|
|
|
|
|
|
|
@command(name="joke", aliases=["blague"], hidden=True)
|
|
|
|
async def joke_cmd(self, ctx):
|
2020-04-28 19:03:35 +00:00
|
|
|
await ctx.message.delete()
|
2020-04-29 23:04:54 +00:00
|
|
|
with open(File.JOKES) as f:
|
2020-04-28 18:25:27 +00:00
|
|
|
jokes = f.read().split("\n\n\n")
|
|
|
|
|
|
|
|
msg = random.choice(jokes)
|
2020-04-29 22:53:57 +00:00
|
|
|
message: discord.Message = await ctx.send(msg)
|
|
|
|
|
2020-04-29 23:04:54 +00:00
|
|
|
await message.add_reaction(Emoji.JOY)
|
|
|
|
await message.add_reaction(Emoji.SOB)
|
2020-04-28 18:25:27 +00:00
|
|
|
|
2020-04-29 14:27:40 +00:00
|
|
|
@command(name="status")
|
2020-04-29 16:43:07 +00:00
|
|
|
@commands.has_role(Role.CNO)
|
2020-04-29 14:27:40 +00:00
|
|
|
async def status_cmd(self, ctx: Context):
|
2020-04-29 16:43:07 +00:00
|
|
|
"""(cno) Affiche des informations à propos du serveur."""
|
2020-04-29 14:27:40 +00:00
|
|
|
guild: Guild = ctx.guild
|
|
|
|
embed = discord.Embed(title="État du serveur", color=EMBED_COLOR)
|
|
|
|
benevoles = [g for g in guild.members if has_role(g, Role.BENEVOLE)]
|
|
|
|
participants = [g for g in guild.members if has_role(g, Role.PARTICIPANT)]
|
|
|
|
no_role = [g for g in guild.members if g.top_role == guild.default_role]
|
|
|
|
uptime = datetime.timedelta(seconds=round(time() - START_TIME))
|
|
|
|
|
|
|
|
infos = {
|
|
|
|
"Bénévoles": len(benevoles),
|
|
|
|
"Participants": len(participants),
|
|
|
|
"Sans rôle": len(no_role),
|
|
|
|
"Total": len(guild.members),
|
|
|
|
"Bot uptime": uptime,
|
|
|
|
}
|
|
|
|
|
|
|
|
width = max(map(len, infos))
|
|
|
|
txt = "\n".join(
|
|
|
|
f"`{key.rjust(width)}`: {value}" for key, value in infos.items()
|
|
|
|
)
|
|
|
|
embed.add_field(name="Stats", value=txt)
|
|
|
|
|
|
|
|
await ctx.send(embed=embed)
|
|
|
|
|
2020-04-29 12:23:44 +00:00
|
|
|
# ----------------- Help ---------------- #
|
|
|
|
|
2020-04-29 11:42:49 +00:00
|
|
|
@command(name="help", aliases=["h"])
|
2020-04-29 12:23:44 +00:00
|
|
|
async def help_cmd(self, ctx: Context, *args):
|
2020-04-29 14:48:11 +00:00
|
|
|
"""Affiche des détails à propos d'une commande."""
|
2020-04-28 23:36:42 +00:00
|
|
|
|
2020-04-28 19:03:35 +00:00
|
|
|
if not args:
|
|
|
|
await self.send_bot_help(ctx)
|
|
|
|
else:
|
2020-04-28 23:57:14 +00:00
|
|
|
await self.send_command_help(ctx, args)
|
2020-04-28 19:03:35 +00:00
|
|
|
|
|
|
|
async def send_bot_help(self, ctx: Context):
|
2020-04-28 23:36:42 +00:00
|
|
|
embed = discord.Embed(
|
|
|
|
title="Aide pour le bot du TFJM²",
|
|
|
|
description="Ici est une liste des commandes utiles (ou pas) "
|
|
|
|
"durant le tournoi. Pour avoir plus de détails il "
|
|
|
|
"suffit d'écrire `!help COMMANDE` en remplacant `COMMANDE` "
|
|
|
|
"par le nom de la commande, par exemple `!help team channel`.",
|
|
|
|
color=0xFFA500,
|
|
|
|
)
|
|
|
|
|
|
|
|
commands = itertools.groupby(self.bot.walk_commands(), attrgetter("cog_name"))
|
|
|
|
|
|
|
|
for cat_name, cat in commands:
|
|
|
|
cat = {c.qualified_name: c for c in cat if not isinstance(c, Group)}
|
|
|
|
cat = await self.filter_commands(
|
|
|
|
ctx, list(cat.values()), sort=True, key=attrgetter("qualified_name")
|
|
|
|
)
|
|
|
|
|
|
|
|
if not cat:
|
|
|
|
continue
|
|
|
|
|
|
|
|
names = ["!" + c.qualified_name for c in cat]
|
|
|
|
width = max(map(len, names))
|
|
|
|
names = [name.rjust(width) for name in names]
|
|
|
|
short_help = [c.short_doc for c in cat]
|
|
|
|
|
|
|
|
lines = [f"`{n}` - {h}" for n, h in zip(names, short_help)]
|
|
|
|
|
|
|
|
if cat_name is None:
|
|
|
|
cat_name = "Autres"
|
|
|
|
|
|
|
|
c: Command
|
|
|
|
text = "\n".join(lines)
|
|
|
|
embed.add_field(name=cat_name, value=text, inline=False)
|
|
|
|
|
|
|
|
embed.set_footer(text="Suggestion ? Problème ? Envoie un message à @Diego")
|
|
|
|
|
|
|
|
await ctx.send(embed=embed)
|
|
|
|
|
2020-04-28 23:57:14 +00:00
|
|
|
async def send_command_help(self, ctx, args):
|
|
|
|
name = " ".join(args)
|
|
|
|
comm: Command = self.bot.get_command(name)
|
|
|
|
if comm is None:
|
2020-04-29 11:42:49 +00:00
|
|
|
return await ctx.send(
|
2020-04-28 23:57:14 +00:00
|
|
|
f"La commande `!{name}` n'existe pas. "
|
|
|
|
f"Utilise `!help` pour une liste des commandes."
|
|
|
|
)
|
2020-04-29 11:42:49 +00:00
|
|
|
elif isinstance(comm, Group):
|
|
|
|
return await self.send_group_help(ctx, comm)
|
2020-04-28 23:57:14 +00:00
|
|
|
|
|
|
|
embed = discord.Embed(
|
|
|
|
title=f"Aide pour la commande `!{comm.qualified_name}`",
|
|
|
|
description=comm.help,
|
|
|
|
color=0xFFA500,
|
|
|
|
)
|
|
|
|
|
|
|
|
if comm.aliases:
|
|
|
|
aliases = ", ".join(f"`{a}`" for a in comm.aliases)
|
|
|
|
embed.add_field(name="Alias", value=aliases, inline=True)
|
|
|
|
if comm.signature:
|
|
|
|
embed.add_field(
|
|
|
|
name="Usage", value=f"`!{comm.qualified_name} {comm.signature}`"
|
|
|
|
)
|
|
|
|
embed.set_footer(text="Suggestion ? Problème ? Envoie un message à @Diego")
|
|
|
|
|
|
|
|
await ctx.send(embed=embed)
|
|
|
|
|
2020-04-29 11:42:49 +00:00
|
|
|
async def send_group_help(self, ctx, group: Group):
|
|
|
|
embed = discord.Embed(
|
|
|
|
title=f"Aide pour le groupe de commandes `!{group.qualified_name}`",
|
|
|
|
description=group.help,
|
|
|
|
color=0xFFA500,
|
|
|
|
)
|
|
|
|
|
|
|
|
comms = await self.filter_commands(ctx, group.commands, sort=True)
|
|
|
|
if not comms:
|
|
|
|
embed.add_field(
|
|
|
|
name="Désolé", value="Il n'y a aucune commande pour toi ici."
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
names = ["!" + c.qualified_name for c in comms]
|
|
|
|
width = max(map(len, names))
|
2020-04-29 12:23:44 +00:00
|
|
|
just_names = [name.rjust(width) for name in names]
|
2020-04-29 11:42:49 +00:00
|
|
|
short_help = [c.short_doc for c in comms]
|
|
|
|
|
2020-04-29 12:23:44 +00:00
|
|
|
lines = [f"`{n}` - {h}" for n, h in zip(just_names, short_help)]
|
2020-04-29 11:42:49 +00:00
|
|
|
|
|
|
|
c: Command
|
|
|
|
text = "\n".join(lines)
|
|
|
|
embed.add_field(name="Sous-commandes", value=text, inline=False)
|
|
|
|
|
|
|
|
if group.aliases:
|
|
|
|
aliases = ", ".join(f"`{a}`" for a in group.aliases)
|
|
|
|
embed.add_field(name="Alias", value=aliases, inline=True)
|
|
|
|
if group.signature:
|
|
|
|
embed.add_field(
|
|
|
|
name="Usage", value=f"`!{group.qualified_name} {group.signature}`"
|
|
|
|
)
|
2020-04-29 12:23:44 +00:00
|
|
|
|
|
|
|
embed.add_field(
|
|
|
|
name="Plus d'aide",
|
|
|
|
value=f"Pour plus de détails sur une commande, "
|
|
|
|
f"il faut écrire `!help COMMANDE` en remplaçant "
|
|
|
|
f"COMMANDE par le nom de la commande qui t'intéresse.\n"
|
|
|
|
f"Exemple: `!help {random.choice(names)[1:]}`",
|
|
|
|
)
|
2020-04-29 11:42:49 +00:00
|
|
|
embed.set_footer(text="Suggestion ? Problème ? Envoie un message à @Diego")
|
|
|
|
|
|
|
|
await ctx.send(embed=embed)
|
|
|
|
|
2020-04-28 23:36:42 +00:00
|
|
|
def _name(self, command: Command):
|
|
|
|
return f"`!{command.qualified_name}`"
|
|
|
|
|
|
|
|
async def filter_commands(self, ctx, commands, *, sort=False, key=None):
|
|
|
|
"""|coro|
|
|
|
|
|
|
|
|
Returns a filtered list of commands and optionally sorts them.
|
|
|
|
|
|
|
|
This takes into account the :attr:`verify_checks` and :attr:`show_hidden`
|
|
|
|
attributes.
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
------------
|
|
|
|
commands: Iterable[:class:`Command`]
|
|
|
|
An iterable of commands that are getting filtered.
|
|
|
|
sort: :class:`bool`
|
|
|
|
Whether to sort the result.
|
|
|
|
key: Optional[Callable[:class:`Command`, Any]]
|
|
|
|
An optional key function to pass to :func:`py:sorted` that
|
|
|
|
takes a :class:`Command` as its sole parameter. If ``sort`` is
|
|
|
|
passed as ``True`` then this will default as the command name.
|
|
|
|
|
|
|
|
Returns
|
|
|
|
---------
|
|
|
|
List[:class:`Command`]
|
|
|
|
A list of commands that passed the filter.
|
|
|
|
"""
|
|
|
|
|
|
|
|
if sort and key is None:
|
2020-04-29 11:42:49 +00:00
|
|
|
key = lambda c: c.qualified_name
|
2020-04-28 23:36:42 +00:00
|
|
|
|
|
|
|
iterator = (
|
|
|
|
commands if self.show_hidden else filter(lambda c: not c.hidden, commands)
|
|
|
|
)
|
|
|
|
|
|
|
|
if not self.verify_checks:
|
|
|
|
# if we do not need to verify the checks then we can just
|
|
|
|
# run it straight through normally without using await.
|
|
|
|
return sorted(iterator, key=key) if sort else list(iterator)
|
|
|
|
|
|
|
|
# if we're here then we need to check every command if it can run
|
|
|
|
async def predicate(cmd):
|
|
|
|
try:
|
|
|
|
return await cmd.can_run(ctx)
|
|
|
|
except CommandError:
|
|
|
|
return False
|
|
|
|
|
|
|
|
ret = []
|
|
|
|
for cmd in iterator:
|
|
|
|
valid = await predicate(cmd)
|
|
|
|
if valid:
|
|
|
|
ret.append(cmd)
|
|
|
|
|
|
|
|
if sort:
|
|
|
|
ret.sort(key=key)
|
|
|
|
return ret
|
2020-04-28 19:03:35 +00:00
|
|
|
|
2020-04-28 18:25:27 +00:00
|
|
|
|
|
|
|
def setup(bot: Bot):
|
2020-04-28 19:03:35 +00:00
|
|
|
bot.add_cog(MiscCog(bot))
|