def _format_events(self, ctx, event_type: str, user_and_action: Tuple[str, str]): for chunk in chunker(user_and_action): embed = ColoredEmbed(title=event_type) for name, value in chunk: embed.add_field(name=name, value=value, inline=False) yield embed
def _format(self, action: str, report: Iterable[Tuple[str, str]]) -> Iterable[ColoredEmbed]: """Formats embeds to show which extensions errored out""" for chunk in chunker([*report]): embed = ColoredEmbed(title=action) for cog, message in chunk: embed.add_field(name=cog, value=f"```py\n{message}```", inline=False) yield embed
async def _format_group_help(self, title, filtered_commands): """Formats the help provided for cogs and groups""" for chunk in chunker(filtered_commands): embed = ColoredEmbed(title=title) for command in chunk: embed.add_field(name=self.get_command_signature(command), value=command.short_doc, inline=False) yield embed
async def _display(self, ctx, event_type: str, reason: str, user): embed = ColoredEmbed(title=event_type) fields = (('Reason', reason, False), ('User', str(user), True), ('Author', ctx.author.mention, True)) for name, value, inline in fields: embed.add_field(name=name, value=value, inline=inline) await ctx.display(embed=embed)
async def extensions_(self, ctx): """Extensions managing commands""" embeds = [] for chunk in chunker([v for v in self.bot.cogs.values()]): embed = ColoredEmbed(title=f"{self.bot.user}'s cogs") for cog in chunk: f_value = f"{len(cog.get_commands())} command(s), {len(cog.get_listeners())} listener(s)" embed.add_field(name=cog.qualified_name, value=f_value, inline=False) embeds.append(embed) await ctx.display(embeds=embeds)
async def on_command_error(self, ctx, error): """Overrides the default error handler""" if self._error_cd.get_bucket(ctx.message).update_rate_limit(): return self.dispatch('global_cooldown', ctx, '_warn_cd', '⚠️') error = getattr(error, 'original', error) is_owner = await ctx.is_owner() e_args = (type(error), error, error.__traceback__, 4) if not isinstance(error, (HTTPException, ClientException, CommandOnCooldown)): print_exception(*e_args) # Cooldown bypass if (isinstance(error, CommandOnCooldown) # there must be a better way and (is_owner or ctx.permissions_for(ctx.author).manage_messages)): return await ctx.reinvoke() if is_owner: lines = ''.join(format_exception(*e_args)) else: lines = str(error) await ctx.display(embed=ColoredEmbed( title='Error', description='```py\n' + lines + '```'))
async def stats(self, ctx): """Shows some stats about the bot""" guilds, channels, members = [s async for s in self._members_stats()] cogs, groups, commands = [s async for s in self._bot_stats()] embed = ColoredEmbed(title='Stats') fields = [('Guilds', f'{guilds} guilds'), ('Channels', f'{channels} channels'), ('Members', f'{members} members'), ('Cogs', f'{cogs} cogs'), ('Groups', f'{groups} groups'), ('Commands', f'{commands} commands')] for name, value in fields: embed.add_field(name=name, value=value) await ctx.display(embed=embed)
async def snipe(self, ctx): msg = self.snipes[ctx.guild.id].get(ctx.channel.id, None) if msg is None: content = "Couldn't find any sniped messages in this channel" return await ctx.send(content=content, delete_after=5) embed = ColoredEmbed(title=f'Sniped a message from {msg.author}', description=msg.content) await ctx.display(embed=embed)
async def find_reaction(self, ctx, min_message_index: int = 0, max_message_index: int = 10, timeout: int = 15): if min_message_index > max_message_index: raise InvalidBound( message= 'The minimal message amount must be smaller than the maximum one' ) if max_message_index > 100: raise InvalidBound( message= 'The maximum amount of message cannot be bigger than 100') if timeout > 120: raise InvalidBound('The timeout cannot be longer than 120 seconds') emoji = rng_choice(self.bot.emojis) embed = ColoredEmbed(title='Find the reaction !') fields = [('minimum message amount', f'{min_message_index} messages'), ('maximum message amount', f'{max_message_index} messages'), ('emoji', str(emoji))] for name, value in fields: embed.add_field(name=name, value=value) to_edit = await ctx.send(embed=embed) messages = await ctx.history(limit=max_message_index).flatten() msg = rng_choice(messages[min_message_index:max_message_index]) await msg.add_reaction(emoji) start = perf_counter() embed = await self._handle_reactions(msg, emoji, embed, start, timeout) await to_edit.edit(embed=embed)
async def reaction_time(self, ctx, min_delay: int = 3, max_delay: int = 6, timeout: int = 15): """Sends an embed and adds a random reaction""" if min_delay > max_delay: raise InvalidDelay( message='The minimal delay must be smaller than the maximum one' ) if max_delay > 120: raise InvalidBound( message='The maximum delay cannot be longer than ') if timeout > 30: raise InvalidBound( message='The timeout cannot be longer than 30 seconds') emoji = rng_choice(self.bot.emojis) embed = ColoredEmbed( title='Be the first to react when the emoji appears !') fields = [('minimum delay', f'{min_delay} seconds'), ('maximum delay', f'{max_delay} seconds'), ('emoji', str(emoji))] for name, value in fields: embed.add_field(name=name, value=value) msg = await ctx.send(embed=embed) await async_sleep(randint(min_delay, max_delay)) await msg.add_reaction(emoji) start = perf_counter() embed = await self._handle_reactions(msg, emoji, embed, start, timeout) await msg.edit(embed=embed)
async def _handle_reactions(self, msg: Message, emoji: Emoji, embed: ColoredEmbed, start: int, timeout: int): def check(p): return (p.channel_id == msg.channel.id and p.message_id == msg.id and not p.member.bot and str(p.emoji) == str(emoji)) try: p = await self.bot.wait_for('raw_reaction_add', timeout=timeout, check=check) except AsyncTimeoutError: embed.add_field(name='Result', value='No one reacted on time', inline=False) else: fields = [('Winner', p.member.mention), ('Time', f'{round(perf_counter() - start, 2)} seconds'), ('Message', f'[Jump url]({msg.jump_url})')] for name, value in fields: embed.add_field(name=name, value=value) finally: return embed
async def _format_bot_help(self, mapping): """Formats the help provided when help is invoked on it's own""" bot_commands = [(cog, com) for cog, com in mapping.items() if cog and com] sorted_commands = sorted(bot_commands, key=lambda tup: tup[0].qualified_name) for chunk in chunker(sorted_commands): embed = ColoredEmbed(title=f"{self.context.bot.user}'s general help command") for cog, command_list in chunk: filtered_commands = await self.filter_commands(command_list, sort=True) command_names = [] for c in filtered_commands: if isinstance(c, Group): command_names.append(f"`{c.name} [+{len(c.commands)}]`") else: command_names.append(f"`{c.name}`") if filtered_commands: embed.add_field(name=cog.qualified_name, value=' | '.join(command_names), inline=False) yield embed
async def format_r34_images(r34posts: List[str]): """Formats the r34 posts into an embed""" for post in r34posts: embed = ColoredEmbed(title=f"Author's id : {post.creator_ID}", url=post.file_url) embed.set_image(url=post.file_url) fields = (('Created at', post.created_at), ('Resolution', f"{post.width} x {post.height}")) for name, value in fields: embed.add_field(name=name, value=value) yield embed
async def format_nhentai_pages(results: List[Doujinshi]): for doujin in results: embed = ColoredEmbed(title=f'{doujin.name} ({doujin.magic})', url=f'https://nhentai.net/g/{doujin.magic}') # Cover image if (cover_url:= getattr(doujin, 'cover', None)): embed.set_image(url=cover_url) # japanese name if (jname:= getattr(doujin, 'jname', None)): embed.add_field(name='Japanese name', value=jname, inline=False)
resp = await self.translator.translate(text, dest=language) await self._display(ctx, resp, text) async def _display(self, ctx, resp, text: str) -> None: """Displays the response""" src = LANGUAGES.get(resp.src) or resp.src dest = LANGUAGES.get(resp.dest) or resp.dest if (r := round(resp.confidence * 100, 1)) < 50.0: f_confidence = f'{r}% (might be innacurate)' else: f_confidence = f'{r}%' embed = ColoredEmbed(title="Translated something !") fields = [('original', text, False), ('Translation', resp.text, False), ('Confidence', f_confidence, True), ('Languages', f'{src} -> {dest}', True)] for name, value, inline in fields: embed.add_field(name=name, value=value, inline=inline) await ctx.display(embed=embed) class LanguageNotFoundError(CommandError): pass
def _format_doujins(self, doujin): for image_url in doujin._images: yield ColoredEmbed(title='Reading mode', url=image_url).set_image(url=image_url)
async def rule34_(self, ctx, fuzzy: Optional[bool] = True, *, query: str): if not (r34posts:= await self.r34client.getImages(singlePage=True, randomPID=True, tags=query, fuzzy=fuzzy)): return await ctx.display(embed=ColoredEmbed(title="Couldn't find any post matching your query"))
async def nhentai_(self, ctx, query: DoujinshiConverter): """Looks for a nhentai doujin, per index or per name and displays it""" if not (pages:= [p async for p in format_nhentai_pages(query)]): return await ctx.display(embed=ColoredEmbed(title='No doujin found'))
async def send_bot_help(self, mapping): embeds = [e async for e in self._format_bot_help(mapping)] or ColoredEmbed(title='No command found') await self.context.display(embeds=embeds, channel=self.get_destination())
async def _display_mass(self, ctx, title, container): await ctx.display( embeds=[*self._format_events(ctx, title, container)] or ColoredEmbed(title=f"Couldn't find anyone to {title.split()[1]}"))
async def send_command_help(self, command): embed = ColoredEmbed(title=self.get_command_signature(command)) embed.add_field(name='Description', value=command.help) await self.context.display(embed=embed, channel=self.get_destination())
await ctx.display(embeds=embeds) @extensions_.command(name='load', aliases=['-l']) async def extensions_load(self, ctx, query: str = None): """ Loads all extensions matching the query """ report = self._manage(self.bot.load_extension, self._get_ext_path(query)) if ctx is None: # On bootup, execute this func with None everywhere return print(*report, sep='\n') if (embeds:= [*self._format('Loaded extensions', report)]): await ctx.display(embeds=embeds) else: await ctx.display(embed=ColoredEmbed(title="Couldn't find any matching extensions")) @extensions_.command(name='reload', aliases=['re', '-r']) async def extension_reload(self, ctx, query: str = None): """ Reloads all extensions matching the query """ exts = [e for e in self.bot.extensions if query in e.split('.') + [None]] report = self._manage(self.bot.reload_extension, exts) if (embeds:= [*self._format('Reloaded extensions', report)]): await ctx.display(embeds=embeds) else: await ctx.display(embed=ColoredEmbed(title="Couldn't find any matching extensions"))