45 lines
1.7 KiB
Python
45 lines
1.7 KiB
Python
import discord
|
|
from fuzzywuzzy import fuzz, process
|
|
from typing import List
|
|
from unidecode import unidecode
|
|
|
|
from discord.ext.commands.converter import IDConverter, _get_from_guilds
|
|
from discord.ext.commands.errors import BadArgument
|
|
|
|
from redbot.core import commands
|
|
|
|
|
|
class FuzzyMember(IDConverter):
|
|
"""
|
|
Original class written by TrustyJaid#0001
|
|
https://github.com/TrustyJAID/Trusty-cogs/blob/c739903aa2c8111c58b3d5e695a1221cbe1f57d9/serverstats/converters.py
|
|
|
|
This will accept partial names and perform a fuzzy search for
|
|
members within the guild and return a list of member objects.
|
|
|
|
Guidance code on how to do this from:
|
|
https://github.com/Rapptz/discord.py/blob/rewrite/discord/ext/commands/converter.py#L85
|
|
https://github.com/Cog-Creators/Red-DiscordBot/blob/V3/develop/redbot/cogs/mod/mod.py#L24
|
|
"""
|
|
|
|
async def convert(self, ctx: commands.Context, argument: str) -> List[discord.Member]:
|
|
bot = ctx.bot
|
|
guild = ctx.guild
|
|
result = []
|
|
|
|
members = {m: unidecode(m.name) for m in guild.members}
|
|
fuzzy_results = process.extract(argument, members, limit=1000, scorer=fuzz.partial_ratio)
|
|
matching_names = [m[2] for m in fuzzy_results if m[1] > 90]
|
|
for x in matching_names:
|
|
result.append(x)
|
|
|
|
nick_members = {m: unidecode(m.nick) for m in guild.members if m.nick and m not in matching_names}
|
|
fuzzy_results2 = process.extract(argument, nick_members, limit=50, scorer=fuzz.partial_ratio)
|
|
matching_nicks = [m[2] for m in fuzzy_results2 if m[1] > 90]
|
|
for x in matching_nicks:
|
|
result.append(x)
|
|
|
|
if not result or result == [None]:
|
|
raise BadArgument('Member "{}" not found'.format(argument))
|
|
|
|
return result
|