mirror of
				https://gitlab.com/ddorn/tfjm-discord-bot.git
				synced 2025-11-04 08:22:12 +01:00 
			
		
		
		
	🚧 new tirages working without save
This commit is contained in:
		@@ -1,5 +1,8 @@
 | 
				
			|||||||
import asyncio
 | 
					import asyncio
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import traceback
 | 
				
			||||||
 | 
					from functools import wraps
 | 
				
			||||||
from pprint import pprint
 | 
					from pprint import pprint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from io import StringIO
 | 
					from io import StringIO
 | 
				
			||||||
@@ -57,12 +60,14 @@ class Team:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return "\n".join(f"`{n.rjust(width)}`: {v}" for n, v in info.items())
 | 
					        return "\n".join(f"`{n.rjust(width)}`: {v}" for n, v in info.items())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return f""" - Accepté: {self.accepted_problems[round]}
 | 
					
 | 
				
			||||||
 - Refusés: {", ".join(p[0] for p in self.rejected[round]) if self.rejected[round] else "aucun"}
 | 
					#
 | 
				
			||||||
 - Coefficient: {self.coeff(round)}
 | 
					#         return f""" - Accepté: {self.accepted_problems[round]}
 | 
				
			||||||
 - Ordre au tirage: {self.tirage_order[round]}
 | 
					#  - Refusés: {", ".join(p[0] for p in self.rejected[round]) if self.rejected[round] else "aucun"}
 | 
				
			||||||
 - Ordre de passage: {self.passage_order[round]}
 | 
					#  - Coefficient: {self.coeff(round)}
 | 
				
			||||||
"""
 | 
					#  - Ordre au tirage: {self.tirage_order[round]}
 | 
				
			||||||
 | 
					#  - Ordre de passage: {self.passage_order[round]}
 | 
				
			||||||
 | 
					# """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Poule:
 | 
					class Poule:
 | 
				
			||||||
