mirror of
				https://gitlab.com/ddorn/tfjm-discord-bot.git
				synced 2025-11-04 03:42:12 +01:00 
			
		
		
		
	✨ Nice help !
This commit is contained in:
		@@ -4,3 +4,4 @@ of the TFJM² bot.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from .tirages import TirageCog
 | 
			
		||||
from .help import TfjmHelpCommand
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										86
									
								
								src/cogs/help.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/cogs/help.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
from discord.ext.commands import MinimalHelpCommand
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# This is mostly a copy paste of MinimalHelpCommand
 | 
			
		||||
# With updated defaults and styles to match what I like
 | 
			
		||||
class TfjmHelpCommand(MinimalHelpCommand):
 | 
			
		||||
    def __init__(self, **options):
 | 
			
		||||
        options.setdefault("no_category", "Autres")
 | 
			
		||||
        super().__init__(**options)
 | 
			
		||||
 | 
			
		||||
    def get_opening_note(self):
 | 
			
		||||
        """Text at the beginning of the help command."""
 | 
			
		||||
 | 
			
		||||
        command_name = self.invoked_with
 | 
			
		||||
        return (
 | 
			
		||||
            "`{0}{1} [commande]` permet d'avoir plus d'info sur une commande.\n"
 | 
			
		||||
            "Vous pouvez aussi utiliser `{0}{1} [catégorie]` "
 | 
			
		||||
            "pour plus d'infos sur une catégorie.".format(
 | 
			
		||||
                self.clean_prefix, command_name
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def get_command_signature(self, command):
 | 
			
		||||
        return "`%s`" % super().get_command_signature(command)
 | 
			
		||||
 | 
			
		||||
    def add_bot_commands_formatting(self, commands, heading):
 | 
			
		||||
        """Adds the minified bot heading with commands to the output.
 | 
			
		||||
 | 
			
		||||
        The formatting should be added to the :attr:`paginator`.
 | 
			
		||||
 | 
			
		||||
        The default implementation is a bold underline heading followed
 | 
			
		||||
        by commands separated by an EN SPACE (U+2002) in the next line.
 | 
			
		||||
 | 
			
		||||
        Parameters
 | 
			
		||||
        -----------
 | 
			
		||||
        commands: Sequence[:class:`Command`]
 | 
			
		||||
            A list of commands that belong to the heading.
 | 
			
		||||
        heading: :class:`str`
 | 
			
		||||
            The heading to add to the line.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        if commands:
 | 
			
		||||
            # U+2002 Middle Dot
 | 
			
		||||
            self.paginator.add_line("__**%s**__" % heading)
 | 
			
		||||
            for c in commands:
 | 
			
		||||
                self.add_subcommand_formatting(c)
 | 
			
		||||
            self.paginator.add_line()
 | 
			
		||||
 | 
			
		||||
    def add_subcommand_formatting(self, command):
 | 
			
		||||
        """Adds formatting information on a subcommand.
 | 
			
		||||
 | 
			
		||||
        The formatting should be added to the :attr:`paginator`.
 | 
			
		||||
 | 
			
		||||
        The default implementation is the prefix and the :attr:`Command.qualified_name`
 | 
			
		||||
        optionally followed by an En dash and the command's :attr:`Command.short_doc`.
 | 
			
		||||
 | 
			
		||||
        Parameters
 | 
			
		||||
        -----------
 | 
			
		||||
        command: :class:`Command`
 | 
			
		||||
            The command to show information of.
 | 
			
		||||
        """
 | 
			
		||||
        fmt = "`{0}{1}` \N{EN DASH} {2}" if command.short_doc else "`{0}{1}`"
 | 
			
		||||
        self.paginator.add_line(
 | 
			
		||||
            fmt.format(self.clean_prefix, command.qualified_name, command.short_doc)
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def add_aliases_formatting(self, aliases):
 | 
			
		||||
        """Adds the formatting information on a command's aliases.
 | 
			
		||||
 | 
			
		||||
        The formatting should be added to the :attr:`paginator`.
 | 
			
		||||
 | 
			
		||||
        The default implementation is the :attr:`aliases_heading` bolded
 | 
			
		||||
        followed by a comma separated list of aliases.
 | 
			
		||||
 | 
			
		||||
        This is not called if there are no aliases to format.
 | 
			
		||||
 | 
			
		||||
        Parameters
 | 
			
		||||
        -----------
 | 
			
		||||
        aliases: Sequence[:class:`str`]
 | 
			
		||||
            A list of aliases to format.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        aliases_str = ", ".join("`%s`" % a for a in aliases)
 | 
			
		||||
        self.paginator.add_line(
 | 
			
		||||
            "**%s** %s" % (self.aliases_heading, aliases_str), empty=True
 | 
			
		||||
        )
 | 
			
		||||
@@ -530,11 +530,78 @@ class TirageCog(Cog, name="Tirages"):
 | 
			
		||||
 | 
			
		||||
        self.tirages = tirages
 | 
			
		||||
 | 
			
		||||
    # ---------- Commandes hors du groupe draw ----------- #
 | 
			
		||||
 | 
			
		||||
    @commands.command(
 | 
			
		||||
        name="dice", aliases=["de", "dé", "roll"], usage="n",
 | 
			
		||||
    )
 | 
			
		||||
    async def dice(self, ctx: Context, n: int):
 | 
			
		||||
        """Lance un dé à `n` faces."""
 | 
			
		||||
        channel = ctx.channel.id
 | 
			
		||||
        if channel in self.tirages:
 | 
			
		||||
            await self.tirages[channel].dice(ctx, n)
 | 
			
		||||
        else:
 | 
			
		||||
            if n < 1:
 | 
			
		||||
                raise TfjmError(f"Je ne peux pas lancer un dé à {n} faces, désolé.")
 | 
			
		||||
 | 
			
		||||
            dice = random.randint(1, n)
 | 
			
		||||
            await ctx.send(
 | 
			
		||||
                f"Le dé à {n} face{'s' * (n > 1)} s'est arrêté sur... **{dice}**"
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    @commands.command(
 | 
			
		||||
        name="random-problem",
 | 
			
		||||
        aliases=["rp", "problème-aléatoire", "probleme-aleatoire", "pa"],
 | 
			
		||||
    )
 | 
			
		||||
    async def random_problem(self, ctx: Context):
 | 
			
		||||
        """Choisit un problème parmi ceux de cette année."""
 | 
			
		||||
 | 
			
		||||
        channel = ctx.channel.id
 | 
			
		||||
        if channel in self.tirages:
 | 
			
		||||
            await self.tirages[channel].choose_problem(ctx)
 | 
			
		||||
        else:
 | 
			
		||||
            problem = random.choice(PROBLEMS)
 | 
			
		||||
            await ctx.send(f"Le problème tiré est... **{problem}**")
 | 
			
		||||
 | 
			
		||||
    @commands.command(
 | 
			
		||||
        name="oui", aliases=["accept", "yes", "o", "accepte", "ouiiiiiii"],
 | 
			
		||||
    )
 | 
			
		||||
    async def accept_cmd(self, ctx):
 | 
			
		||||
        """
 | 
			
		||||
        Accepte le problème qui vient d'être tiré.
 | 
			
		||||
 | 
			
		||||
        Sans effet si il n'y a pas de tirage en cours.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        channel = ctx.channel.id
 | 
			
		||||
        if channel in self.tirages:
 | 
			
		||||
            await self.tirages[channel].accept(ctx, True)
 | 
			
		||||
        else:
 | 
			
		||||
            await ctx.send(f"{ctx.author.mention} approuve avec vigeur !")
 | 
			
		||||
 | 
			
		||||
    @commands.command(
 | 
			
		||||
        name="non", aliases=["refuse", "no", "n", "nope", "jaaamais"],
 | 
			
		||||
    )
 | 
			
		||||
    async def refuse_cmd(self, ctx):
 | 
			
		||||
        """
 | 
			
		||||
        Refuse le problème qui vient d'être tiré.
 | 
			
		||||
 | 
			
		||||
        Sans effet si il n'y a pas de tirage en cours.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        channel = ctx.channel.id
 | 
			
		||||
        if channel in self.tirages:
 | 
			
		||||
            await self.tirages[channel].accept(ctx, False)
 | 
			
		||||
        else:
 | 
			
		||||
            await ctx.send(f"{ctx.author.mention} nie tout en block !")
 | 
			
		||||
 | 
			
		||||
    # ---------- Commandes du groupe draw ----------- #
 | 
			
		||||
 | 
			
		||||
    @group(
 | 
			
		||||
        name="draw", aliases=["d", "tirage"],
 | 
			
		||||
    )
 | 
			
		||||
    async def draw_group(self, ctx: Context) -> None:
 | 
			
		||||
        """Commandes pour les tirages."""
 | 
			
		||||
        """Groupe de commandes pour les tirages."""
 | 
			
		||||
 | 
			
		||||
    @draw_group.command(
 | 
			
		||||
        name="start", usage="équipe1 équipe2 équipe3 (équipe4)",
 | 
			
		||||
@@ -596,6 +663,13 @@ class TirageCog(Cog, name="Tirages"):
 | 
			
		||||
    )
 | 
			
		||||
    @commands.has_role(ORGA_ROLE)
 | 
			
		||||
    async def abort_draw_cmd(self, ctx):
 | 
			
		||||
        """
 | 
			
		||||
        Annule le tirage en cours.
 | 
			
		||||
 | 
			
		||||
        Le tirage ne pourra pas être continué. Si besoin,
 | 
			
		||||
        n'hésitez pas à appeller un @dev : il peut réparer
 | 
			
		||||
        plus de choses qu'on imagine (mais moins qu'on voudrait).
 | 
			
		||||
        """
 | 
			
		||||
        channel_id = ctx.channel.id
 | 
			
		||||
        if channel_id in self.tirages:
 | 
			
		||||
            await self.tirages[channel_id].end(ctx)
 | 
			
		||||
@@ -604,6 +678,7 @@ class TirageCog(Cog, name="Tirages"):
 | 
			
		||||
    @draw_group.command(name="skip", aliases=["s"])
 | 
			
		||||
    @commands.has_role(CNO_ROLE)
 | 
			
		||||
    async def draw_skip(self, ctx, *teams):
 | 
			
		||||
        """Skip certaines phases du tirage."""
 | 
			
		||||
        channel = ctx.channel.id
 | 
			
		||||
        self.tirages[channel] = tirage = Tirage(ctx, channel, teams)
 | 
			
		||||
 | 
			
		||||
@@ -620,7 +695,15 @@ class TirageCog(Cog, name="Tirages"):
 | 
			
		||||
        await tirage.update_phase(ctx)
 | 
			
		||||
 | 
			
		||||
    @draw_group.command(name="show")
 | 
			
		||||
    async def show_cmd(self, ctx: Context, arg: str):
 | 
			
		||||
    async def show_cmd(self, ctx: Context, tirage_id: str):
 | 
			
		||||
        """
 | 
			
		||||
        Affiche le résumé d'un tirage
 | 
			
		||||
 | 
			
		||||
        Les ID de tirages valides sont visibles avec
 | 
			
		||||
        `!draw show all` et les details avec `!draw show 42`
 | 
			
		||||
         (si l'ID qui vous intéresse est 42).
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        if not TIRAGES_FILE.exists():
 | 
			
		||||
            await ctx.send("Il n'y a pas encore eu de tirages.")
 | 
			
		||||
            return
 | 
			
		||||
@@ -628,7 +711,7 @@ class TirageCog(Cog, name="Tirages"):
 | 
			
		||||
        with open(TIRAGES_FILE) as f:
 | 
			
		||||
            tirages = list(yaml.load_all(f))
 | 
			
		||||
 | 
			
		||||
        if arg.lower() == "all":
 | 
			
		||||
        if tirage_id.lower() == "all":
 | 
			
		||||
            msg = "\n".join(
 | 
			
		||||
                f"{i}: {', '.join(team.name for team in tirage.teams)}"
 | 
			
		||||
                for i, tirage in enumerate(tirages)
 | 
			
		||||
@@ -640,13 +723,13 @@ class TirageCog(Cog, name="Tirages"):
 | 
			
		||||
            await ctx.send(msg)
 | 
			
		||||
        else:
 | 
			
		||||
            try:
 | 
			
		||||
                n = int(arg)
 | 
			
		||||
                n = int(tirage_id)
 | 
			
		||||
                if n < 0:
 | 
			
		||||
                    raise ValueError
 | 
			
		||||
                tirage = tirages[n]
 | 
			
		||||
            except (ValueError, IndexError):
 | 
			
		||||
                await ctx.send(
 | 
			
		||||
                    f"`{arg}` n'est pas un identifiant valide. "
 | 
			
		||||
                    f"`{tirage_id}` n'est pas un identifiant valide. "
 | 
			
		||||
                    f"Les identifiants valides sont visibles avec `!show all`"
 | 
			
		||||
                )
 | 
			
		||||
            else:
 | 
			
		||||
 
 | 
			
		||||
@@ -9,10 +9,11 @@ import discord
 | 
			
		||||
from discord.ext import commands
 | 
			
		||||
from discord.ext.commands import Context
 | 
			
		||||
 | 
			
		||||
from src.cogs import TfjmHelpCommand
 | 
			
		||||
from src.constants import *
 | 
			
		||||
from src.errors import TfjmError, UnwantedCommand
 | 
			
		||||
 | 
			
		||||
bot = commands.Bot("!", help_command=commands.MinimalHelpCommand(no_category="Autres"))
 | 
			
		||||
bot = commands.Bot("!", help_command=TfjmHelpCommand())
 | 
			
		||||
 | 
			
		||||
# Variable globale qui contient les tirages.
 | 
			
		||||
tirages = {}
 | 
			
		||||
@@ -23,78 +24,34 @@ async def on_ready():
 | 
			
		||||
    print(f"{bot.user} has connected to Discord!")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@bot.command(
 | 
			
		||||
    name="dice",
 | 
			
		||||
    help="Lance un dé à `n` faces. ",
 | 
			
		||||
    aliases=["de", "dé", "roll"],
 | 
			
		||||
    usage="n",
 | 
			
		||||
)
 | 
			
		||||
async def dice(ctx: Context, n: int):
 | 
			
		||||
    channel = ctx.channel.id
 | 
			
		||||
    if channel in tirages:
 | 
			
		||||
        await tirages[channel].dice(ctx, n)
 | 
			
		||||
    else:
 | 
			
		||||
        if n < 1:
 | 
			
		||||
            raise TfjmError(f"Je ne peux pas lancer un dé à {n} faces, désolé.")
 | 
			
		||||
 | 
			
		||||
        dice = random.randint(1, n)
 | 
			
		||||
        await ctx.send(f"Le dé à {n} face{'s'*(n>1)} s'est arrêté sur... **{dice}**")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@bot.command(
 | 
			
		||||
    name="choose",
 | 
			
		||||
    help="Choisit une option parmi tous les arguments.",
 | 
			
		||||
    usage="choix1 choix2...",
 | 
			
		||||
    usage='choix1 choix2 "choix 3"...',
 | 
			
		||||
    aliases=["choice", "choix", "ch"],
 | 
			
		||||
)
 | 
			
		||||
async def choose(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}**")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@bot.command(
 | 
			
		||||
    name="random-problem",
 | 
			
		||||
    help="Choisit un problème parmi ceux de cette année.",
 | 
			
		||||
    aliases=["rp", "problème-aléatoire", "probleme-aleatoire", "pa"],
 | 
			
		||||
)
 | 
			
		||||
async def random_problem(ctx: Context):
 | 
			
		||||
    channel = ctx.channel.id
 | 
			
		||||
    if channel in tirages:
 | 
			
		||||
        await tirages[channel].choose_problem(ctx)
 | 
			
		||||
    else:
 | 
			
		||||
        problem = random.choice(PROBLEMS)
 | 
			
		||||
        await ctx.send(f"Le problème tiré est... **{problem}**")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@bot.command(
 | 
			
		||||
    name="accept",
 | 
			
		||||
    help="Accepte le problème qui vient d'être tiré. \n Ne fonctionne que lors d'un tirage.",
 | 
			
		||||
    aliases=["oui", "yes", "o", "accepte", "ouiiiiiii"],
 | 
			
		||||
)
 | 
			
		||||
async def accept_cmd(ctx):
 | 
			
		||||
    channel = ctx.channel.id
 | 
			
		||||
    if channel in tirages:
 | 
			
		||||
        await tirages[channel].accept(ctx, True)
 | 
			
		||||
    else:
 | 
			
		||||
        await ctx.send(f"{ctx.author.mention} approuve avec vigeur !")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@bot.command(
 | 
			
		||||
    name="refuse",
 | 
			
		||||
    help="Refuse le problème qui vient d'être tiré. \n Ne fonctionne que lors d'un tirage.",
 | 
			
		||||
    aliases=["non", "no", "n", "nope", "jaaamais"],
 | 
			
		||||
)
 | 
			
		||||
async def refuse_cmd(ctx):
 | 
			
		||||
    channel = ctx.channel.id
 | 
			
		||||
    if channel in tirages:
 | 
			
		||||
        await tirages[channel].accept(ctx, False)
 | 
			
		||||
    else:
 | 
			
		||||
        await ctx.send(f"{ctx.author.mention} nie tout en block !")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@bot.command(name="interrupt")
 | 
			
		||||
@commands.has_role(CNO_ROLE)
 | 
			
		||||
async def interrupt_cmd(ctx):
 | 
			
		||||
    """
 | 
			
		||||
    :warning: Ouvre une console là où un @dev m'a lancé. :warning:
 | 
			
		||||
 | 
			
		||||
    A utiliser en dernier recours:
 | 
			
		||||
     - le bot sera inactif pendant ce temps.
 | 
			
		||||
     - toutes les commandes seront executées à sa reprise.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    await ctx.send(
 | 
			
		||||
        "J'ai été arrêté et une console interactive a été ouverte là où je tourne. "
 | 
			
		||||
        "Toutes les commandes rateront tant que cette console est ouverte.\n"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user