Ejemplo n.º 1
0
 async def get_teams_info(self,
                          ctx,
                          tournament,
                          players_spreadsheet,
                          match_info,
                          retry=False):
     """Returns ally and enemy team info"""
     try:
         team1_info = TeamInfo.from_team_name(players_spreadsheet,
                                              match_info.team1.get())
         team2_info = TeamInfo.from_team_name(players_spreadsheet,
                                              match_info.team2.get())
     except tosurnament.SpreadsheetHttpError as e:
         await self.on_cog_command_error(ctx, e)
         return None, None
     if players_spreadsheet.range_team_name:
         team_captain_role = tosurnament.get_role(
             ctx.guild.roles, tournament.team_captain_role_id,
             "Team Captain")
         if team_captain_role and not tosurnament.get_role(
                 ctx.author.roles, tournament.team_captain_role_id,
                 "Team Captain"):
             raise tosurnament.NotRequiredRole(team_captain_role.name)
     if self.get_player_in_team(ctx.author, team1_info):
         return team1_info, team2_info
     if self.get_player_in_team(ctx.author, team2_info):
         return team2_info, team1_info
     raise tosurnament.InvalidMatch()
Ejemplo n.º 2
0
 async def get_player_role_for_bracket(self, guild, tournament, user,
                                       user_name, player_role):
     """Gives the player role of the bracket to the user, if he is a player of this bracket."""
     bracket = tournament.current_bracket
     try:
         is_player, team_info = await self.is_a_player(bracket, user_name)
     except HttpError as e:
         raise tosurnament.SpreadsheetHttpError(e.code, e.operation,
                                                bracket.name, "players")
     if not is_player:
         return False
     roles_to_give = [player_role]
     bracket_role = tosurnament.get_role(guild.roles, bracket.role_id,
                                         bracket.name)
     if bracket_role:
         roles_to_give.append(bracket_role)
     if team_info:
         team_name = team_info.team_name.value
         team_role = tosurnament.get_role(guild.roles, None, team_name)
         if not team_role:
             try:
                 team_role = await guild.create_role(name=team_name,
                                                     mentionable=False)
             except discord.InvalidArgument:
                 raise tosurnament.InvalidRoleName(team_name)
         if team_role:
             roles_to_give.append(team_role)
         if team_name == team_info.players[0].value:
             team_captain_role = tosurnament.get_role(
                 guild.roles, tournament.team_captain_role_id,
                 "Team Captain")
             if team_captain_role:
                 roles_to_give.append(team_captain_role)
     await user.add_roles(*roles_to_give)
     return True
Ejemplo n.º 3
0
 async def get_player_role_for_user(self, guild, user, channel=None):
     """Gives the corresponding player role to the user."""
     tournament = self.get_tournament(guild.id)
     player_role_id = tournament.player_role_id
     if tosurnament.get_role(user.roles, player_role_id, "Player"):
         raise tosurnament.UserAlreadyPlayer()
     try:
         tosurnament_user = self.get_verified_user(user.id)
         user_name = tosurnament_user.osu_name
     except (tosurnament.UserNotLinked, tosurnament.UserNotVerified):
         user_name = user.display_name
     roles = guild.roles
     player_role = tosurnament.get_role(roles, player_role_id, "Player")
     if not player_role:
         raise tosurnament.RoleDoesNotExist("Player")
     got_role = False
     for bracket in tournament.brackets:
         tournament.current_bracket_id = bracket.id
         try:
             got_role |= await self.get_player_role_for_bracket(
                 guild,
                 tournament,
                 user,
                 user_name,
                 player_role,
             )
         except Exception as e:
             if channel:
                 await self.on_cog_command_error(channel, "get_player_role",
                                                 e)
     return got_role
Ejemplo n.º 4
0
    async def register(
            self,
            ctx,
            timezone: str = ""):  # TODO handle teams + multiples brackets
        """Registers the player to the tournament."""
        verified_user = self.get_verified_user(ctx.author.id)
        tournament = self.get_tournament(ctx.guild.id)
        if len(tournament.brackets) != 1:
            await self.send_reply(ctx, "not_supported_yet")
            return
        bracket = tournament.current_bracket
        if bracket.registration_end_date:
            registration_end_date = datetime.datetime.strptime(
                bracket.registration_end_date,
                tosurnament.DATABASE_DATE_FORMAT)
            if datetime.datetime.now() > registration_end_date:
                raise tosurnament.RegistrationEnded()

        players_spreadsheet = await bracket.get_players_spreadsheet()
        if not players_spreadsheet:
            raise tosurnament.NoSpreadsheet("players")
        if players_spreadsheet.range_team_name:
            await self.send_reply(ctx, "not_supported_yet")
            return
        if players_spreadsheet.range_timezone:
            if not timezone:
                raise commands.UserInputError()
            if not re.match(r"(UTC)?[-\+]([0-9]|1[0-4])(:[0-5][0-9])?$",
                            timezone, re.IGNORECASE):
                raise tosurnament.InvalidTimezone(timezone)
            timezone = "UTC" + re.sub(
                r"^UTC", "", timezone, flags=re.IGNORECASE)
        osu_user = osu.get_user(verified_user.osu_id, m=tournament.game_mode)
        if not osu_user:
            raise tosurnament.UserNotFound(verified_user.osu_id)
        team_info = TeamInfo.get_first_blank_fields(players_spreadsheet)
        player_info = team_info.players[0]
        player_info.name.set(osu_user.name)
        player_info.discord.set(str(ctx.author))
        player_info.discord_id.set(ctx.author.id)
        player_info.rank.set(str(osu_user.rank))
        player_info.bws_rank.set(str(osu_user.rank))
        player_info.osu_id.set(str(osu_user.id))
        player_info.pp.set(str(int(float(osu_user.pp))))
        player_info.country.set(str(osu_user.country))
        team_info.timezone.set(timezone)
        self.add_update_spreadsheet_background_task(players_spreadsheet)
        roles_to_give = [
            tosurnament.get_role(ctx.guild.roles, tournament.player_role_id,
                                 "Player")
        ]
        roles_to_give.append(
            tosurnament.get_role(ctx.guild.roles, bracket.role_id,
                                 bracket.name))
        await ctx.author.add_roles(*filter(None, roles_to_give))
        try:
            await ctx.author.edit(nick=osu_user.name)
        except (discord.Forbidden, discord.HTTPException):
            pass
        await self.send_reply(ctx, "success")
