Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b3ad47a
Feature: suggest command usage for misspelt commands
F4zii Feb 18, 2020
adfb87e
Merge branch 'master' into feat/F4zi/CommandSuggestion
Akarys42 Feb 18, 2020
dfe9dd8
Seperated tags.get_command into a function and a wrapper
F4zii Feb 19, 2020
eb01f3f
Feature: suggest command usage for misspelt commands
F4zii Feb 19, 2020
777088b
Merge branches 'feat/F4zi/CommandSuggestion' and 'master' of https://…
F4zii Feb 19, 2020
f192e02
Deletion of the consuming rest (*) used in _get_command
F4zii Feb 19, 2020
8599c68
Delete_after added for suggestion message
F4zii Feb 19, 2020
1625c18
Suggest aliases when invoked instead of full command name
F4zii Feb 19, 2020
21a3486
Removal of unused logs
F4zii Feb 19, 2020
337374e
Rearrange, exception and NoneTypes handling
F4zii Feb 19, 2020
e570b29
Rearrange, Function naming and Docstrings
F4zii Feb 19, 2020
72be687
Rearrange, NoneTypes handling
F4zii Feb 19, 2020
4ebefe4
Return Logic Fixed
F4zii Feb 19, 2020
aceeba6
Rearrange - Function naming and Docstrings
F4zii Feb 20, 2020
d0c3a07
Rearrange - Function naming and Docstrings
F4zii Feb 20, 2020
ec1ffab
Command suggestion message reformat.
F4zii Feb 20, 2020
7fd9225
Handling and logging CommandError
F4zii Feb 21, 2020
7eb1acd
Only replace the misspelt command, and not the whole occurrences of it
F4zii Feb 21, 2020
093fb2c
Handling CommandError and Optimization
F4zii Feb 22, 2020
5a6a5b6
awaited can_run Coroutine
F4zii Feb 22, 2020
bff2ea5
Return False (not sent) at the end of display_tag
F4zii Feb 22, 2020
53753f0
(display_tag) Return False if no tags were found.
F4zii Feb 22, 2020
9477f0f
Merge remote-tracking branch 'origin/master' into feat/F4zi/CommandSu…
MarkKoz Feb 22, 2020
de53605
Nontype handling Logic fix
F4zii Feb 22, 2020
dc0bc87
Boolean Logic fix
F4zii Feb 22, 2020
5f4b04b
Return True after a tag suggestion was sent
F4zii Mar 7, 2020
34ef099
Update bot/cogs/tags.py, cleaner return logic
F4zii Mar 7, 2020
9a00d70
Merge branch 'feat/F4zi/CommandSuggestion' of https://github.com/pyth…
F4zii Mar 7, 2020
01406f8
Rebased after a long time of being abandon
Xithrius Jan 3, 2021
012f90f
Removed possibility of exception via walrus.
Xithrius Jan 3, 2021
431afbf
If user is a staff member, no command suggestions.
Xithrius Jan 6, 2021
69ed1cc
Only helpers and below now get command suggestions
Xithrius Jan 7, 2021
6912639
Merge branch 'master' into feat/F4zi/CommandSuggestion
Xithrius Jan 17, 2021
491e0b9
Removed 'Channels' import, unused.
Xithrius Jan 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 39 additions & 1 deletion bot/exts/backend/error_handler.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import contextlib
import difflib
import logging
import typing as t

Expand All @@ -8,7 +9,7 @@

from bot.api import ResponseCodeError
from bot.bot import Bot
from bot.constants import Colours
from bot.constants import Colours, Icons, MODERATION_ROLES
from bot.converters import TagNameConverter
from bot.errors import LockedResourceError
from bot.utils.checks import InWhitelistCheckFailure
Expand Down Expand Up @@ -155,9 +156,46 @@ async def try_get_tag(self, ctx: Context) -> None:
else:
with contextlib.suppress(ResponseCodeError):
await ctx.invoke(tags_get_command, tag_name=tag_name)

if not any(role.id in MODERATION_ROLES for role in ctx.author.roles):
tags_cog = self.bot.get_cog("Tags")
command_name = ctx.invoked_with
sent = await tags_cog.display_tag(ctx, command_name)

