async def logs_closed_by(self, ctx, *, user: User = None): """ Get all logs closed by the specified user. If no `user` is provided, the user will be the person who sent this command. `user` may be a user ID, mention, or name. """ user = user if user is not None else ctx.author query = { "guild_id": str(self.bot.guild_id), "open": False, "closer.id": str(user.id), } projection = {"messages": {"$slice": 5}} entries = await self.bot.db.logs.find(query, projection).to_list(None) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: embed = discord.Embed( color=discord.Color.red(), description="No log entries have been found for that query", ) return await ctx.send(embed=embed) session = PaginatorSession(ctx, *embeds) await session.run()
async def logs(self, ctx, *, member: User = None): """Affiche une liste des tickets support d'un membre.""" await ctx.trigger_typing() if not member: thread = ctx.thread if not thread: raise commands.UserInputError user = thread.recipient else: user = member default_avatar = 'https://cdn.discordapp.com/embed/avatars/0.png' icon_url = getattr(user, 'avatar_url', default_avatar) logs = await self.bot.api.get_user_logs(user.id) if not any(not log['open'] for log in logs): embed = discord.Embed(color=discord.Color.red(), description="Cet utilisateur n'a pas " "n'a pas eu de ticket.") return await ctx.send(embed=embed) logs = reversed([e for e in logs if not e['open']]) embeds = self.format_log_embeds(logs, avatar_url=icon_url) session = PaginatorSession(ctx, *embeds) await session.run()
async def snippets(self, ctx): """Renvoie une liste des snippets actuellement définis.""" if ctx.invoked_subcommand is not None: return embeds = [] if self.bot.snippets: embed = discord.Embed(color=self.bot.main_color, description='Voici une liste de snippets ' 'qui sont actuellement configurés.') else: embed = discord.Embed( color=discord.Color.red(), description="Vous n'avez pas de snippets pour le moment." ) embed.set_footer( text=f'Tapez {self.bot.prefix}help snippets pour plus de commandes.' ) embed.set_author(name='Snippets', icon_url=ctx.guild.icon_url) embeds.append(embed) for name, value in self.bot.snippets.items(): if len(embed.fields) == 5: embed = discord.Embed(color=self.bot.main_color, description=embed.description) embed.set_author(name='Snippets', icon_url=ctx.guild.icon_url) embeds.append(embed) embed.add_field(name=name, value=value, inline=False) session = PaginatorSession(ctx, *embeds) await session.run()
async def snippets(self, ctx): """Returns a list of snippets that are currently set.""" if ctx.invoked_subcommand is not None: return embeds = [] em = discord.Embed(color=discord.Color.blurple()) em.set_author(name='Snippets', icon_url=ctx.guild.icon_url) embeds.append(em) em.description = 'Here is a list of snippets that are currently configured.' if not self.bot.snippets: em.color = discord.Color.red() em.description = f'You dont have any snippets at the moment.' em.set_footer( text=f'Do {self.bot.prefix}help snippets for more commands.') for name, value in self.bot.snippets.items(): if len(em.fields) == 5: em = discord.Embed(color=discord.Color.blurple(), description=em.description) em.set_author(name='Snippets', icon_url=ctx.guild.icon_url) embeds.append(em) em.add_field(name=name, value=value, inline=False) session = PaginatorSession(ctx, *embeds) await session.run()
async def closed_by(self, ctx, *, user: User = None): """Returns all logs closed by a user.""" if not self.bot.self_hosted: embed = discord.Embed(color=discord.Color.red(), description='This command only works if ' 'you are self-hosting your logs.') return await ctx.send(embed=embed) user = user or ctx.author query = { 'guild_id': str(self.bot.guild_id), 'open': False, 'closer.id': str(user.id) } projection = {'messages': {'$slice': 5}} entries = await self.bot.db.logs.find(query, projection).to_list(None) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: embed = discord.Embed( color=discord.Color.red(), description='No log entries have been found for that query') return await ctx.send(embed=embed) session = PaginatorSession(ctx, *embeds) await session.run()
async def search(self, ctx, limit: Optional[int] = None, *, query): """Searches all logs for a message that contains your query.""" await ctx.trigger_typing() if not self.bot.self_hosted: embed = discord.Embed(color=discord.Color.red(), description='This command only works if you ' 'are self-hosting your logs.') return await ctx.send(embed=embed) query = { 'guild_id': str(self.bot.guild_id), 'open': False, '$text': { '$search': f'"{query}"' } } projection = {'messages': {'$slice': 5}} entries = await self.bot.db.logs.find(query, projection).to_list(limit) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: embed = discord.Embed( color=discord.Color.red(), description='No log entries have been found for that query') return await ctx.send(embed=embed) session = PaginatorSession(ctx, *embeds) await session.run()
async def alias(self, ctx): """Returns a list of aliases that are currently set.""" if ctx.invoked_subcommand is not None: return embeds = [] desc = 'Here is a list of aliases that are currently configured.' if self.bot.aliases: embed = Embed(color=Color.blurple(), description=desc) else: embed = Embed( color=Color.blurple(), description='You dont have any aliases at the moment.') embed.set_author(name='Command aliases', icon_url=ctx.guild.icon_url) embed.set_footer(text=f'Do {self.bot.prefix}' 'help aliases for more commands.') embeds.append(embed) for name, value in self.bot.aliases.items(): if len(embed.fields) == 5: embed = Embed(color=Color.blurple(), description=desc) embed.set_author(name='Command aliases', icon_url=ctx.guild.icon_url) embed.set_footer(text=f'Do {self.bot.prefix}help ' 'aliases for more commands.') embeds.append(embed) embed.add_field(name=name, value=value, inline=False) session = PaginatorSession(ctx, *embeds) return await session.run()
async def help(self, ctx, *, command: str = None): """Shows the help message.""" await ctx.trigger_typing() if command is not None: cog = self.bot.cogs.get(command) cmd = self.bot.get_command(command) if cog is not None: em = self.format_cog_help(ctx, cog) elif cmd is not None: em = self.format_command_help(ctx, cmd) else: em = self.format_not_found(ctx, command) if em: return await ctx.send(embed=em) pages = [] for _, cog in sorted(self.bot.cogs.items()): em = self.format_cog_help(ctx, cog) if em: pages.append(em) p_session = PaginatorSession(ctx, *pages) await p_session.run()
async def logs(self, ctx, *, member: Union[discord.Member, discord.User, obj]=None): """Shows a list of previous Modmail thread logs of a member.""" if not member: thread = await self.bot.threads.find(channel=ctx.channel) if not thread: raise commands.UserInputError user = member or thread.recipient icon_url = getattr(user, 'avatar_url', 'https://cdn.discordapp.com/embed/avatars/0.png') username = str(user) if hasattr(user, 'name') else str(user.id) logs = await self.bot.modmail_api.get_user_logs(user.id) if not any(not e['open'] for e in logs): return await ctx.send(embed=discord.Embed(color=discord.Color.red(), description='This user does not have any previous logs')) em = discord.Embed(color=discord.Color.blurple()) em.set_author(name=f'{username} - Previous Logs', icon_url=icon_url) embeds = [em] current_day = dateutil.parser.parse(logs[0]['created_at']).strftime(r'%d %b %Y') fmt = '' closed_logs = [l for l in logs if not l['open']] for index, entry in enumerate(closed_logs): if len(embeds[-1].fields) == 3: em = discord.Embed(color=discord.Color.blurple()) em.set_author(name='Previous Logs', icon_url=icon_url) embeds.append(em) date = dateutil.parser.parse(entry['created_at']) new_day = date.strftime(r'%d %b %Y') time = date.strftime(r'%H:%M') key = entry['key'] closer = entry['closer']['name'] log_url = f"https://logs.modmail.tk/{key}" if not self.bot.selfhosted else self.bot.config.log_url.strip('/') + f'/logs/{key}' truncate = lambda c: c[:47].strip() + '...' if len(c) > 50 else c if entry['messages']: short_desc = truncate(entry['messages'][0]['content']) or 'No content' else: short_desc = 'No content' fmt += f"[`[{time}][closed-by:{closer}]`]({log_url}) - {short_desc}\n" if current_day != new_day or index == len(closed_logs) - 1: embeds[-1].add_field(name=current_day, value=fmt, inline=False) current_day = new_day fmt = '' session = PaginatorSession(ctx, *embeds) await session.run()
async def plugin_registry_compact(self, ctx): """Shows a compact view of all plugins within the registry.""" await self.populate_registry() registry = list(self.registry.items()) registry.sort(key=lambda elem: elem[0]) pages = [""] for name, details in registry: repo = f"https://github.com/{details['repository']}" url = f"{repo}/tree/{details['branch']}/{name}" desc = details["description"].replace("\n", "") fmt = f"[`{name}`]({url}) - {desc}" length = len(fmt) - len(url) - 4 fmt = fmt[: 75 + len(url)].strip() + "..." if length > 75 else fmt if len(fmt) + len(pages[-1]) >= 2048: pages.append(fmt + "\n") else: pages[-1] += fmt + "\n" embeds = [] for page in pages: embed = discord.Embed(color=self.bot.main_color, description=page) embed.set_author(name="Plugin Registry", icon_url=self.bot.user.avatar_url) embeds.append(embed) paginator = PaginatorSession(ctx, *embeds) await paginator.run()
async def logs(self, ctx, *, member: User = None): """Shows a list of previous Modmail thread logs of a member.""" await ctx.trigger_typing() if not member: thread = ctx.thread if not thread: raise commands.UserInputError user = thread.recipient else: user = member default_avatar = 'https://cdn.discordapp.com/embed/avatars/0.png' icon_url = getattr(user, 'avatar_url', default_avatar) logs = await self.bot.api.get_user_logs(user.id) if not any(not log['open'] for log in logs): embed = discord.Embed(color=discord.Color.red(), description='This user does not ' 'have any previous logs.') return await ctx.send(embed=embed) logs = reversed([e for e in logs if not e['open']]) embeds = self.format_log_embeds(logs, avatar_url=icon_url) session = PaginatorSession(ctx, *embeds) await session.run()
async def logs_search(self, ctx, limit: Optional[int] = None, *, query): """ Retrieve all logs that contain messages with your query. Provide a `limit` to specify the maximum number of logs the bot should find. """ await ctx.trigger_typing() query = { "guild_id": str(self.bot.guild_id), "open": False, "$text": { "$search": f'"{query}"' }, } projection = {"messages": {"$slice": 5}} entries = await self.bot.db.logs.find(query, projection).to_list(limit) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: embed = discord.Embed( color=discord.Color.red(), description="No log entries have been found for that query", ) return await ctx.send(embed=embed) session = PaginatorSession(ctx, *embeds) await session.run()
async def changelog(self, ctx): """Show a paginated changelog of the bot.""" changelog = await Changelog.from_url(self.bot) try: paginator = PaginatorSession(ctx, *changelog.embeds) await paginator.run() except: await ctx.send(changelog.CHANGELOG_URL)
async def get_perms_level(self, ctx, *, level: str = None): """View the currently-set permissions for commands of a permission level.""" def get_level(perm_level): permissions = self.bot.config.level_permissions.get( perm_level.name, []) if not permissions: embed = Embed( title='Permission entries for permission ' f'level `{perm_level.name}`:', description='No permission entries found.', color=self.bot.main_color, ) else: values = [] for perm in permissions: if perm == -1: values.insert(0, '**everyone**') continue member = ctx.guild.get_member(perm) if member is not None: values.append(member.mention) continue user = self.bot.get_user(perm) if user is not None: values.append(user.mention) continue role = ctx.guild.get_role(perm) if role is not None: values.append(role.mention) else: values.append(str(perm)) embed = Embed( title= f'Permission entries for permission level `{perm_level.name}`:', description=', '.join(values), color=self.bot.main_color, ) return embed embeds = [] if level is not None: if level.upper() not in PermissionLevel.__members__: embed = Embed( title='Error', color=Color.red(), description= 'The permission level you are attempting to point ' f'to does not exist: `{level}`.') return await ctx.send(embed=embed) embeds.append(get_level(PermissionLevel[level.upper()])) else: for perm_level in PermissionLevel: embeds.append(get_level(perm_level)) p_session = PaginatorSession(ctx, *embeds) return await p_session.run()
async def permissions_get_command(self, ctx, *, command: str = None): """View the currently-set permissions for a command.""" def get_command(cmd): permissions = self.bot.config.command_permissions.get(cmd.name, []) if not permissions: embed = Embed( title=f'Permission entries for command `{cmd.name}`:', description='No permission entries found.', color=self.bot.main_color, ) else: values = [] for perm in permissions: if perm == -1: values.insert(0, '**everyone**') continue member = ctx.guild.get_member(perm) if member is not None: values.append(member.mention) continue user = self.bot.get_user(perm) if user is not None: values.append(user.mention) continue role = ctx.guild.get_role(perm) if role is not None: values.append(role.mention) else: values.append(str(perm)) embed = Embed( title=f'Permission entries for command `{cmd.name}`:', description=', '.join(values), color=self.bot.main_color ) return embed embeds = [] if command is not None: if command not in self.bot.all_commands: embed = Embed( title='Error', color=Color.red(), description='The command you are attempting to point ' f'to does not exist: `{command}`.' ) return await ctx.send(embed=embed) embeds.append(get_command(self.bot.all_commands[command])) else: for cmd in self.bot.commands: embeds.append(get_command(cmd)) p_session = PaginatorSession(ctx, *embeds) return await p_session.run()
async def permissions_get(self, ctx, *, user_or_role: Union[User, Role, str]): """ View the currently-set permissions. You can specify `user_or_role` as an alternative to get-by-command or get-by-level. Do not ping `@everyone` for granting permission to everyone, use "everyone" or "all" instead, `user_or_role` may be a role ID, name, mention, user ID, name, mention, "all", or "everyone". """ if hasattr(user_or_role, "id"): value = user_or_role.id elif user_or_role in {"everyone", "all"}: value = -1 else: raise commands.BadArgument(f'User or Role "{user_or_role}" not found') cmds = [] levels = [] for cmd in self.bot.commands: permissions = self.bot.config.command_permissions.get(cmd.name, []) if value in permissions: cmds.append(cmd.name) for level in PermissionLevel: permissions = self.bot.config.level_permissions.get(level.name, []) if value in permissions: levels.append(level.name) mention = user_or_role.name if hasattr(user_or_role, "name") else user_or_role desc_cmd = ( ", ".join(map(lambda x: f"`{x}`", cmds)) if cmds else "No permission entries found." ) desc_level = ( ", ".join(map(lambda x: f"`{x}`", levels)) if levels else "No permission entries found." ) embeds = [ Embed( title=f"{mention} has permission with the following commands:", description=desc_cmd, color=self.bot.main_color, ), Embed( title=f"{mention} has permission with the following permission groups:", description=desc_level, color=self.bot.main_color, ), ] p_session = PaginatorSession(ctx, *embeds) return await p_session.run()
async def logs(self, ctx, *, member: Union[discord.Member, discord.User] = None): """Shows a list of previous modmail thread logs of a member.""" if not member: thread = await self.bot.threads.find(channel=ctx.channel) if not thread: raise commands.UserInputError user = member or thread.recipient logs = await self.bot.modmail_api.get_user_logs(user.id) if not any(not e['open'] for e in logs): return await ctx.send('This user has no previous logs.') em = discord.Embed(color=discord.Color.green()) em.set_author(name='Previous Logs', icon_url=user.avatar_url) embeds = [em] current_day = dateutil.parser.parse( logs[0]['created_at']).strftime(r'%d %b %Y') fmt = '' closed_logs = [l for l in logs if not l['open']] for index, entry in enumerate(closed_logs): if len(embeds[-1].fields) == 3: em = discord.Embed(color=discord.Color.green()) em.set_author(name='Previous Logs', icon_url=user.avatar_url) embeds.append(em) date = dateutil.parser.parse(entry['created_at']) new_day = date.strftime(r'%d %b %Y') key = entry['key'] user_id = entry['user_id'] log_url = f"https://logs.modmail.tk/{user_id}/{key}" fmt += f"[`{key}`]({log_url})\n" if current_day != new_day or index == len(closed_logs) - 1: embeds[-1].add_field(name=current_day, value=fmt) current_day = new_day fmt = '' session = PaginatorSession(ctx, *embeds) await session.run()
async def help(self, ctx, *, command: str = None): """Shows the help message.""" if command is not None: cmd = self.bot.get_command(command) cog = self.bot.cogs.get(command) if cmd is not None: embeds = [self.format_command_help(cmd)] elif cog is not None: embeds = self.format_cog_help(ctx, cog) else: embeds = [self.format_not_found(ctx, command)] p_session = PaginatorSession(ctx, *embeds) return await p_session.run() embeds = [] for cog in sorted(self.bot.cogs.values(), key=lambda cog: cog.__class__.__name__): embeds.extend(self.format_cog_help(ctx, cog)) p_session = PaginatorSession(ctx, *embeds) return await p_session.run()
async def snippets(self, ctx): """ Create pre-defined messages for use in threads. When `{prefix}snippets` is used by itself, this will retrieve a list of snippets that are currently set. To use snippets: First create a snippet using: - `{prefix}snippets add snippet-name A pre-defined text.` Afterwards, you can use your snippet in a thread channel with `{prefix}snippet-name`, the message "A pre-defined text." will be sent to the recipient. See also `{prefix}alias`. """ embeds = [] if self.bot.snippets: embed = discord.Embed( color=self.bot.main_color, description="Here is a list of snippets " "that are currently configured.", ) else: embed = discord.Embed( color=discord.Color.red(), description="You dont have any snippets at the moment.", ) embed.set_footer( text=f"Do {self.bot.prefix}help snippets for more commands." ) embed.set_author(name="Snippets", icon_url=ctx.guild.icon_url) embeds.append(embed) for name, value in self.bot.snippets.items(): if len(embed.fields) == 5: embed = discord.Embed( color=self.bot.main_color, description=embed.description ) embed.set_author(name="Snippets", icon_url=ctx.guild.icon_url) embeds.append(embed) embed.add_field(name=name, value=value, inline=False) session = PaginatorSession(ctx, *embeds) await session.run()
async def alias(self, ctx): """ Create shortcuts to bot commands. When `{prefix}alias` is used by itself, this will retrieve a list of alias that are currently set. To use alias: First create a snippet using: - `{prefix}alias add alias-name other-command` For example: - `{prefix}alias add r reply` - Now you can use `{prefix}r` as an replacement for `{prefix}reply`. See also `{prefix}snippets`. """ embeds = [] desc = "Here is a list of aliases that are currently configured." if self.bot.aliases: embed = Embed(color=self.bot.main_color, description=desc) else: embed = Embed( color=self.bot.main_color, description="You dont have any aliases at the moment.", ) embed.set_author(name="Command aliases", icon_url=ctx.guild.icon_url) embed.set_footer(text=f"Do {self.bot.prefix}" "help aliases for more commands.") embeds.append(embed) for name, value in self.bot.aliases.items(): if len(embed.fields) == 5: embed = Embed(color=self.bot.main_color, description=desc) embed.set_author(name="Command aliases", icon_url=ctx.guild.icon_url) embed.set_footer( text=f"Do {self.bot.prefix}help " "aliases for more commands." ) embeds.append(embed) embed.add_field(name=name, value=value, inline=False) session = PaginatorSession(ctx, *embeds) return await session.run()
async def sponsors(self, ctx): """Shows a list of sponsors.""" resp = await self.bot.session.get( "https://raw.githubusercontent.com/kyb3r/modmail/master/SPONSORS.json" ) data = loads(await resp.text()) embeds = [] for elem in data: em = Embed.from_dict(elem["embed"]) embeds.append(em) random.shuffle(embeds) session = PaginatorSession(ctx, *embeds) await session.run()
async def get_perms(self, ctx, *, user_or_role: Union[User, Role, str]): """View the currently-set permissions.""" if hasattr(user_or_role, 'id'): value = user_or_role.id elif user_or_role in {'everyone', 'all'}: value = -1 else: raise commands.BadArgument( f'User or Role "{user_or_role}" not found') cmds = [] levels = [] for cmd in self.bot.commands: permissions = self.bot.config.command_permissions.get(cmd.name, []) if value in permissions: cmds.append(cmd.name) for level in PermissionLevel: permissions = self.bot.config.level_permissions.get(level.name, []) if value in permissions: levels.append(level.name) mention = user_or_role.name if hasattr(user_or_role, 'name') else user_or_role desc_cmd = ', '.join( map(lambda x: f'`{x}`', cmds)) if cmds else 'No permission entries found.' desc_level = ', '.join( map(lambda x: f'`{x}`', levels)) if levels else 'No permission entries found.' embeds = [ Embed( title=f'{mention} has permission with the following commands:', description=desc_cmd, color=self.bot.main_color), Embed( title= f'{mention} has permission with the following permission groups:', description=desc_level, color=self.bot.main_color) ] p_session = PaginatorSession(ctx, *embeds) return await p_session.run()
async def search(self, ctx, limit: Optional[int] = None, *, query): """Recherche dans tous les tickets un message contenant votre requête.""" await ctx.trigger_typing() if not self.bot.self_hosted: embed = discord.Embed( color=discord.Color.red(), description='Cette commande ne fonctionne ' 'que si vous auto-hébergez vos logs.' ) return await ctx.send(embed=embed) query = { 'guild_id': str(self.bot.guild_id), 'open': False, '$text': { '$search': f'"{query}"' } } projection = { 'messages': {'$slice': 5} } entries = await self.bot.db.logs.find(query, projection).to_list(limit) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: embed = discord.Embed( color=discord.Color.red(), description="Aucun ticket n'a été trouvée pour cette requête." ) return await ctx.send(embed=embed) session = PaginatorSession(ctx, *embeds) await session.run()
async def logs(self, ctx, *, user: User = None): """ Get previous Modmail thread logs of a member. Leave `user` blank when this command is used within a thread channel to show logs for the current recipient. `user` may be a user ID, mention, or name. """ await ctx.trigger_typing() if not user: thread = ctx.thread if not thread: raise commands.MissingRequiredArgument(param(name="member")) user = thread.recipient default_avatar = "https://cdn.discordapp.com/embed/avatars/0.png" icon_url = getattr(user, "avatar_url", default_avatar) logs = await self.bot.api.get_user_logs(user.id) if not any(not log["open"] for log in logs): embed = discord.Embed( color=discord.Color.red(), description="This user does not " "have any previous logs.", ) return await ctx.send(embed=embed) logs = reversed([e for e in logs if not e["open"]]) embeds = self.format_log_embeds(logs, avatar_url=icon_url) session = PaginatorSession(ctx, *embeds) await session.run()
async def closed_by(self, ctx, *, user: User = None): """Renvoie tous les ticket fermés par un utilisateur.""" if not self.bot.self_hosted: embed = discord.Embed( color=discord.Color.red(), description='Cette commande ne fonctionne ' 'que si vous auto-hébergez vos logs.' ) return await ctx.send(embed=embed) user = user or ctx.author query = { 'guild_id': str(self.bot.guild_id), 'open': False, 'closer.id': str(user.id) } projection = { 'messages': {'$slice': 5} } entries = await self.bot.db.logs.find(query, projection).to_list(None) embeds = self.format_log_embeds(entries, avatar_url=self.bot.guild.icon_url) if not embeds: embed = discord.Embed( color=discord.Color.red(), description="Aucun ticket n'a été trouvée pour cette requête." ) return await ctx.send(embed=embed) session = PaginatorSession(ctx, *embeds) await session.run()
async def send_bot_help(self, cogs): embeds = [] # TODO: Implement for no cog commands cogs = list(filter(None, cogs)) bot = self.context.bot # always come first default_cogs = [ bot.get_cog("Modmail"), bot.get_cog("Utility"), bot.get_cog("Plugins"), ] default_cogs.extend(c for c in cogs if c not in default_cogs) for cog in default_cogs: embeds.extend(await self.format_cog_help(cog)) p_session = PaginatorSession( self.context, *embeds, destination=self.get_destination() ) return await p_session.run()
async def changelog(self, ctx): '''Show a paginated changelog of the bot.''' changelog = await ChangeLog.from_repo(self.bot) p = PaginatorSession(ctx, *changelog.embeds) await p.run()
async def plugin_registry(self, ctx, *, plugin_name: str = None): """Shows a list of all approved plugins.""" await self.populate_registry() embeds = [] registry = list(self.registry.items()) random.shuffle(registry) def find_index(find_name): for i, (n, _) in enumerate(registry): if find_name == n: return i index = 0 if plugin_name in self.registry: index = find_index(plugin_name) elif plugin_name is not None: embed = discord.Embed( color=discord.Color.red(), description= f'Could not find a plugin with name "{plugin_name}" within the registry.', ) matches = get_close_matches(plugin_name, self.registry.keys()) if matches: embed.add_field( name="Perhaps you meant:", value="\n".join(f"`{m}`" for m in matches), ) return await ctx.send(embed=embed) for name, details in registry: repo = f"https://github.com/{details['repository']}" url = f"{repo}/tree/master/{name}" embed = discord.Embed( color=self.bot.main_color, description=details["description"], url=repo, title=details["repository"], ) embed.add_field(name="Installation", value=f"```{self.bot.prefix}plugins add {name}```") embed.set_author(name=details["title"], icon_url=details.get("icon_url"), url=url) if details.get("thumbnail_url"): embed.set_thumbnail(url=details.get("thumbnail_url")) if details.get("image_url"): embed.set_image(url=details.get("image_url")) embeds.append(embed) paginator = PaginatorSession(ctx, *embeds) paginator.current = index await paginator.run()
async def changelog(self, ctx): """Show a paginated changelog of the bot.""" changelog = await Changelog.from_url(self.bot) paginator = PaginatorSession(ctx, *changelog.embeds) await paginator.run()
async def changelog(self, ctx): changelog = await ChangeLog.from_repo(self.bot) p = PaginatorSession(ctx, *changelog.embeds) await p.run()