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 link(self, ctx, *, osu_name: str): """ Sends a private message to the command runner to link his account. If the user is already linked but not verified, a new code is generated (in case the previous one is lost). """ user = self.get_user(ctx.author.id) if user and user.verified: raise UserAlreadyVerified() osu_user = osu.get_user(osu_name) if not osu_user: raise base.UserNotFound(osu_name) osu_id = osu_user.id code = base64.urlsafe_b64encode(os.urandom(16)).rstrip(b"=").decode("ascii") if not user: user = User(discord_id=ctx.author.id, osu_id=osu_id, verified=False, code=code, osu_name=osu_name) self.bot.session.add(user) else: user.osu_id = osu_id user.code = code user.osu_name = osu_name self.bot.session.update(user) await self.send_reply(ctx.author, ctx.command.name, "success", code)
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")
async def name_change(self, ctx): """Allows users to change their nickname to their osu! username or update it.""" user = self.get_verified_user(ctx.author.id) previous_name = user.osu_previous_name new_name = user.osu_name osu_user = osu.get_user(user.osu_id) if not osu_user: await self.send_reply(ctx, ctx.command.name, "osu_get_user_error") if osu_user.name != new_name: previous_name = new_name new_name = osu_user.name if not previous_name: await self.send_reply(ctx, ctx.command.name, "change_name_unneeded") return # TODO: allow disabling write on spreadsheet # user_details = tosurnament.UserDetails.get_from_ctx(ctx) # if user_details.is_user(): # tournament = self.get_tournament(ctx.guild.id) # for bracket in tournament.brackets: # try: # if user_details.player: # await self.change_name_in_player_spreadsheet(ctx, bracket, previous_name, new_name) # if user_details.player or user_details.is_staff(): # await self.change_name_in_schedules_spreadsheet( # ctx, bracket, previous_name, new_name, user_details # ) # if bracket.challonge: # participants = challonge.get_participants(bracket.challonge) # for participant in participants: # if participant.name == previous_name: # participant.update_name(new_name) # except Exception as e: # await self.on_cog_command_error(ctx, ctx.command.name, e) # return try: await ctx.author.edit(nick=new_name) except discord.Forbidden: await self.send_reply(ctx, ctx.command.name, "change_nickname_forbidden") user.osu_previous_name = previous_name user.osu_name = new_name user.osu_name_hash = new_name.lower() self.bot.session.update(user) await self.send_reply(ctx, ctx.command.name, "success")
async def update_players_spreadsheet_registration(self, guild, tournament): now = datetime.datetime.now() for bracket in tournament.brackets: if not bracket.registration_end_date: continue registration_end_date = datetime.datetime.strptime( bracket.registration_end_date, tosurnament.DATABASE_DATE_FORMAT) if now > registration_end_date: continue players_spreadsheet = await bracket.get_players_spreadsheet() if not players_spreadsheet: continue team_infos, _ = await self.get_all_teams_infos_and_roles( guild, players_spreadsheet) update_spreadsheet = False for team_info in team_infos: for player_info in team_info.players: osu_id = player_info.name.get() if player_info.osu_id: osu_id = player_info.osu_id.get() osu_user = osu.get_user(osu_id, m=tournament.game_mode) if not osu_user: continue if player_info.name != osu_user.name: user = tosurnament.UserAbstraction.get_from_player_info( self.bot, player_info, guild) member = user.get_member(guild) if member: try: await member.edit(nick=osu_user.name) except (discord.Forbidden, discord.HTTPException): pass player_info.name.set(osu_user.name) player_info.rank.set(str(osu_user.rank)) player_info.bws_rank.set(str(osu_user.rank)) player_info.pp.set(str(int(float(osu_user.pp)))) update_spreadsheet = True if update_spreadsheet: self.add_update_spreadsheet_background_task( players_spreadsheet)
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)