Exemple #1
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()
Exemple #2
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()
Exemple #3
0
    async def reschedule(self, ctx, match_id: str, *, date: str):
        """Allows players to reschedule their matches."""
        try:
            new_date = dateparser.parse(date)
        except ValueError:
            raise commands.UserInputError()
        tournament = self.get_tournament(ctx.guild.id)
        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

        now = datetime.datetime.utcnow()
        self.validate_new_date(tournament, now, new_date,
                               skip_deadline_validation)
        try:
            tosurnament_user = self.get_verified_user(ctx.author.id)
            user_name = tosurnament_user.osu_name
        except (tosurnament.UserNotLinked, tosurnament.UserNotVerified
                ):  # ! Temporary for nik's tournament
            user_name = ""
        for bracket in tournament.brackets:
            schedules_spreadsheet = bracket.schedules_spreadsheet
            if not schedules_spreadsheet:
                continue
            try:
                match_info = MatchInfo.from_id(schedules_spreadsheet, match_id)
            except tosurnament.SpreadsheetHttpError as e:
                await self.on_cog_command_error(ctx, ctx.command.name, e)
                continue
            except DuplicateMatchId:
                await self.send_reply(ctx, ctx.command.name,
                                      "duplicate_match_id", match_id)
                continue
            except (InvalidWorksheet, MatchIdNotFound):
                continue
            match_id = match_info.match_id.value

            players_spreadsheet = bracket.players_spreadsheet
            if players_spreadsheet and players_spreadsheet.range_team_name:
                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)
                    continue
                except (InvalidWorksheet, TeamNotFound, DuplicateTeam):
                    continue
                if user_name in [cell.value for cell in team1_info.players]:
                    team_name = team1_info.team_name.value
                    opponent_team_name = team2_info.team_name.value
                    opponent_team_captain_name = team2_info.players[0].value
                else:
                    team_name = team2_info.team_name.value
                    opponent_team_name = team1_info.team_name.value
                    opponent_team_captain_name = team1_info.players[0].value
            else:
                # ! Temporary
                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)
                    continue
                except (InvalidWorksheet, DuplicateTeam):
                    continue
                except TeamNotFound:
                    raise tosurnament.InvalidMatch()
                if team1_info.discord[0] == str(ctx.author):
                    user_name = team1_info.players[0].value
                    opponent_team_captain = ctx.guild.get_member_named(
                        team2_info.discord[0])
                elif team2_info.discord[0] == str(ctx.author):
                    user_name = team2_info.players[0].value
                    opponent_team_captain = ctx.guild.get_member_named(
                        team1_info.discord[0])
                else:
                    raise tosurnament.InvalidMatch()
                # ! Temporary
                team_name = user_name
                if match_info.team1.value == user_name:
                    opponent_team_name = match_info.team2.value
                    opponent_team_captain_name = opponent_team_name
                elif match_info.team2.value == user_name:
                    opponent_team_name = match_info.team1.value
                    opponent_team_captain_name = opponent_team_name
                else:
                    raise tosurnament.InvalidMatch()

            previous_date = self.validate_reschedule_feasibility(
                tournament, schedules_spreadsheet, match_info, now, new_date,
                skip_deadline_validation)

            if not opponent_team_captain:  # ! Temporary
                opponent_team_captain = ctx.guild.get_member_named(
                    opponent_team_captain_name)
            if not opponent_team_captain:
                raise tosurnament.OpponentNotFound(ctx.author.mention)

            reschedule_message = RescheduleMessage(tournament_id=tournament.id,
                                                   bracket_id=bracket.id,
                                                   in_use=False)

            opponent_to_ping = opponent_team_captain
            if tournament.reschedule_ping_team:
                role = tosurnament.get_role(ctx.guild.roles, None,
                                            opponent_team_name)
                if role:
                    opponent_to_ping = role
                role = tosurnament.get_role(ctx.guild.roles, None, team_name)
                if role:
                    reschedule_message.ally_team_role_id = role.id

            reschedule_message.match_id = match_id
            reschedule_message.ally_user_id = ctx.author.id
            reschedule_message.opponent_user_id = opponent_team_captain.id
            previous_date_string = previous_date.strftime(
                tosurnament.PRETTY_DATE_FORMAT)
            reschedule_message.previous_date = previous_date.strftime(
                tosurnament.DATABASE_DATE_FORMAT)
            new_date_string = new_date.strftime(tosurnament.PRETTY_DATE_FORMAT)
            reschedule_message.new_date = new_date.strftime(
                tosurnament.DATABASE_DATE_FORMAT)
            sent_message = await self.send_reply(
                ctx,
                ctx.command.name,
                "success",
                opponent_to_ping.mention,
                escape_markdown(user_name),
                match_id,
                previous_date_string,
                new_date_string,
            )
            reschedule_message.message_id = sent_message.id
            self.bot.session.add(reschedule_message)
            await sent_message.add_reaction("👍")
            await sent_message.add_reaction("👎")
            return
        raise tosurnament.InvalidMatchId()
