diff --git a/redbot/cogs/alias/alias.py b/redbot/cogs/alias/alias.py index 6d9fd33e0..66a97e43a 100644 --- a/redbot/cogs/alias/alias.py +++ b/redbot/cogs/alias/alias.py @@ -338,6 +338,75 @@ class Alias(commands.Cog): ) ) + @checks.mod_or_permissions(manage_guild=True) + @alias.command(name="edit") + @commands.guild_only() + async def _edit_alias(self, ctx: commands.Context, alias_name: str, *, command): + """Edit an existing alias in this server.""" + # region Alias Add Validity Checking + alias = await self._aliases.get_alias(ctx.guild, alias_name) + if not alias: + await ctx.send( + _("The alias with the name {name} does not exist.").format(name=alias_name) + ) + return + + given_command_exists = self.bot.get_command(command.split(maxsplit=1)[0]) is not None + if not given_command_exists: + await ctx.send(_("You attempted to edit an alias to a command that doesn't exist.")) + return + # endregion + + # So we figured it is a valid alias and the command exists + # we can go ahead editing the command + try: + if await self._aliases.edit_alias(ctx, alias_name, command): + await ctx.send( + _("The alias with the trigger `{name}` has been edited sucessfully.").format( + name=alias_name + ) + ) + else: + # This part should technically never be reached... + await ctx.send( + _("Alias with the name `{name}` was not found.").format(name=alias_name) + ) + except ArgParseError as e: + return await ctx.send(" ".join(e.args)) + + @checks.is_owner() + @global_.command(name="edit") + async def _edit_global_alias(self, ctx: commands.Context, alias_name: str, *, command): + """Edit an existing global alias.""" + # region Alias Add Validity Checking + alias = await self._aliases.get_alias(None, alias_name) + if not alias: + await ctx.send( + _("The alias with the name {name} does not exist.").format(name=alias_name) + ) + return + + given_command_exists = self.bot.get_command(command.split(maxsplit=1)[0]) is not None + if not given_command_exists: + await ctx.send(_("You attempted to edit an alias to a command that doesn't exist.")) + return + # endregion + + try: + if await self._aliases.edit_alias(ctx, alias_name, command, global_=True): + await ctx.send( + _("The alias with the trigger `{name}` has been edited sucessfully.").format( + name=alias_name + ) + ) + else: + # This part should technically never be reached... + await ctx.send( + _("Alias with the name `{name}` was not found.").format(name=alias_name) + ) + except ArgParseError as e: + return await ctx.send(" ".join(e.args)) + @alias.command(name="help") async def _help_alias(self, ctx: commands.Context, alias_name: str): """Try to execute help for the base command of the alias.""" diff --git a/redbot/cogs/alias/alias_entry.py b/redbot/cogs/alias/alias_entry.py index bc6a12ad9..1efde17bb 100644 --- a/redbot/cogs/alias/alias_entry.py +++ b/redbot/cogs/alias/alias_entry.py @@ -187,9 +187,10 @@ class AliasCache: return None - async def add_alias( - self, ctx: commands.Context, alias_name: str, command: str, global_: bool = False - ) -> AliasEntry: + @staticmethod + def format_command_for_alias(command: str) -> str: + # This was present in add_alias previously + # Made this into a separate method so as to reuse the same code in edit_alias indices = findall(r"{(\d*)}", command) if indices: try: @@ -206,6 +207,12 @@ class AliasCache: + ", ".join(str(i + low) for i in gaps) ) command = command.format(*(f"{{{i}}}" for i in range(-low, high + low + 1))) + return command + + async def add_alias( + self, ctx: commands.Context, alias_name: str, command: str, global_: bool = False + ) -> AliasEntry: + command = self.format_command_for_alias(command) if global_: alias = AliasEntry(alias_name, command, ctx.author.id, None) @@ -225,6 +232,32 @@ class AliasCache: return alias + async def edit_alias( + self, ctx: commands.Context, alias_name: str, command: str, global_: bool = False + ) -> bool: + command = self.format_command_for_alias(command) + + if global_: + settings = self.config + else: + settings = self.config.guild(ctx.guild) + + async with settings.entries() as aliases: + for index, alias in enumerate(aliases): + if alias["name"] == alias_name: + alias_edited = AliasEntry.from_json(alias) + alias_edited.command = command + aliases[index] = alias_edited.to_json() + + if self._cache_enabled: + if global_: + self._aliases[None][alias_edited.name] = alias_edited + else: + self._aliases[ctx.guild.id][alias_edited.name] = alias_edited + return True + + return False + async def delete_alias( self, ctx: commands.Context, alias_name: str, global_: bool = False ) -> bool: