def __init__(self, client: Bot): self.emoji: str = get_cog(self.__class__.__name__)['emoji'] async def after_ready_(): await client.wait_until_ready() await self.after_ready() client.loop.create_task(after_ready_())
async def after_ready(self): with open(get_path('reactions'), 'r', encoding='utf-8') as f: self.reactions = f.read().split('\n') with open(get_path('greetings'), 'r', encoding='utf-8') as f: self.greetings = f.read().split('\n') self.protocol_cog = self.client.get_cog(get_cog('ProtocolCog')['name']) for initial in ('ㅁ', 'ㅇ', 'ㄹ', 'ㄴ'): for final in ('ㅁ', 'ㅇ', 'ㄴ', None): for medial in map(str, CHAR_MEDIALS): self.characters.append( join_jamos_char(initial, medial, final))
async def send_cog_list(self, ctx: Context): literal = literals('send_cog_list') states = list() count = len(self.client.cogs) message = None for i, cog in enumerate(sorted(self.client.cogs.items(), key=lambda item: get_cog(type(item[1]).__name__)['priority'])): name, cog = cog if isinstance(cog, CustomCog): name = cog.emoji + ' ' + name page_embed = ChainedEmbed(title=literal['title'], description=literal['description']) page_embed.set_thumbnail(url=self.client.user.avatar_url) page_embed.add_field(name=name, value=brief_cog(cog)) page_embed.set_footer(text=literal['footer'] % (i + 1, count)) if message is None: message = await ctx.send(embed=page_embed) states.append(InterfaceState(callback=message.edit, embed=page_embed)) await attach_page_interface(self.client, message, states, user=ctx.author)
class ProtocolCog(CustomCog, BotProtocol, name=get_cog('ProtocolCog')['name']): """ 다른 봇과 소통하기 위한 기능을 포함합니다. """ def __init__(self, client: Bot): super().__init__(client) self.client: Bot = client self.holding_data: dict = dict() self.done: list = list() @CustomCog.listener() async def on_message(self, message): if message.author.id == get_constant('kenken_id'): return await super().on_message(message) @CustomCog.listener() async def on_command_error(self, ctx: commands.Context, _): if ctx.guild is not None and ctx.prefix in self.client.command_prefix: Log.command('pass protocol request generated.') request = Request(receiver=BotProtocol.ALL, signal=BotProtocol.PASS, addition=f'{ctx.prefix} {ctx.channel.mention} {ctx.message.id}') await ctx.send(str(request), delete_after=1) async def on_echo(self, request: Request): Log.command('detected.') if request.addition: await request.message.channel.send(request.addition) async def on_pass(self, request: Request): Log.command('detected.') addition = request.addition.split(' ', 2) if len(addition) < 3: Log.error('lack of components') return self.client.command_prefix.insert(0, addition[0]) request_ctx = await self.client.get_context(request.message) try: channel: TextChannel = await TextChannelConverter().convert(request_ctx, addition[1]) message: Message = await channel.fetch_message(int(addition[2])) ctx: Context = await self.client.get_context(message) await self.client.invoke(ctx) except BadArgument: Log.error(f'channel {addition[1]} not found') except NotFound: Log.error(f'message {addition[2]} not found') self.client.command_prefix = self.client.command_prefix[-1:] async def on_send(self, request: Request): literal = literals('on_send') key = request.addition.strip() async def respond(data_, key_): here_request = request.generate_respond(signal=BotProtocol.HERE, addition=key_ + ' ') addition_length = MESSAGE_MAX_LENGTH - len(str(here_request)) - 1 here_request.addition += data_[:addition_length] data_ = data_[addition_length:] await request.message.channel.send(str(here_request), delete_after=1) if data_: for d in split_by_length(data_): await request.message.channel.send(d, delete_after=1) done_request = request.generate_respond(signal=BotProtocol.DONE, addition=key_) await request.message.channel.send(str(done_request), delete_after=1) if key == literal['application']: data = json.dumps(get_application_sheet(), ensure_ascii=False) await respond(data, key) if key == literal['regulation']: data = doc_read(get_constant('regulation')['doc_id']) await respond(data, key) async def on_here(self, request: Request): addition = request.addition.split(' ', 1) while len(addition) < 2: Log.error('lack of components') return key = addition[0] data = addition[1] while not self.done or self.done[-1].addition != key: message = await self.client.wait_for('message', check=lambda msg: msg.author == request.message.author) data += message.content self.done.pop(-1) if key not in self.holding_data: self.holding_data[key] = list() self.holding_data[key].append(FreshData(data)) async def on_done(self, request: Request): self.done.append(request)
class ShteloCog(CustomCog, name=get_cog('ShteloCog')['name']): """ 슈텔로의 관리를 위한 기능을 포함합니다. """ def __init__(self, client: Bot): super().__init__(client) self.client: Bot = client self.regulation: Optional[FreshData] = None self.deck_handler: DeckHandler = DeckHandler(client) self.shtelo_guild: Optional[Guild] = None self.partner_channel: Optional[TextChannel] = None self.member_role: Optional[Role] = None self.tester_role: Optional[Role] = None self.title_div_role: Optional[Role] = None self.deck_div_role: Optional[Role] = None self.partner_role: Optional[Role] = None async def after_ready(self): self.shtelo_guild = self.client.get_guild(get_constant('shtelo_guild')) self.partner_channel = self.client.get_channel( get_constant('partner_channel')) self.member_role = self.shtelo_guild.get_role( get_constant('member_role')) self.tester_role = self.shtelo_guild.get_role( get_constant('tester_role')) self.title_div_role = self.shtelo_guild.get_role( get_constant('title_div_role')) self.deck_div_role = self.shtelo_guild.get_role( get_constant('deck_div_role')) self.partner_role = self.shtelo_guild.get_role( get_constant('partner_role')) def fetch_regulation(self): if self.regulation is None \ or self.regulation.data is None: paragraphs = wrap_codeblock(doc_read( get_constant('regulation')['doc_id']), split_paragraph=True) self.regulation = FreshData(paragraphs, SECOND_PER_HOUR) else: paragraphs = self.regulation.data return paragraphs async def receive_application(self, member: Member, remarks: str, on_error=None, keys=None, rows=None): await update_application(member, APPLICATION_RECEIVED, remarks, on_error, keys, rows) tasks = list() if self.tester_role not in member.roles: tasks.append(member.add_roles(self.tester_role)) if self.title_div_role not in member.roles: tasks.append(member.add_roles(self.title_div_role)) if self.deck_div_role not in member.roles: tasks.append(member.add_roles(self.deck_div_role)) if tasks: await asyncio.wait(tasks) @modules.CustomCog.listener(name='on_message') async def receive_automatically(self, message: Message): literal = literals('receive_automatically') async def failed(): await self.partner_channel.send(literal['failed'] % message.author.mention) if message.channel.id != get_constant( 'self_introduction_channel') or len(message.content) < 10: return keys, rows = get_application_sheet() application = get_application_of(message.author, rows) if application is None or application[APPLICATION_STATE]: return trigger_member_name = application[APPLICATION_INVITER] trigger_role = self.member_role if not trigger_member_name: trigger_member_name = application[APPLICATION_SUBACCOUNT] trigger_role = None try: trigger_member = await MemberConverter().convert( await self.client.get_context(message), trigger_member_name) except BadArgument as e: await failed() raise e if trigger_role is not None and trigger_role not in trigger_member.roles: await failed() return remark = str(message.author.id) if not application[APPLICATION_INVITER]: remark = literal['subaccount'] % (trigger_member.id, remark) await self.receive_application(message.author, remark, None, keys, rows) await message.add_reaction(CONFIRM_EMOJI) if application[APPLICATION_INVITER]: add_member(message.author, application[APPLICATION_NICKNAME]) await self.partner_channel.send( literal['done'] % (message.author.mention, message.jump_url), embed=get_application_embed(application)) @modules.group(name='가입신청서', aliases=('가입', '신청서')) @partner_only() async def applications(self, ctx: Context, *query: str): literal = literals('applications') start_message = await ctx.author.send(literal['start']) message = None _, replies = get_application_sheet() query = tuple(set(query)) query_state = tuple( filter(lambda q: q in (APPLICATION_RECEIVED, APPLICATION_APPROVED), query)) query = tuple( filter( lambda q: q not in (APPLICATION_RECEIVED, APPLICATION_APPROVED), query)) if not query_state: if not query: query_state = (APPLICATION_RECEIVED, ) else: query_state = (APPLICATION_RECEIVED, APPLICATION_APPROVED) queried = list( filter( lambda r: (not r[APPLICATION_STATE] or r[APPLICATION_STATE] in query_state) and (not query or tuple(filter(lambda q: q in str(r), query))), replies)) query_str = ', '.join(query + query_state) count = len(queried) states = list() for i, reply in enumerate(reversed(queried)): reply_embed = get_application_embed(reply) reply_embed.set_footer(text=literal['footer'] % (i + 1, count)) if message is None: await start_message.edit(content=literal['done'] % (query_str, count), embed=reply_embed) message = start_message states.append(InterfaceState(message.edit, embed=reply_embed)) if message is None: await start_message.edit(content=literal['not_found'] % query_str) else: await attach_page_interface(self.client, message, states, user=ctx.author, after=message.delete()) @applications.command(name='접수') @guild_only() @partner_only() async def application_receive(self, ctx: Context, member: Member, *, remarks: str = None): literal = literals('application_receive') message = await ctx.send(literal['start']) keys, rows = get_application_sheet() appilcation = get_application_of(member, rows) if appilcation is None: await message.edit(content=literal['failed'] % str(member)) return if remarks is None: remarks = str(member.id) if appilcation[APPLICATION_SUBACCOUNT] is not NO: try: main_account = await MemberConverter().convert( ctx, appilcation[APPLICATION_SUBACCOUNT]) except BadArgument: pass else: remarks = literal['subaccount'] % (main_account.id, remarks) await self.receive_application(member, remarks, message.delete) await message.edit(content=literal['done'] % str(member)) @applications.command(name='승인') @guild_only() @partner_only() async def application_approve(self, ctx: Context, member: Member, *, remarks: str = None): literal = literals('application_approve') message = await ctx.send(literal['start']) if remarks is None: remarks = member.id await update_application(member, APPLICATION_APPROVED, remarks, message.delete) tester_role = ctx.guild.get_role(get_constant('tester_role')) member_role = ctx.guild.get_role(get_constant('member_role')) tasks = list() if tester_role in member.roles: tasks.append(member.remove_roles(tester_role)) if member_role not in member.roles: tasks.append(member.add_roles(member_role)) tasks.append(message.edit(content=literal['done'] % member.mention)) await asyncio.wait(tasks) @modules.group(name='회원', enabled=False) async def member(self, ctx: Context): pass @member.command(name='등록') @guild_only() @partner_only() async def member_register(self, ctx: Context, member: Member): literal = literals('member') message = await ctx.send(literal['start']) add_member(member) await message.edit(content=literal['done']) @member.group(name='수정', enabled=False) @guild_only() @partner_only() async def member_edit(self, ctx: Context): pass @member_edit.command(name='닉네임') @guild_only() @partner_only() async def member_edit_nickname(self, ctx: Context, query: str, *, nickname: str): literal = literals('member') message = await ctx.send(literal['start']) edit_member(query, nickname) await message.edit(content=literal['done']) @member_edit.command(name='상태') @guild_only() @partner_only() async def member_edit_state(self, ctx: Context, query: str, *, state: str): literal = literals('member') message = await ctx.send(literal['start']) edit_member(query, None, state) await message.edit(content=literal['done']) # @applications.command(name='기각') # @guild_only() # @partner_only() # async def application_reject(self, ctx: Context, member: Member, *, remarks: str = None): # literal = literals('application_reject') # message = await ctx.send(literal['start']) # if remarks is None: # remarks = member.id # application = await update_application(member, STATE_REJECTED, remarks, message.delete()) # tester_role = ctx.guild.get_role(get_constant('tester_role')) # if tester_role in member.roles: # await member.remove_roles(tester_role) # update_member_list(member, application[NICKNAME], STATE_QUIT) # await message.edit(content=literal['done'] % member.mention) @applications.command(name='전체', aliases=('*', )) async def applications_all(self, ctx: Context): await self.applications(ctx, APPLICATION_RECEIVED, APPLICATION_APPROVED) @modules.group(name='회칙') async def regulation(self, ctx: Context, *, keyword: str = ''): literal = literals('regulation') message = await ctx.send(literal['start']) paragraphs = self.fetch_regulation() await message.edit(content=literal['done']) if not keyword: await ctx.author.send(paragraphs[0]) await ctx.author.send(literal['no_keyword']) else: found = [p for p in paragraphs[1:] if '# ' + keyword + '\n' in p] if not found: found = [p for p in paragraphs[1:] if keyword in p] if not found: await ctx.author.send(literal['not_found'] % keyword) else: for p in found: await ctx.author.send(p) @regulation.command(name='전체', aliases=('*', )) async def regulation_all(self, ctx: Context): literal = literals('regulation_all') message = await ctx.send(literal['start']) paragraphs = wrap_codeblock(doc_read( get_constant('regulation')['doc_id']), split_paragraph=True) await message.edit(content=literal['done']) for p in paragraphs: await ctx.author.send(p) @modules.command(name='회의록') async def meeting_log(self, ctx: Context): await ctx.send(literals('meeting_log')['message'])
class BaseCog(CustomCog, name=get_cog('BaseCog')['name']): """ 기본적인 기능을 포함합니다. """ def __init__(self, client: Bot): super().__init__(client) self.client: Bot = client self.reactions: list = list() self.greetings: list = list() self.characters: list = list() self.protocol_cog = None async def after_ready(self): with open(get_path('reactions'), 'r', encoding='utf-8') as f: self.reactions = f.read().split('\n') with open(get_path('greetings'), 'r', encoding='utf-8') as f: self.greetings = f.read().split('\n') self.protocol_cog = self.client.get_cog(get_cog('ProtocolCog')['name']) for initial in ('ㅁ', 'ㅇ', 'ㄹ', 'ㄴ'): for final in ('ㅁ', 'ㅇ', 'ㄴ', None): for medial in map(str, CHAR_MEDIALS): self.characters.append( join_jamos_char(initial, medial, final)) def get_greeting(self, message): greeting = f'{choice(self.greetings)}' if random() >= 0.5: greeting += f' **{message.author.display_name}**!' else: greeting += '!' return greeting def kenken_called(self, message: str): count = 0 for ken in ('켄', '캔', '켼', '컌', '꺤', '꼔', '껜', '깬'): count += message.count(ken) if count < 2: count = 0 if not count and any( word in message.upper() for word in ('KENKEN', '켄켄', str(self.client.user.id), self.client.user.display_name)): count = 2 return count def get_custom_emoji_embed(self, emoji_id: int): emoji: PartialEmoji = self.client.get_emoji(emoji_id) embed = ChainedEmbed() embed.set_image(url=emoji.url) embed.set_author(name=f':{emoji.name}:') return embed @CustomCog.listener(name='on_message') async def react_to_mention(self, message: Message): ctx: commands.Context = await self.client.get_context(message) if ctx.valid or message.author.id == self.client.user.id or self.protocol_cog.get_request( message) is not None: return if count := self.kenken_called(message.content): if any(word in message.content.upper() for word in self.greetings): Log.command('kenkenjr greeted.') await ctx.send(self.get_greeting(message)) elif count <= 2: Log.command('kenkenjr called.') await message.channel.send(f'{choice(self.reactions)}') else: await message.channel.send( ''.join([choice(self.characters) for _ in range(count)])[:1997] + ''.join([choice(tuple('!?.')) for _ in range(3)]))
class GameCog(CustomCog, name=get_cog('GameCog')['name']): """ 심심할 때 한 번 쯤 시험삼아 써 볼만한 기능들을 포함합니다. """ def __init__(self, client: Bot): super().__init__(client) self.client: Bot = client @modules.command(name='왕', aliases=('왕게임', 'king')) @guild_only() async def king(self, ctx: Context, player1: Member, player2: Member, player3: Member, *players: Member): players = list(players) players.extend((player1, player2, player3)) tasks = list() king = None i = 0 count_description = literals('king')['count'] % (len(players) - 1) footer = literals('king')['footer'] while len(players): player1 = players.pop(randrange(0, len(players))) if i == 0: king = player1 else: embed = ChainedEmbed(title=literals('king')['number'] % i, description=count_description) embed.set_footer(text=footer) tasks.append(player1.send(embed=embed)) i = i + 1 embed = ChainedEmbed(title=literals('king')['king'] % king.display_name, description=count_description) embed.set_image(url=king.avatar_url) embed.set_footer(text=footer) tasks.append( ctx.send(' '.join( [member.mention for member in ctx.message.mentions]), embed=embed)) tasks.append(ctx.message.delete()) await asyncio.wait(tasks) @modules.command(name='인디언포커', aliases=('인디언', )) @guild_only() async def indian_poker(self, ctx: Context, player1: User, player2: User, chip: int = 15): if IndianPoker.get_game(player1) is not None: await ctx.send(ALREADY_PLAYING % player1.mention) elif IndianPoker.get_game(player2) is not None: await ctx.send(ALREADY_PLAYING % player2.mention) else: game = IndianPoker(ctx, player1, player2, chip) await game.run() @modules.group(name='요트') async def yacht(self, ctx: Context): game = Yacht.get_game(ctx.author) if game is not None and isinstance(game, Yacht): await ctx.send(ALREADY_PLAYING % ctx.author.mention) else: game = Yacht(ctx, ctx.author) await game.run() @yacht.command(name='도움말', aliases=('규칙', )) async def yacht_help(self, ctx: Context): literal = literals('yacht_help') help_embed: ChainedEmbed = ChainedEmbed( title=literal['title'], description=literal['description']) for field in literal['fields']: help_embed.add_field(name=field['name'], value=field['value']) await ctx.send(embed=help_embed) @modules.group(name='게임') async def game(self, ctx: Context): pass @game.command(name='중단', aliases=('종료', '포기')) async def game_close(self, ctx: Context): literal = literals('game_close') game = Game.get_game(ctx.author) if game is None or not game.stop(): await ctx.send(literal['not_found']) else: await ctx.send( literal['done'] % ' '.join([player.mention for player in game.players]))
class ControlCog(CustomCog, name=get_cog('ControlCog')['name']): """ 봇의 관리와 직결되는 기능들을 포함합니다. """ def __init__(self, client: CustomBot): super().__init__(client) self.client: CustomBot = client @modules.group(name='테스트', aliases=('test', 't')) @owner_only() async def test(self, ctx: Context): pass @modules.command(name='따라해', aliases=('echo', 'e')) @partner_only() async def echo(self, ctx: Context, *, content: str): await ctx.send(content) @modules.command(name='삭제', aliases=('delete', )) @partner_only() @guild_only() async def delete(self, ctx: Context, count: int): count = min(max(1, count), 100) messages = await ctx.channel.purge(limit=count, bulk=True) try: await ctx.channel.delete_messages(messages) except NotFound: if count != 1: await ctx.channel.send(literals('delete')['failed']) except (ClientException, Forbidden, HTTPException) as e: await ctx.channel.send(literals('delete')['failed']) raise e await ctx.channel.send(literals('delete')['done'] % count, delete_after=10) @modules.group(name='리로드', enabled=False) @owner_only() async def reload(self, ctx: Context): await self.reload_literals(ctx) await self.reload_cogs(ctx) @reload.command(name='리터럴', enabled=False) @owner_only() async def reload_literals(self, ctx: Context): reload_literals() await ctx.send(literals('reload_literals')['done']) @reload.command(name='코그', aliases=('기능', ), enabled=False) @owner_only() async def reload_cogs(self, ctx: Context): message = await ctx.send(literals('reload_cogs')['start']) try: done = self.client.reload_all_extensions() except Exception as e: await message.edit(content=(literals('reload_cogs')['failed'] + '```\n' + str(e) + '```')) Log.error(e) else: if done: await message.edit(content=literals('reload_cogs')['done']) else: await message.edit(content=(literals('reload_cogs')['failed']))
class HelpCog(CustomCog, name=get_cog('HelpCog')['name']): """ 필요한 명령어를 찾거나 사용볍을 확인하기 위한 기능을 포함합니다. """ def __init__(self, client: Bot): super().__init__(client) self.client: Bot = client @modules.command(name='검색', aliases=('찾기', 'search', 's')) async def search(self, ctx: Context, keyword: str, *keywords: str): literal = literals('search') keywords = list(keywords) keywords.append(keyword) description = literal['found'] embeds = ChainedEmbed(title=literal['title'], description=description) embeds.set_thumbnail(url=self.client.user.avatar_url) found = 0 for command in self.client.commands: found += check_correlation(command, keywords, embeds) embeds.description = description % (found, ', '.join(keywords)) if found \ else literal['not_found'] % ', '.join(keywords) for embed in embeds.to_list(): await ctx.send(embed=embed) @modules.command(name='명령어', aliases=('commands', 'cmd', 'cmds')) async def commands(self, ctx: Context, *, category: str = ''): cog: Cog = self.client.get_cog(category) if cog is not None: await self.send_cog_info(ctx, cog) else: await self.send_cog_list(ctx) @modules.command(name='도움말', aliases=('help', 'h')) async def help(self, ctx: Context, *, command_name: str = ''): if not command_name: command_name = '도움말' command: Command = self.client.get_command(command_name) cog: Cog = self.client.get_cog(command_name) if command is not None: await self.send_command_help(ctx, command) elif cog is not None: await self.send_cog_info(ctx, cog) else: raise BadArgument(f'command "{command_name}" is not found') async def send_cog_info(self, ctx: Context, cog: Cog): cog_name = cog.qualified_name if isinstance(cog, CustomCog): cog_name = cog.emoji + ' ' + cog_name brief = brief_cog(cog) embeds = ChainedEmbed(title=cog_name, description=brief) embeds.set_thumbnail(url=self.client.user.avatar_url) for embed in embeds.to_list(): await ctx.send(embed=embed) async def send_cog_list(self, ctx: Context): literal = literals('send_cog_list') states = list() count = len(self.client.cogs) message = None for i, cog in enumerate(sorted(self.client.cogs.items(), key=lambda item: get_cog(type(item[1]).__name__)['priority'])): name, cog = cog if isinstance(cog, CustomCog): name = cog.emoji + ' ' + name page_embed = ChainedEmbed(title=literal['title'], description=literal['description']) page_embed.set_thumbnail(url=self.client.user.avatar_url) page_embed.add_field(name=name, value=brief_cog(cog)) page_embed.set_footer(text=literal['footer'] % (i + 1, count)) if message is None: message = await ctx.send(embed=page_embed) states.append(InterfaceState(callback=message.edit, embed=page_embed)) await attach_page_interface(self.client, message, states, user=ctx.author) async def send_command_help(self, ctx: Context, command: Command): literal = literals('send_command_help') command_name = command.qualified_name default_signature = get_command_default_signature(command) footer = get_command_signature(command) description = '' if command.help is not None: description = command.help + '\n' elif command.brief is not None: description = command.brief + '\n' description += f'`{default_signature}`' embeds = ChainedEmbed(title=get_constant('default_prefix') + command_name, description=description) embeds.set_thumbnail(url=self.client.user.avatar_url) if not command.enabled: embeds.add_field(name=literal['disabled_name'], value=literal['disabled_value']) if isinstance(command, CustomGroup): embeds.add_field(name=literal['subcommand'], value=f'\n{brief_group(command)}\n') for check in command.checks: data = get_check(check.name) if data is None: continue embeds.add_field(name=f'{data["emoji"]} {data["name"]}', value=data["description"]) if command.cog is not None: category = command.cog.qualified_name if isinstance(command.cog, CustomCog): category = command.cog.emoji + ' ' + category footer += ' · ' + category embeds.set_footer(text=footer) for embed in embeds.to_list(): await ctx.send(embed=embed)
class DeckCog(CustomCog, name=get_cog('DeckCog')['name']): """ 슈텔로 데크의 운영을 위한 기능을 포함합니다. """ def __init__(self, client: Bot): super().__init__(client) self.client: Bot = client self.deck_handler: DeckHandler = DeckHandler(client) async def get_deck_embed(self, deck: Deck, brief: bool = True) -> ChainedEmbed: literal = literals('get_deck_embed') deck_embed = ChainedEmbed(title=literal['title'] % deck.name, description=deck.topic) deck_role = discord.utils.get(await self.deck_handler.guild.fetch_roles(), name=deck.name) deck_members = list() async for member in self.deck_handler.guild.fetch_members(): if deck_role in member.roles: deck_members.append(str(member)) deck_embed.set_thumbnail(url=deck.manager.avatar_url) deck_embed.add_field(name=literal['manager'], value=str(deck.manager)) if deck.public: deck_embed.add_field(name=literal['public_name'], value=literal['public_value']) if deck.nsfw: deck_embed.add_field(name=literal['nsfw_name'], value=literal['nsfw_value']) if deck.auto: deck_embed.add_field(name=literal['auto_name'], value=literal['auto_value']) if deck.lock: deck_embed.add_field(name=literal['lock_name'], value=literal['lock_value']) if deck.pending: deck_embed.add_field(name=literal['pending'] % len(deck.pending), value=' '.join( [str(member) for member in deck.pending])) if not brief: if deck_members: deck_embed.add_field(name=literal['members'] % len(deck_members), value='\n'.join(deck_members), inline=True) channels = list() for channel in deck.category_channel.channels: channels.append( (literal['voice'] if isinstance(channel, VoiceChannel ) else '') + (channel.name if channel != deck.default_channel else f'**__{channel.name}__**')) deck_embed.add_field(name=literal['channels'] % len(deck.category_channel.channels), value='\n'.join(channels), inline=True) deck_embed.set_footer(text=literal['id'] % deck.id) return deck_embed async def accept_joining(self, ctx: Context, deck: Deck, *members: Member): check_deck_manager(deck, ctx.author) literal = literals('accept_joining') async def accept_joining_(member: Member): await member.add_roles(deck.role) deck.pending.remove(member) pending = [member for member in members if member in deck.pending] if not pending: raise BadArgument('no pending found') tasks = [accept_joining_(member) for member in pending] if tasks: message = await ctx.send(literal['start'] % len(tasks)) done, yet = await asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION) for coro in done: if (e := coro.exception()) is not None: await self.deck_handler.fetch_deck(deck.default_channel) raise e await self.deck_handler.update_deck(deck) await message.edit(content=literal['done'] % (' '.join([str(member) for member in pending]), deck.name))