async def register_to_lobby(self, ctx, *, lobby_id: str): """Registers to a qualifier lobby.""" tournament = self.get_tournament(ctx.guild.id) qualifiers_spreadsheet_found = False team_found = False for bracket in tournament.brackets: qualifiers_spreadsheet = await bracket.get_qualifiers_spreadsheet() if not qualifiers_spreadsheet: continue qualifiers_spreadsheet_found = True players_spreadsheet = await bracket.get_players_spreadsheet() if not players_spreadsheet: raise tosurnament.NoSpreadsheet("players") team_info = await self.get_team_of_author(ctx, players_spreadsheet) if not team_info: continue team_found = True team_name = team_info.team_name.get() if not self.add_team_to_lobby(qualifiers_spreadsheet, lobby_id, team_name): continue self.clear_team_from_other_lobbies(qualifiers_spreadsheet, lobby_id, team_name) self.add_update_spreadsheet_background_task(qualifiers_spreadsheet) await self.send_reply(ctx, "success", lobby_id) return if not qualifiers_spreadsheet_found: raise tosurnament.NoSpreadsheet("qualifiers") if not team_found: raise tosurnament.NotAPlayer() raise tosurnament.LobbyNotFound(lobby_id)
async def show_players_spreadsheet_team(self, ctx, index: int = 0): """Shows the players spreadsheet settings.""" tournament = self.get_tournament(ctx.guild.id) bracket = tournament.current_bracket players_spreadsheet = await bracket.get_players_spreadsheet() if not players_spreadsheet: raise tosurnament.NoSpreadsheet("players") team_infos, _ = await self.get_all_teams_infos_and_roles( ctx.guild, players_spreadsheet) try: selected_team_info = team_infos[index] except Exception: # TODO: send error message return output = "**__" + selected_team_info.team_name + ":__**\n\n" for player_info in selected_team_info.players: output += "__Player name:__ " + str(player_info.name) + "\n" if player_info.discord: output += "__Discord tag:__ " + str(player_info.discord) + "\n" if player_info.discord_id: output += "__Discord id:__ " + str( player_info.discord_id) + "\n" # TODO: other fields output += "\n" await ctx.send(output)
async def step8_per_bracket(self, ctx, post_result_message, tournament): bracket = tournament.current_bracket schedules_spreadsheet = bracket.schedules_spreadsheet if not schedules_spreadsheet: raise tosurnament.NoSpreadsheet("schedules") await schedules_spreadsheet.get_spreadsheet() match_info = MatchInfo.from_id(schedules_spreadsheet, post_result_message.match_id, False) if tournament.staff_channel_id: error_channel = self.bot.get_channel(tournament.staff_channel_id) else: error_channel = ctx prbuilder = await self.create_prbuilder(ctx, post_result_message, tournament, bracket, match_info, error_channel) if tournament.post_result_message: result_string = tournament.post_result_message else: result_string = self.get_string("post_result", "default") result_string = prbuilder.build(result_string, self, tournament) if bracket.challonge: await self.step8_challonge(ctx, tournament, error_channel, prbuilder) await self.step8_write_in_spreadsheet(bracket, match_info, prbuilder) post_result_channel = ctx if bracket.post_result_channel_id: post_result_channel = self.bot.get_channel( bracket.post_result_channel_id) await post_result_channel.send(result_string)
async def step7_send_message(self, channel, tournament, post_result_message): bracket = self.bot.session.query(Bracket).where( Bracket.id == post_result_message.bracket_id).first() if not bracket: self.bot.session.delete(post_result_message) raise tosurnament.NoBracket() schedules_spreadsheet = bracket.schedules_spreadsheet if not schedules_spreadsheet: raise tosurnament.NoSpreadsheet("schedules") await schedules_spreadsheet.get_spreadsheet() match_info = MatchInfo.from_id(schedules_spreadsheet, post_result_message.match_id, False) prbuilder = await self.create_prbuilder(None, post_result_message, tournament, bracket, match_info, channel) if tournament.post_result_message: result_string = tournament.post_result_message else: result_string = self.get_string("post_result", "default") result_string = prbuilder.build(result_string, self, tournament) await self.update_post_result_setup_message(post_result_message, channel, 8) preview_message = await self.send_reply(channel, "post_result", "preview", result_string) post_result_message.preview_message_id = preview_message.id
async def step7_send_message(self, ctx, tournament, post_result_message): bracket = tosurnament_api.get_bracket(tournament.id, post_result_message.bracket_id) if not bracket: self.bot.session.delete(post_result_message) raise tosurnament.NoBracket() schedules_spreadsheet = await bracket.get_schedules_spreadsheet() if not schedules_spreadsheet: raise tosurnament.NoSpreadsheet("schedules") match_info = MatchInfo.from_id(schedules_spreadsheet, post_result_message.match_id, False) prbuilder = await self.create_prbuilder(None, post_result_message, tournament, bracket, match_info, ctx) if tournament.post_result_message: result_string = tournament.post_result_message else: result_string = self.get_string(ctx, "default") result_string = prbuilder.build(ctx, result_string, self, tournament) await self.update_post_result_setup_message(ctx, post_result_message, 8) preview_message = await self.send_reply(ctx, "preview", result_string) post_result_message.preview_message_id = preview_message.id
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")
async def set_players_spreadsheet_values(self, ctx, values): """Puts the input values into the corresponding bracket.""" tournament = self.get_tournament(ctx.guild.id) players_spreadsheet = tournament.current_bracket.get_spreadsheet_from_type( "players") if not players_spreadsheet: raise tosurnament.NoSpreadsheet("players") for key, value in values.items(): setattr(players_spreadsheet, key, value) tosurnament_api.update_players_spreadsheet( tournament.id, tournament.current_bracket.id, players_spreadsheet) await self.send_reply(ctx, "success", value)
async def step7_send_message(self, ctx, tournament, post_result_message): bracket = self.bot.session.query(Bracket).where(Bracket.id == post_result_message.bracket_id).first() if not bracket: self.bot.session.delete(post_result_message) raise tosurnament.NoBracket() schedules_spreadsheet = bracket.schedules_spreadsheet if not schedules_spreadsheet: raise tosurnament.NoSpreadsheet("schedules") match_info = MatchInfo.from_id(schedules_spreadsheet, post_result_message.match_id, False) prbuilder = await self.create_prbuilder(post_result_message, tournament, bracket, match_info, ctx) if tournament.post_result_message: result_string = tournament.post_result_message else: result_string = self.get_string("post_result", "default") result_string = prbuilder.build(result_string, self, tournament) message = await self.send_reply( ctx, "post_result", "step8", post_result_message.match_id, post_result_message.best_of, post_result_message.roll_team1, post_result_message.roll_team2, post_result_message.n_warmup, osu.build_mp_links(post_result_message.mp_links.split("\n")), post_result_message.bans_team1, post_result_message.bans_team2, post_result_message.tb_bans_team1, post_result_message.tb_bans_team2, ) post_result_message.setup_message_id = message.id post_result_message.step = 8 preview_message = await self.send_reply(ctx, "post_result", "preview", result_string) post_result_message.preview_message_id = preview_message.id return message
async def reaction_on_staff_reschedule_message(self, message_id, emoji, guild, channel, user): """Removes the referee from the schedule spreadsheet""" staff_reschedule_message = ( self.bot.session.query(StaffRescheduleMessage).where( StaffRescheduleMessage.message_id == message_id).first()) if not staff_reschedule_message or staff_reschedule_message.in_use: return if user.id != staff_reschedule_message.staff_id: return if emoji.name != "❌": return try: tosurnament_user = self.get_verified_user(user.id) osu_name = tosurnament_user.osu_name except (tosurnament.UserNotLinked, tosurnament.UserNotVerified ): # ! Temporary for nik's tournament osu_name = user.display_name staff_reschedule_message.in_use = True self.bot.session.update(staff_reschedule_message) try: tournament = self.get_tournament(guild.id) bracket = self.bot.session.query(Bracket).where( Bracket.id == staff_reschedule_message.bracket_id).first() if not bracket: raise tosurnament.UnknownError("Bracket not found") schedules_spreadsheet = bracket.schedules_spreadsheet if not schedules_spreadsheet: raise tosurnament.NoSpreadsheet() match_id = staff_reschedule_message.match_id match_info = MatchInfo.from_id(schedules_spreadsheet, match_id) staff_cells = match_info.referees + match_info.streamers + match_info.commentators for staff_cell in staff_cells: if staff_cell.has_value(osu_name): if schedules_spreadsheet.use_range: staff_cell.value = "" else: staffs = staff_cell.value.split("/") if len(staffs) == 2 and staffs[0].strip() == osu_name: staff_cell.value = staffs[1].strip() elif len(staffs) == 2 and staffs[1].strip == osu_name: staff_cell.value = staffs[0].strip() elif len( staffs) == 1 and staffs[0].strip() == osu_name: staff_cell.value = "" try: schedules_spreadsheet.spreadsheet.update() except HttpError as e: raise tosurnament.SpreadsheetHttpError(e.code, e.operation, bracket.name, "schedules") to_channel = channel staff_channel = self.bot.get_channel(tournament.staff_channel_id) if staff_channel: to_channel = staff_channel await self.send_reply( to_channel, "reschedule", "removed_from_match", user.mention, match_id, ) self.bot.session.delete(staff_reschedule_message) except Exception as e: staff_reschedule_message.in_use = False self.bot.session.update(staff_reschedule_message) await self.reaction_on_staff_reschedule_message_handler(channel, e)
async def agree_to_reschedule(self, reschedule_message, guild, channel, user, tournament): """Updates the schedules spreadsheet with reschedule time.""" schedules_spreadsheet = tournament.current_bracket.schedules_spreadsheet if not schedules_spreadsheet: raise tosurnament.NoSpreadsheet(tournament.current_bracket.name, "schedules") match_id = reschedule_message.match_id match_info = MatchInfo.from_id(schedules_spreadsheet, match_id) previous_date = datetime.datetime.strptime( reschedule_message.previous_date, tosurnament.DATABASE_DATE_FORMAT) new_date = datetime.datetime.strptime(reschedule_message.new_date, tosurnament.DATABASE_DATE_FORMAT) date_format = "%d %B" if schedules_spreadsheet.date_format: date_format = schedules_spreadsheet.date_format if schedules_spreadsheet.range_date and schedules_spreadsheet.range_time: match_info.date.value = new_date.strftime(date_format) match_info.time.value = new_date.strftime("%H:%M") elif schedules_spreadsheet.range_date: match_info.date.value = new_date.strftime(date_format + " %H:%M") elif schedules_spreadsheet.range_time: match_info.time.value = new_date.strftime(date_format + " %H:%M") else: raise tosurnament.UnknownError("No date range") staff_name_to_ping = set() staff_cells = match_info.referees + match_info.streamers + match_info.commentators for staff_cell in staff_cells: if schedules_spreadsheet.use_range: staff_name_to_ping.add(staff_cell.value) else: staffs = staff_cell.value.split("/") for staff in staffs: staff_name_to_ping.add(staff.strip()) staff_to_ping = list( filter( None, [guild.get_member_named(name) for name in staff_name_to_ping])) try: schedules_spreadsheet.spreadsheet.update() except HttpError as e: raise tosurnament.SpreadsheetHttpError( e.code, e.operation, tournament.current_bracket.name, "schedules") 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", "accepted", ally_to_mention.mention, match_id, ) else: raise tosurnament.OpponentNotFound(user.mention) previous_date_string = previous_date.strftime( tosurnament.PRETTY_DATE_FORMAT) new_date_string = new_date.strftime(tosurnament.PRETTY_DATE_FORMAT) staff_channel = None if tournament.staff_channel_id: staff_channel = self.bot.get_channel(tournament.staff_channel_id) if staff_to_ping: if staff_channel: to_channel = staff_channel else: to_channel = channel for staff in staff_to_ping: sent_message = await self.send_reply( to_channel, "reschedule", "staff_notification", staff.mention, match_id, match_info.team1.value, match_info.team2.value, previous_date_string, new_date_string, ) staff_reschedule_message = StaffRescheduleMessage( tournament_id=reschedule_message.tournament_id, bracket_id=tournament.current_bracket.id, message_id=sent_message.id, match_id=match_id, new_date=reschedule_message.new_date, staff_id=staff.id, ) self.bot.session.add(staff_reschedule_message) elif staff_channel: await self.send_reply( staff_channel, "reschedule", "no_staff_notification", match_id, match_info.team1.value, match_info.team2.value, previous_date_string, new_date_string, ) allowed_reschedules = (self.bot.session.query(AllowedReschedule).where( AllowedReschedule.tournament_id == tournament.id).all()) for allowed_reschedule in allowed_reschedules: if allowed_reschedule.match_id.upper() == match_id.upper(): self.bot.session.delete(allowed_reschedule)
async def set_spreadsheet_values(self, ctx, spreadsheet_type, values): tournament = self.get_tournament(ctx.guild.id) any_spreadsheet = tournament.current_bracket.get_spreadsheet_from_type(spreadsheet_type) if not any_spreadsheet: raise tosurnament.NoSpreadsheet(spreadsheet_type) await self.update_table(ctx, any_spreadsheet, values)
async def create_or_update_qualifiers_results_message( self, ctx, qualifiers_results_message, status): tournament = self.get_tournament(ctx.guild.id) referee_role = tosurnament.get_role(ctx.author.roles, tournament.referee_role_id, "Referee") if not self.is_admin( ctx ) and not ctx.guild.owner == ctx.author and not referee_role: raise tosurnament.NotRequiredRole("Referee") if len(tournament.brackets) > 1: await self.send_reply(ctx, "not_supported_yet") return bracket = tournament.current_bracket qualifiers_results_spreadsheet = await bracket.get_qualifiers_results_spreadsheet( retry=True, force_sync=True) if not qualifiers_results_spreadsheet: raise tosurnament.NoSpreadsheet("qualifiers_results") results_info = QualifiersResultInfo.get_all( qualifiers_results_spreadsheet) top10 = [] scores = [] cut_off = None for i, result_info in enumerate(results_info): score = result_info.score.get() if score <= 0.0: continue scores.append(score) if i < 10: top10.append(result_info) if i == 31: cut_off = result_info avg_score = sum(scores) / len(scores) top10_string = "" for i, result_info in enumerate(top10): osu_name = result_info.osu_id.get() osu_user = osu.get_user(osu_name) if not osu_user: flag = ":flag_white:" else: flag = ":flag_" + osu_user.country.lower() + ":" top10_string += "`" + str(i + 1) if i < 9: top10_string += ". `" else: top10_string += ".`" top10_string += flag + " **" + escape_markdown(osu_name) + "** " top10_string += "(%.2f%%)\n" % (result_info.score.get() * 100) channel = ctx.guild.get_channel( int(qualifiers_results_message.channel_id)) if qualifiers_results_message.message_id: message = await channel.fetch_message( int(qualifiers_results_message.message_id)) await message.delete() message = await self.send_reply( ctx, "embed", tournament.name, status, top10_string, escape_markdown(top10[0].osu_id.get()), "%.2f%%" % (avg_score * 100), "%.2f%% `(32. %s)`" % ((cut_off.score.get() * 100), escape_markdown(cut_off.osu_id.get())), str(ctx.guild.icon_url), channel=channel, ) qualifiers_results_message.message_id = message.id self.bot.session.update(qualifiers_results_message)
async def agree_to_reschedule(self, ctx, reschedule_message, tournament): """Updates the schedules spreadsheet with reschedule time.""" schedules_spreadsheet = await tournament.current_bracket.get_schedules_spreadsheet( ) if not schedules_spreadsheet: raise tosurnament.NoSpreadsheet(tournament.current_bracket.name, "schedules") match_id = reschedule_message.match_id match_info = MatchInfo.from_id(schedules_spreadsheet, match_id) if reschedule_message.previous_date: previous_date = datetime.datetime.strptime( reschedule_message.previous_date, tosurnament.DATABASE_DATE_FORMAT) previous_date_string = self.get_pretty_date( ctx, tournament, previous_date) else: previous_date_string = self.get_string(ctx, "no_previous_date") new_date = datetime.datetime.strptime(reschedule_message.new_date, tosurnament.DATABASE_DATE_FORMAT) date_format = "%d %B" if schedules_spreadsheet.date_format: date_format = schedules_spreadsheet.date_format if tournament.date_format: date_format = tournament.date_format match_info.set_datetime(schedules_spreadsheet, new_date, date_format) self.add_update_spreadsheet_background_task(schedules_spreadsheet) 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, "accepted", ally_to_mention.mention, match_id) else: # TODO not raise raise tosurnament.OpponentNotFound(ctx.author.mention) referees_to_ping, _ = self.find_staff_to_ping(ctx.guild, match_info.referees) streamers_to_ping, _ = self.find_staff_to_ping(ctx.guild, match_info.streamers) commentators_to_ping, _ = self.find_staff_to_ping( ctx.guild, match_info.commentators) new_date_string = self.get_pretty_date(ctx, tournament, new_date) staff_channel = None if tournament.staff_channel_id: staff_channel = self.bot.get_channel( int(tournament.staff_channel_id)) if referees_to_ping or streamers_to_ping or commentators_to_ping: if staff_channel: to_channel = staff_channel else: to_channel = ctx.channel sent_message = await self.send_reply( ctx, "staff_notification", match_id, match_info.team1.get(), match_info.team2.get(), previous_date_string, new_date_string, " / ".join([referee.mention for referee in referees_to_ping]), " / ".join( [streamer.mention for streamer in streamers_to_ping]), " / ".join([ commentator.mention for commentator in commentators_to_ping ]), channel=to_channel, ) staff_reschedule_message = StaffRescheduleMessage( tournament_id=reschedule_message.tournament_id, bracket_id=tournament.current_bracket.id, message_id=sent_message.id, team1=match_info.team1.get(), team2=match_info.team2.get(), match_id=match_id, previous_date=reschedule_message.previous_date, new_date=reschedule_message.new_date, referees_id="\n".join( [str(referee.id) for referee in referees_to_ping]), streamers_id="\n".join( [str(streamer.id) for streamer in streamers_to_ping]), commentators_id="\n".join([ str(commentator.id) for commentator in commentators_to_ping ]), ) self.bot.session.add(staff_reschedule_message) elif staff_channel and tournament.notify_no_staff_reschedule: await self.send_reply( ctx, "no_staff_notification", match_id, match_info.team1.get(), match_info.team2.get(), previous_date_string, new_date_string, channel=staff_channel, ) allowed_reschedules = tosurnament_api.get_allowed_reschedules( tournament.id) for allowed_reschedule in allowed_reschedules: if allowed_reschedule.match_id.upper() == match_id.upper(): tosurnament_api.delete_allowed_reschedule( tournament.id, match_id.upper())
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
async def agree_to_reschedule(self, reschedule_message, guild, channel, user, tournament): """Updates the schedules spreadsheet with reschedule time.""" schedules_spreadsheet = tournament.current_bracket.schedules_spreadsheet if not schedules_spreadsheet: raise tosurnament.NoSpreadsheet(tournament.current_bracket.name, "schedules") await schedules_spreadsheet.get_spreadsheet() match_id = reschedule_message.match_id match_info = MatchInfo.from_id(schedules_spreadsheet, match_id) if reschedule_message.previous_date: previous_date = datetime.datetime.strptime( reschedule_message.previous_date, tosurnament.DATABASE_DATE_FORMAT) previous_date_string = tosurnament.get_pretty_date( tournament, previous_date) else: previous_date_string = "**No previous date**" new_date = datetime.datetime.strptime(reschedule_message.new_date, tosurnament.DATABASE_DATE_FORMAT) date_format = "%d %B" if schedules_spreadsheet.date_format: date_format = schedules_spreadsheet.date_format if schedules_spreadsheet.range_date and schedules_spreadsheet.range_time: match_info.date.value = new_date.strftime(date_format) match_info.time.value = new_date.strftime("%H:%M") elif schedules_spreadsheet.range_date: match_info.date.value = new_date.strftime(date_format + " %H:%M") elif schedules_spreadsheet.range_time: match_info.time.value = new_date.strftime(date_format + " %H:%M") else: raise tosurnament.UnknownError("No date range") self.add_update_spreadsheet_background_task(schedules_spreadsheet) 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", "accepted", ally_to_mention.mention, match_id) else: # TODO not raise raise tosurnament.OpponentNotFound(user.mention) referees_to_ping, _ = self.find_staff_to_ping(guild, match_info.referees) streamers_to_ping, _ = self.find_staff_to_ping(guild, match_info.streamers) commentators_to_ping, _ = self.find_staff_to_ping( guild, match_info.commentators) new_date_string = tosurnament.get_pretty_date(tournament, new_date) staff_channel = None if tournament.staff_channel_id: staff_channel = self.bot.get_channel(tournament.staff_channel_id) if referees_to_ping + streamers_to_ping + commentators_to_ping: if staff_channel: to_channel = staff_channel else: to_channel = channel sent_message = await self.send_reply( to_channel, "reschedule", "staff_notification", match_id, match_info.team1.value, match_info.team2.value, previous_date_string, new_date_string, " / ".join([referee.mention for referee in referees_to_ping]), " / ".join( [streamer.mention for streamer in streamers_to_ping]), " / ".join([ commentator.mention for commentator in commentators_to_ping ]), ) staff_reschedule_message = StaffRescheduleMessage( tournament_id=reschedule_message.tournament_id, bracket_id=tournament.current_bracket.id, message_id=sent_message.id, team1=match_info.team1.value, team2=match_info.team2.value, match_id=match_id, previous_date=reschedule_message.previous_date, new_date=reschedule_message.new_date, referees_id="\n".join( [str(referee.id) for referee in referees_to_ping]), streamers_id="\n".join( [str(streamer.id) for streamer in streamers_to_ping]), commentators_id="\n".join([ str(commentator.id) for commentator in commentators_to_ping ]), ) self.bot.session.add(staff_reschedule_message) elif staff_channel and tournament.notify_no_staff_reschedule: await self.send_reply( staff_channel, "reschedule", "no_staff_notification", match_id, match_info.team1.value, match_info.team2.value, previous_date_string, new_date_string, ) allowed_reschedules = (self.bot.session.query(AllowedReschedule).where( AllowedReschedule.tournament_id == tournament.id).all()) for allowed_reschedule in allowed_reschedules: if allowed_reschedule.match_id.upper() == match_id.upper(): self.bot.session.delete(allowed_reschedule)