Skip to content

Commit

Permalink
Add tip when using a redundant rtfm selector (#51)
Browse files Browse the repository at this point in the history
Add a tip to rtfm/rtfs and update docs/ux around them
  • Loading branch information
IAmTomahawkx authored Aug 2, 2023
1 parent 87c69f4 commit 92d3e5e
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 89 deletions.
49 changes: 33 additions & 16 deletions core/utils/paginator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
from discord import ui # shortcut because I'm lazy
from discord.ext.commands import CommandError, Paginator as _Paginator # type: ignore # why does this need a stub file?
from discord.utils import MISSING
from typing_extensions import Self

from core import Bot, Context

if TYPE_CHECKING:
from typing_extensions import Self

from core import Context
if TYPE_CHECKING:
from discord.abc import MessageableChannel


__all__ = ("CannotPaginate", "Pager", "KVPager", "TextPager")
Expand All @@ -61,19 +62,27 @@ def __init__(
author: discord.User | discord.Member | None = None,
author_url: str | None = None,
stop: bool = False,
reply_author_takes_paginator: bool = False,
):
super().__init__()
self.bot = ctx.bot
self.stoppable = stop
self.ctx = ctx
self.delete_after = delete_after
self.entries = entries
self.embed_author = author, author_url
self.channel = ctx.channel
self.author = ctx.author
self.nocount = nocount
self.title = title
self.per_page = per_page
self.bot: Bot = ctx.bot
self.stoppable: bool = stop
self.ctx: Context = ctx
self.delete_after: bool = delete_after
self.entries: list[Any] = entries
self.embed_author: tuple[discord.User | discord.Member | None, str | None] = author, author_url
self.channel: MessageableChannel = ctx.channel
self.nocount: bool = nocount
self.title: str | None = title
self.per_page: int = per_page

if reply_author_takes_paginator:
if ctx.replied_reference:
self.author = ctx.replied_message.author
else:
self.author = ctx.author
else:
self.author = ctx.author

pages, left_over = divmod(len(self.entries), self.per_page)
if left_over:
Expand Down Expand Up @@ -298,13 +307,21 @@ def prepare_embed(self, entries: list[Any], page: int, *, first: bool = False):

class TextPager(Pager):
def __init__(
self, ctx: Context, text: str, *, prefix: str = "```", suffix: str = "```", max_size: int = 2000, stop: bool = False
self,
ctx: Context,
text: str,
*,
prefix: str = "```",
suffix: str = "```",
max_size: int = 2000,
stop: bool = False,
**kwargs: Any,
) -> None:
paginator = _Paginator(prefix=prefix, suffix=suffix, max_size=max_size - 200)
for line in text.split("\n"):
paginator.add_line(line)

super().__init__(ctx, entries=paginator.pages, per_page=1, show_entry_count=False, stop=stop)
super().__init__(ctx, entries=paginator.pages, per_page=1, show_entry_count=False, stop=stop, **kwargs)

def get_page(self, page: int) -> Any:
return self.entries[page - 1]
Expand Down
147 changes: 74 additions & 73 deletions modules/manuals.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,49 @@ def _smart_guess_lib(self, ctx: core.Context) -> LibEnum | None:

return None

async def get_lib(self, ctx: core.Context, query: str) -> tuple[LibEnum, str, str] | None: # enum, query, notice
if not query:
lib = self._smart_guess_lib(ctx)

if not lib:
await ctx.reply("Sorry, I couldn't apply a default library to this channel. Try again with a library?")
return None

await ctx.send(str(lib.value), reference=ctx.replied_message)
return None

view = StringView(query)
maybe_lib = view.get_word()
view.skip_ws()
final_query = view.read_rest()

tip = ""
lib: LibEnum | None = None

if maybe_lib in lib_names:
lib = lib_names[maybe_lib]
else:
maybe_lib = None
final_query = query # ignore the stringview stuff then

if lib is None:
lib = self._smart_guess_lib(ctx)

if lib is None:
await ctx.reply("Sorry, I couldn't find a library that matched. Try again with a different library?")
return None

elif (
maybe_lib
and isinstance(ctx.channel, discord.Thread)
and ctx.channel.parent_id == constants.Channels.HELP_FORUM
and lib == self._smart_guess_lib(ctx)
):
if 1006717008613740596 not in ctx.channel._applied_tags: # type: ignore # other-help tag, that one doesnt get a smart guess
tip += "\n• Tip: Forum posts with tags will automatically have the relevant libraries used, no need to specify it!"

return lib, final_query, tip

@commands.command(
"rtfm",
brief="Searches documentation",
Expand All @@ -111,28 +154,18 @@ async def rtfm(self, ctx: core.Context, *, query: str) -> None:
On its own it will do its best to figure out the most relevant documentation,
but you can always specify by prefixing the query with the library you wish to use.
The following libraries are supported (you can use either the full name or the shorthand):
```
- wavelink | wl
- twitchio | tio
- python | py
- discordpy | dpy
```
The following flags are available for this command:
```
- --labels (Include labels in search results)
- --clear (Clearly labels labels with a `label:` prefix. If --labels has not be set it will be implicitly set)
"""
if not query:
lib = self._smart_guess_lib(ctx)
• wavelink | wl
• twitchio | tio
• python | py
• discordpy | dpy
if not lib:
await ctx.reply("Sorry, I couldn't apply a default library to this channel. Try again with a library?")
return
await ctx.send(str(lib.value), reference=ctx.replied_message)
return
The following flags are available for this command:
• --labels (Include labels in search results)
• --clear (Clearly labels labels with a `label:` prefix. If --labels has not be set it will be implicitly set)
"""
labels = False
clear_labels = False

Expand All @@ -144,26 +177,14 @@ async def rtfm(self, ctx: core.Context, *, query: str) -> None:
labels = clear_labels = True # implicitly set --labels
query = query.replace("--clear", "")

view = StringView(query)
maybe_lib = view.get_word()
view.skip_ws()
final_query = view.read_rest()
lib: LibEnum | None = None

if maybe_lib in lib_names:
lib = lib_names[maybe_lib]
else:
final_query = query # ignore the stringview stuff then

if lib is None:
lib = self._smart_guess_lib(ctx)

if lib is None:
await ctx.reply("Sorry, I couldn't find a library that matched. Try again with a different library?")
optional = await self.get_lib(ctx, query)
if not optional:
return

lib, final_query, tip = optional

if not final_query:
await ctx.send(str(lib.value[0]), reference=ctx.replied_message)
await ctx.send(str(lib.value[0]) + tip, reference=ctx.replied_message)
return

url = self.target.with_path("/api/public/rtfm.sphinx").with_query(
Expand Down Expand Up @@ -196,7 +217,7 @@ async def rtfm(self, ctx: core.Context, *, query: str) -> None:
e.description = "\n".join(f"[`{key}`]({url})" for key, url in matches["nodes"].items())
e.set_author(name=f"Query Time: {float(matches['query_time']):.2f}")

await ctx.send(embed=e)
await ctx.send(tip or None, embed=e)

@commands.command(
name="rtfs",
Expand All @@ -212,53 +233,31 @@ async def rtfs(self, ctx: core.Context, *, query: str) -> None:
On its own it will do its best to figure out the most relevant library,
but you can always specify by prefixing the query with the library you wish to use.
The following libraries are supported (you can use either the full name or the shorthand):
```
- wavelink | wl
- twitchio | tio
- discordpy | dpy
- aiohttp |
```
The following flags are available for this command:
```
- --source (Sends source code instead of links to the github repository)
"""
if not query:
lib = self._smart_guess_lib(ctx)
• wavelink | wl
• twitchio | tio
• discordpy | dpy
• aiohttp |
if not lib:
await ctx.reply("Sorry, I couldn't apply a default library to this channel. Try again with a library?")
return
The following flags are available for this command:
await ctx.send(str(lib.value), reference=ctx.replied_message)
return
• --source (Sends source code instead of links to the github repository)
"""

source = False

if "--source" in query:
source = True
query = query.replace("--source", "")

view = StringView(query)
maybe_lib = view.get_word()
view.skip_ws()
final_query = view.read_rest()
lib: LibEnum | None = None

if maybe_lib in lib_names:
lib = lib_names[maybe_lib]
else:
final_query = query # ignore the stringview stuff then

if lib is None:
lib = self._smart_guess_lib(ctx)

if lib is None:
await ctx.reply("Sorry, I couldn't find a library that matched. Try again with a different library?")
optional = await self.get_lib(ctx, query)
if not optional:
return

lib, final_query, tip = optional

if not final_query:
await ctx.reply(str(lib.value[0]))
await ctx.reply(str(lib.value[0]) + tip)
return

url = self.target.with_path("/api/public/rtfs").with_query(
Expand Down Expand Up @@ -291,7 +290,7 @@ async def rtfs(self, ctx: core.Context, *, query: str) -> None:
out = [f"[{name}]({url})" for name, url in nodes.items()]

author: str = f"query Time: {float(matches['query_time']):.03f} • commit {matches['commit'][:6]}"
footer: str = f"Is the api behind on commits? Use {discord.utils.escape_mentions(ctx.prefix)}rtfs-reload" # type: ignore
footer: str | None = tip or None

embed: discord.Embed = discord.Embed(title=f"{lib.name.title()}: {final_query}", colour=lib.value[1])
embed.description = "\n".join(out)
Expand All @@ -302,9 +301,11 @@ async def rtfs(self, ctx: core.Context, *, query: str) -> None:

else:
n = next(iter(nodes.items()))
await ctx.send(f"Showing source for `{n[0]}`\nCommit: {matches['commit'][:6]}", reference=ctx.replied_message)
await ctx.send(
f"Showing source for `{n[0]}`\nCommit: {matches['commit'][:6]}" + tip, reference=ctx.replied_message
)

pages = TextPager(ctx, n[1], prefix="```py")
pages = TextPager(ctx, n[1], prefix="```py", reply_author_takes_paginator=True)
await pages.paginate()


Expand Down

0 comments on commit 92d3e5e

Please sign in to comment.