Ejemplo n.º 5
0
 async def get_player_role_for_bracket(self, guild, tournament, member,
                                       player_role):
     """Gives the player role of the bracket to the user, if he is a player of this bracket."""
     bracket = tournament.current_bracket
     team_infos, _ = await self.get_all_teams_infos_and_roles(
         guild, await bracket.get_players_spreadsheet())
     for team_info in team_infos:
         player = self.get_player_in_team(member, team_info)
         if not player:
             continue
         roles_to_give = [player_role]
         team_name = team_info.team_name.get()
         team_role = tosurnament.get_role(guild.roles, None, team_name)
         if not team_role:
             try:
                 team_role = await guild.create_role(name=team_name,
                                                     mentionable=False)
             except discord.InvalidArgument:
                 raise tosurnament.InvalidRoleName(team_name)
         if team_role:
             roles_to_give.append(team_role)
         if player.is_captain:
             team_captain_role = tosurnament.get_role(
                 guild.roles, tournament.team_captain_role_id,
                 "Team Captain")
             if team_captain_role:
                 roles_to_give.append(team_captain_role)
         await member.add_roles(*roles_to_give)
         return True
     return False
Ejemplo n.º 6
0
 async def step8_remove_player_role(self, ctx, error_channel, tournament, challonge_tournament, loser_participant):
     if challonge_tournament.state == "group_stages_underway":
         for match in challonge_tournament.matches:
             if not match.state == "complete":
                 return
         self.send_reply(error_channel, "post_result", "group_stages_complete")
     elif challonge_tournament.state == "underway":
         matches = challonge.get_participant_with_matches(challonge_tournament.id, loser_participant.id)
         for match in matches:
             if not match.state == "complete":
                 return
         bracket = tournament.current_bracket
         try:
             team_info = TeamInfo.from_team_name(bracket.players_spreadsheet, loser_participant.name)
             player_role = tosurnament.get_role(ctx.guild.roles, tournament.player_role_id, "Player")
             roles_to_remove = [player_role]
             bracket_role = tosurnament.get_role(ctx.guild.roles, bracket.role_id, bracket.name)
             if bracket_role:
                 roles_to_remove.append(bracket_role)
             team_name = team_info.team_name.value
             team_role = tosurnament.get_role(ctx.guild.roles, None, team_name)
             if team_role:
                 roles_to_remove.append(team_role)
             if team_info.discord[0]:
                 member = ctx.guild.get_member_named(team_info.discord[0])
                 if member:
                     member.remove_roles(*roles_to_remove)
             for player_cell in team_info.players:
                 member = ctx.guild.get_member_named(player_cell.value)
                 if member:
                     member.remove_roles(*roles_to_remove)
         except Exception:
             return
Ejemplo n.º 7
0
 async def fill_matches_info_for_roles(self, ctx, tournament, bracket,
                                       user_details):
     user_name = user_details.name
     team_name = None
     has_bracket_role = False
     bracket_role = tosurnament.get_role(ctx.guild.roles, bracket.role_id)
     if not bracket_role or tosurnament.get_role(ctx.author.roles,
                                                 bracket.role_id):
         has_bracket_role = True
     if user_details.player:
         team_name = await self.find_player_identification(
             ctx, bracket, user_name)
     matches_data = await self.get_next_matches_info_for_bracket(
         tournament, bracket)
     for match_info, match_date in matches_data:
         if (user_details.player and has_bracket_role and team_name
                 and (match_info.team1.has_value(team_name)
                      or match_info.team2.has_value(team_name))):
             user_details.player.taken_matches.append(
                 (bracket.name, match_info, match_date))
         for referee_cell in match_info.referees:
             if user_details.referee and referee_cell.has_value(user_name):
                 user_details.referee.taken_matches.append(
                     (bracket.name, match_info, match_date))
         for streamer_cell in match_info.streamers:
             if user_details.streamer and streamer_cell.has_value(
                     user_name):
                 user_details.streamer.taken_matches.append(
                     (bracket.name, match_info, match_date))
         for commentator_cell in match_info.commentators:
             if user_details.commentator and commentator_cell.has_value(
                     user_name):
                 user_details.commentator.taken_matches.append(
                     (bracket.name, match_info, match_date))
Ejemplo n.º 8
0
 async def give_player_role(self, guild, tournament):
     player_role = tosurnament.get_role(guild.roles,
                                        tournament.player_role_id, "Player")
     if not player_role:
         return
     for bracket in tournament.brackets:
         players_spreadsheet = await bracket.get_players_spreadsheet(
             retry=True, force_sync=True)
         if not players_spreadsheet:
             continue
         bracket_role = tosurnament.get_role(guild.roles, bracket.role_id,
                                             bracket.name)
         team_infos, team_roles = await self.get_all_teams_infos_and_roles(
             guild, players_spreadsheet)
         for team_info_index, team_info in enumerate(team_infos):
             team_role = None
             if players_spreadsheet.range_team_name:
                 team_role = team_roles[team_info_index]
                 if not team_role:
                     team_role = await guild.create_role(
                         name=team_info.team_name.get(), mentionable=False)
             for player in team_info.players:
                 user = tosurnament.UserAbstraction.get_from_player_info(
                     self.bot, player, guild)
                 member = user.get_member(guild)
                 if member:
                     try:
                         await member.add_roles(*filter(
                             None, [player_role, bracket_role, team_role]))
                         await member.edit(nick=player.name.get())
                     except Exception:
                         continue
