diff options
| -rw-r--r-- | arthur/bot.py | 8 | ||||
| -rw-r--r-- | arthur/exts/cloudflare/zones.py | 84 |
2 files changed, 70 insertions, 22 deletions
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 457efc5..aadeac9 100644 --- a/arthur/exts/cloudflare/zones.py +++ b/arthur/exts/cloudflare/zones.py @@ -1,6 +1,5 @@ """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,6 +7,63 @@ from arthur.bot import KingArthur 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="🌐"), + discord.SelectOption(label="pydis.com", emoji="🌐"), + discord.SelectOption(label="pydis.org", emoji="🌐") + ] + + def __init__(self) -> None: + 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( + 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: + """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: + """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 += " **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"]: + 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): """Commands for working with Cloudflare zones.""" @@ -20,25 +76,13 @@ class Zones(commands.Cog): await ctx.send_help(ctx.command) @zones.command(name="purge") - async def purge( - self, ctx: commands.Context, zone_name: Optional[str] = "pythondiscord.com" - ) -> None: + async def purge(self, ctx: commands.Context) -> None: """Command to clear the Cloudflare cache of the specified zone.""" - 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 ctx.send(message) + view = ZonesView() + await ctx.send( + "Pick which zone(s) that should have their cache purged :cloud_lightning:", + view=view + ) def setup(bot: KingArthur) -> None: |