From 728c8ee8d0cbebb1ed42c8fda9aaafe6c2e3590e Mon Sep 17 00:00:00 2001 From: Ske Date: Fri, 30 Nov 2018 21:51:57 +0100 Subject: [PATCH] Add member name conflict warning. Closes #10. --- src/pluralkit/bot/commands/__init__.py | 3 +-- src/pluralkit/bot/commands/member_commands.py | 13 +++++++++++++ src/pluralkit/bot/commands/switch_commands.py | 2 +- src/pluralkit/bot/commands/system_commands.py | 5 ++--- src/pluralkit/bot/utils.py | 3 +++ src/pluralkit/system.py | 5 +++++ 6 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/pluralkit/bot/commands/__init__.py b/src/pluralkit/bot/commands/__init__.py index 5bd9cbdc..14c13b21 100644 --- a/src/pluralkit/bot/commands/__init__.py +++ b/src/pluralkit/bot/commands/__init__.py @@ -103,8 +103,7 @@ class CommandContext: async def reply_warn(self, content=None, embed=None): return await self.reply(content="\u26a0 {}".format(content or ""), embed=embed) - async def confirm_react(self, user: Union[discord.Member, discord.User], message: str): - message = await self.reply(message) + async def confirm_react(self, user: Union[discord.Member, discord.User], message: discord.Message): await message.add_reaction("\u2705") # Checkmark await message.add_reaction("\u274c") # Red X diff --git a/src/pluralkit/bot/commands/member_commands.py b/src/pluralkit/bot/commands/member_commands.py index 2ac040f0..206cac6b 100644 --- a/src/pluralkit/bot/commands/member_commands.py +++ b/src/pluralkit/bot/commands/member_commands.py @@ -19,6 +19,12 @@ async def new_member(ctx: CommandContext): new_name = ctx.remaining() + existing_member = await Member.get_member_by_name(ctx.conn, system.id, new_name) + if existing_member: + msg = await ctx.reply_warn("There is already a member with this name, with the ID `{}`. Do you want to create a duplicate member anyway?".format(existing_member.hid)) + if not await ctx.confirm_react(ctx.message.author, msg): + raise CommandError("Member creation cancelled.") + try: member = await system.create_member(ctx.conn, new_name) except PluralKitError as e: @@ -39,6 +45,13 @@ async def member_name(ctx: CommandContext): member = await ctx.pop_member(CommandError("You must pass a member name.", help=help.edit_member)) new_name = ctx.pop_str(CommandError("You must pass a new member name.", help=help.edit_member)) + # Warn if there's a member by the same name already + existing_member = await Member.get_member_by_name(ctx.conn, system.id, new_name) + if existing_member: + msg = await ctx.reply_warn("There is already a member with this name, with the ID `{}`. Do you want to rename this member anyway? This will result in two members with the same name.".format(existing_member.hid)) + if not await ctx.confirm_react(ctx.message.author, msg): + raise CommandError("Member renaming cancelled.") + await member.set_name(ctx.conn, new_name) await ctx.reply_ok("Member name updated.") diff --git a/src/pluralkit/bot/commands/switch_commands.py b/src/pluralkit/bot/commands/switch_commands.py index 85175777..f29e0902 100644 --- a/src/pluralkit/bot/commands/switch_commands.py +++ b/src/pluralkit/bot/commands/switch_commands.py @@ -106,7 +106,7 @@ async def switch_move(ctx: CommandContext): new_relative = humanize.naturaltime(pluralkit.utils.fix_time(new_time)) # Confirm with user - switch_confirm_message = "This will move the latest switch ({}) from {} ({}) to {} ({}). Is this OK?".format(members, last_absolute, last_relative, new_absolute, new_relative) + switch_confirm_message = await ctx.reply("This will move the latest switch ({}) from {} ({}) to {} ({}). Is this OK?".format(members, last_absolute, last_relative, new_absolute, new_relative)) if not await ctx.confirm_react(ctx.message.author, switch_confirm_message): raise CommandError("Switch move cancelled.") diff --git a/src/pluralkit/bot/commands/system_commands.py b/src/pluralkit/bot/commands/system_commands.py index e738d5b7..5d10461b 100644 --- a/src/pluralkit/bot/commands/system_commands.py +++ b/src/pluralkit/bot/commands/system_commands.py @@ -112,9 +112,8 @@ async def system_link(ctx: CommandContext): if account_system: raise CommandError(AccountAlreadyLinkedError(account_system).message) - if not await ctx.confirm_react(linkee, - "{}, please confirm the link by clicking the ✅ reaction on this message.".format( - linkee.mention)): + msg = await ctx.reply("{}, please confirm the link by clicking the \u2705 reaction on this message.".format(linkee.mention)) + if not await ctx.confirm_react(linkee, msg): raise CommandError("Account link cancelled.") await system.link_account(ctx.conn, linkee.id) diff --git a/src/pluralkit/bot/utils.py b/src/pluralkit/bot/utils.py index 8060168d..07bbcca5 100644 --- a/src/pluralkit/bot/utils.py +++ b/src/pluralkit/bot/utils.py @@ -10,9 +10,11 @@ from pluralkit.member import Member logger = logging.getLogger("pluralkit.utils") + def escape(s): return s.replace("`", "\\`") + def bounds_check_member_name(new_name, system_tag): if len(new_name) > 32: return "Name cannot be longer than 32 characters." @@ -21,6 +23,7 @@ def bounds_check_member_name(new_name, system_tag): if len("{} {}".format(new_name, system_tag)) > 32: return "This name, combined with the system tag ({}), would exceed the maximum length of 32 characters. Please reduce the length of the tag, or use a shorter name.".format(system_tag) + async def parse_mention(client: discord.Client, mention: str) -> Optional[discord.User]: # First try matching mention format match = re.fullmatch("<@!?(\\d+)>", mention) diff --git a/src/pluralkit/system.py b/src/pluralkit/system.py index 05797bd4..6e79f325 100644 --- a/src/pluralkit/system.py +++ b/src/pluralkit/system.py @@ -147,6 +147,11 @@ class System(namedtuple("System", ["id", "hid", "name", "description", "tag", "a proxy_prefix = member.prefix or "" proxy_suffix = member.suffix or "" + if not proxy_prefix and not proxy_suffix: + # If the member has neither a prefix or a suffix, cancel early + # Otherwise it'd match any message no matter what + continue + # Check if the message matches these tags if message.startswith(proxy_prefix) and message.endswith(proxy_suffix): # If the message starts with a mention, "separate" that and match the bit after