Ejemplo n.º 9
0
 async def give_player_role(self, guild, tournament):  # TODO: better
     player_role = tosurnament.get_role(guild.roles,
                                        tournament.player_role_id, "Player")
     if not player_role:
         return
     for bracket in tournament.brackets:
         players_spreadsheet = bracket.players_spreadsheet
         if not players_spreadsheet:
             continue
         bracket_role = tosurnament.get_role(guild.roles, bracket.role_id,
                                             bracket.name)
         await players_spreadsheet.get_spreadsheet()
         if players_spreadsheet.range_team_name:
             team_name_cells = players_spreadsheet.spreadsheet.get_cells_with_value_in_range(
                 players_spreadsheet.range_team_name)
             for team_name_cell in team_name_cells:
                 team_info = TeamInfo.from_team_name(
                     players_spreadsheet, team_name_cell.value)
                 team_name = team_info.team_name.value
                 team_role = tosurnament.get_role(guild.roles, None,
                                                  team_name)
                 if not team_role:
                     team_role = await guild.create_role(name=team_name,
                                                         mentionable=False)
                 for i, player_cell in enumerate(team_info.players):
                     player_name = player_cell.value
                     if not player_name:
                         continue
                     discord_tag = None
                     if len(team_info.discord
                            ) > i and team_info.discord[i].value:
                         discord_tag = team_info.discord[i].value
                     user = tosurnament.UserAbstraction.get_from_osu_name(
                         self.bot, player_name, discord_tag)
                     member = user.get_member(guild)
                     if not member:
                         member = guild.get_member_named(user.name)
                     if member:
                         await member.add_roles(*filter(
                             None, [player_role, bracket_role, team_role]))
         else:
             team_cells = players_spreadsheet.spreadsheet.get_cells_with_value_in_range(
                 players_spreadsheet.range_team)
             for cell in team_cells:
                 try:
                     team_info = TeamInfo.from_player_name(
                         players_spreadsheet, cell.value)
                     if team_info.discord[0].value:
                         user = guild.get_member_named(
                             team_info.discord[0].value)
                     else:
                         user = guild.get_member_named(
                             team_info.team_name.value)
                     if user:
                         await user.add_roles(
                             *filter(None, [player_role, bracket_role]))
                 except Exception:
                     continue
Ejemplo n.º 10
0
    async def clear_player_role(self, ctx, bracket_index: int = None, remove_player_role: bool = True):
        """Removes the player role of users not present in the challonge."""
        tournament = self.get_tournament(ctx.guild.id)
        brackets = tournament.brackets
        if len(brackets) != 1:
            if bracket_index is None:
                brackets_string = ""
                for i, bracket in enumerate(brackets):
                    brackets_string += str(i + 1) + ": `" + bracket.name + "`\n"
                await self.send_reply(ctx, ctx.command.name, "default", brackets_string)
                return
            elif bracket_index <= 0 or bracket_index > len(brackets):
                raise commands.UserInputError()
            bracket_index -= 1
        else:
            bracket_index = 0
        bracket = brackets[bracket_index]
        if not bracket.challonge:
            raise tosurnament.NoChallonge(bracket.name)
        player_role = tosurnament.get_role(ctx.guild.roles, tournament.player_role_id, "Player")
        bracket_role = tosurnament.get_role(ctx.guild.roles, bracket.role_id, bracket.name)
        team_captain_role = tosurnament.get_role(ctx.guild.roles, tournament.team_captain_role_id, "Team Captain")
        if remove_player_role:
            roles_to_removes = list(filter(None, [player_role, bracket_role, team_captain_role]))
        else:
            roles_to_removes = list(filter(None, [bracket_role, team_captain_role]))

        challonge_tournament = challonge.get_tournament(bracket.challonge)
        participants = [participant.name for participant in challonge_tournament.participants]
        participants_lower = [participant.lower() for participant in participants]

        players_spreadsheet = bracket.players_spreadsheet
        teams_info = []
        if players_spreadsheet:
            await players_spreadsheet.get_spreadsheet()
            if players_spreadsheet.range_team_name:
                team_cells = players_spreadsheet.spreadsheet.get_cells_with_value_in_range(
                    players_spreadsheet.range_team_name
                )
            else:
                team_cells = players_spreadsheet.spreadsheet.get_cells_with_value_in_range(
                    players_spreadsheet.range_team
                )
            teams_info = []
            for cell in team_cells:
                try:
                    team_info = TeamInfo.from_team_name(players_spreadsheet, cell.value)
                except Exception:
                    continue
                if players_spreadsheet.range_team_name:
                    if team_role := tosurnament.get_role(ctx.guild.roles, None, team_info.team_name.value):
                        roles_to_removes.append(team_role)
                teams_info.append(team_info)
