def add_faq_slashcommands(slash: SlashCommand, faqs: List[FAQ]) -> None: """ Register /faq subcommands for each FAQ. This is pretty ugly - it'd be nicer if we could do this with a Cog or something, but Discord's commands are still in beta, so nothing is really ready yet. """ if len(faqs) <= 10: # Slash commands don't accept more than 10 options, so we only can # register it then. Yes, that is incredibly stupid. for faq in faqs: _add_slash(slash, faq) else: @slash.slash( name="faq", description="Retrieves FAQs related to given keyword(s).", options=[ manage_commands.create_option( name="search", description="The FAQ to find.", option_type=3, required=True, ), ], guild_ids=guild_ids(), ) async def _run(ctx: SlashContext, search: str) -> None: await _search(ctx, faqs, search)
def add_faq_slashcommands(slash: SlashCommand, faqs: List[FAQ]) -> None: """ Register /faq subcommands for each FAQ. This is pretty ugly - it'd be nicer if we could do this with a Cog or something, but Discord's commands are still in beta, so nothing is really ready yet. """ if len(faqs) <= 25: # Slash commands don't accept more than 25 options, so we only can # register it then. Thankfully we shouldn't hit that limit for a while. for faq in faqs: _add_slash(slash, faq) else: @slash.slash( name="faq", description="Retrieves FAQs related to given keyword(s).", options=[ manage_commands.create_option( name="search", description="The FAQ to find.", option_type=3, required=True, ), ], guild_ids=guild_ids(), ) @with_async_timer(COMMAND_TIME.labels('faq', 'slash')) async def _run(ctx: SlashContext, search: str) -> None: await _search(ctx, faqs, search)
def _add_slash(slash: SlashCommand, faq: FAQ) -> None: @slash.subcommand( base="faq", name=faq.name, description=faq.title, guild_ids=guild_ids(), ) async def _run(ctx: SlashContext) -> None: await ctx.send(embeds=[_embed(faq)])
def _add_slash(slash: SlashCommand, faq: FAQ) -> None: @slash.subcommand( base="faq", name=faq.name, description=faq.title, guild_ids=guild_ids(), ) @with_async_timer(COMMAND_TIME.labels('faq', 'slash')) async def _run(ctx: SlashContext) -> None: LOG.info(f'event=faq search="{faq.name}"') await ctx.send(embeds=[_embed(faq)])
class DocsCog(commands.Cog): """ Provides a %doc (%d) and %source (%s) command. """ def __init__(self, slash: SlashCommand): self.methods = CachedRequest( 60, "https://tweaked.cc/index.json", lambda contents: { k.lower(): {"original_name": k, **v} for k, v in json.loads(contents).items() } ) slash.get_cog_commands(self) async def _search_docs(self, ctx: Sendable, search: str, link: Callable[[dict], str]) -> None: """Search the documentation with a query and link to the result""" methods = await self.methods.get() search_k = search.lower() if search_k in methods: await ctx.send(embeds=[_embed(methods[search_k], link)]) return # We've not found a perfect match, so find an approximate one. A "good" match # is either a unique one, or one with a significantly higher score than the # next best one. best_matches = sorted( _score_methods(methods, search_k), key=lambda k: k[1], reverse=True, ) if ( len(best_matches) == 1 or (len(best_matches) >= 2 and best_matches[0][1] >= best_matches[1][1] + 0.05) ): best_match, _ = best_matches[0] method = methods[best_match] await ctx.send( content=f"Cannot find '{search}', using '{method['original_name']}'' instead.", embeds=[_embed(method, link)], ) return await ctx.send(content=f"Cannot find method '{search}'. Please check your spelling, or contribute to the documentation at https://github.com/SquidDev-CC/CC-Tweaked.") @commands.command(name="doc", aliases=["d", "docs"]) async def doc(self, ctx: commands.Context, *, search: str) -> None: """Searches for a function with the current name and returns its documentation.""" await self._search_docs(SendableContext(ctx), search, lambda x: f"https://tweaked.cc/{x['url']}") @commands.command(name="source", aliases=["s"]) async def source(self, ctx: commands.Context, *, search: str) -> None: """Searches for a function with the current name, and returns a link to its source code.""" await self._search_docs(SendableContext(ctx), search, lambda x: x["source"]) @doc.error @source.error async def doc_error(self, ctx: commands.Context, error) -> None: """Reports an error on the source and doc commands.""" if isinstance(error, commands.MissingRequiredArgument): await ctx.send(content="Missing arguments! Please provide a CC:T method to search for.") else: LOG.exception("Error processing command: %s", error) await ctx.send("An unexpected error occurred when processing the command.") @cog_slash( name="docs", description="Searches for a function with the current name and returns its documentation.", options=[ manage_commands.create_option( name="name", description="The function's name", option_type=3, required=True, ), ], guild_ids=guild_ids(), ) async def doc_slash(self, ctx: SlashContext, name: str) -> None: await self._search_docs(ctx, name, lambda x: f"https://tweaked.cc/{x['url']}") @cog_slash( name="source", description="Searches for a function with the current name and returns a link to its source code.", options=[ manage_commands.create_option( name="name", description="The function's name", option_type=3, required=True, ), ], guild_ids=guild_ids(), ) async def doc_source(self, ctx: SlashContext, name: str) -> None: await self._search_docs(ctx, name, lambda x: x["source"])