♻️ move Tirage things to a Cog

This commit is contained in:
ddorn 2020-04-27 11:43:16 +02:00
parent ec9671efaf
commit b24921d8ba
3 changed files with 153 additions and 132 deletions

View File

@ -2,3 +2,5 @@
This package contains all the cogs (groups of commands)
of the TFJM² bot.
"""
from .tirages import TirageCog

View File

@ -6,7 +6,8 @@ from typing import Type
import discord
import yaml
from discord.ext.commands import Context
from discord.ext import commands
from discord.ext.commands import Context, group, Cog
from discord.utils import get
from src.constants import *
@ -103,11 +104,7 @@ class Tirage(yaml.YAMLObject):
await self.phase.start(ctx)
async def end(self, ctx):
from src.tfjm_discord_bot import tirages
del tirages[self.channel]
if False:
# Allow everyone to send messages again
send = discord.PermissionOverwrite() # reset
await ctx.channel.edit(overwrites={ctx.guild.default_role: send})
@ -519,3 +516,142 @@ class TirageOrderPhase(OrderPhase):
"comme ceci `!dice 100`. "
"L'ordre des tirages suivants sera l'ordre croissant des lancers. "
)
class TirageCog(Cog, name="Tirages"):
def __init__(self, bot):
self.bot: commands.Bot = bot
# We retrieve the global variable.
# We don't want tirages to be ust an attribute
# as we want them to outlive the Cog, for instance
# if the cog is reloaded turing a tirage.
from src.tfjm_discord_bot import tirages
self.tirages = tirages
@group(
name="draw", aliases=["d", "tirage"],
)
async def draw_group(self, ctx: Context) -> None:
"""Commandes pour les tirages."""
@draw_group.command(
name="start", usage="équipe1 équipe2 équipe3 (équipe4)",
)
@commands.has_role(ORGA_ROLE)
async def start(self, ctx: Context, *teams):
"""
Commence un tirage avec 3 ou 4 équipes.
Cette commande attend trois trigrammes d'équipes, par ex:
!draw start AAA BBB CCC
"""
channel: discord.TextChannel = ctx.channel
channel_id = channel.id
if channel_id in self.tirages:
raise TfjmError("Il y a déjà un tirage en cours sur cette Channel.")
if len(teams) not in (3, 4):
raise TfjmError("Il faut 3 ou 4 équipes pour un tirage.")
roles = {role.name for role in ctx.guild.roles}
for team in teams:
if team not in roles:
raise TfjmError(
"Le nom de l'équipe doit être exactement celui du rôle."
)
# Here all data should be valid
# Prevent everyone from writing except Capitaines, Orga, CNO, Benevole
if False:
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(CAPTAIN_ROLE): send,
r(BENEVOLE_ROLE): send,
}
await channel.edit(overwrites=overwrites)
await ctx.send(
"Nous allons commencer le tirage du premier tour. "
"Seuls les capitaines de chaque équipe peuvent désormais écrire ici. "
"Merci de d'envoyer seulement ce que est nécessaire et suffisant au "
"bon déroulement du tournoi. Vous pouvez à tout moment poser toute question "
"si quelque chose n'est pas clair ou ne va pas. \n\n"
"Pour plus de détails sur le déroulement du tirgae au sort, le règlement "
"est accessible sur https://tfjm.org/reglement."
)
self.tirages[channel_id] = Tirage(ctx, channel_id, teams)
await self.tirages[channel_id].phase.start(ctx)
@draw_group.command(
name="abort", help="Annule le tirage en cours.",
)
@commands.has_role(ORGA_ROLE)
async def abort_draw_cmd(self, ctx):
channel_id = ctx.channel.id
if channel_id in self.tirages:
await self.tirages[channel_id].end(ctx)
await ctx.send("Le tirage est annulé.")
@draw_group.command(name="skip", aliases=["s"])
@commands.has_role(CNO_ROLE)
async def draw_skip(self, ctx, *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)
@draw_group.command(name="show")
async def show_cmd(self, ctx: Context, arg: str):
if not TIRAGES_FILE.exists():
await ctx.send("Il n'y a pas encore eu de tirages.")
return
with open(TIRAGES_FILE) as f:
tirages = list(yaml.load_all(f))
if arg.lower() == "all":
msg = "\n".join(
f"{i}: {', '.join(team.name for team in tirage.teams)}"
for i, tirage in enumerate(tirages)
)
await ctx.send(
"Voici in liste de tous les tirages qui ont été faits. "
"Vous pouvez en consulter un en particulier avec `!show ID`."
)
await ctx.send(msg)
else:
try:
n = int(arg)
if n < 0:
raise ValueError
tirage = tirages[n]
except (ValueError, IndexError):
await ctx.send(
f"`{arg}` n'est pas un identifiant valide. "
f"Les identifiants valides sont visibles avec `!show all`"
)
else:
await tirage.show(ctx)
def setup(bot):
bot.add_cog(TirageCog(bot))

View File

@ -1,107 +1,21 @@
#!/bin/python
import asyncio
import code
import random
import sys
import traceback
from collections import defaultdict, namedtuple
from pprint import pprint
from typing import Dict, Type
import discord
import yaml
from discord.ext import commands
from discord.ext.commands import Context
from discord.utils import get
from src.cogs.tirages import Tirage, TiragePhase
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=commands.DefaultHelpCommand(no_category="Commandes")
)
# global variable to hold every running tirage
tirages: Dict[int, Tirage] = {}
@bot.command(
name="start-draw",
help="Commence un tirage avec 3 ou 4 équipes.",
usage="équipe1 équipe2 équipe3 (équipe4)",
)
@commands.has_role(ORGA_ROLE)
async def start_draw(ctx: Context, *teams):
channel: discord.TextChannel = ctx.channel
channel_id = channel.id
if channel_id in tirages:
raise TfjmError("Il y a déjà un tirage en cours sur cette Channel.")
if len(teams) not in (3, 4):
raise TfjmError("Il faut 3 ou 4 équipes pour un tirage.")
roles = {role.name for role in ctx.guild.roles}
for team in teams:
if team not in roles:
raise TfjmError("Le nom de l'équipe doit être exactement celui du rôle.")
# Here all data should be valid
# Prevent everyone from writing except Capitaines, Orga, CNO, Benevole
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(CAPTAIN_ROLE): send,
r(BENEVOLE_ROLE): send,
}
await channel.edit(overwrites=overwrites)
await ctx.send(
"Nous allons commencer le tirage du premier tour. "
"Seuls les capitaines de chaque équipe peuvent désormais écrire ici. "
"Merci de d'envoyer seulement ce que est nécessaire et suffisant au "
"bon déroulement du tournoi. Vous pouvez à tout moment poser toute question "
"si quelque chose n'est pas clair ou ne va pas. \n\n"
"Pour plus de détails sur le déroulement du tirgae au sort, le règlement "
"est accessible sur https://tfjm.org/reglement."
)
tirages[channel_id] = Tirage(ctx, channel_id, teams)
await tirages[channel_id].phase.start(ctx)
@bot.command(
name="abort-draw", help="Annule le tirage en cours.",
)
@commands.has_role(ORGA_ROLE)
async def abort_draw_cmd(ctx):
channel_id = ctx.channel.id
if channel_id in tirages:
await tirages[channel_id].end(ctx)
await ctx.send("Le tirage est annulé.")
@bot.command(name="draw-skip", aliases=["skip"])
@commands.has_role(CNO_ROLE)
async def draw_skip(ctx, *teams):
channel = ctx.channel.id
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)
# Variable globale qui contient les tirages.
tirages = {}
@bot.event
@ -178,40 +92,6 @@ async def refuse_cmd(ctx):
await ctx.send(f"{ctx.author.mention} nie tout en block !")
@bot.command(name="show")
async def show_cmd(ctx: Context, arg: str):
if not TIRAGES_FILE.exists():
await ctx.send("Il n'y a pas encore eu de tirages.")
return
with open(TIRAGES_FILE) as f:
tirages = list(yaml.load_all(f))
if arg.lower() == "all":
msg = "\n".join(
f"{i}: {', '.join(team.name for team in tirage.teams)}"
for i, tirage in enumerate(tirages)
)
await ctx.send(
"Voici in liste de tous les tirages qui ont été faits. "
"Vous pouvez en consulter un en particulier avec `!show ID`."
)
await ctx.send(msg)
else:
try:
n = int(arg)
if n < 0:
raise ValueError
tirage = tirages[n]
except (ValueError, IndexError):
await ctx.send(
f"`{arg}` n'est pas un identifiant valide. "
f"Les identifiants valides sont visibles avec `!show all`"
)
else:
await tirage.show(ctx)
@bot.command(name="interrupt")
@commands.has_role(CNO_ROLE)
async def interrupt_cmd(ctx):
@ -260,5 +140,8 @@ async def on_command_error(ctx: Context, error, *args, **kwargs):
await ctx.send(msg)
bot.load_extension("src.cogs.tirages")
if __name__ == "__main__":
bot.run(TOKEN)