Ejemplo n.º 11
0
 async def allow_next_reschedule(self,
                                 ctx,
                                 match_id: str,
                                 allowed_hours: int = 24):
     """Allows a match to be reschedule without any time constraint applied."""
     tournament = self.get_tournament(ctx.guild.id)
     tosurnament_guild = self.get_guild(ctx.guild.id)
     admin_role = tosurnament.get_role(ctx.author.roles,
                                       tosurnament_guild.admin_role_id)
     referee_role = tosurnament.get_role(ctx.author.roles,
                                         tournament.referee_role_id,
                                         "Referee")
     if not admin_role and not ctx.guild.owner == ctx.author and not referee_role:
         raise tosurnament.NotRequiredRole("Referee")
     match_found = False
     for bracket in tournament.brackets:
         schedules_spreadsheet = bracket.schedules_spreadsheet
         if not schedules_spreadsheet:
             continue
         await schedules_spreadsheet.get_spreadsheet()
         try:
             match_info = MatchInfo.from_id(schedules_spreadsheet, match_id)
         except (tosurnament.SpreadsheetHttpError, InvalidWorksheet) as e:
             await self.on_cog_command_error(ctx, ctx.command.name, e)
             continue
         except MatchIdNotFound as e:
             self.bot.info(str(type(e)) + ": " + str(e))
             continue
         match_found = True
         if admin_role or ctx.guild.owner == ctx.author:
             break
         user = tosurnament.UserAbstraction.get_from_ctx(ctx)
         is_referee_of_match = False
         for referee_cell in match_info.referees:
             if referee_cell.has_value(user.name):
                 is_referee_of_match = True
                 break
         if not is_referee_of_match:
             raise tosurnament.NotRefereeOfMatch()
     if not match_found:
         raise MatchIdNotFound(match_id)
     team1 = await self.get_team_mention(ctx.guild,
                                         bracket.players_spreadsheet,
                                         match_info.team1.value)
     team2 = await self.get_team_mention(ctx.guild,
                                         bracket.players_spreadsheet,
                                         match_info.team2.value)
     allowed_reschedule = AllowedReschedule(tournament_id=tournament.id,
                                            match_id=match_id,
                                            allowed_hours=allowed_hours)
     self.bot.session.add(allowed_reschedule)
     await self.send_reply(ctx, ctx.command.name, "success", match_id,
                           allowed_hours, team1, team2)
Ejemplo n.º 12
0
 async def register(
         self,
         ctx,
         osu_link: str,
         timezone: str = ""):  # TODO handle teams + multiples brackets
     """Registers the player to the tournament."""
     tournament = self.get_tournament(ctx.guild.id)
     if len(tournament.brackets) != 1:
         await self.send_reply(ctx, ctx.command.name, "not_supported_yet")
         return
     bracket = tournament.current_bracket
     players_spreadsheet = bracket.players_spreadsheet
     if players_spreadsheet.range_timezone:
         if not timezone:
             raise commands.MissingRequiredArgument("timezone")
         if not re.match(r"(UTC)?[-\+]([0-9]|1[0-4])$", timezone,
                         re.IGNORECASE):
             raise InvalidTimezone(timezone)
         timezone = "UTC" + re.sub(
             r"^UTC", "", timezone, flags=re.IGNORECASE)
     if players_spreadsheet.range_team_name:
         await self.send_reply(ctx, ctx.command.name, "not_supported_yet")
         return
     await players_spreadsheet.get_spreadsheet()
     team_info = TeamInfo.get_first_blank_fields(players_spreadsheet)
     osu_name = osu.get_from_string(osu_link)
     osu_user = osu.get_user(osu_name)
     if not osu_user:
         raise tosurnament.UserNotFound(osu_name)
     team_info.players[0].value = osu_user.name
     team_info.discord[0].value = str(ctx.author)
     team_info.discord_ids[0].value = str(ctx.author.id)
     team_info.ranks[0].value = str(osu_user.rank)
     team_info.bws_ranks[0].value = str(osu_user.rank)  # TODO
     team_info.osu_ids[0].value = str(osu_user.id)
     team_info.pps[0].value = str(int(float(osu_user.pp)))
     team_info.timezones[0].value = timezone
     self.add_update_spreadsheet_background_task(players_spreadsheet)
     roles_to_give = [
         tosurnament.get_role(ctx.guild.roles, tournament.player_role_id,
                              "Player")
     ]
     roles_to_give.append(
         tosurnament.get_role(ctx.guild.roles, bracket.role_id,
                              bracket.name))
     await ctx.author.add_roles(*filter(None, roles_to_give))
     try:
         await ctx.author.edit(nick=osu_user.name)
     except (discord.Forbidden, discord.HTTPException):
         pass
     await self.send_reply(ctx, ctx.command.name, "success")
Ejemplo n.º 13
0
    async def clear_player_role(self, ctx, *, number: int = None):
        """Removes the player role of users not present in the challonge."""
        # TODO improve to handle teams, bracket roles, team captain role
        # TODO and remove special code for nik's tournament and handle challonge error
        tournament = self.get_tournament(ctx.guild.id)
        player_role = tosurnament.get_role(ctx.guild.roles, tournament.player_role_id, "Player")
        if not player_role:
            return
        for bracket in tournament.brackets:
            players_spreadsheet = bracket.players_spreadsheet
            if not bracket.challonge or not players_spreadsheet:
                continue
            challonge_tournament = challonge.get_tournament(tournament.current_bracket.challonge)
            participants = [participant.name for participant in challonge_tournament.participants]
            team_cells = players_spreadsheet.worksheet.get_cells_with_value_in_range(players_spreadsheet.range_team)
            teams_info = []
            for cell in team_cells:
                try:
                    team_info = TeamInfo.from_player_name(players_spreadsheet, cell.value)
                    teams_info.append(team_info)
                except Exception:
                    continue

            players_found = []
            users_role_not_removed = []
            n_roles_removed = 0
            for member in ctx.guild.members:
                member_id = str(member)
                if player_name := self.is_player_in_challonge(member_id, teams_info, participants):
                    players_found.append(player_name)
                else:
                    try:
                        user = ctx.guild.get_member_named(member_id)
                        if user and tosurnament.get_role(user.roles, player_role.id, "Player"):
                            await user.remove_roles(player_role)
                            n_roles_removed += 1
                    except Exception:
                        users_role_not_removed.append(member_id)
                        continue
            success_extra = ""
            players_not_found = "\n".join(list(set(participants) - set(players_found)))
            if players_not_found:
                success_extra += self.get_string(ctx.command.name, "players_not_found", players_not_found)
            if users_role_not_removed:
                success_extra += self.get_string(
                    ctx.command.name, "users_role_not_removed", "\n".join(users_role_not_removed)
                )
            await self.send_reply(
                ctx, ctx.command.name, "success", bracket.name, n_roles_removed, len(players_found), success_extra,
            )