@@ -110,6 +115,9 @@ class BaseTirage:
 | 
				
			|||||||
        ]
 | 
					        ]
 | 
				
			||||||
        return await self.event(Event(trigram, random.choice(available)))
 | 
					        return await self.event(Event(trigram, random.choice(available)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def accept(self, trigram, yes: bool):
 | 
				
			||||||
 | 
					        return await self.event(Event(trigram, yes))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def next(self, typ, team=None):
 | 
					    async def next(self, typ, team=None):
 | 
				
			||||||
        while True:
 | 
					        while True:
 | 
				
			||||||
            event = await self.queue.get()
 | 
					            event = await self.queue.get()
 | 
				
			||||||
@@ -148,6 +156,7 @@ class BaseTirage:
 | 
				
			|||||||
                # TODO: avoid KeyError
 | 
					                # TODO: avoid KeyError
 | 
				
			||||||
                if dices[event.team] is None:
 | 
					                if dices[event.team] is None:
 | 
				
			||||||
                    dices[event.team] = event.value
 | 
					                    dices[event.team] = event.value
 | 
				
			||||||
 | 
					                    await self.info_dice(event.team, event.value)
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    await self.warn_twice(int)
 | 
					                    await self.warn_twice(int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -173,6 +182,9 @@ class BaseTirage:
 | 
				
			|||||||
        return poules
 | 
					        return poules
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def draw_poule(self, poule):
 | 
					    async def draw_poule(self, poule):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await self.start_draw_poule(poule)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Trigrams in draw order
 | 
					        # Trigrams in draw order
 | 
				
			||||||
        trigrams = await self.draw_order(poule)
 | 
					        trigrams = await self.draw_order(poule)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -184,25 +196,27 @@ class BaseTirage:
 | 
				
			|||||||
            if team.accepted_problems[poule.rnd] is not None:
 | 
					            if team.accepted_problems[poule.rnd] is not None:
 | 
				
			||||||
                # The team already accepted a problem
 | 
					                # The team already accepted a problem
 | 
				
			||||||
                current += 1
 | 
					                current += 1
 | 
				
			||||||
 | 
					                current %= len(teams)
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Choose problem
 | 
					            # Choose problem
 | 
				
			||||||
            await self.start_select_pb(team)
 | 
					            await self.start_select_pb(team)
 | 
				
			||||||
            event = await self.next(str, team.name)
 | 
					            pevent = await self.next(str, team.name)
 | 
				
			||||||
            # TODO: Add check for already selected / taken by someone else
 | 
					            # TODO: Add check for already selected / taken by someone else
 | 
				
			||||||
            # This is not a bug for now, since it cannot happen yet
 | 
					            # This is not a bug for now, since it cannot happen yet
 | 
				
			||||||
            await self.info_draw_pb(team, event.value, rnd)
 | 
					            await self.info_draw_pb(team, pevent.value, poule.rnd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Accept it
 | 
					            # Accept it
 | 
				
			||||||
            accept = await self.next(bool, team.name)
 | 
					            accept = await self.next(bool, team.name)
 | 
				
			||||||
            if accept:
 | 
					            if accept.value:
 | 
				
			||||||
                team.accepted_problems[poule.rnd] = event.value
 | 
					                team.accepted_problems[poule.rnd] = pevent.value
 | 
				
			||||||
                await self.info_accepted(team, event.value)
 | 
					                await self.info_accepted(team, pevent.value)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                await self.info_rejected(team, event.value, rnd=poule.rnd)
 | 
					                await self.info_rejected(team, pevent.value, rnd=poule.rnd)
 | 
				
			||||||
                team.rejected[poule.rnd].add(event.value)
 | 
					                team.rejected[poule.rnd].add(pevent.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            current += 1
 | 
					            current += 1
 | 
				
			||||||
 | 
					            current %= len(teams)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await self.annonce_poule(poule)
 | 
					        await self.annonce_poule(poule)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -212,7 +226,7 @@ class BaseTirage:
 | 
				
			|||||||
        teams = self.poules[poule]
 | 
					        teams = self.poules[poule]
 | 
				
			||||||
        dices = await self.get_dices(teams)
 | 
					        dices = await self.get_dices(teams)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        order = sorted(self.teams, key=lambda t: dices[t], reverse=True)
 | 
					        order = sorted(teams, key=lambda t: dices[t], reverse=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        await self.annonce_draw_order(order)
 | 
					        await self.annonce_draw_order(order)
 | 
				
			||||||
        return order
 | 
					        return order
 | 
				
			||||||
@@ -232,6 +246,9 @@ class BaseTirage:
 | 
				
			|||||||
    async def start_make_poule(self, rnd):
 | 
					    async def start_make_poule(self, rnd):
 | 
				
			||||||
        """Called when it starts drawing the poules for round `rnd`"""
 | 
					        """Called when it starts drawing the poules for round `rnd`"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def start_draw_poule(self, poule):
 | 
				
			||||||
 | 
					        """Called when we start a poule."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def start_draw_order(self, poule):
 | 
					    async def start_draw_order(self, poule):
 | 
				
			||||||
        """Called when we start to draw the order."""
 | 
					        """Called when we start to draw the order."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -253,6 +270,9 @@ class BaseTirage:
 | 
				
			|||||||
    async def info_finish(self):
 | 
					    async def info_finish(self):
 | 
				
			||||||
        """Called when the tirage has ended."""
 | 
					        """Called when the tirage has ended."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def info_dice(self, team, dice):
 | 
				
			||||||
 | 
					        """Called on a dice roll."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def info_draw_pb(self, team, pb, rnd):
 | 
					    async def info_draw_pb(self, team, pb, rnd):
 | 
				
			||||||
        """Called when a team draws a problem."""
 | 
					        """Called when a team draws a problem."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -262,3 +282,7 @@ class BaseTirage:
 | 
				
			|||||||
    async def info_rejected(self, team, pb, rnd):
 | 
					    async def info_rejected(self, team, pb, rnd):
 | 
				
			||||||
        """Called when a team rejects a problem,
 | 
					        """Called when a team rejects a problem,
 | 
				
			||||||
        before it is added to the rejected set."""
 | 
					        before it is added to the rejected set."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def setup(_):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ from src.constants import *
 | 
				
			|||||||
from src.core import CustomBot
 | 
					from src.core import CustomBot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COGS_SHORTCUTS = {
 | 
					COGS_SHORTCUTS = {
 | 
				
			||||||
 | 
					    "bt": "src.base_tirage",
 | 
				
			||||||
    "c": "src.constants",
 | 
					    "c": "src.constants",
 | 
				
			||||||
    "d": "tirages",
 | 
					    "d": "tirages",
 | 
				
			||||||
    "e": "errors",
 | 
					    "e": "errors",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import asyncio
 | 
					import asyncio
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import traceback
 | 
				
			||||||
from collections import defaultdict, namedtuple
 | 
					from collections import defaultdict, namedtuple
 | 
				
			||||||
from dataclasses import dataclass
 | 
					from dataclasses import dataclass
 | 
				
			||||||
from functools import wraps
 | 
					from functools import wraps
 | 
				
			||||||
@@ -15,7 +17,7 @@ from discord.ext import commands
 | 
				
			|||||||
from discord.ext.commands import group, Cog, Context
 | 
					from discord.ext.commands import group, Cog, Context
 | 
				
			||||||
from discord.utils import get
 | 
					from discord.utils import get
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from src.base_tirage import BaseTirage
 | 
					from src.base_tirage import BaseTirage, Event
 | 
				
			||||||
from src.constants import *
 | 
					from src.constants import *
 | 
				
			||||||
from src.core import CustomBot
 | 
					from src.core import CustomBot
 | 
				
			||||||
from src.errors import TfjmError, UnwantedCommand
 | 
					from src.errors import TfjmError, UnwantedCommand
 | 
				
			||||||
@@ -34,7 +36,7 @@ Record = namedtuple("Record", ["name", "pb", "penalite"])
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def delete_and_pm(f):
 | 
					def delete_and_pm(f):
 | 
				
			||||||
    @wraps(f)
 | 
					    @wraps(f)
 | 
				
			||||||
    def wrapper(self, *args, **kwargs):
 | 
					    async def wrapper(self, *args, **kwargs):
 | 
				
			||||||
        await self.ctx.message.delete()
 | 
					        await self.ctx.message.delete()
 | 
				
			||||||
        await self.ctx.author.send(
 | 
					        await self.ctx.author.send(
 | 
				
			||||||
            "J'ai supprimé ton message:\n> "
 | 
					            "J'ai supprimé ton message:\n> "
 | 
				
			||||||
@@ -47,6 +49,8 @@ def delete_and_pm(f):
 | 
				
			|||||||
        if msg:
 | 
					        if msg:
 | 
				
			||||||
            await self.ctx.author.send(f"Raison: {msg}")
 | 
					            await self.ctx.author.send(f"Raison: {msg}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return wrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def send_all(f):
 | 
					def send_all(f):
 | 
				
			||||||
    @wraps(f)
 | 
					    @wraps(f)
 | 
				
			||||||
@@ -57,12 +61,33 @@ def send_all(f):
 | 
				
			|||||||
    return wrapper
 | 
					    return wrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def safe(f):
 | 
				
			||||||
 | 
					    @wraps(f)
 | 
				
			||||||
 | 
					    async def wrapper(*args, **kwargs):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            return await f(*args, **kwargs)
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            traceback.print_tb(e.__traceback__, file=sys.stderr)
 | 
				
			||||||
 | 
					            print(e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return wrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DiscordTirage(BaseTirage):
 | 
					class DiscordTirage(BaseTirage):
 | 
				
			||||||
    def __init__(self, ctx, *teams, fmt):
 | 
					    def __init__(self, ctx, *teams, fmt):
 | 
				
			||||||
        super(DiscordTirage, self).__init__(*teams, fmt=fmt)
 | 
					        super(DiscordTirage, self).__init__(*teams, fmt=fmt)
 | 
				
			||||||
        self.ctx = ctx
 | 
					        self.ctx = ctx
 | 
				
			||||||
        self.captain_mention = get(ctx.guild.roles, name=Role.CAPTAIN).mention
 | 
					        self.captain_mention = get(ctx.guild.roles, name=Role.CAPTAIN).mention
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def team_for(self, author):
 | 
				
			||||||
 | 
					        for team in self.teams:
 | 
				
			||||||
 | 
					            if get(author.roles, name=team):
 | 
				
			||||||
 | 
					                return team
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def mention(self, trigram):
 | 
				
			||||||
 | 
					        return get(self.ctx.guild.roles, name=trigram).mention
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def records(self, teams, rnd):
 | 
					    def records(self, teams, rnd):
 | 
				
			||||||
        """Get the strings needed for show the tirage in a list of Records"""
 | 
					        """Get the strings needed for show the tirage in a list of Records"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,6 +100,36 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
            for team in teams
 | 
					            for team in teams
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def dice(self, ctx, n):
 | 
				
			||||||
 | 
					        self.ctx = ctx
 | 
				
			||||||
 | 
					        trigram = self.team_for(ctx.author)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if trigram is None:
 | 
				
			||||||
 | 
					            await self.warn_wrong_team(None, None)
 | 
				
			||||||
 | 
					        elif n == 100:
 | 
				
			||||||
 | 
					            await super().dice(trigram)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            await self.warn_unwanted(int, int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def rproblem(self, ctx):
 | 
				
			||||||
 | 
					        self.ctx = ctx
 | 
				
			||||||
 | 
					        trigram = self.team_for(ctx.author)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if trigram is None:
 | 
				
			||||||
 | 
					            await self.warn_wrong_team(None, None)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            await super().rproblem(trigram)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def accept(self, ctx, yes):
 | 
				
			||||||
 | 
					        self.ctx = ctx
 | 
				
			||||||
 | 
					        trigram = self.team_for(ctx.author)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if trigram is None:
 | 
				
			||||||
 | 
					            await self.warn_wrong_team(None, None)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            await super().accept(trigram, yes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    @delete_and_pm
 | 
					    @delete_and_pm
 | 
				
			||||||
    async def warn_unwanted(self, wanted: Type, got: Type):
 | 
					    async def warn_unwanted(self, wanted: Type, got: Type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,6 +146,8 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
            else "Halte là ! Ce serait bien de tirer un problème d'abord... "
 | 
					            else "Halte là ! Ce serait bien de tirer un problème d'abord... "
 | 
				
			||||||
            "et peut-être qu'il te plaira :) ",
 | 
					            "et peut-être qu'il te plaira :) ",
 | 
				
			||||||
            (bool, int): "Il tirer un dé avec `!dice 100` d'abord.",
 | 
					            (bool, int): "Il tirer un dé avec `!dice 100` d'abord.",
 | 
				
			||||||
 | 
					            (int, int): "Il faut lancer un dé à 100 faces.",
 | 
				
			||||||
 | 
					            (str, str): f"'{got}' n'est pas un problème valide.",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        reason = texts.get((type(got), wanted))
 | 
					        reason = texts.get((type(got), wanted))
 | 
				
			||||||
@@ -100,10 +157,12 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
            reason = "Je sais pas, le code ne devrait pas venir ici..."
 | 
					            reason = "Je sais pas, le code ne devrait pas venir ici..."
 | 
				
			||||||
        return reason
 | 
					        return reason
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    @delete_and_pm
 | 
					    @delete_and_pm
 | 
				
			||||||
    async def warn_wrong_team(self, expected, got):
 | 
					    async def warn_wrong_team(self, expected, got):
 | 
				
			||||||
        return "ce n'était pas à ton tour."
 | 
					        return "ce n'était pas à ton tour."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    async def warn_colisions(self, collisions: List[str]):
 | 
					    async def warn_colisions(self, collisions: List[str]):
 | 
				
			||||||
        await self.ctx.send(
 | 
					        await self.ctx.send(
 | 
				
			||||||
            f"Les equipes {french_join(collisions)} ont fait le même résultat "
 | 
					            f"Les equipes {french_join(collisions)} ont fait le même résultat "
 | 
				
			||||||
@@ -111,6 +170,7 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
            "Le nouveau lancer effacera l'ancien."
 | 
					            "Le nouveau lancer effacera l'ancien."
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    @delete_and_pm
 | 
					    @delete_and_pm
 | 
				
			||||||
    async def warn_twice(self, typ: Type):
 | 
					    async def warn_twice(self, typ: Type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,6 +180,7 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
        print("Weird, DiscordTirage.warn_twice was called with", typ)
 | 
					        print("Weird, DiscordTirage.warn_twice was called with", typ)
 | 
				
			||||||
        return "Je sais pas, le code ne devrait pas venir ici..."
 | 
					        return "Je sais pas, le code ne devrait pas venir ici..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    @send_all
 | 
					    @send_all
 | 
				
			||||||
    async def start_make_poule(self, rnd):
 | 
					    async def start_make_poule(self, rnd):
 | 
				
			||||||
        if rnd == 0:
 | 
					        if rnd == 0:
 | 
				
			||||||
@@ -135,50 +196,82 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
                f"afin de déterminer les poules du second tour."
 | 
					                f"afin de déterminer les poules du second tour."
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def start_draw_order(self, poule):
 | 
					    @safe
 | 
				
			||||||
        print(poule)
 | 
					    @send_all
 | 
				
			||||||
 | 
					    async def start_draw_poule(self, poule):
 | 
				
			||||||
 | 
					        yield (
 | 
				
			||||||
 | 
					            f"Nous allons commencer le tirage pour la poule **{poule}** entre les "
 | 
				
			||||||
 | 
					            f"équipes {french_join('**%s**' %p for p in self.poules[poule])}. Les autres équipes peuvent "
 | 
				
			||||||
 | 
					            f"quitter le salon si elles le souhaitent et revenir quand elles seront mentionnées."
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
 | 
					    @send_all
 | 
				
			||||||
 | 
					    async def start_draw_order(self, poule):
 | 
				
			||||||
 | 
					        mentions = [self.mention(tri) for tri in self.poules[poule]]
 | 
				
			||||||
 | 
					        yield (
 | 
				
			||||||
 | 
					            f"Les capitaines de {french_join(mentions)}, vous pouvez à nouveau lancer un dé 100, "
 | 
				
			||||||
 | 
					            f"qui déterminera l'ordre de tirage des problèmes. Le plus grand lancer tirera en premier "
 | 
				
			||||||
 | 
					            f"les problèmes."
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    async def start_select_pb(self, team):
 | 
					    async def start_select_pb(self, team):
 | 
				
			||||||
        await self.ctx.send(f"C'est au tour de {team.mention} de choisir un problème.")
 | 
					        await self.ctx.send(f"C'est au tour de {team.mention} de choisir un problème.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
 | 
					    @send_all
 | 
				
			||||||
    async def annonce_poules(self, poules):
 | 
					    async def annonce_poules(self, poules):
 | 
				
			||||||
        print(poules)
 | 
					        first = "\n".join(
 | 
				
			||||||
 | 
					            f"{p}: {french_join(t)}" for p, t in poules.items() if p.rnd == 0
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        second = "\n".join(
 | 
				
			||||||
 | 
					            f"{p}: {french_join(t)}" for p, t in poules.items() if p.rnd == 1
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        yield (
 | 
				
			||||||
 | 
					            f"Les poules sont donc, pour le premier tour :"
 | 
				
			||||||
 | 
					            f"```{first}```\n"
 | 
				
			||||||
 | 
					            f"Et pour le second tour :"
 | 
				
			||||||
 | 
					            f"```{second}```"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    @send_all
 | 
					    @send_all
 | 
				
			||||||
    async def annonce_draw_order(self, order):
 | 
					    async def annonce_draw_order(self, order):
 | 
				
			||||||
        order_str = "\n ".join(f"{i}) {tri}" for i, tri in enumerate(order))
 | 
					        order_str = "\n".join(f"{i+1}) {tri}" for i, tri in enumerate(order))
 | 
				
			||||||
        yield "L'ordre de tirage des problèmes pour ce tour est donc: \n" + order_str
 | 
					        yield f"L'ordre de tirage des problèmes pour ce tour est donc: ```{order_str}```"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    async def annonce_poule(self, poule):
 | 
					    async def annonce_poule(self, poule):
 | 
				
			||||||
        teams = [self.teams[tri] for tri in self.poules[poule]]
 | 
					        teams = [self.teams[tri] for tri in self.poules[poule]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if len(teams) == 3:
 | 
					        if len(teams) == 3:
 | 
				
			||||||
            table = """```
 | 
					            table = """```
 | 
				
			||||||
            +-----+---------+---------+---------+
 | 
					+-----+---------+---------+---------+
 | 
				
			||||||
            |     | Phase 1 | Phase 2 | Phase 3 |
 | 
					|     | Phase 1 | Phase 2 | Phase 3 |
 | 
				
			||||||
            |     |   Pb {0.pb}  |   Pb {1.pb}  |   Pb {2.pb}  |
 | 
					|     |   Pb {0.pb}  |   Pb {1.pb}  |   Pb {2.pb}  |
 | 
				
			||||||
            +-----+---------+---------+---------+
 | 
					+-----+---------+---------+---------+
 | 
				
			||||||
            | {0.name} |   Déf   |   Rap   |   Opp   |
 | 
					| {0.name} |   Déf   |   Rap   |   Opp   |
 | 
				
			||||||
            +-----+---------+---------+---------+
 | 
					+-----+---------+---------+---------+
 | 
				
			||||||
            | {1.name} |   Opp   |   Déf   |   Rap   |
 | 
					| {1.name} |   Opp   |   Déf   |   Rap   |
 | 
				
			||||||
            +-----+---------+---------+---------+
 | 
					+-----+---------+---------+---------+
 | 
				
			||||||
            | {2.name} |   Rap   |   Opp   |   Déf   |
 | 
					| {2.name} |   Rap   |   Opp   |   Déf   |
 | 
				
			||||||
            +-----+---------+---------+---------+
 | 
					+-----+---------+---------+---------+
 | 
				
			||||||
        ```"""
 | 
					        ```"""
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            table = """```
 | 
					            table = """```
 | 
				
			||||||
            +-----+---------+---------+---------+---------+
 | 
					+-----+---------+---------+---------+---------+
 | 
				
			||||||
            |     | Phase 1 | Phase 2 | Phase 3 | Phase 4 |
 | 
					|     | Phase 1 | Phase 2 | Phase 3 | Phase 4 |
 | 
				
			||||||
            |     |   Pb {0.pb}  |   Pb {1.pb}  |   Pb {2.pb}  |   Pb {3.pb}  |
 | 
					|     |   Pb {0.pb}  |   Pb {1.pb}  |   Pb {2.pb}  |   Pb {3.pb}  |
 | 
				
			||||||
            +-----+---------+---------+---------+---------+
 | 
					+-----+---------+---------+---------+---------+
 | 
				
			||||||
            | {0.name} |   Déf   |         |   Rap   |   Opp   |
 | 
					| {0.name} |   Déf   |         |   Rap   |   Opp   |
 | 
				
			||||||
            +-----+---------+---------+---------+---------+
 | 
					+-----+---------+---------+---------+---------+
 | 
				
			||||||
            | {1.name} |   Opp   |   Déf   |         |   Rap   |
 | 
					| {1.name} |   Opp   |   Déf   |         |   Rap   |
 | 
				
			||||||
            +-----+---------+---------+---------+---------+
 | 
					+-----+---------+---------+---------+---------+
 | 
				
			||||||
            | {2.name} |   Rap   |   Opp   |   Déf   |         |
 | 
					| {2.name} |   Rap   |   Opp   |   Déf   |         |
 | 
				
			||||||
            +-----+---------+---------+---------+---------+
 | 
					+-----+---------+---------+---------+---------+
 | 
				
			||||||
            | {3.name} |         |   Rap   |   Opp   |   Déf   |
 | 
					| {3.name} |         |   Rap   |   Opp   |   Déf   |
 | 
				
			||||||
            +-----+---------+---------+---------+---------+
 | 
					+-----+---------+---------+---------+---------+
 | 
				
			||||||
        ```"""
 | 
					        ```"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        embed = discord.Embed(
 | 
					        embed = discord.Embed(
 | 
				
			||||||
@@ -205,6 +298,7 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        await self.ctx.send(embed=embed)
 | 
					        await self.ctx.send(embed=embed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    @send_all
 | 
					    @send_all
 | 
				
			||||||
    async def info_start(self):
 | 
					    async def info_start(self):
 | 
				
			||||||
        yield (
 | 
					        yield (
 | 
				
			||||||
@@ -225,6 +319,7 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
            "l'ordre de tirage pour le tour et les problèmes."
 | 
					            "l'ordre de tirage pour le tour et les problèmes."
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    @send_all
 | 
					    @send_all
 | 
				
			||||||
    async def info_finish(self):
 | 
					    async def info_finish(self):
 | 
				
			||||||
        yield "Le tirage est fini, merci à tout le monde !"
 | 
					        yield "Le tirage est fini, merci à tout le monde !"
 | 
				
			||||||
@@ -235,9 +330,19 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
        # TODO: Save it
 | 
					        # TODO: Save it
 | 
				
			||||||
        # TODO: make them available with the api
 | 
					        # TODO: make them available with the api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
 | 
					    @send_all
 | 
				
			||||||
 | 
					    async def info_dice(self, team, dice):
 | 
				
			||||||
 | 
					        yield f"L'équipe {team} a lancé un... {dice} :game_die:"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
 | 
					    @send_all
 | 
				
			||||||
    async def info_draw_pb(self, team, pb, rnd):
 | 
					    async def info_draw_pb(self, team, pb, rnd):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        yield (f"L'équipe {self.mention(team.name)} a tiré... **{pb}**")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if pb in team.rejected[rnd]:
 | 
					        if pb in team.rejected[rnd]:
 | 
				
			||||||
            await self.ctx.send(
 | 
					            yield (
 | 
				
			||||||
                f"Vous avez déjà refusé **{pb}**, "
 | 
					                f"Vous avez déjà refusé **{pb}**, "
 | 
				
			||||||
                f"vous pouvez le refuser à nouveau (`!non`) et "
 | 
					                f"vous pouvez le refuser à nouveau (`!non`) et "
 | 
				
			||||||
                f"tirer immédiatement un nouveau problème "
 | 
					                f"tirer immédiatement un nouveau problème "
 | 
				
			||||||
@@ -245,19 +350,20 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            if len(team.rejected[rnd]) >= MAX_REFUSE:
 | 
					            if len(team.rejected[rnd]) >= MAX_REFUSE:
 | 
				
			||||||
                await self.ctx.send(
 | 
					                yield (
 | 
				
			||||||
                    f"Vous pouvez accepter ou refuser **{pb}** "
 | 
					                    f"Vous pouvez accepter ou refuser **{pb}** "
 | 
				
			||||||
                    f"mais si vous choisissez de le refuser, il y "
 | 
					                    f"mais si vous choisissez de le refuser, il y "
 | 
				
			||||||
                    f"aura une pénalité de 0.5 sur le multiplicateur du "
 | 
					                    f"aura une pénalité de 0.5 sur le multiplicateur du "
 | 
				
			||||||
                    f"défenseur."
 | 
					                    f"défenseur."
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                await self.ctx.send(
 | 
					                yield (
 | 
				
			||||||
                    f"Vous pouvez accepter (`!oui`) ou refuser (`!non`) **{pb}**. "
 | 
					                    f"Vous pouvez l'accepter (`!oui`) ou le refuser (`!non`). "
 | 
				
			||||||
                    f"Il reste {MAX_REFUSE - len(team.rejected[rnd])} refus sans pénalité "
 | 
					                    f"Il reste {MAX_REFUSE - len(team.rejected[rnd])} refus sans pénalité "
 | 
				
			||||||
                    f"pour {team.mention}."
 | 
					                    f"pour {team.mention}."
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    async def info_accepted(self, team, pb):
 | 
					    async def info_accepted(self, team, pb):
 | 
				
			||||||
        await self.ctx.send(
 | 
					        await self.ctx.send(
 | 
				
			||||||
            f"L'équipe {team.mention} a accepté "
 | 
					            f"L'équipe {team.mention} a accepté "
 | 
				
			||||||
@@ -265,6 +371,7 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
            f"ne peuvent plus l'accepter."
 | 
					            f"ne peuvent plus l'accepter."
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @safe
 | 
				
			||||||
    async def info_rejected(self, team, pb, rnd):
 | 
					    async def info_rejected(self, team, pb, rnd):
 | 
				
			||||||
        msg = f"{team.mention} a refusé **{pb}** "
 | 
					        msg = f"{team.mention} a refusé **{pb}** "
 | 
				
			||||||
        if pb in team.rejected[rnd]:
 | 
					        if pb in team.rejected[rnd]:
 | 
				
			||||||
@@ -274,152 +381,7 @@ class DiscordTirage(BaseTirage):
 | 
				
			|||||||
        await self.ctx.send(msg)
 | 
					        await self.ctx.send(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Tirage(yaml.YAMLObject):
 | 
					class TiragePhase:
 | 
				
			||||||
    yaml_tag = "Tirage"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, ctx, channel, teams):
 | 
					 | 
				
			||||||
        assert len(teams) in (3, 4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.channel: int = channel
 | 
					 | 
				
			||||||
        self.teams = [Team(team) for team in teams]
 | 
					 | 
				
			||||||
        self.phase = TirageOrderPhase(self, round=0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def update_phase(self, ctx):
 | 
					 | 
				
			||||||
        if self.phase.finished():
 | 
					 | 
				
			||||||
            next_class = await self.phase.next(ctx)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if next_class is None:
 | 
					 | 
				
			||||||
                await self.end(ctx)
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                # Continue on the same round.
 | 
					 | 
				
			||||||
                # If a Phase wants to change the round
 | 
					 | 
				
			||||||
                # it needs to change its own round.
 | 
					 | 
				
			||||||
                self.phase = next_class(self, self.phase.round)
 | 
					 | 
				
			||||||
                await self.phase.start(ctx)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def end(self, ctx):
 | 
					 | 
				
			||||||
        self.phase = None
 | 
					 | 
				
			||||||
        if False:
 | 
					 | 
				
			||||||
            # Allow everyone to send messages again
 | 
					 | 
				
			||||||
            send = discord.PermissionOverwrite()  # reset
 | 
					 | 
				
			||||||
            await ctx.channel.edit(overwrites={ctx.guild.default_role: send})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        tl = {}
 | 
					 | 
				
			||||||
        if File.TIRAGES.exists():
 | 
					 | 
				
			||||||
            with open(File.TIRAGES) as f:
 | 
					 | 
				
			||||||
                tl = yaml.load(f)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            File.TIRAGES.touch()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        key = max(0, *tl.keys()) + 1
 | 
					 | 
				
			||||||
        tl[key] = self
 | 
					 | 
				
			||||||
        with open(File.TIRAGES, "w") as f:
 | 
					 | 
				
			||||||
            yaml.dump(tl, f)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        await ctx.send(
 | 
					 | 
				
			||||||
            f"A tout moment, ce rapport peut " f"être envoyé avec `!draw show {key}`"
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        from src.tfjm_discord_bot import tirages
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.channel in tirages:
 | 
					 | 
				
			||||||
            del tirages[self.channel]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def show_tex(self, ctx):
 | 
					 | 
				
			||||||
        if len(self.teams) == 3:
 | 
					 | 
				
			||||||
            table = r"""
 | 
					 | 
				
			||||||
\begin{{table}}[]
 | 
					 | 
				
			||||||
\begin{{tabular}}{{|c|c|c|c|}}
 | 
					 | 
				
			||||||
\hline
 | 
					 | 
				
			||||||
          & Phase 1 - {0.pb} & Phase 2 - {1.pb} & Phase {2.pb} \\\\ \hline
 | 
					 | 
				
			||||||
 {0.name} & Déf & Rap & Opp \\ \hline
 | 
					 | 
				
			||||||
 {1.name} & Opp & Déf & Rap \\ \hline
 | 
					 | 
				
			||||||
 {2.name} & Rap & Opp & Déf \\ \hline
 | 
					 | 
				
			||||||
\end{{tabular}}
 | 
					 | 
				
			||||||
\end{{table}}
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            table = r"""
 | 
					 | 
				
			||||||
            \begin{{table}}[]
 | 
					 | 
				
			||||||
            \begin{{tabular}}{{|c|c|c|c|c|}}
 | 
					 | 
				
			||||||
            \hline
 | 
					 | 
				
			||||||
                      & Phase 1 - {0.pb} & Phase 2 - {1.pb} & Phase 3 - {2.pb} & Phase 4 - {3.pb} \\\\ \hline
 | 
					 | 
				
			||||||
             {0.name} & Déf &     & Rap & Opp \\ \hline
 | 
					 | 
				
			||||||
             {1.name} & Opp & Déf &     & Rap \\ \hline
 | 
					 | 
				
			||||||
             {2.name} & Rap & Opp & Déf &     \\ \hline
 | 
					 | 
				
			||||||
             {3.name} &     & Rap & Opp & Déf \\ \hline
 | 
					 | 
				
			||||||
            \end{{tabular}}
 | 
					 | 
				
			||||||
            \end{{table}}
 | 
					 | 
				
			||||||
            """
 | 
					 | 
				
			||||||
        msg = ",tex "
 | 
					 | 
				
			||||||
        for i in (0, 1):
 | 
					 | 
				
			||||||
            msg += rf"\section{{ {ROUND_NAMES[i].capitalize()} }}"
 | 
					 | 
				
			||||||
            msg += table.format(*self.records(i))
 | 
					 | 
				
			||||||
        await ctx.send(msg)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Phase:
 | 
					 | 
				
			||||||
    ...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class OrderPhase(Phase):
 | 
					 | 
				
			||||||
    def __init__(self, tirage, round, name, order_name, reverse=False):
 | 
					 | 
				
			||||||
        super().__init__(tirage, round)
 | 
					 | 
				
			||||||
        self.name = name
 | 
					 | 
				
			||||||
        self.reverse = reverse
 | 
					 | 
				
			||||||
        self.order_name = order_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def order_for(self, team):
 | 
					 | 
				
			||||||
        return getattr(team, self.order_name)[self.round]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_order_for(self, team, order):
 | 
					 | 
				
			||||||
        getattr(team, self.order_name)[self.round] = order
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def dice(self, ctx, author, dice):
 | 
					 | 
				
			||||||
        team = self.team_for(author)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.order_for(team) is None:
 | 
					 | 
				
			||||||
            self.set_order_for(team, dice)
 | 
					 | 
				
			||||||
            await ctx.send(f"L'équipe {team.mention} a obtenu... **{dice}**")
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            raise UnwantedCommand("tu as déjà lancé un dé !")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def finished(self) -> bool:
 | 
					 | 
				
			||||||
        return all(self.order_for(team) is not None for team in self.teams)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async def next(self, ctx) -> "Type[Phase]":
 | 
					 | 
				
			||||||
        orders = [self.order_for(team) for team in self.teams]
 | 
					 | 
				
			||||||
        if len(set(orders)) == len(orders):
 | 
					 | 
				
			||||||
            # All dice are different: good
 | 
					 | 
				
			||||||
            self.teams.sort(key=self.order_for, reverse=self.reverse)
 | 
					 | 
				
			||||||
            await ctx.send(
 | 
					 | 
				
			||||||
                f"L'ordre {self.name} pour ce tour est donc :\n"
 | 
					 | 
				
			||||||
                " - "
 | 
					 | 
				
			||||||
                + "\n - ".join(
 | 
					 | 
				
			||||||
                    f"{team.mention} ({self.order_for(team)})" for team in self.teams
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            return self.NEXT
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            # Find dice that are the same
 | 
					 | 
				
			||||||
            count = defaultdict(list)
 | 
					 | 
				
			||||||
            for team in self.teams:
 | 
					 | 
				
			||||||
                count[self.order_for(team)].append(team)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            re_do = []
 | 
					 | 
				
			||||||
            for teams in count.values():
 | 
					 | 
				
			||||||
                if len(teams) > 1:
 | 
					 | 
				
			||||||
                    re_do.extend(teams)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            teams_str = ", ".join(team.mention for team in re_do)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            for team in re_do:
 | 
					 | 
				
			||||||
                self.set_order_for(team, None)
 | 
					 | 
				
			||||||
            # We need to do this phase again.
 | 
					 | 
				
			||||||
            return self.__class__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class TiragePhase(Phase):
 | 
					 | 
				
			||||||
    """The phase where captains accept or refuse random problems."""
 | 
					    """The phase where captains accept or refuse random problems."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, tirage, round=0):
 | 
					    def __init__(self, tirage, round=0):
 | 
				
			||||||
@@ -654,6 +616,15 @@ class TirageCog(Cog, name="Tirages"):
 | 
				
			|||||||
            dice = random.randint(1, n)
 | 
					            dice = random.randint(1, n)
 | 
				
			||||||
            return f"{ctx.author.mention} : {Emoji.DICE} {dice}"
 | 
					            return f"{ctx.author.mention} : {Emoji.DICE} {dice}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @commands.command(name="dice-all", aliases=["da"], hidden=True)
 | 
				
			||||||
 | 
					    @commands.has_role(Role.DEV)
 | 
				
			||||||
 | 
					    async def dice_all_cmd(self, ctx, *teams):
 | 
				
			||||||
 | 
					        channel = ctx.channel.id
 | 
				
			||||||
 | 
					        if channel in self.tirages:
 | 
				
			||||||
 | 
					            for t in teams:
 | 
				
			||||||
 | 
					                d = random.randint(1, 100)
 | 
				
			||||||
 | 
					                await self.tirages[channel].event(Event(t, d))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.command(
 | 
					    @commands.command(
 | 
				
			||||||
        name="random-problem",
 | 
					        name="random-problem",
 | 
				
			||||||
        aliases=["rp", "problème-aléatoire", "probleme-aleatoire", "pa"],
 | 
					        aliases=["rp", "problème-aléatoire", "probleme-aleatoire", "pa"],
 | 
				
			||||||
@@ -663,7 +634,7 @@ class TirageCog(Cog, name="Tirages"):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        channel = ctx.channel.id
 | 
					        channel = ctx.channel.id
 | 
				
			||||||
        if channel in self.tirages:
 | 
					        if channel in self.tirages:
 | 
				
			||||||
            await self.tirages[channel].choose_problem(ctx)
 | 
					            await self.tirages[channel].rproblem(ctx)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            problem = random.choice(PROBLEMS)
 | 
					            problem = random.choice(PROBLEMS)
 | 
				
			||||||
            await ctx.send(f"Le problème tiré est... **{problem}**")
 | 
					            await ctx.send(f"Le problème tiré est... **{problem}**")
 | 
				
			||||||
@@ -712,7 +683,7 @@ class TirageCog(Cog, name="Tirages"):
 | 
				
			|||||||
        name="start", usage="équipe1 équipe2 équipe3 (équipe4)",
 | 
					        name="start", usage="équipe1 équipe2 équipe3 (équipe4)",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    @commands.has_any_role(*Role.ORGAS)
 | 
					    @commands.has_any_role(*Role.ORGAS)
 | 
				
			||||||
    async def start(self, ctx: Context, *teams: discord.Role):
 | 
					    async def start(self, ctx: Context, fmt, *teams: discord.Role):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        (orga) Commence un tirage avec 3 ou 4 équipes.
 | 
					        (orga) Commence un tirage avec 3 ou 4 équipes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -730,28 +701,25 @@ class TirageCog(Cog, name="Tirages"):
 | 
				
			|||||||
                "il est possible d'en commencer un autre sur une autre channel."
 | 
					                "il est possible d'en commencer un autre sur une autre channel."
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if len(teams) not in (3, 4):
 | 
					        try:
 | 
				
			||||||
 | 
					            fmt = list(map(int, fmt.split("+")))
 | 
				
			||||||
 | 
					        except ValueError:
 | 
				
			||||||
            raise TfjmError(
 | 
					            raise TfjmError(
 | 
				
			||||||
                "Il faut 3 ou 4 équipes pour un tirage. "
 | 
					                "Le premier argument doit être le format du tournoi, "
 | 
				
			||||||
                "Exemple: `!draw start @AAA @BBB @CCC`"
 | 
					                "par exemple `3+3` pour deux poules à trois équipes"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not set(fmt).issubset({3, 4}):
 | 
				
			||||||
 | 
					            raise TfjmError("Seuls les poules à 3 ou 4 équipes sont suportées.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Here all data should be valid
 | 
					        # Here all data should be valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Prevent everyone from writing except Capitaines, Orga, CNO, Benevole
 | 
					        self.tirages[channel_id] = DiscordTirage(ctx, *teams, fmt=fmt)
 | 
				
			||||||
        if False:
 | 
					        await self.tirages[channel_id].run()
 | 
				
			||||||
            read = discord.PermissionOverwrite(send_messages=False)
 | 
					 | 
				
			||||||
            send = discord.PermissionOverwrite(send_messages=True)
 | 
					 | 
				
			||||||
            r = lambda role_name: get(ctx.guild.roles, name=role_name)
 | 
					 | 
				
			||||||
            overwrites = {
 | 
					 | 
				
			||||||
                ctx.guild.default_role: read,
 | 
					 | 
				
			||||||
                r(Role.CAPTAIN): send,
 | 
					 | 
				
			||||||
                r(Role.BENEVOLE): send,
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            await channel.edit(overwrites=overwrites)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.tirages[channel_id] = Tirage(ctx, channel_id, teams)
 | 
					        if self.tirages[channel_id]:
 | 
				
			||||||
        await self.tirages[channel_id].phase.start(ctx)
 | 
					            # Check if aborted in an other way
 | 
				
			||||||
 | 
					            del self.tirages[channel_id]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @draw_group.command(name="abort")
 | 
					    @draw_group.command(name="abort")
 | 
				
			||||||
    @commands.has_any_role(*Role.ORGAS)
 | 
					    @commands.has_any_role(*Role.ORGAS)
 | 
				
			||||||
@@ -768,32 +736,32 @@ class TirageCog(Cog, name="Tirages"):
 | 
				
			|||||||
        if channel_id in self.tirages:
 | 
					        if channel_id in self.tirages:
 | 
				
			||||||
            print(self.tirages, channel_id)
 | 
					            print(self.tirages, channel_id)
 | 
				
			||||||
            print(self.tirages[channel_id])
 | 
					            print(self.tirages[channel_id])
 | 
				
			||||||
 | 
					            del self.tirages[channel_id]
 | 
				
			||||||
            await self.tirages[channel_id].end(ctx)
 | 
					 | 
				
			||||||
            await ctx.send("Le tirage est annulé.")
 | 
					            await ctx.send("Le tirage est annulé.")
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            await ctx.send("Il n'y a pas de tirage en cours.")
 | 
					            await ctx.send("Il n'y a pas de tirage en cours.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @draw_group.command(name="skip", aliases=["s"])
 | 
					    #
 | 
				
			||||||
    @commands.has_role(Role.DEV)
 | 
					    # @draw_group.command(name="skip", aliases=["s"])
 | 
				
			||||||
    async def draw_skip(self, ctx, *teams: discord.Role):
 | 
					    # @commands.has_role(Role.DEV)
 | 
				
			||||||
        """(dev) Passe certaines phases du tirage."""
 | 
					    # async def draw_skip(self, ctx, *teams: discord.Role):
 | 
				
			||||||
        channel = ctx.channel.id
 | 
					    #     """(dev) Passe certaines phases du tirage."""
 | 
				
			||||||
        self.tirages[channel] = tirage = Tirage(ctx, channel, teams)
 | 
					    #     channel = ctx.channel.id
 | 
				
			||||||
 | 
					    #     self.tirages[channel] = tirage = Tirage(ctx, channel, teams)
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    #     tirage.phase = TiragePhase(tirage, round=1)
 | 
				
			||||||
 | 
					    #     for i, team in enumerate(tirage.teams):
 | 
				
			||||||
 | 
					    #         team.tirage_order = [i + 1, i + 1]
 | 
				
			||||||
 | 
					    #         team.passage_order = [i + 1, i + 1]
 | 
				
			||||||
 | 
					    #         team.accepted_problems = [PROBLEMS[i], PROBLEMS[-i - 1]]
 | 
				
			||||||
 | 
					    #     tirage.teams[0].rejected = [{PROBLEMS[3]}, set(PROBLEMS[4:8])]
 | 
				
			||||||
 | 
					    #     tirage.teams[1].rejected = [{PROBLEMS[7]}, set()]
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    #     await ctx.send(f"Skipping to {tirage.phase.__class__.__name__}.")
 | 
				
			||||||
 | 
					    #     await tirage.phase.start(ctx)
 | 
				
			||||||
 | 
					    #     await tirage.update_phase(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        tirage.phase = TiragePhase(tirage, round=1)
 | 
					    def get_tirages(self) -> Dict[int, BaseTirage]:
 | 
				
			||||||
        for i, team in enumerate(tirage.teams):
 | 
					 | 
				
			||||||
            team.tirage_order = [i + 1, i + 1]
 | 
					 | 
				
			||||||
            team.passage_order = [i + 1, i + 1]
 | 
					 | 
				
			||||||
            team.accepted_problems = [PROBLEMS[i], PROBLEMS[-i - 1]]
 | 
					 | 
				
			||||||
        tirage.teams[0].rejected = [{PROBLEMS[3]}, set(PROBLEMS[4:8])]
 | 
					 | 
				
			||||||
        tirage.teams[1].rejected = [{PROBLEMS[7]}, set()]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        await ctx.send(f"Skipping to {tirage.phase.__class__.__name__}.")
 | 
					 | 
				
			||||||
        await tirage.phase.start(ctx)
 | 
					 | 
				
			||||||
        await tirage.update_phase(ctx)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_tirages(self) -> Dict[int, Tirage]:
 | 
					 | 
				
			||||||
        if not File.TIRAGES.exists():
 | 
					        if not File.TIRAGES.exists():
 | 
				
			||||||
            return {}
 | 
					            return {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -812,6 +780,7 @@ class TirageCog(Cog, name="Tirages"):
 | 
				
			|||||||
            `!draw show 42` - Affiche le tirage n°42
 | 
					            `!draw show 42` - Affiche le tirage n°42
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
        tirages = self.get_tirages()
 | 
					        tirages = self.get_tirages()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not tirages:
 | 
					        if not tirages:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ from discord.ext.commands import Bot
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def french_join(l):
 | 
					def french_join(l):
 | 
				
			||||||
 | 
					    l = list(l)
 | 
				
			||||||
    start = ", ".join(l[:-1])
 | 
					    start = ", ".join(l[:-1])
 | 
				
			||||||
    return f"{start} et {l[-1]}"
 | 
					    return f"{start} et {l[-1]}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user