From 3fb5287027e94cbfed22b0e9a95b032dfccd41f2 Mon Sep 17 00:00:00 2001 From: Vivaan Verma Date: Tue, 17 Aug 2021 21:01:40 +0100 Subject: feat: Make purge zones command use dropdown to choose zone to purge --- arthur/exts/cloudflare/zones.py | 57 +++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'arthur/exts/cloudflare/zones.py') diff --git a/arthur/exts/cloudflare/zones.py b/arthur/exts/cloudflare/zones.py index 457efc5..969c340 100644 --- a/arthur/exts/cloudflare/zones.py +++ b/arthur/exts/cloudflare/zones.py @@ -1,6 +1,7 @@ """The zones cog helps with managing Cloudflare zones.""" from typing import Optional +import discord from discord.ext import commands from arthur.apis.cloudflare import zones @@ -8,22 +9,25 @@ from arthur.bot import KingArthur from arthur.utils import generate_error_message -class Zones(commands.Cog): - """Commands for working with Cloudflare zones.""" +class ZonesDropdown(discord.ui.Select): - def __init__(self, bot: KingArthur) -> None: - self.bot = bot + def __init__(self): + options = [ + discord.SelectOption(label="pythondiscord.com", emoji="🌐", default=True), + discord.SelectOption(label="pythondiscord.org", emoji="🌐"), + discord.SelectOption(label="pydis.com", emoji="🌐"), + discord.SelectOption(label="pydis.org", emoji="🌐") + ] - @commands.group(name="zones", invoke_without_command=True) - async def zones(self, ctx: commands.Context) -> None: - """Commands for working with Cloudflare zones.""" - await ctx.send_help(ctx.command) + super().__init__( + placeholder="Select the zone which should be purged...", + min_values=1, + max_values=1, + options=options + ) - @zones.command(name="purge") - async def purge( - self, ctx: commands.Context, zone_name: Optional[str] = "pythondiscord.com" - ) -> None: - """Command to clear the Cloudflare cache of the specified zone.""" + async def callback(self, interaction: discord.Interaction): + zone_name = self.values[0] pydis_zones = await zones.list_zones(zone_name) required_id = pydis_zones[zone_name] purge_attempt_response = await zones.purge_zone(required_id) @@ -38,7 +42,32 @@ class Zones(commands.Cog): description_content += f"`{error['code']}`: {error['message']}\n" message = generate_error_message(description=description_content, emote=":x:") - await ctx.send(message) + await interaction.response.send(message) + + +class ZonesView(discord.ui.View): + + def __init__(self): + super().__init__() + self.add_item(ZonesDropdown()) + + +class Zones(commands.Cog): + """Commands for working with Cloudflare zones.""" + + def __init__(self, bot: KingArthur) -> None: + self.bot = bot + + @commands.group(name="zones", invoke_without_command=True) + async def zones(self, ctx: commands.Context) -> None: + """Commands for working with Cloudflare zones.""" + await ctx.send_help(ctx.command) + + @zones.command(name="purge") + async def purge(self, ctx: commands.Context) -> None: + """Command to clear the Cloudflare cache of the specified zone.""" + view = ZonesView() + await ctx.send("Pick which zone's cache to purge:", view=view) def setup(bot: KingArthur) -> None: -- cgit v1.2.3 From 2c0224c2b11c6c34664aea8c623f29ca7a3af2fd Mon Sep 17 00:00:00 2001 From: Vivaan Verma Date: Tue, 17 Aug 2021 23:26:51 +0100 Subject: feat: Allow for selection of multiple zones --- arthur/bot.py | 8 +++-- arthur/exts/cloudflare/zones.py | 70 +++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 40 deletions(-) (limited to 'arthur/exts/cloudflare/zones.py') diff --git a/arthur/bot.py b/arthur/bot.py index 249ada7..ffcb476 100644 --- a/arthur/bot.py +++ b/arthur/bot.py @@ -1,7 +1,8 @@ """Module containing the core bot base for King Arthur.""" from pathlib import Path -from typing import Any +from typing import Any, Union +from discord import Interaction from discord.ext import commands from discord.ext.commands import Bot from kubernetes_asyncio import config @@ -27,8 +28,11 @@ class KingArthur(Bot): self.add_check(self._is_devops) @staticmethod - async def _is_devops(ctx: commands.Context) -> bool: + def _is_devops(ctx: Union[commands.Context, Interaction]) -> bool: """Check all commands are executed by authorised personnel.""" + if isinstance(ctx, Interaction): + return CONFIG.devops_role in [r.id for r in ctx.author.roles] + if ctx.command.name == "ed": return True diff --git a/arthur/exts/cloudflare/zones.py b/arthur/exts/cloudflare/zones.py index 969c340..aefa760 100644 --- a/arthur/exts/cloudflare/zones.py +++ b/arthur/exts/cloudflare/zones.py @@ -9,47 +9,41 @@ from arthur.bot import KingArthur from arthur.utils import generate_error_message -class ZonesDropdown(discord.ui.Select): - - def __init__(self): - options = [ - discord.SelectOption(label="pythondiscord.com", emoji="🌐", default=True), - discord.SelectOption(label="pythondiscord.org", emoji="🌐"), - discord.SelectOption(label="pydis.com", emoji="🌐"), - discord.SelectOption(label="pydis.org", emoji="🌐") - ] - - super().__init__( - placeholder="Select the zone which should be purged...", - min_values=1, - max_values=1, - options=options - ) - - async def callback(self, interaction: discord.Interaction): - zone_name = self.values[0] - pydis_zones = await zones.list_zones(zone_name) - required_id = pydis_zones[zone_name] - purge_attempt_response = await zones.purge_zone(required_id) - - if purge_attempt_response["success"]: - message = ":white_check_mark:" - message += f" **Cache cleared!** The Cloudflare cache for `{zone_name}` was cleared." - else: - description_content = f"The cache for `{zone_name}` couldn't be cleared.\n" - if errors := purge_attempt_response["errors"]: - for error in errors: - description_content += f"`{error['code']}`: {error['message']}\n" - message = generate_error_message(description=description_content, emote=":x:") - - await interaction.response.send(message) - - class ZonesView(discord.ui.View): + OPTIONS = [ + discord.SelectOption(label="pythondiscord.com", emoji="🌐"), + discord.SelectOption(label="pythondiscord.org", emoji="🌐"), + discord.SelectOption(label="pydis.com", emoji="🌐"), + discord.SelectOption(label="pydis.org", emoji="🌐") + ] + def __init__(self): super().__init__() - self.add_item(ZonesDropdown()) + + async def interaction_check(self, interaction: discord.Interaction) -> bool: + return KingArthur._is_devops(interaction) + + @discord.ui.select(placeholder="The zone(s) which should be purged...", min_values=1, max_values=4, options=OPTIONS, custom_id="select") + async def select_zones(self, dropdown: discord.ui.Select, interaction: discord.Interaction) -> None: + pass + + @discord.ui.button(label="Purge zones!", style=discord.ButtonStyle.primary) + async def purge_zones(self, button: discord.ui.Button, interaction: discord.Interaction) -> None: + for zone_name in [child for child in self.children if child._provided_custom_id][0].values: + pydis_zones = await zones.list_zones(zone_name) + required_id = pydis_zones[zone_name] + purge_attempt_response = await zones.purge_zone(required_id) + if purge_attempt_response["success"]: + message = ":white_check_mark:" + message += f" **Cache cleared!** The Cloudflare cache for `{zone_name}` was cleared." + else: + description_content = f"The cache for `{zone_name}` couldn't be cleared.\n" + if errors := purge_attempt_response["errors"]: + for error in errors: + description_content += f"`{error['code']}`: {error['message']}\n" + message = generate_error_message(description=description_content, emote=":x:") + await interaction.response.send(message) class Zones(commands.Cog): @@ -67,7 +61,7 @@ class Zones(commands.Cog): async def purge(self, ctx: commands.Context) -> None: """Command to clear the Cloudflare cache of the specified zone.""" view = ZonesView() - await ctx.send("Pick which zone's cache to purge:", view=view) + await ctx.send("Pick which zone(s) that should have their cache purged :cloud_lightning:", view=view) def setup(bot: KingArthur) -> None: -- cgit v1.2.3 From 2561b4b97fec860952c3caee67c94011cc245c47 Mon Sep 17 00:00:00 2001 From: Vivaan Verma <54081925+doublevcodes@users.noreply.github.com> Date: Tue, 17 Aug 2021 23:52:50 +0100 Subject: lint: Remove lint --- arthur/exts/cloudflare/zones.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'arthur/exts/cloudflare/zones.py') diff --git a/arthur/exts/cloudflare/zones.py b/arthur/exts/cloudflare/zones.py index aefa760..6c990db 100644 --- a/arthur/exts/cloudflare/zones.py +++ b/arthur/exts/cloudflare/zones.py @@ -1,6 +1,4 @@ """The zones cog helps with managing Cloudflare zones.""" -from typing import Optional - import discord from discord.ext import commands @@ -10,7 +8,7 @@ from arthur.utils import generate_error_message class ZonesView(discord.ui.View): - + """This view allows users to select and purge the zones specified.""" OPTIONS = [ discord.SelectOption(label="pythondiscord.com", emoji="🌐"), discord.SelectOption(label="pythondiscord.org", emoji="🌐"), @@ -18,18 +16,31 @@ class ZonesView(discord.ui.View): discord.SelectOption(label="pydis.org", emoji="🌐") ] - def __init__(self): + def __init__(self) -> None: super().__init__() async def interaction_check(self, interaction: discord.Interaction) -> bool: return KingArthur._is_devops(interaction) - @discord.ui.select(placeholder="The zone(s) which should be purged...", min_values=1, max_values=4, options=OPTIONS, custom_id="select") - async def select_zones(self, dropdown: discord.ui.Select, interaction: discord.Interaction) -> None: + @discord.ui.select( + placeholder="The zone(s) which should be purged...", + min_values=1, + max_values=4, + options=OPTIONS, + # This is needed in order to identify the drop down later on + # because discord.Item.type is NotImplemented + custom_id="select" + ) + async def select_zones( + self, dropdown: discord.ui.Select, + interaction: discord.Interaction + ) -> None: + """The drop down menu containing the list of zones.""" pass @discord.ui.button(label="Purge zones!", style=discord.ButtonStyle.primary) async def purge_zones(self, button: discord.ui.Button, interaction: discord.Interaction) -> None: + """The button that actually purges the zones.""" for zone_name in [child for child in self.children if child._provided_custom_id][0].values: pydis_zones = await zones.list_zones(zone_name) required_id = pydis_zones[zone_name] @@ -61,7 +72,10 @@ class Zones(commands.Cog): async def purge(self, ctx: commands.Context) -> None: """Command to clear the Cloudflare cache of the specified zone.""" view = ZonesView() - await ctx.send("Pick which zone(s) that should have their cache purged :cloud_lightning:", view=view) + await ctx.send( + "Pick which zone(s) that should have their cache purged :cloud_lightning:", + view=view + ) def setup(bot: KingArthur) -> None: -- cgit v1.2.3 From 88546432af0772cd3e1bafd13d0d1da2c4e50459 Mon Sep 17 00:00:00 2001 From: Vivaan Verma <54081925+doublevcodes@users.noreply.github.com> Date: Wed, 18 Aug 2021 00:06:35 +0100 Subject: lint: Remove extraneous lint --- arthur/exts/cloudflare/zones.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'arthur/exts/cloudflare/zones.py') diff --git a/arthur/exts/cloudflare/zones.py b/arthur/exts/cloudflare/zones.py index 6c990db..527bb8e 100644 --- a/arthur/exts/cloudflare/zones.py +++ b/arthur/exts/cloudflare/zones.py @@ -9,6 +9,7 @@ from arthur.utils import generate_error_message class ZonesView(discord.ui.View): """This view allows users to select and purge the zones specified.""" + OPTIONS = [ discord.SelectOption(label="pythondiscord.com", emoji="🌐"), discord.SelectOption(label="pythondiscord.org", emoji="🌐"), @@ -20,6 +21,7 @@ class ZonesView(discord.ui.View): super().__init__() async def interaction_check(self, interaction: discord.Interaction) -> bool: + """Ensure the user has the DevOps role.""" return KingArthur._is_devops(interaction) @discord.ui.select( @@ -35,19 +37,24 @@ class ZonesView(discord.ui.View): self, dropdown: discord.ui.Select, interaction: discord.Interaction ) -> None: - """The drop down menu containing the list of zones.""" + """Drop down menu contains the list of zones.""" pass @discord.ui.button(label="Purge zones!", style=discord.ButtonStyle.primary) - async def purge_zones(self, button: discord.ui.Button, interaction: discord.Interaction) -> None: - """The button that actually purges the zones.""" + async def purge_zones( + self, + button: discord.ui.Button, + interaction: discord.Interaction + ) -> None: + """Button to purge the zones.""" for zone_name in [child for child in self.children if child._provided_custom_id][0].values: pydis_zones = await zones.list_zones(zone_name) required_id = pydis_zones[zone_name] purge_attempt_response = await zones.purge_zone(required_id) if purge_attempt_response["success"]: message = ":white_check_mark:" - message += f" **Cache cleared!** The Cloudflare cache for `{zone_name}` was cleared." + message += f" **Cache cleared!** " + message += "The Cloudflare cache for `{zone_name}` was cleared." else: description_content = f"The cache for `{zone_name}` couldn't be cleared.\n" if errors := purge_attempt_response["errors"]: -- cgit v1.2.3 From 304df40b9535fc3d38295c1763698a020e29e2e4 Mon Sep 17 00:00:00 2001 From: Vivaan Verma <54081925+doublevcodes@users.noreply.github.com> Date: Wed, 18 Aug 2021 00:08:51 +0100 Subject: fix: Make string f-string --- arthur/exts/cloudflare/zones.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arthur/exts/cloudflare/zones.py') diff --git a/arthur/exts/cloudflare/zones.py b/arthur/exts/cloudflare/zones.py index 527bb8e..aadeac9 100644 --- a/arthur/exts/cloudflare/zones.py +++ b/arthur/exts/cloudflare/zones.py @@ -53,8 +53,8 @@ class ZonesView(discord.ui.View): purge_attempt_response = await zones.purge_zone(required_id) if purge_attempt_response["success"]: message = ":white_check_mark:" - message += f" **Cache cleared!** " - message += "The Cloudflare cache for `{zone_name}` was cleared." + message += " **Cache cleared!** " + message += f"The Cloudflare cache for `{zone_name}` was cleared." else: description_content = f"The cache for `{zone_name}` couldn't be cleared.\n" if errors := purge_attempt_response["errors"]: -- cgit v1.2.3