Ejemplo n.º 14
0
    async def reschedule(self, ctx, match_id: str, *, date: str):
        """Allows players to reschedule their matches."""
        tournament = self.get_tournament(ctx.guild.id)
        try:
            new_date = tournament.parse_date(date, prefer_dates_from="future")
        except ValueError:
            raise commands.UserInputError()
        if not new_date:
            raise commands.UserInputError()
        skip_deadline_validation = False
        allowed_reschedule_match_ids = [
            allowed_reschedule.match_id.upper() for allowed_reschedule in
            self.bot.session.query(AllowedReschedule).where(
                AllowedReschedule.tournament_id == tournament.id).all()
        ]
        if match_id.upper() in allowed_reschedule_match_ids:
            skip_deadline_validation = True

        user = tosurnament.UserAbstraction.get_from_ctx(ctx)
        bracket_role_present = False
        for bracket in tournament.brackets:
            bracket_role = tosurnament.get_role(ctx.guild.roles,
                                                bracket.role_id)
            if bracket_role and not tosurnament.get_role(
                    ctx.author.roles, bracket.role_id):
                bracket_role_present = True
                continue
            schedules_spreadsheet = bracket.schedules_spreadsheet
            if not schedules_spreadsheet:
                continue
            await schedules_spreadsheet.get_spreadsheet()
            players_spreadsheet = bracket.players_spreadsheet
            if players_spreadsheet:
                await players_spreadsheet.get_spreadsheet()

            if await self.reschedule_for_bracket(
                    ctx,
                    tournament,
                    bracket,
                    schedules_spreadsheet,
                    players_spreadsheet,
                    match_id,
                    new_date,
                    user,
                    skip_deadline_validation,
            ):
                return
        if bracket_role_present:
            raise tosurnament.InvalidMatchIdOrNoBracketRole()
        raise tosurnament.InvalidMatchId()
Ejemplo n.º 15
0
 async def get_teams_info(self, ctx, tournament, players_spreadsheet,
                          match_info, user):
     """Returns ally and enemy team info"""
     try:
         team1_info = TeamInfo.from_team_name(players_spreadsheet,
                                              match_info.team1.value)
         team2_info = TeamInfo.from_team_name(players_spreadsheet,
                                              match_info.team2.value)
     except tosurnament.SpreadsheetHttpError as e:
         await self.on_cog_command_error(ctx, ctx.command.name, e)
         return None, None
     if players_spreadsheet.range_team_name:
         team_captain_role = tosurnament.get_role(
             ctx.guild.roles, tournament.team_captain_role_id,
             "Team Captain")
         if team_captain_role:
             if not tosurnament.get_role(ctx.author.roles,
                                         tournament.team_captain_role_id,
                                         "Team Captain"):
                 raise tosurnament.NotRequiredRole(team_captain_role.name)
             if user.verified:
                 if user.name in [
                         cell.value.lower() for cell in team1_info.players
                 ]:
                     return team1_info, team2_info
                 elif user.name in [
                         cell.value.lower() for cell in team2_info.players
                 ]:
                     return team2_info, team1_info
             if str(ctx.author) in [
                     cell.value for cell in team1_info.discord
             ]:
                 return team1_info, team2_info
             elif str(ctx.author) in [
                     cell.value for cell in team2_info.discord
             ]:
                 return team2_info, team1_info
             raise tosurnament.InvalidMatch()
     if user.verified:
         if user.name == team1_info.players[0].value:
             return team1_info, team2_info
         elif user.name == team2_info.players[0].value:
             return team2_info, team1_info
     if str(ctx.author) == team1_info.discord[0].value:
         return team1_info, team2_info
     elif str(ctx.author) == team2_info.discord[0].value:
         return team2_info, team1_info
     raise tosurnament.InvalidMatch()
Ejemplo n.º 16
0
 async def reaction_on_reschedule_message(self, ctx, emoji,
                                          reschedule_message):
     """Reschedules a match or denies the reschedule."""
     if str(ctx.author.id) != reschedule_message.opponent_user_id:
         return
     try:
         tournament = self.get_tournament(ctx.guild.id)
         tournament.current_bracket_id = reschedule_message.bracket_id
         if not tournament.current_bracket:
             raise tosurnament.UnknownError("Bracket not found")
         if emoji.name == "👍":
             await self.agree_to_reschedule(ctx, reschedule_message,
                                            tournament)
         else:
             self.bot.session.delete(reschedule_message)
             ally_to_mention = None
             if reschedule_message.ally_team_role_id:
                 ally_to_mention = tosurnament.get_role(
                     ctx.guild.roles, reschedule_message.ally_team_role_id)
             if not ally_to_mention:
                 ally_to_mention = ctx.guild.get_member(
                     int(reschedule_message.ally_user_id))
             if ally_to_mention:
                 await self.send_reply(ctx, "refused",
                                       ally_to_mention.mention,
                                       reschedule_message.match_id)
             else:
                 raise tosurnament.OpponentNotFound(ctx.author.mention)
     except Exception as e:
         await self.on_cog_command_error(ctx, e)
