[Tools] Remove old converter, add uid
This commit is contained in:
@@ -1,57 +1,45 @@
|
||||
"""
|
||||
Because discord.py rewrite doesn't come with a general channel converter anymore
|
||||
Written by sitryk
|
||||
"""
|
||||
import discord
|
||||
import re
|
||||
from fuzzywuzzy import fuzz, process
|
||||
from typing import List
|
||||
from unidecode import unidecode
|
||||
|
||||
from discord.ext.commands import converter, BadArgument
|
||||
from discord.ext.commands.converter import IDConverter, _get_from_guilds
|
||||
from discord.ext.commands.errors import BadArgument
|
||||
|
||||
from redbot.core import commands
|
||||
|
||||
|
||||
class GuildChannelConverter(converter.IDConverter, converter.Converter):
|
||||
class FuzzyMember(IDConverter):
|
||||
"""
|
||||
Check order is:
|
||||
Original class written by TrustyJaid#0001
|
||||
https://github.com/TrustyJAID/Trusty-cogs/blob/c739903aa2c8111c58b3d5e695a1221cbe1f57d9/serverstats/converters.py
|
||||
|
||||
1. Text Channels
|
||||
2. Voice Channels
|
||||
3. Categories
|
||||
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, argument):
|
||||
async def convert(self, ctx: commands.Context, argument: str) -> List[discord.Member]:
|
||||
bot = ctx.bot
|
||||
match = self._get_id_match(argument) or re.match(r"<#([0-9]+)>$", argument)
|
||||
result = None
|
||||
guild = ctx.guild
|
||||
result = []
|
||||
|
||||
if match is None:
|
||||
order = [
|
||||
(discord.TextChannel, guild.text_channels),
|
||||
(discord.VoiceChannel, guild.voice_channels),
|
||||
(discord.CategoryChannel, guild.categories),
|
||||
]
|
||||
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)
|
||||
|
||||
# not a mention
|
||||
for c_types in order:
|
||||
if guild:
|
||||
result = discord.utils.get(c_types[1], name=argument)
|
||||
if result is not None:
|
||||
break
|
||||
else:
|
||||
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)
|
||||
|
||||
def check(c):
|
||||
return isinstance(c, c_types[0]) and c.name == argument
|
||||
|
||||
result = discord.utils.find(check, bot.get_all_channels())
|
||||
if result is not None:
|
||||
break
|
||||
else:
|
||||
channel_id = int(match.group(1))
|
||||
if guild:
|
||||
result = guild.get_channel(channel_id)
|
||||
else:
|
||||
result = converter._get_from_guilds(bot, "get_channel", channel_id)
|
||||
|
||||
if not isinstance(result, (discord.TextChannel, discord.VoiceChannel, discord.CategoryChannel)):
|
||||
raise BadArgument('Channel "{}" not found.'.format(argument))
|
||||
if not result or result == [None]:
|
||||
raise BadArgument('Member "{}" not found'.format(argument))
|
||||
|
||||
return result
|
||||
|
||||
@@ -5,13 +5,17 @@ import inspect
|
||||
import itertools
|
||||
import logging
|
||||
import re
|
||||
|
||||
from contextlib import suppress as sps
|
||||
from tabulate import tabulate
|
||||
from typing import Optional
|
||||
|
||||
from redbot.core import checks, commands
|
||||
from redbot.core.utils import chat_formatting as cf
|
||||
from redbot.core.utils.common_filters import filter_invites
|
||||
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS, close_menu
|
||||
from tabulate import tabulate
|
||||
from contextlib import suppress as sps
|
||||
|
||||
from .converter import FuzzyMember
|
||||
|
||||
log = logging.getLogger("red.aikaterna.tools")
|
||||
|
||||
@@ -661,6 +665,38 @@ class Tools(commands.Cog):
|
||||
await asyncio.sleep(1)
|
||||
await waiting.edit(content=data)
|
||||
|
||||
@commands.guild_only()
|
||||
@commands.command()
|
||||
async def uid(self, ctx, partial_name_or_nick: Optional[FuzzyMember]):
|
||||
"""Get a member's id from a fuzzy name search."""
|
||||
if partial_name_or_nick is None:
|
||||
partial_name_or_nick = [ctx.author]
|
||||
|
||||
table = []
|
||||
headers = ["ID", "Name", "Nickname"]
|
||||
for user_obj in partial_name_or_nick:
|
||||
table.append([user_obj.id, user_obj.name, user_obj.nick if not None else ""])
|
||||
msg = tabulate(table, headers, tablefmt="simple")
|
||||
|
||||
embed_list = []
|
||||
for page in cf.pagify(msg, delims=["\n"], page_length=1800):
|
||||
embed = discord.Embed(
|
||||
description="",
|
||||
colour=await ctx.embed_colour(),
|
||||
)
|
||||
embed.add_field(name="Matching Users", value=cf.box(page))
|
||||
embed_list.append(embed)
|
||||
|
||||
final_embed_list = []
|
||||
for i, embed in enumerate(embed_list):
|
||||
embed.set_footer(text=f"Page {i + 1}/{len(embed_list)}")
|
||||
final_embed_list.append(embed)
|
||||
if len(embed_list) == 1:
|
||||
close_control = {"\N{CROSS MARK}": close_menu}
|
||||
await menu(ctx, final_embed_list, close_control)
|
||||
else:
|
||||
await menu(ctx, final_embed_list, DEFAULT_CONTROLS)
|
||||
|
||||
@commands.guild_only()
|
||||
@commands.command()
|
||||
async def uinfo(self, ctx, user: discord.Member = None):
|
||||
|
||||
Reference in New Issue
Block a user