def render_state_0(self): other = self.other text = [ 'Type "new" to show this message up again.' 'Type "A-J" "1-10" for coordinate.' 'And "1-3" "1-3" for ship placement' 'It always places the ship right-down from the source coordinate' ] text.extend(render_map(self.data, SHIP_VALUES)) embed = Embed('', '\n'.join(text), 0x010101) embed.add_author(other.user.avatar_url_as(size=64), f'vs.: {other.user.full_name}') text.clear() if sum(self.ships_left): sub_text = [] amount = self.ships_left[1] if amount: sub_text.append(f'{amount} size 1x3 ship left') amount = self.ships_left[2] if amount: sub_text.append(f'{amount} size 1x4 ship left') amount = self.ships_left[3] if amount: sub_text.append(f'{amount} size 2x2 ship left') text.append(', '.join(sub_text)) text.append(' ship is left to place. ') text.append(self.text) embed.add_footer(''.join(text)) return embed
def create_page(self, index): end = index * 10 start = end - 9 if end > len(self.source.history): end = len(self.source.history) shard = [] embed = Embed('Statistics', f'{start} - {end}', color=KANAKO_COLOR) add_options = self.source.possibilities for question_index, element in enumerate( self.source.history[start - 1:end], start): shard.append('```diff') if add_options: shard.append('\n') shard.append(', '.join([ f'{index}. : {option}' for index, option in enumerate(element.options, 1) ])) for user_index, user in enumerate(self.source.users): value, time = element.answers[user_index] shard.append( f'\n{"+" if element.answer==value else "-"} {user:f} : {value} ( {time:.2f} s )' ) shard.append('\n```') embed.add_field( f'{question_index}.: {element.question} - {element.answer}', ''.join(shard)) shard.clear() embed.add_footer(f'Page {index+1} / {len(self.cache)}') self.cache[index] = embed return embed
def render_state_1(self): other = self.other text = [] if self.state: text.append('**It is your turn!**') else: text.append('**It is your opponent\'s turn!**') text.append( 'Type "new" to show this message up again.' 'Type "A-J" "1-10" to torpedo a ship.' 'If you hit your opponent, then it is your turn again.',) if self.page: text.append('**Your opponents ship:**') text.extend(render_map(other.data, HIDDEN_VALUES)) footer = f'Your opponent has {sum(other.ships_left)} ships left on {len(other.ship_positions)} tiles. {self.text}' else: text.append('**Your ships:**') text.extend(render_map(self.data, SHIP_VALUES)) footer = f'You have {sum(self.ships_left)} ships left on {len(self.ship_positions)} tiles. {self.text}' embed = Embed('', '\n'.join(text), 0x010101) embed.add_author(other.user.avatar_url_as(size=64), f'vs.: {other.user:f}') embed.add_footer(footer) return embed
def createpage0(self, guild): embed = Embed(f'Roles of **{guild.name}**:', '\n'.join([role.mention for role in self.roles]), color=(guild.icon_hash & 0xFFFFFF if (guild.icon_type is ICON_TYPE_NONE) else (guild.id >> 22) & 0xFFFFFF)) embed.add_footer(f'Page 1 / {len(self.cache)}') self.cache[0] = embed
def embed_template(user, titles=None, descript=None): """ Template for error embeds """ embeded = Embed(color=RED, title=titles, description=descript, timestamp=datetime.utcnow()) embeded.add_footer(user.id) embeded.add_author(user.avatar_url, user.full_name) return embeded
def render_state_2(self): other = self.other text = [] if self.state: text.append('**You won!**\n') else: text.append('**You lost :cry:**\n') if self.page: text.append('Your opponent\'s ships:') text.extend(render_map(other.data, SHIP_VALUES)) else: text.append('Your ships:') text.extend(render_map(self.data, SHIP_VALUES)) embed = Embed('', '\n'.join(text), 0x010101) embed.add_author(other.user.avatar_url_as(size=64), f'vs.: {other.user:f}') embed.add_footer(self.text) return embed
async def command(client, message): chunks = [] actual_chunk = [] index = 0 limit = len(CHESUTO_BGM_TRACKS_SORTED) collected = 0 while True: if index == limit: break actual = CHESUTO_BGM_TRACKS_SORTED[index].display_name index += 1 actual_chunk.append(repr(index)) actual_chunk.append('.: ') actual_chunk.append(actual) actual_chunk.append('\n') collected += 1 if collected == 20: del actual_chunk[-1] chunks.append(''.join(actual_chunk)) actual_chunk.clear() collected = 0 if collected: chunks.append(''.join(actual_chunk)) actual_chunk = None embeds = [] limit = len(chunks) index = 0 while index < limit: embed = Embed('Chesuto BGMs:', color=FLAN_HELP_COLOR, description=chunks[index]) index += 1 embed.add_footer(f'page {index}/{limit}') embeds.append(embed) await Pagination(client, message.channel, embeds)
def create_page(self, index): role = self.roles[index - 1] embed = Embed(role.name, '\n'.join([ f'id : {role.id!r}', f'color : {role.color.as_html}', f'permission number : {role.permissions:d}', f'managed : {role.managed}', f'separated : {role.separated}', f'mentionable : {role.mentionable}', '\nPermissions:\n```diff', *(f'{"+" if value else "-"}{key.replace("_", "-")}' for key, value in role.permissions.items()), '```', ]), color=role.color) embed.add_footer(f'Page {index+1} / {len(self.roles)+1}') self.cache[index] = embed return embed
def render_showcase(name, map_): result = [] element_index = 0 element_limit = len(map_) page_index = 1 page_limit = (element_limit + 29) // 30 field_text = [] while True: if page_index > page_limit: break embed = Embed(name.capitalize(), '', KANAKO_COLOR) embed.add_footer(f'page {page_index} / {page_limit}') for _ in range(((element_limit % 30) + 9) // 10 if page_index == page_limit else 3): field_index_limit = element_index + 10 if field_index_limit > element_limit: field_index_limit = element_limit while element_index < field_index_limit: element = map_[element_index] element_index += 1 field_text.append( f'{element_index}.: **{element[0]} - {element[1]}**') embed.add_field(f'{element_index-9} - {element_index}', '\n'.join(field_text), inline=True) field_text.clear() result.append(embed) page_index += 1 return result
async def buy(client, event, item : ([(item.name, item.id) for item in BUYABLE], 'Select the item to buy nya!'), amount : (int, 'How much items would you want to buy?'), ): """Buy?""" try: item = ITEMS[item] except KeyError: abort('Item not available.') permissions = event.channel.cached_permissions_for(client) if (not permissions.can_send_messages) or (not permissions.can_add_reactions): abort('I need `send messages` and `add reactions` permissions to execute the command.') yield user = event.user async with DB_ENGINE.connect() as connector: response = await connector.execute( select([currency_model.total_love]). \ where(currency_model.user_id==user.id)) results = await response.fetchall() if results: total_love = results[0] else: total_love = 0 embed = Embed('Confirm buying', f'Selected item: {item.emoji:e} **{item.name}**\n' f'Amount: **{amount}**\n' f'\n' f'Price: {calculate_buy_cost(item.market_cost, amount)} {EMOJI__HEART_CURRENCY:e}\n' f'Budget: {total_love} {EMOJI__HEART_CURRENCY:e}' ) embed.add_author(user.avaar_url, user.full_name) embed.add_footer('The prices of context of demand and supply.') message = await client.message_create(event.channel, embed=embed) await client.reaction_add(message, item.emoji) await client.reaction_add(message, CONFIRM_NAH) try: event = await wait_for_reaction(client, message, partial_func(check_confirm_emoji, item.emoji), 300.0) except TimeoutError: return if event.emoji is CONFIRM_NAH: embed.title = 'Buying cancelled' else: user = event.user async with DB_ENGINE.connect() as connector: response = await connector.execute( select([currency_model.total_love, currency_model.total_allocated]). \ where(currency_model.user_id==user.id)) results = await response.fetchall() if results: total_love, total_allocated = results[0] else: total_love = total_allocated = 0 if total_love == 0: amount = cost = 0 else: amount, cost = calculate_buyable_and_cost(item.market_cost, amount, total_love-total_allocated) item.market_cost += amount if cost == 0: new_love = total_love else: new_love = total_love-cost await connector.execute(update(currency_model.user_id==user.id). \ values(total_love = new_love)) response = await connector.execute(select([item_model.id, item_model.amount]). \ where(item_model.user_id==user.id).where(item_model.type==item.id)) results = await response.fetchall() if results: row_id, actual_amount = results[0] new_amount = actual_amount+amount to_execute = ITEM_TABLE.update().values( amount=new_amount ).where(item_model.id==row_id) else: to_execute = ITEM_TABLE.insert().values( user_id = user.id, amount = amount, type = item.id ) await connector.execute(to_execute) embed.title = 'Buying confirmed' embed.description = ( f'Selected item: {item.emoji:e} **{item.name}**\n' f'Bought mount: **{amount}**\n' f'\n' f'Hearts: {total_love} {EMOJI__HEART_CURRENCY:e} -> {new_love} {EMOJI__HEART_CURRENCY:e}' ) await client.message_edit(message, embed=embed)
def create_page_0(self): user_count = len(self.source.users) win_counts = [0 for _ in range(user_count)] lose_counts = win_counts.copy() win_firsts = win_counts.copy() lose_firsts = win_counts.copy() win_times = [[] for _ in range(user_count)] lose_times = [[] for _ in range(user_count)] for element in self.source.history: answer = element.answer answers = element.answers first_time = CIRCLE_TIME first_index = 0 first_won = True for index in range(user_count): value, time = answers[index] if value == answer: win_counts[index] += 1 win_times[index].append(time) if time < first_time: first_time = time first_index = index first_won = True else: lose_counts[index] += 1 lose_times[index].append(time) if time < first_time: first_time = time first_index = index first_won = False if first_time != CIRCLE_TIME: if first_won: win_firsts[first_index] += 1 else: lose_firsts[first_index] += 1 win_medians = [ value[len(value) // 2] if value else CIRCLE_TIME for value in win_times ] lose_medians = [ value[len(value) // 2] if value else CIRCLE_TIME for value in lose_times ] embed = Embed('Statistics', color=KANAKO_COLOR) for index, user in enumerate(self.source.users): win_count = win_counts[index] lose_count = lose_counts[index] win_median = win_medians[index] lose_median = lose_medians[index] win_first = win_firsts[index] lose_first = lose_firsts[index] total = float(win_count) total += (((2**.5) - 1.) - ((((CIRCLE_TIME + win_median) / CIRCLE_TIME)**.5) - 1.)) * win_count total += win_first / 5. total -= (((2**.5) - 1.) - ((((CIRCLE_TIME + lose_median) / CIRCLE_TIME)**.5) - 1.)) * lose_count * 2. total -= lose_first / 2.5 embed.add_field( f'{user:f} :', f'Correct answers : {win_count}\n' f'Bad answers : {lose_count}\n' f'Good answer time median : {win_median:.2f} s\n' f'Bad answer time median : {lose_median:.2f} s\n' f'Answered first: {win_first} GOOD / {lose_first} BAD\n' f'Rated : {total:.2f}') embed.add_footer(f'Page 1 / {len(self.cache)}') self.cache[0] = embed
async def receive_sync(client, partner): try: async with SYNC_LOCK: # some delay is needed or Koishi might answer too fast. await sleep(0.4, KOKORO) await client.message_create(CHANNEL__SYSTEM__SYNC, REQUEST_APPROVED) while True: try: message = await wait_for_message(client, CHANNEL__SYSTEM__SYNC, check_any(partner), 60.) except TimeoutError: sys.stderr.write('Sync request failed, timeout.\n') return content = message.content if content == SYNC_DONE: break path_full, file_name = content.split(':') path_parts = path_full.split('.') if not path_parts: sys.stderr.write( 'Empty content received, aborting sync.\n') return source_path = path_parts[0] try: source_path = RELATIONS[source_path] except KeyError: sys.stderr.write( f'Source path not found: {source_path!r}, aborting sync.\n' ) return for path_part in path_parts[1:]: source_path = join(source_path, path_part) if not exists(source_path): make_dir(source_path) attachments = message.attachments if (attachments is not None): attachment = attachments[0] binary = await client.download_attachment(attachment) if binary is None: sys.stdout.write( f'{attachment!r} yielded empty binary.\n') continue source_path = join(source_path, file_name) with (await AsyncIO(source_path, 'wb')) as file: await file.write(binary) # Wait some. It can happen that we send this message, before the other side gets it's answer. await client.message_create(CHANNEL__SYSTEM__SYNC, RECEIVED) except BaseException as err: with StringIO() as buffer: await KOKORO.render_exc_async(err, ['```'], file=buffer) buffer.seek(0) lines = buffer.readlines() pages = [] page_length = 0 page_contents = [] index = 0 limit = len(lines) while True: if index == limit: embed = Embed(description=''.join(page_contents)) pages.append(embed) page_contents = None break line = lines[index] index = index + 1 line_length = len(line) # long line check, should not happen if line_length > 500: line = line[:500] + '...\n' line_length = 504 if page_length + line_length > 1997: if index == limit: # If we are at the last element, we don't need to shard up, # because the last element is always '```' page_contents.append(line) embed = Embed(description=''.join(page_contents)) pages.append(embed) page_contents = None break page_contents.append('```') embed = Embed(description=''.join(page_contents)) pages.append(embed) page_contents.clear() page_contents.append('```py\n') page_contents.append(line) page_length = 6 + line_length continue page_contents.append(line) page_length += line_length continue limit = len(pages) index = 0 while index < limit: embed = pages[index] index += 1 embed.add_footer(f'page {index}/{limit}') await Pagination(client, message.channel, pages)
async def command_error_handler(ctx, exception): if ctx.guild is not GUILD__NEKO_DUNGEON: return False with StringIO() as buffer: await KOKORO.render_exc_async(exception,[ ctx.client.full_name, ' ignores an occurred exception at command ', repr(ctx.command), '\n\nMessage details:\nGuild: ', repr(ctx.guild), '\nChannel: ', repr(ctx.channel), '\nAuthor: ', ctx.author.full_name, ' (', repr(ctx.author.id), ')\nContent: ', repr(ctx.content), '\n```py\n'], '```', file=buffer) buffer.seek(0) lines = buffer.readlines() pages = [] page_length = 0 page_contents = [] index = 0 limit = len(lines) while True: if index == limit: embed = Embed(description=''.join(page_contents)) pages.append(embed) page_contents = None break line = lines[index] index = index+1 line_length = len(line) # long line check, should not happen if line_length > 500: line = line[:500]+'...\n' line_length = 504 if page_length+line_length > 1997: if index == limit: # If we are at the last element, we don\'t need to shard up, # because the last element is always '```' page_contents.append(line) embed = Embed(description=''.join(page_contents)) pages.append(embed) page_contents = None break page_contents.append('```') embed = Embed(description=''.join(page_contents)) pages.append(embed) page_contents.clear() page_contents.append('```py\n') page_contents.append(line) page_length = 6+line_length continue page_contents.append(line) page_length += line_length continue limit = len(pages) index = 0 while index < limit: embed = pages[index] index += 1 embed.add_footer(f'page {index}/{limit}') await Pagination(ctx.client, ctx.channel, pages) return True
async def add_bot_channel_name(client, message, weight: int, name): """ Adds the given channel name to the bot channel names. When adding a command please also define weight and not only name as: `weight | name` """ if EDIT_LOCK.locked(): await Closer( client, message.channel, Embed('Ohoho', 'A bot channel editing is already taking place.')) return async with EDIT_LOCK: name = escape_name(name) if not 2 <= len(name) <= 100: await Closer(client, message.channell, Embed(f'Too long or short name', name)) return names = await read_channels() close_matches = get_close_matches( name, [describer.name for describer in names], n=1, cutoff=0.8) if not close_matches: overwrite = False embed = Embed( 'Add bot channel name', f'Would you like to add a channel name:\n{name}\nWith weight of {weight}.' ) elif close_matches[0] == name: overwrite = True embed = Embed( 'Add bot channel name', f'Would you like to overwrite the following bot channel name:\n' f'{name}\n' f'To weight of {weight}.') else: overwrite = False embed = Embed( 'Add bot channel name', f'There is a familiar channel name already added: {close_matches[0]}\n' f'Would you like to overwrite the following bot channel name:\n' f'{name}\n' f'To weight of {weight}.') message = await client.message_create(message.channel, embed=embed, components=ADD_COMPONENTS) try: event = await wait_for_component_interaction( message, timeout=300., check=check_staff_role) except TimeoutError: event = None cancelled = False else: cancelled = (event.interaction == ADD_BUTTON_CANCEL) if cancelled: footer = 'Name adding cancelled.' else: if overwrite: for describer in names: if describer.name == describer: describer.weight = weight footer = 'Name overwritten successfully.' else: describer = ChannelNameDescriber.from_name_and_weight( name, weight) names.append(describer) footer = 'Name added successfully.' await write_channels(names) embed.add_footer(footer) if event is None: await client.message_edit(message, embed=embed, components=None) else: await client.interaction_component_message_edit(event, embed=embed, components=None)
async def set_bgm_name(client, message, content): bgm = get_bgm(content) if bgm is None: await client.message_create(message.channel, embed=Embed(None, '*Nothing found.*', CHESUTO_COLOR)) return embed = Embed(f'Renaming: *{bgm.display_name}*', bgm.description, color=CHESUTO_COLOR) \ .add_footer('Your next message will be captured as the new display name of the bgm.') message = await client.message_create(message.channel, embed=embed) try: response = await wait_for_message(client, message.channel, check_has_cards_role, 300.0) except TimeoutError: content = None footer = 'Timeout occurred.' else: content = response.content if len(content) > 100: content = None footer = '*That\'s pretty long*. That\'s what she said. Please give a display name with maximum of 100 ' \ 'characters.' else: footer = f'Are you sure to set the bgm\'s display name as: {content!r}?' embed.add_footer(footer) await client.message_edit(message, embed=embed) if content is None: return if message.channel.cached_permissions_for(client).can_manage_messages: try: await client.message_delete(response) except BaseException as err: if isinstance(err, ConnectionError): # no internet return if isinstance(err, DiscordException): if err.code in ( ERROR_CODES.missing_access, # client removed ERROR_CODES.unknown_message, # message deleted ERROR_CODES.unknown_channel, # channel deleted ERROR_CODES.missing_permissions, # permissions changed meanwhile ): return raise for emoji_ in SET_BGM_NAME_EMOJI_EMOJIS: await client.reaction_add(message, emoji_) try: event = await wait_for_reaction(client, message, check_reaction_cards_role, 300.) except TimeoutError: emoji_ = None else: emoji_ = event.emoji if message.channel.cached_permissions_for(client).can_manage_messages: try: await client.reaction_clear(message) except BaseException as err: if isinstance(err, ConnectionError): # no internet return if isinstance(err, DiscordException): if err.code in ( ERROR_CODES.missing_access, # client removed ERROR_CODES.unknown_message, # message deleted ERROR_CODES.unknown_channel, # channel deleted ERROR_CODES.missing_permissions, # permissions changed meanwhile ): return raise if emoji_ is None: footer = 'Timeout occurred.' elif emoji_ is SET_BGM_NAME_EMOJI_OK: BGM_NAMES[bgm.source_name] = content await write_bgm_names() bgm.display_name = content footer = 'Rename done.' else: footer = 'Rename cancelled.' embed.add_footer(footer) await client.message_edit(message, embed=embed)
async def command(client, message): guild = message.channel.guild if (guild is None): return if not guild.cached_permissions_for(client).can_ban_users: await client.message_create(message.channel, embed = Embed( description = 'I have no permissions at the guild.', color=ADMINISTRATION_COLOR)) return ban_data = await client.guild_bans(guild) if not ban_data: await client.message_create(message.channel, 'None') return embeds = [] maintext = f'Guild bans for {guild.name} {guild.id}:' limit = len(ban_data) index = 0 while True: field_count = 0 embed_length = len(maintext) embed = Embed(title=maintext) embeds.append(embed) while True: user, reason = ban_data[index] if reason is None: reason = 'Not defined.' name = f'{user:f} {user.id}' embed_length += len(reason)+len(name) if embed_length > 5900: break embed.add_field(name,reason) field_count += 1 if field_count == 25: break index +=1 if index == limit: break if index == limit: break index = 0 field_count = 0 embed_ln = len(embeds) result = [] while True: embed = embeds[index] index +=1 embed.add_footer(f'Page: {index}/{embed_ln}. Bans {field_count+1}-{field_count+len(embed.fields)}/{limit}') field_count += len(embed.fields) result.append(embed) if index == embed_ln: break await Pagination(client, message.channel, result)
async def yeet( client, event, user: ('user', 'Select the user to yeet!'), reason: ('str', 'Any reason why you would want to yeet?') = None, delete_message_days: (range(8), 'Delete previous messages?') = 0, notify_user: ('bool', 'Whether the user should get DM about the ban.') = True, ): """Yeets someone out of the guild. You must have ban users permission.""" # Check permissions guild = event.guild if guild is None: abort('Guild only command.') if guild not in client.guild_profiles: abort('I must be in the guild to do this.') if not event.user_permissions.can_ban_users: abort('You must have yeet users permission to use this command.') if not guild.cached_permissions_for(client).can_ban_users: abort(f'{client.name_at(guild)} cannot yeet in the guild.') if not event.user.has_higher_role_than_at(user, guild): abort('You must have higher role than the person to be yeeted.') if not client.has_higher_role_than_at(user, guild): abort('I must have higher role than the person to yeeted.') # Ask, whether the user should be banned. if (reason is not None) and (not reason): reason = None embed = Embed('Confirmation', f'Are you sure to yeet {user.mention} from {guild.name}?'). \ add_field('Delete message day', str(delete_message_days), inline=True). \ add_field('Notify user', 'true' if notify_user else 'false', inline=True). \ add_field('Reason', '*No reason provided.*' if reason is None else reason) message = yield InteractionResponse(embed=embed, components=BAN_COMPONENTS, allowed_mentions=None) # Wait for user input try: component_interaction = await wait_for_component_interaction( message, timeout=300.0, check=partial_func(check_banner, event.user)) except TimeoutError: embed.title = 'Timeout' embed.description = f'{user.mention} was not yeeted from {guild.name}.' # Edit the source message with the source interaction yield InteractionResponse(embed=embed, components=None, allowed_mentions=None, message=message) return if component_interaction.interaction == BAN_BUTTON_CANCEL: embed.title = 'Cancelled' embed.description = f'{user.mention} was not yeeted from {guild.name}.' # Edit the source message with the component interaction yield InteractionResponse(embed=embed, components=None, allowed_mentions=None, event=component_interaction) return # Acknowledge the event await client.interaction_component_acknowledge(component_interaction) # Try to notify the user. Ignore bot notifications. if notify_user: if user.is_bot: notify_note = None else: try: channel = await client.channel_private_create(user) except BaseException as err: if isinstance(err, ConnectionError): return # We cannot help no internet raise embed = Embed('Yeeted', f'You were yeeted from {guild.name}.'). \ add_field('Reason', '*No reason provided.*' if reason is None else reason) try: await client.message_create(channel, embed=embed) except BaseException as err: if isinstance(err, ConnectionError): return # We cannot help no internet elif isinstance(err, DiscordException) and ( err.code == ERROR_CODES.cannot_message_user): notify_note = 'Notification cannot be delivered: user has DM disabled.' else: raise else: notify_note = None else: notify_note = None if reason is None: caller = event.user reason = f'Requested by: {caller.full_name} [{caller.id}]' await client.guild_ban_add(guild, user, delete_message_days=delete_message_days, reason=reason) embed = Embed('Hecatia yeah!', f'{user.full_name} has been yeeted.') if (notify_note is not None): embed.add_footer(notify_note) # Edit the source message yield InteractionResponse(embed=embed, message=message, components=None)
async def bans(client, event): """Lists the guild's bans.""" guild = event.guild if guild is None: abort('Guild only command') if guild not in client.guild_profiles: abort('I must be in the guild to execute the command.') if not event.user_permissions.can_ban_users: abort('You must have `ban users` permission to invoke this command.') if not guild.cached_permissions_for(client).can_ban_users: abort( 'I must have `ban users` permission invite to execute this command.' ) yield ban_data = await client.guild_ban_get_all(guild) embeds = [] main_text = f'Guild bans for {guild.name} {guild.id}:' limit = len(ban_data) if limit: index = 0 while True: field_count = 0 embed_length = len(main_text) embed = Embed(main_text) embeds.append(embed) while True: user, reason = ban_data[index] if reason is None: reason = 'Not defined.' name = f'{user:f} {user.id}' embed_length += len(reason) + len(name) if embed_length > 5900: break embed.add_field(name, reason) field_count += 1 if field_count == 25: break index += 1 if index == limit: break if index == limit: break else: embed = Embed(main_text, '*none*') embeds.append(embed) index = 0 field_count = 0 embed_ln = len(embeds) result = [] while True: embed = embeds[index] index += 1 embed.add_footer( f'Page: {index}/{embed_ln}. Bans {field_count+1}-{field_count+len(embed.fields)}/{limit}' ) field_count += len(embed.fields) result.append(embed) if index == embed_ln: break await Pagination(client, event, result, check=bans_pagination_check)
async def command(client, message, emoji:Emoji, *roles:'role'): permissions = message.channel.cached_permissions_for(client) if (not permissions.can_manage_emojis) or (not permissions.can_add_reactions): await client.message_create(message.channel, embed = Embed(description='I have no permissions to edit emojis, or to add reactions.')) return roles = sorted(roles) roles_ = emoji.roles embed = Embed().add_author(emoji.url, emoji.name) if (roles_ is None) or (not roles_): role_text = '*none*' else: role_text = ', '.join([role.mention for role in roles_]) embed.add_field('Roles before:', role_text) if (not roles): role_text = '*none*' else: role_text = ', '.join([role.mention for role in roles]) embed.add_field('Roles after:', role_text) message = await client.message_create(message.channel, embed=embed) for emoji_ in ROLE_EMOJI_EMOJIS: await client.reaction_add(message, emoji_) try: event = await wait_for_reaction(client, message, _role_emoji_emoji_checker(message.guild), 300.) except TimeoutError: emoji_ = ROLE_EMOJI_CANCEL else: emoji_ = event.emoji if message.channel.cached_permissions_for(client).can_manage_messages: try: await client.reaction_clear(message) except BaseException as err: if isinstance(err, ConnectionError): # no internet return if isinstance(err, DiscordException): if err.code in ( ERROR_CODES.invalid_access, # client removed ERROR_CODES.unknown_message, # message deleted ERROR_CODES.invalid_permissions, # permissions changed meanwhile ): return raise if emoji_ is ROLE_EMOJI_OK: try: await client.emoji_edit(emoji, roles=roles) except DiscordException as err: footer = repr(err) else: footer = 'Emoji edited succesfully.' elif emoji_ is ROLE_EMOJI_CANCEL: footer = 'Emoji edit cancelled' else: #should not happen return embed.add_footer(footer) await client.message_edit(message, embed=embed)
async def run(self): client = self.client channel = self.channel answers = self.answers buffer = ReuBytesIO() embed = Embed(color=KANAKO_COLOR) embed.add_image('attachment://guessme.png') embed.add_footer('') time_till_notify = CIRCLE_TIME - 10 for index, (question, answer) in enumerate(self.map, 1): embed.footer.text = f'{index} / {len(self.map)}' if self.possibilities: self.options = self.generate_options(answer) embed.description = '\n'.join([ f'**{index}.: {value}**' for index, value in enumerate(self.options, 1) ]) try: await client.message_create(channel, embed=embed, file=('guessme.png', draw(buffer, question))) except DiscordException: return self.cancel() circle_start = LOOP_TIME() waiter = sleep(time_till_notify, client.loop) self.waiter = waiter try: await waiter Task( self.send_or_except( Embed( 'Hurry! Only 10 seconds left!', '\n'.join([ user.full_name for user in self.users if user.id not in answers ]), KANAKO_COLOR)), client.loop) waiter = sleep(time_till_notify, client.loop) self.waiter = waiter await waiter self.calculate_leavers() except CancelledError: pass except InterruptedError as err: return self.cancel() element = history_element() element.question = question element.answer = answer element.options = self.options element.answers = [(value[0], value[1] - circle_start) for value in (answers[user.id] for user in self.users)] self.history.append(element) answers.clear() embed.title = f'Last answer: {answer}' await self.send_or_except(Embed(embed.title, '', KANAKO_COLOR)) del ACTIVE_GAMES[channel.id] client.events.message_create.remove(self.channel, self) self.running = False await game_statistics(self)