Ejemplo n.º 17
0
 async def reaction_on_match_notification(self, ctx, emoji,
                                          match_notification):
     """Allows a referee to take a match from its notification."""
     tournament = tosurnament_api.get_tournament(
         match_notification.tournament_id)
     if not tournament:
         self.bot.session.delete(match_notification)
         return
     referee_role = tosurnament.get_role(ctx.author.roles,
                                         tournament.referee_role_id,
                                         "Referee")
     if not referee_role:
         return
     bracket = tosurnament_api.get_bracket(tournament.id,
                                           match_notification.bracket_id)
     if not bracket:
         self.bot.session.delete(match_notification)
         return
     try:
         await self.take_or_drop_match_in_spreadsheets(
             [match_notification.match_id],
             tosurnament.UserDetails.get_as_referee(self.bot, ctx.author),
             True,
             await bracket.get_schedules_spreadsheet(),
             await bracket.get_qualifiers_spreadsheet(),
         )
         # TODO if return of function not empty send error
     except Exception as e:
         await self.on_cog_command_error(ctx, e)
         return
     ctx.command.name = "player_match_notification"
     if match_notification.notification_type == 1:
         ctx.command.name = "referee_match_notification"
     elif match_notification.notification_type == 2:
         ctx.command.name = "qualifier_match_notification"
     match_notification_message = await ctx.channel.fetch_message(
         match_notification.message_id_int)
     if match_notification.notification_type == 2:
         await match_notification_message.edit(content=self.get_string(
             ctx,
             "edited",
             match_notification.match_id,
             match_notification.teams_mentions,
             referee_role.mention,
             match_notification.date_info,
             ctx.author.mention,
         ))
     else:
         await match_notification_message.edit(content=self.get_string(
             ctx,
             "edited",
             match_notification.match_id,
             match_notification.team1_mention,
             match_notification.team2_mention,
             referee_role.mention,
             match_notification.date_info,
             ctx.author.mention,
         ))
     self.bot.session.delete(match_notification)
Ejemplo n.º 18
0
 async def fill_matches_info_for_roles(self, ctx, tournament, bracket,
                                       user_details):
     user_name = user_details.name
     team_name = None
     if user_details.player:
         bracket_role = tosurnament.get_role(ctx.guild.roles,
                                             bracket.role_id)
         if not bracket_role or tosurnament.get_role(
                 ctx.author.roles, bracket.role_id):
             team_name = await self.find_team_name_of_member(ctx, bracket)
     matches_data = await self.get_next_matches_info_for_bracket(
         tournament, bracket)
     for match_info, match_date in matches_data:
         if isinstance(match_info, MatchInfo):
             if team_name and (match_info.team1.has_value(team_name)
                               or match_info.team2.has_value(team_name)):
                 user_details.player.taken_matches.append(
                     (bracket.name, match_info, match_date))
             if user_details.referee:
                 for referee_cell in match_info.referees:
                     if referee_cell.has_value(user_name):
                         user_details.referee.taken_matches.append(
                             (bracket.name, match_info, match_date))
                         break
             if user_details.streamer:
                 for streamer_cell in match_info.streamers:
                     if streamer_cell.has_value(user_name):
                         user_details.streamer.taken_matches.append(
                             (bracket.name, match_info, match_date))
                         break
             if user_details.commentator:
                 for commentator_cell in match_info.commentators:
                     if commentator_cell.has_value(user_name):
                         user_details.commentator.taken_matches.append(
                             (bracket.name, match_info, match_date))
                         break
         else:
             if team_name:
                 for team_cell in match_info.teams:
                     if team_cell.has_value(team_name):
                         user_details.player.taken_matches.append(
                             (bracket.name, match_info, match_date))
             if user_details.referee and match_info.referee and match_info.referee.has_value(
                     user_name):
                 user_details.referee.taken_matches.append(
                     (bracket.name, match_info, match_date))
Ejemplo n.º 19
0
 async def step8_remove_player_role(self, ctx, error_channel, tournament,
                                    challonge_tournament,
                                    loser_participant):
     if challonge_tournament.state == "group_stages_underway":
         for match in challonge_tournament.matches:
             if not match.state == "complete":
                 return
         await self.send_reply(ctx,
                               "group_stage_complete",
                               channel=error_channel)
     elif challonge_tournament.state == "underway":
         matches = challonge.get_matches_of_participant(
             challonge_tournament.id, loser_participant.id)
         for match in matches:
             if not match.state == "complete":
                 return
         bracket = tournament.current_bracket
         players_spreadsheet = await bracket.get_players_spreadsheet()
         if not players_spreadsheet:
             return
         try:
             team_info = TeamInfo.from_team_name(players_spreadsheet,
                                                 loser_participant.name)
             player_role = tosurnament.get_role(ctx.guild.roles,
                                                tournament.player_role_id,
                                                "Player")
             roles_to_remove = [player_role]
             bracket_role = tosurnament.get_role(ctx.guild.roles,
                                                 bracket.role_id,
                                                 bracket.name)
             if bracket_role:
                 roles_to_remove.append(bracket_role)
             team_role = tosurnament.get_role(ctx.guild.roles, None,
                                              team_info.team_name)
             if team_role:
                 roles_to_remove.append(team_role)
             for player in team_info.players:
                 user = tosurnament.UserAbstraction.get_from_player_info(
                     self.bot, player, ctx.guild)
                 member = user.get_member(ctx.guild)
                 if member:
                     await member.remove_roles(*roles_to_remove)
         except Exception:
             return
Ejemplo n.º 20
0
 async def reaction_on_match_notification(self, message_id, emoji, guild,
                                          channel, user):
     """Allows a referee to take a match from its notification."""
     if emoji.name != "💪":
         return
     match_notification = (self.bot.session.query(MatchNotification).where(
         MatchNotification.message_id_hash == message_id).first())
     if not match_notification or match_notification.in_use:
         return
     tournament = self.bot.session.query(Tournament).where(
         Tournament.id == match_notification.tournament_id).first()
     if not tournament:
         self.bot.session.delete(match_notification)
         return
     referee_role = tosurnament.get_role(user.roles,
                                         tournament.referee_role_id,
                                         "Referee")
     if not referee_role:
         return
     match_notification.in_use = True
     self.bot.session.update(match_notification)
     bracket = self.bot.session.query(Bracket).where(
         Bracket.id == match_notification.bracket_id).first()
     if not bracket:
         self.bot.session.delete(match_notification)
         return
     try:
         await self.take_or_drop_match_in_spreadsheets(
             [match_notification.match_id],
             tosurnament.UserDetails.get_as_referee(self.bot, user),
             True,
             set(),
             bracket.schedules_spreadsheet,
         )
         # TODO if not write_cells send error
     except Exception as e:
         match_notification.in_use = False
         self.bot.session.update(match_notification)
         await self.on_cog_command_error(channel, "take_match", e)
         return
     command_name = "player_match_notification"
     if match_notification.notification_type == 1:
         command_name = "referee_match_notification"
     match_notification_message = await channel.fetch_message(
         match_notification.message_id)
     await match_notification_message.edit(content=self.get_string(
         command_name,
         "edited",
         match_notification.match_id,
         match_notification.team1_mention,
         match_notification.team2_mention,
         referee_role.mention,
         match_notification.date_info,
         user.mention,
     ))
     self.bot.session.delete(match_notification)
