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)
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)
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 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()
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)
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