From 1148d669cd9ce5bcff024bd19e44f9b9760b457a Mon Sep 17 00:00:00 2001 From: ddorn Date: Sun, 26 Apr 2020 16:44:24 +0200 Subject: [PATCH] :sparkles: save/show tirages --- poetry.lock | 23 ++++++++++- pyproject.toml | 1 + tfjm-discord-bot.py | 97 ++++++++++++++++++++++++++++++++------------- 3 files changed, 93 insertions(+), 28 deletions(-) diff --git a/poetry.lock b/poetry.lock index 69e29af..92f8bbf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -109,6 +109,14 @@ optional = false python-versions = ">=3.5" version = "4.7.5" +[[package]] +category = "main" +description = "YAML parser and emitter for Python" +name = "pyyaml" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "5.3.1" + [[package]] category = "main" description = "Backported and Experimental Type Hints for Python 3.5+" @@ -139,7 +147,7 @@ idna = ">=2.0" multidict = ">=4.0" [metadata] -content-hash = "7d5f1147714cfcf19cf2c9cda4a38eecc11832a7e5b774467785d167676f363c" +content-hash = "290c4d1821ff75607bc72026a3530752235431e29b064e7ebc5ac897ce6a5565" python-versions = "^3.6" [metadata.files] @@ -203,6 +211,19 @@ multidict = [ {file = "multidict-4.7.5-cp38-cp38-win_amd64.whl", hash = "sha256:544fae9261232a97102e27a926019100a9db75bec7b37feedd74b3aa82f29969"}, {file = "multidict-4.7.5.tar.gz", hash = "sha256:aee283c49601fa4c13adc64c09c978838a7e812f85377ae130a24d7198c0331e"}, ] +pyyaml = [ + {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, + {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, + {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, + {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, +] typing-extensions = [ {file = "typing_extensions-3.7.4.2-py2-none-any.whl", hash = "sha256:f8d2bd89d25bc39dabe7d23df520442fa1d8969b82544370e03d88b5a591c392"}, {file = "typing_extensions-3.7.4.2-py3-none-any.whl", hash = "sha256:6e95524d8a547a91e08f404ae485bbb71962de46967e1b71a0cb89af24e761c5"}, diff --git a/pyproject.toml b/pyproject.toml index d283a3c..a7c5cd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,7 @@ authors = ["ddorn "] [tool.poetry.dependencies] python = "^3.6" discord = "^1.0.1" +pyyaml = "^5.0.0" [tool.poetry.dev-dependencies] diff --git a/tfjm-discord-bot.py b/tfjm-discord-bot.py index d5279f1..8663314 100644 --- a/tfjm-discord-bot.py +++ b/tfjm-discord-bot.py @@ -5,14 +5,14 @@ import random import sys import traceback from collections import defaultdict, namedtuple -from operator import attrgetter -from time import sleep +from pathlib import Path from typing import Dict, Type import discord from discord.ext import commands from discord.ext.commands import Context from discord.utils import get +import yaml TOKEN = os.environ.get("TFJM_DISCORD_TOKEN") @@ -35,6 +35,7 @@ with open("problems") as f: MAX_REFUSE = len(PROBLEMS) - 5 ROUND_NAMES = ["premier tour", "deuxième tour"] +TIRAGES_FILE = Path(__file__).parent / "tirages.yaml" def in_passage_order(teams, round=0): @@ -56,10 +57,12 @@ class UnwantedCommand(TfjmError): super(UnwantedCommand, self).__init__(msg) -class Team: +class Team(yaml.YAMLObject): + yaml_tag = "Team" + def __init__(self, ctx, name): self.name = name - self.role = get(ctx.guild.roles, name=name) + self.mention = get(ctx.guild.roles, name=name).mention self.tirage_order = [None, None] self.passage_order = [None, None] @@ -67,10 +70,6 @@ class Team: self.drawn_problem = None # Waiting to be accepted or refused self.rejected = [set(), set()] - @property - def mention(self): - return self.role.mention - def coeff(self, round): if len(self.rejected[round]) <= MAX_REFUSE: return 2 @@ -87,11 +86,13 @@ class Team: """ -class Tirage: +class Tirage(yaml.YAMLObject): + yaml_tag = "Tirage" + def __init__(self, ctx, channel, teams): assert len(teams) in (3, 4) - self.channel = channel + self.channel: int = channel self.teams = [Team(ctx, team) for team in teams] self.phase = TirageOrderPhase(self, round=0) @@ -128,10 +129,11 @@ class Tirage: next_class = await self.phase.next(ctx) if next_class is None: + self.phase = None await ctx.send( "Le tirage est fini ! Bonne chance à tous pour la suite !" ) - await self.show_tirage(ctx) + await self.show(ctx) await self.end(ctx) else: # Continue on the same round. @@ -148,7 +150,21 @@ class Tirage: send = discord.PermissionOverwrite() # reset await ctx.channel.edit(overwrites={ctx.guild.default_role: send}) - async def show_tirage(self, ctx): + tl = [] + if TIRAGES_FILE.exists(): + with open(TIRAGES_FILE) as f: + tl = list(yaml.load_all(f)) + else: + TIRAGES_FILE.touch() + tl.append(self) + with open(TIRAGES_FILE, "w") as f: + yaml.dump_all(tl, f) + + await ctx.send( + f"A tout moment, ce rapport peut être envoyé avec `!show {len(tl) - 1}`" + ) + + async def show(self, ctx): teams = ", ".join(team.mention for team in self.teams) msg = f"Voici un résumé du tirage entre les équipes {teams}." @@ -181,8 +197,9 @@ class Tirage: +-----+---------+---------+---------+---------+ ```""" Record = namedtuple("Record", ["name", "pb", "penalite"]) - records = [ - [ + + for round in (0, 1): + records = [ Record( team.name, team.accepted_problems[round][0], @@ -190,18 +207,11 @@ class Tirage: ) for team in in_passage_order(self.teams, round) ] - for round in (0, 1) - ] - msg += "\n\nPremier tour:\n" - msg += table.format(*records[0]) - for team in self.teams: - msg += team.details(0) - - msg += "\n\n Deuxième tour:\n" - msg += table.format(*records[1]) - for team in self.teams: - msg += team.details(1) + msg += f"\n\n**{ROUND_NAMES[round].capitalize()}**:\n" + msg += table.format(*records[round]) + "\n" + for team in self.teams: + msg += team.details(round) await ctx.send(msg) @@ -288,8 +298,7 @@ class OrderPhase(Phase): f"L'ordre {self.name} pour ce tour est donc :\n" " - " + "\n - ".join( - f"{team.role.mention} ({self.order_for(team)})" - for team in self.teams + f"{team.mention} ({self.order_for(team)})" for team in self.teams ) ) return self.NEXT @@ -707,6 +716,40 @@ 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.event async def on_command_error(ctx: Context, error, *args, **kwargs): if isinstance(error, commands.CommandInvokeError):