Ejemplo n.º 21
0
 async def get_player_role_for_user(self, ctx, guild, member):
     """Gives the corresponding player role to the user."""
     tournament = self.get_tournament(guild.id)
     player_role_id = tournament.player_role_id
     if tosurnament.get_role(member.roles, player_role_id, "Player"):
         raise tosurnament.UserAlreadyPlayer()
     player_role = tosurnament.get_role(guild.roles, player_role_id,
                                        "Player")
     if not player_role:
         raise tosurnament.RoleDoesNotExist("Player")
     got_role = False
     for bracket in tournament.brackets:
         tournament.current_bracket_id = bracket.id
         try:
             got_role |= await self.get_player_role_for_bracket(
                 guild, tournament, member, player_role)
         except Exception as e:
             if ctx:
                 await self.on_cog_command_error(ctx, e)
     return got_role
Ejemplo n.º 22
0
 def cog_check(self, ctx):
     """Check function called before any command of the cog."""
     if not ctx.guild:
         raise commands.NoPrivateMessage()
     if ctx.guild.owner == ctx.author:
         return True
     guild = self.get_guild(ctx.guild.id)
     if not guild or not guild.admin_role_id:
         raise tosurnament.NotBotAdmin()
     if not tosurnament.get_role(ctx.author.roles, guild.admin_role_id):
         raise tosurnament.NotBotAdmin()
     return True
Ejemplo n.º 23
0
 def cog_check(self, ctx):
     if ctx.guild is None:
         raise commands.NoPrivateMessage()
     role_name = "Referee"
     tournament = self.get_tournament(ctx.guild.id)
     role_id = tournament.get_role_id(role_name)
     role = tosurnament.get_role(ctx.guild.roles, role_id, role_name)
     if not role:
         raise tosurnament.RoleDoesNotExist(role_name)
     if role in ctx.author.roles:
         return True
     raise tosurnament.NotRequiredRole(role.name)
Ejemplo n.º 24
0
 def get_referees_mentions_of_match(self, ctx, match_info):
     referees_to_ping, _ = self.find_staff_to_ping(ctx.guild,
                                                   match_info.referees)
     referees_mentions = " / ".join(
         [referee.mention for referee in referees_to_ping])
     if not referees_mentions:
         tosurnament_guild = self.get_guild(ctx.guild.id)
         admin_role = tosurnament.get_role(ctx.guild.roles,
                                           tosurnament_guild.admin_role_id)
         if admin_role:
             referees_mentions = admin_role.mention
         else:
             referees_mentions = self.get_string(ctx, "no_admin_role")
     return referees_mentions
Ejemplo n.º 25
0
 async def reaction_on_reschedule_message(self, message_id, emoji, guild,
                                          channel, user):
     """Reschedules a match or denies the reschedule."""
     reschedule_message = (self.bot.session.query(RescheduleMessage).where(
         RescheduleMessage.message_id == message_id).first())
     if not reschedule_message or reschedule_message.in_use:
         return
     if user.id != reschedule_message.opponent_user_id:
         return
     reschedule_message.in_use = True
     self.bot.session.update(reschedule_message)
     bracket = None
     try:
         tournament = self.get_tournament(guild.id)
         tournament.current_bracket_id = reschedule_message.bracket_id
         if not tournament.current_bracket:
             raise tosurnament.UnknownError("Bracket not found")
         if emoji.name == "👍":
             await self.agree_to_reschedule(reschedule_message, guild,
                                            channel, user, tournament)
         elif emoji.name == "👎":
             self.bot.session.delete(reschedule_message)
             ally_to_mention = None
             if reschedule_message.ally_team_role_id:
                 ally_to_mention = tosurnament.get_role(
                     guild.roles, reschedule_message.ally_team_role_id)
             if not ally_to_mention:
                 ally_to_mention = guild.get_member(
                     reschedule_message.ally_user_id)
             if ally_to_mention:
                 await self.send_reply(
                     channel,
                     "reschedule",
                     "refused",
                     ally_to_mention.mention,
                     reschedule_message.match_id,
                 )
             else:
                 raise tosurnament.OpponentNotFound(user.mention)
         else:
             reschedule_message.in_use = False
             self.bot.session.update(reschedule_message)
     except Exception as e:
         reschedule_message.in_use = False
         self.bot.session.update(reschedule_message)
         await self.reaction_on_reschedule_message_handler(
             channel, e, bracket)
Ejemplo n.º 26
0
 async def referee_match_notification(self, guild, tournament, bracket,
                                      channel, match_info, delta,
                                      match_date):
     if list(filter(None, [cell for cell in match_info.referees])):
         return
     if not (delta.days == 0 and delta.seconds >= 20700
             and delta.seconds < 21600):
         return
     referee_role = tosurnament.get_role(guild.roles,
                                         tournament.referee_role_id,
                                         "Referee")
     if referee_role:
         referee = referee_role.mention
     else:
         referee = self.get_simple_string(guild, "referee")
     match_date_str = self.get_pretty_date_for_guild(
         guild, tournament, match_date)
     team1 = escape_markdown(match_info.team1.get())
     team2 = escape_markdown(match_info.team2.get())
     message = await self.send_reply_in_bg_task(
         guild,
         channel,
         "referee_match_notification",
         "notification",
         match_info.match_id.get(),
         team1,
         team2,
         referee,
         match_date_str,
     )
     match_notification = MatchNotification(
         message_id_int=message.id,
         message_id=message.id,
         tournament_id=tournament.id,
         bracket_id=bracket.id,
         match_id=match_info.match_id.get(),
         team1_mention=team1,
         team2_mention=team2,
         date_info=match_date_str,
         notification_type=1,
     )
     self.bot.session.add(match_notification)
     try:
         await message.add_reaction("😱")
         await message.add_reaction("💪")
     except Exception as e:
         self.bot.info(str(type(e)) + ": " + str(e))
