Don't run command checks on each message starting with a prefix (#3718)

This commit is contained in:
jack1142 2020-04-24 18:12:25 +02:00 committed by GitHub
parent 0d6a7eb797
commit b1fe807b47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 18 deletions

View File

@ -566,13 +566,14 @@ class RedHelpFormatter:
"""
Sends an error, fuzzy help, or stays quiet based on settings
"""
coms = {
c
async for c in self.help_filter_func(
fuzzy_commands = await fuzzy_command_search(
ctx,
help_for,
commands=self.help_filter_func(
ctx, ctx.bot.walk_commands(), help_settings=help_settings
)
}
fuzzy_commands = await fuzzy_command_search(ctx, help_for, commands=coms, min_score=75)
),
min_score=75,
)
use_embeds = await ctx.embed_requested()
if fuzzy_commands:
ret = await format_fuzzy_results(ctx, fuzzy_commands, embed=use_embeds)

View File

@ -197,12 +197,9 @@ def init_events(bot, cli_flags):
help_settings = await HelpSettings.from_context(ctx)
fuzzy_commands = await fuzzy_command_search(
ctx,
commands={
c
async for c in RedHelpFormatter.help_filter_func(
ctx, bot.walk_commands(), help_settings=help_settings
)
},
commands=RedHelpFormatter.help_filter_func(
ctx, bot.walk_commands(), help_settings=help_settings
),
)
if not fuzzy_commands:
pass

View File

@ -1,6 +1,7 @@
from __future__ import annotations
import asyncio
import collections.abc
import json
import logging
import os
@ -9,7 +10,16 @@ import shutil
import tarfile
from datetime import datetime
from pathlib import Path
from typing import Awaitable, Callable, List, Optional, Set, Union, TYPE_CHECKING
from typing import (
AsyncIterator,
Awaitable,
Callable,
Iterator,
List,
Optional,
Union,
TYPE_CHECKING,
)
import discord
from fuzzywuzzy import fuzz, process
@ -51,7 +61,7 @@ async def fuzzy_command_search(
ctx: Context,
term: Optional[str] = None,
*,
commands: Optional[Set[Command]] = None,
commands: Optional[Union[AsyncIterator[Command], Iterator[Command]]] = None,
min_score: int = 80,
) -> Optional[List[Command]]:
"""Search for commands which are similar in name to the one invoked.
@ -66,7 +76,7 @@ async def fuzzy_command_search(
term : Optional[str]
The name of the invoked command. If ``None``,
`Context.invoked_with` will be used instead.
commands : Optional[Set[commands.Command]]
commands : Optional[Union[AsyncIterator[commands.Command], Iterator[commands.Command]]]
The commands available to choose from when doing a fuzzy match.
When omitted, `Bot.walk_commands` will be used instead.
min_score : int
@ -108,10 +118,15 @@ async def fuzzy_command_search(
else:
return None
if commands is None:
choices = set(ctx.bot.walk_commands())
elif isinstance(commands, collections.abc.AsyncIterator):
choices = {c async for c in commands}
else:
choices = set(commands)
# Do the scoring. `extracted` is a list of tuples in the form `(command, score)`
extracted = process.extract(
term, (commands or set(ctx.bot.walk_commands())), limit=5, scorer=fuzz.QRatio
)
extracted = process.extract(term, choices, limit=5, scorer=fuzz.QRatio)
if not extracted:
return None