-
Notifications
You must be signed in to change notification settings - Fork 6
/
kill.py
107 lines (87 loc) · 4.16 KB
/
kill.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""Contains cog classes for any killing interactions."""
from collections.abc import Sequence
__all__: Sequence[str] = ("ConfirmKillView", "KillCommandCog")
import contextlib
import logging
from logging import Logger
from typing import Final
import discord
from discord.ui import View
from exceptions import CommitteeRoleDoesNotExistError
from utils import CommandChecks, TeXBotApplicationContext, TeXBotBaseCog
logger: Final[Logger] = logging.getLogger("TeX-Bot")
class ConfirmKillView(View):
"""A discord.View containing two buttons to confirm shutting down TeX-Bot."""
@discord.ui.button( # type: ignore[misc]
label="SHUTDOWN",
style=discord.ButtonStyle.red,
custom_id="shutdown_confirm",
)
async def confirm_shutdown_button_callback(self, _: discord.Button, interaction: discord.Interaction) -> None: # noqa: E501
"""When the shutdown button is pressed, delete the message."""
logger.debug("\"Confirm\" button pressed. %s", interaction)
@discord.ui.button( # type: ignore[misc]
label="CANCEL",
style=discord.ButtonStyle.grey,
custom_id="shutdown_cancel",
)
async def cancel_shutdown_button_callback(self, _: discord.Button, interaction: discord.Interaction) -> None: # noqa: E501
"""When the cancel button is pressed, delete the message."""
logger.debug("\"Cancel\" button pressed. %s", interaction)
class KillCommandCog(TeXBotBaseCog):
"""Cog class that defines the "/kill" command and its call-back method."""
@discord.slash_command( # type: ignore[no-untyped-call, misc]
name="kill",
description="Shutdown TeX-Bot.",
)
@CommandChecks.check_interaction_user_has_committee_role
@CommandChecks.check_interaction_user_in_main_guild
async def kill(self, ctx: TeXBotApplicationContext) -> None:
"""
Definition & callback response of the "kill" command.
The "kill" command shuts down TeX-Bot,
but only after the user has confirmed that this is the action they wish to take.
"""
committee_role: discord.Role | None = None
with contextlib.suppress(CommitteeRoleDoesNotExistError):
committee_role = await self.bot.committee_role
response: discord.Message | discord.Interaction = await ctx.respond(
content=(
f"{f"Hi {committee_role.mention}, a" if committee_role else "A"}"
"re you sure you want to kill me?\n"
"This action is irreversible "
"and will prevent me from performing any further actions "
"until I am manually restarted.\n\n"
"Please confirm using the buttons below."
),
view=ConfirmKillView(),
)
confirmation_message: discord.Message = (
response
if isinstance(response, discord.Message)
else await response.original_response()
)
button_interaction: discord.Interaction = await self.bot.wait_for(
"interaction",
check=lambda interaction: (
interaction.type == discord.InteractionType.component
and interaction.message.id == confirmation_message.id
and ((committee_role in interaction.user.roles) if committee_role else True)
and "custom_id" in interaction.data
and interaction.data["custom_id"] in {"shutdown_confirm", "shutdown_cancel"}
),
)
if button_interaction.data["custom_id"] == "shutdown_confirm": # type: ignore[index, typeddict-item]
await confirmation_message.edit(
content="My battery is low and it's getting dark...",
view=None,
)
await self.bot.perform_kill_and_close(initiated_by_user=ctx.interaction.user)
if button_interaction.data["custom_id"] == "shutdown_cancel": # type: ignore[index, typeddict-item]
await confirmation_message.edit(
content="Shutdown has been cancelled.",
view=None,
)
logger.info("Manual shutdown cancelled by %s.", ctx.interaction.user)
return
raise ValueError