if not sent:
await self.send_command_suggestion(ctx, command_name)

# Return to not raise the exception
return

async def send_command_suggestion(self, ctx: Context, command_name: str) -> None:
"""Sends user similar commands if any can be found."""
# No similar tag found, or tag on cooldown -
# searching for a similar command
raw_commands = []
for cmd in self.bot.walk_commands():
if not cmd.hidden:
raw_commands += (cmd.name, *cmd.aliases)
if similar_command_data := difflib.get_close_matches(command_name, raw_commands, 1):
similar_command_name = similar_command_data[0]
similar_command = self.bot.get_command(similar_command_name)

log_msg = "Cancelling attempt to suggest a command due to failed checks."
try:
if not await similar_command.can_run(ctx):
log.debug(log_msg)
return
except errors.CommandError as cmd_error:
log.debug(log_msg)
await self.on_command_error(ctx, cmd_error)
return

misspelled_content = ctx.message.content
e = Embed()
e.set_author(name="Did you mean:", icon_url=Icons.questionmark)
e.description = f"{misspelled_content.replace(command_name, similar_command_name, 1)}"
await ctx.send(embed=e, delete_after=10.0)

async def handle_user_input_error(self, ctx: Context, e: errors.UserInputError) -> None:
"""
Send an error message in `ctx` for UserInputError, sometimes invoking the help command too.
Expand Down
24 changes: 20 additions & 4 deletions bot/exts/info/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,15 @@ async def search_tag_content_any_keyword(self, ctx: Context, *, keywords: Option
matching_tags = self._get_tags_via_content(any, keywords or 'any', ctx.author)
await self._send_matching_tags(ctx, keywords, matching_tags)

@tags_group.command(name='get', aliases=('show', 'g'))
async def get_command(self, ctx: Context, *, tag_name: TagNameConverter = None) -> None:
"""Get a specified tag, or a list of all tags if no tag is specified."""
async def display_tag(self, ctx: Context, tag_name: str = None) -> bool:
"""
If a tag is not found, display similar tag names as suggestions.

If a tag is not specified, display a paginated embed of all tags.

Tags are on cooldowns on a per-tag, per-channel basis. If a tag is on cooldown, display
nothing and return False.
"""
def _command_on_cooldown(tag_name: str) -> bool:
"""
Check if the command is currently on cooldown, on a per-tag, per-channel basis.
Expand All @@ -212,7 +217,7 @@ def _command_on_cooldown(tag_name: str) -> bool:
f"{ctx.author} tried to get the '{tag_name}' tag, but the tag is on cooldown. "
f"Cooldown ends in {time_left:.1f} seconds."
)
return
return False

if tag_name is not None:
temp_founds = self._get_tag(tag_name)
Expand All @@ -237,6 +242,7 @@ def _command_on_cooldown(tag_name: str) -> bool:
await ctx.send(embed=Embed.from_dict(tag['embed'])),
[ctx.author.id],
)
return True
elif founds and len(tag_name) >= 3:
await wait_for_deletion(
await ctx.send(
Expand All @@ -247,6 +253,7 @@ def _command_on_cooldown(tag_name: str) -> bool:
),
[ctx.author.id],
)
return True

else:
tags = self._cache.values()
Expand All @@ -255,6 +262,7 @@ def _command_on_cooldown(tag_name: str) -> bool:
description="**There are no tags in the database!**",
colour=Colour.red()
))
return True
else:
embed: Embed = Embed(title="**Current tags**")
await LinePaginator.paginate(
Expand All @@ -268,6 +276,14 @@ def _command_on_cooldown(tag_name: str) -> bool:
empty=False,
max_lines=15
)
return True

return False

@tags_group.command(name='get', aliases=('show', 'g'))
async def get_command(self, ctx: Context, *, tag_name: TagNameConverter = None) -> None:
"""Get a specified tag, or a list of all tags if no tag is specified."""
await self.display_tag(ctx, tag_name)


def setup(bot: Bot) -> None:
Expand Down