Skip to content

Commit

Permalink
[Tournaments] Change the internal upload system
Browse files Browse the repository at this point in the history
* Participants are uploaded with their seeding, removing the need to use !upload --force
* If there's no ranking, participants will be immediatly uploaded
* Check-in ending will remove participants from the bracket
  • Loading branch information
laggron42 committed Jun 22, 2021
1 parent 47a446c commit e657fed
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
13 changes: 13 additions & 0 deletions tournaments/objects/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,8 @@ def __init__(
# self.debug_task = asyncio.get_event_loop().create_task(self.debug_loop_task())
self.matches_to_announce: List[str] = [] # matches to announce in the queue channel
self.cancelling = False # see Tournament.__del__ and Match.__del__
# 5 min cooldown on ranking fetch (use saved one instead)
self.last_ranking_fetch: Optional[datetime] = None

def __repr__(self):
return (
Expand Down Expand Up @@ -2323,6 +2325,11 @@ async def register_participant(self, member: discord.Member, send_dm: bool = Tru
):
# either there's no ranking, in which case we always upload on register, or
# last registered participant has a player ID, so we should upload him to the bracket
# first we seed him, if possible
try:
await self.seed_participants()
except Exception:
pass # any exception will roll back the list of participants so we're safe
await self.add_participant(participant)
self.participants.append(participant)
log.debug(f"[Guild {self.guild.id}] Player {member} registered.")
Expand Down Expand Up @@ -2385,6 +2392,11 @@ async def unregister_participant(self, member: discord.Member, send_dm: bool = T
# 95% of this code is made by Wonderfall, from ATOS bot (original)
# https://github.com/Wonderfall/ATOS/blob/master/utils/seeding.py
async def _fetch_braacket_ranking_info(self):
if self.last_ranking_fetch and self.last_ranking_fetch + timedelta(
minutes=5
) < datetime.now(self.tz):
# 5 min cooldown on ranking fetch
return
league_name, league_id = self.ranking["league_name"], self.ranking["league_id"]
headers = {
"User-Agent": (
Expand All @@ -2411,6 +2423,7 @@ async def _fetch_braacket_ranking_info(self):
if page != 1 and filecmp.cmp(file_path, path / f"page{page-1}.csv"):
await aiofiles.os.remove(file_path)
break
self.last_ranking_fetch = datetime.now(self.tz)

async def _seed_participants(self):
ranking = {}
Expand Down
15 changes: 11 additions & 4 deletions tournaments/objects/challonge.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging

from copy import copy
from typing import List, Optional
from typing import List, Optional, Tuple

from redbot.core import Config
from redbot.core.bot import Red
Expand Down Expand Up @@ -380,6 +380,9 @@ async def add_participants(
participants = copy(participants or self.participants)
if not participants:
raise RuntimeError("No participant provided")
participants: List[Tuple[ChallongeParticipant, int]] = [
(x, i) for i, x in enumerate(participants, start=1)
]
if force is True:
# remove previous participants
await self.request(achallonge.participants.clear, self.id)
Expand All @@ -388,18 +391,22 @@ async def add_participants(
raw_participants = await self.list_participants()
if raw_participants:
raw_ids = [x.get("id") for x in raw_participants]
participants = [x for x in participants if x.player_id not in raw_ids]
participants = [x for x in participants if x[0].player_id not in raw_ids]
if not participants:
return
# raise RuntimeError("No new participant to add")
participants = [str(x) for x in participants]
seed = all(x.elo is not None for x, i in participants)
size = len(participants)
# make a composite list (to avoid "414 Request-URI Too Large")
participants = [participants[x : x + (50)] for x in range(0, size, 50)]
# Send to Challonge and assign IDs
for chunk_participants in participants:
params = {}
if seed:
params.update({"seed": [i for x, i in chunk_participants]})
participants = [str(x) for x in chunk_participants]
challonge_players = await self.request(
achallonge.participants.bulk_add, self.id, chunk_participants
achallonge.participants.bulk_add, self.id, participants, **params
)
for player in challonge_players:
participant = self.find_participant(discord_name=player["name"])[1]
Expand Down
2 changes: 1 addition & 1 deletion tournaments/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ async def remove(self, ctx: commands.Context, *members: discord.Member):
async with ctx.typing():
for member in members:
try:
await tournament.unregister_participant(member)
await tournament.unregister_participant(member, send_dm=False)
except discord.HTTPException:
if len(members) == 1:
raise # single members should raise exceptions
Expand Down
2 changes: 1 addition & 1 deletion tournaments/tournaments.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def __init__(self, bot: Red):
except Exception as e:
log.error("Couldn't load dev env values.", exc_info=e)

__version__ = "1.1.9"
__version__ = "1.1.10"
__author__ = ["retke (El Laggron)", "Wonderfall", "Xyleff"]

@commands.command(hidden=True)
Expand Down

0 comments on commit e657fed

Please sign in to comment.