Exemple #4
0
    async def reschedule_for_bracket(
        self,
        ctx,
        tournament,
        bracket,
        match_id,
        new_date,
    ):
        schedules_spreadsheet = await bracket.get_schedules_spreadsheet()
        if not schedules_spreadsheet:
            return False
        match_info = await self.get_match_from_id(schedules_spreadsheet,
                                                  match_id)
        if not match_info:
            return False
        match_id = match_info.match_id.get()

        players_spreadsheet = await bracket.get_players_spreadsheet()
        if not players_spreadsheet:
            raise tosurnament.NoSpreadsheet("players")
        ally_team_info, opponent_team_info = await self.get_teams_info(
            ctx, tournament, players_spreadsheet, match_info)
        if not ally_team_info:
            raise tosurnament.InvalidMatch()

        skip_deadline_validation = self.is_skip_deadline_validation(
            tournament, match_id)
        new_date = self.validate_new_date(ctx, tournament, match_info,
                                          new_date, skip_deadline_validation)
        previous_date = self.validate_reschedule_feasibility(
            ctx, tournament, schedules_spreadsheet, match_info, new_date,
            skip_deadline_validation)

        team_name = ally_team_info.team_name.get()
        opponent_team_name = opponent_team_info.team_name.get()
        opponent_user = tosurnament.UserAbstraction.get_from_player_info(
            ctx.bot, opponent_team_info.get_team_captain(), ctx.guild)

        opponent_team_captain = opponent_user.get_member(ctx.guild)
        if not opponent_team_captain:
            raise tosurnament.OpponentNotFound(ctx.author.mention)

        reschedule_message = RescheduleMessage(tournament_id=tournament.id,
                                               bracket_id=bracket.id)

        opponent_to_ping = opponent_team_captain
        if players_spreadsheet.range_team_name and tournament.reschedule_ping_team:
            opponent_team_role = tosurnament.get_role(ctx.guild.roles, None,
                                                      opponent_team_name)
            if opponent_team_role:
                opponent_to_ping = opponent_team_role
            ally_team_role = tosurnament.get_role(ctx.guild.roles, None,
                                                  team_name)
            if ally_team_role:
                reschedule_message.ally_team_role_id = str(ally_team_role.id)

        reschedule_message.match_id = match_id
        reschedule_message.match_id_hash = match_id
        reschedule_message.ally_user_id = str(ctx.author.id)
        reschedule_message.opponent_user_id = str(opponent_team_captain.id)
        if previous_date:
            previous_date_string = self.get_pretty_date(
                ctx, tournament, previous_date)
            reschedule_message.previous_date = previous_date.strftime(
                tosurnament.DATABASE_DATE_FORMAT)
        else:
            previous_date_string = self.get_string(ctx, "no_previous_date")
            reschedule_message.previous_date = ""
        new_date_string = self.get_pretty_date(ctx, tournament, new_date)
        reschedule_message.new_date = new_date.strftime(
            tosurnament.DATABASE_DATE_FORMAT)
        sent_message = await self.send_reply(
            ctx,
            "success",
            opponent_to_ping.mention,
            escape_markdown(team_name),
            match_id,
            previous_date_string,
            new_date_string,
        )
        reschedule_message.message_id = sent_message.id

        previous_reschedule_message = (
            self.bot.session.query(RescheduleMessage).where(
                RescheduleMessage.tournament_id == tournament.id).where(
                    RescheduleMessage.match_id_hash == match_id).first())
        if previous_reschedule_message:
            self.bot.session.delete(previous_reschedule_message)

        self.bot.session.add(reschedule_message)
        await sent_message.add_reaction("👍")
        await sent_message.add_reaction("👎")
        return True
