diff --git a/bot/ext/rsudo.py b/bot/ext/rsudo.py index 269179b..c468493 100644 --- a/bot/ext/rsudo.py +++ b/bot/ext/rsudo.py @@ -1,5 +1,6 @@ import logging import asyncio +from typing import Dict import discord from discord.ext import commands @@ -7,7 +8,7 @@ from discord.ext import commands from .common import Cog log = logging.getLogger(__name__) - +UserID = int async def shell(command: str): process = await asyncio.create_subprocess_shell( @@ -20,10 +21,61 @@ async def shell(command: str): return f'{out}{err}'.strip() +async def distance(s, len_s, t, len_t): + cost = 0 + + if not len_s: + return len_t + + if not len_t: + return len_s + + if s[len_s - 1] == t[len_t - 1]: + cost = 0 + else: + cost = 1 + + l = [ + (await distance(s, len_s - 1, t, len_t)) + 1, + (await distance(s, len_s, t, len_t - 1)) + 1, + (await distance(s, len_s - 1, t, len_t - 1)) + cost + ] + + return min(l) + + class Rsudo(Cog): def __init__(self, bot): super().__init__(bot) + async def lookupuser(self, uname: str) -> Dict[UserID, float]: + lu = len(uname) + + cchan = self.bot.get_channel( + self.bot.config.command_channel + ) + + if not cchan: + return None + + members = cchan.guild.members + scores = {} + for member in members: + if member.bot: continue + + lmn = len(member.name) + d = await distance(member.name, lmn, uname, lu) + scores[member.id] = d + + if uname in member.name or uname in member.nick: + scores[member.id] = -1 + + users = sorted(scores.keys(), key=lambda k: scores[k]) + if not users: + return None + + return users[0] + async def create_request(self, message): command_channel = self.bot.get_channel( self.bot.config.command_channel @@ -120,6 +172,14 @@ class Rsudo(Cog): except discord.HTTPException: await command_channel.send(f'Failed to send denial message to {user}.') + @commands.command() + async def lookup(self, ctx, uname: str): + u = await self.lookupuser(uname) + if not u: + return await ctx.send('none found') + + u = self.bot.get_user(u) + await ctx.send(repr(u)) def setup(bot): bot.add_cog(Rsudo(bot))