Ejemplo n.º 27
0
 async def get_team_mention(self, guild, players_spreadsheet, team_name):
     if not players_spreadsheet:
         return escape_markdown(team_name)
     try:
         team_info = TeamInfo.from_team_name(players_spreadsheet, team_name)
         if players_spreadsheet.range_team_name:
             team_role = tosurnament.get_role(guild.roles, None, team_name)
             if team_role:
                 return team_role.mention
         user = tosurnament.UserAbstraction.get_from_player_info(
             self.bot, team_info.get_team_captain(), guild)
         member = user.get_member(guild)
         if member:
             return member.mention
         return escape_markdown(team_name)
     except Exception as e:
         self.bot.info(str(type(e)) + ": " + str(e))
         return escape_markdown(team_name)
Ejemplo n.º 28
0
 async def reaction_on_match_notification(self, message_id, emoji, guild, channel, user):
     """Allows a referee to take a match from its notification."""
     match_notification = (
         self.bot.session.query(MatchNotification).where(MatchNotification.message_id_hash == message_id).first()
     )
     if not match_notification or match_notification.in_use:
         return
     tournament = self.bot.session.query(Tournament).where(Tournament.id == match_notification.tournament_id).first()
     if not tournament:
         self.bot.session.delete(match_notification)
         return
     if not tosurnament.get_role(user.roles, tournament.referee_role_id, "Referee"):
         return
     match_notification.in_use = True
     self.bot.session.update(match_notification)
     bracket = self.bot.session.query(Bracket).where(Bracket.id == match_notification.bracket_id).first()
     if not bracket:
         self.bot.session.delete(match_notification)
         return
     try:
         await self.take_or_drop_match(
             guild.id, user, channel, [match_notification.match_id], True, tosurnament.UserRoles.get_as_referee()
         )
     except Exception as e:
         match_notification.in_use = False
         self.bot.session.update(match_notification)
         await self.on_cog_command_error(channel, "take_match", e)
         return
     command_name = "player_match_notification"
     if match_notification.notification_type == 1:
         command_name = "referee_match_notification"
     match_notification_message = await channel.fetch_message(match_notification.message_id)
     await match_notification_message.edit(
         content=self.get_string(
             command_name,
             "edited",
             match_notification.match_id,
             match_notification.team1_mention,
             match_notification.team2_mention,
             user.mention,
             match_notification.date_info,
         )
     )
     self.bot.session.delete(match_notification)
Ejemplo n.º 29
0
 async def give_player_role(self, guild):
     tournament = self.get_tournament(guild.id)
     player_role = tosurnament.get_role(guild.roles,
                                        tournament.player_role_id, "Player")
     if not player_role:
         return
     for bracket in tournament.brackets:
         players_spreadsheet = bracket.players_spreadsheet
         if not players_spreadsheet:
             continue
         if players_spreadsheet.range_team_name:
             team_name_cells = players_spreadsheet.worksheet.get_cells_with_value_in_range(
                 players_spreadsheet.range_team_name)
             team_info = None
             for team_name_cell in team_name_cells:
                 team_info = TeamInfo.from_team_name(
                     players_spreadsheet, team_name_cell.value)
             if not team_info:
                 continue
             for player_cell in team_info.players:
                 user = guild.get_member_named(player_cell.value)
                 if user:
                     await user.add_roles(player_role)
         else:
             team_cells = players_spreadsheet.worksheet.get_cells_with_value_in_range(
                 players_spreadsheet.range_team)
             for cell in team_cells:
                 try:
                     team_info = TeamInfo.from_player_name(
                         players_spreadsheet, cell.value)
                     if team_info.discord[0]:
                         user = guild.get_member_named(team_info.discord[0])
                     else:
                         user = guild.get_member_named(
                             team_info.team_name.value)
                     if user:
                         await user.add_roles(player_role)
                 except Exception:
                     continue
Ejemplo n.º 30
0
 async def referee_match_notification(self, guild, tournament, bracket, channel, match_info, delta, match_date):
     if not list(filter(None, [cell.value for cell in match_info.referees])):
         if delta.days == 0 and delta.seconds >= 20700 and delta.seconds < 21600:
             referee_role = tosurnament.get_role(guild.roles, tournament.referee_role_id, "Referee")
             if referee_role:
                 referee = referee_role.mention
             else:
                 referee = "Referees"
             match_date_str = match_date.strftime(tosurnament.PRETTY_DATE_FORMAT)
             team1 = escape_markdown(match_info.team1.value)
             team2 = escape_markdown(match_info.team2.value)
             message = await self.send_reply(
                 channel,
                 "referee_match_notification",
                 "notification",
                 match_info.match_id.value,
                 team1,
                 team2,
                 referee,
                 match_date_str,
             )
             match_notification = MatchNotification(
                 message_id_hash=message.id,
                 message_id=message.id,
                 tournament_id=tournament.id,
                 bracket_id=bracket.id,
                 match_id=match_info.match_id.value,
                 team1_mention=team1,
                 team2_mention=team2,
                 date_info=match_date_str,
                 notification_type=1,
             )
             self.bot.session.add(match_notification)
             try:
                 await message.add_reaction("😱")
                 await message.add_reaction("💪")
             except Exception:
                 return