Exemple #5
0
    async def reschedule_for_bracket(
        self,
        ctx,
        tournament,
        bracket,
        schedules_spreadsheet,
        players_spreadsheet,
        match_id,
        new_date,
        user,
        skip_deadline_validation,
        retry=False,
    ):
        try:
            match_info = MatchInfo.from_id(schedules_spreadsheet, match_id)
        except (tosurnament.SpreadsheetHttpError, InvalidWorksheet) as e:
            if retry:
                await self.on_cog_command_error(ctx, ctx.command.name, e)
            return False
        except MatchIdNotFound as e:
            if retry:
                self.bot.info_exception(e)
            return False
        match_id = match_info.match_id.value

        players_spreadsheet = bracket.players_spreadsheet
        if players_spreadsheet:
            await players_spreadsheet.get_spreadsheet()
            if not user.verified:
                # TODO find player_name from discord_id in players_spreadsheet
                pass
            ally_team_info, opponent_team_info = await self.get_teams_info(
                ctx, tournament, players_spreadsheet, match_info, user)
            if not ally_team_info:
                return False
            team_name = ally_team_info.team_name.value
            opponent_team_name = opponent_team_info.team_name.value
            opponent_user = tosurnament.UserAbstraction.get_from_osu_name(
                ctx.bot, opponent_team_info.players[0].value,
                opponent_team_info.discord[0].value)
        else:
            team_name = user.name
            if team_name == match_info.team1.value:
                opponent_team_name = match_info.team2.value
            elif team_name == match_info.team2.value:
                opponent_team_name = match_info.team1.value
            else:
                raise tosurnament.InvalidMatch()
            opponent_user = tosurnament.UserAbstraction.get_from_osu_name(
                ctx.bot, opponent_team_name)

        now = datetime.datetime.utcnow()
        new_date = self.validate_new_date(ctx, tournament,
                                          schedules_spreadsheet, match_info,
                                          now, new_date,
                                          skip_deadline_validation)
        previous_date = self.validate_reschedule_feasibility(
            ctx, tournament, schedules_spreadsheet, match_info, now, new_date,
            skip_deadline_validation)

        opponent_team_captain = opponent_user.get_member(ctx.guild)
        if not opponent_team_captain:
            raise tosurnament.OpponentNotFound(ctx.author.mention)

        opponent_to_ping = opponent_team_captain
        if players_spreadsheet and players_spreadsheet.range_team_name and tournament.reschedule_ping_team:
            role = tosurnament.get_role(ctx.guild.roles, None,
                                        opponent_team_name)
            if role:
                opponent_to_ping = role

        reschedule_message = RescheduleMessage(tournament_id=tournament.id,
                                               bracket_id=bracket.id,
                                               in_use=False)
        role = tosurnament.get_role(ctx.guild.roles, None, team_name)
        if role:
            reschedule_message.ally_team_role_id = role.id
        reschedule_message.match_id = match_id
        reschedule_message.match_id_hash = match_id
        reschedule_message.ally_user_id = ctx.author.id
        reschedule_message.opponent_user_id = opponent_team_captain.id
        if previous_date:
            previous_date_string = tosurnament.get_pretty_date(
                tournament, previous_date)
            reschedule_message.previous_date = previous_date.strftime(
                tosurnament.DATABASE_DATE_FORMAT)
        else:
            previous_date_string = "**No previous date**"
            reschedule_message.previous_date = ""
        new_date_string = tosurnament.get_pretty_date(tournament, new_date)
        reschedule_message.new_date = new_date.strftime(
            tosurnament.DATABASE_DATE_FORMAT)
        sent_message = await self.send_reply(
            ctx,
            ctx.command.name,
            "success",
            opponent_to_ping.mention,
            escape_markdown(team_name),
            match_id,
            previous_date_string,
            new_date_string,
        )
        reschedule_message.message_id = sent_message.id

        previous_reschedule_message = (
            self.bot.session.query(RescheduleMessage).where(
                RescheduleMessage.tournament_id == tournament.id).where(
                    RescheduleMessage.match_id_hash == match_id).first())
        if previous_reschedule_message:
            self.bot.session.delete(previous_reschedule_message)

        self.bot.session.add(reschedule_message)
        await sent_message.add_reaction("👍")
        await sent_message.add_reaction("👎")
        return True