Ruby-Cogs/tools/converter.py
2025-02-19 22:02:13 -05:00

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