scurrypy 0.4__py3-none-any.whl → 0.6.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scurrypy/__init__.py +429 -0
- scurrypy/client.py +335 -0
- {discord → scurrypy}/client_like.py +8 -1
- scurrypy/dispatch/command_dispatcher.py +205 -0
- {discord → scurrypy}/dispatch/event_dispatcher.py +21 -21
- {discord → scurrypy}/dispatch/prefix_dispatcher.py +31 -12
- {discord → scurrypy}/error.py +6 -18
- {discord → scurrypy}/events/channel_events.py +2 -1
- scurrypy/events/gateway_events.py +31 -0
- {discord → scurrypy}/events/guild_events.py +2 -1
- {discord → scurrypy}/events/interaction_events.py +28 -13
- {discord → scurrypy}/events/message_events.py +8 -5
- {discord → scurrypy}/events/reaction_events.py +1 -2
- {discord → scurrypy}/events/ready_event.py +1 -3
- scurrypy/gateway.py +183 -0
- scurrypy/http.py +310 -0
- {discord → scurrypy}/intents.py +5 -7
- {discord → scurrypy}/logger.py +14 -61
- scurrypy/model.py +71 -0
- scurrypy/models.py +258 -0
- scurrypy/parts/channel.py +42 -0
- scurrypy/parts/command.py +90 -0
- scurrypy/parts/components.py +224 -0
- scurrypy/parts/components_v2.py +144 -0
- scurrypy/parts/embed.py +83 -0
- scurrypy/parts/message.py +134 -0
- scurrypy/parts/modal.py +16 -0
- {discord → scurrypy}/parts/role.py +2 -14
- {discord → scurrypy}/resources/application.py +1 -2
- {discord → scurrypy}/resources/bot_emojis.py +1 -1
- {discord → scurrypy}/resources/channel.py +9 -8
- {discord → scurrypy}/resources/guild.py +14 -16
- {discord → scurrypy}/resources/interaction.py +50 -43
- {discord → scurrypy}/resources/message.py +15 -16
- {discord → scurrypy}/resources/user.py +3 -4
- scurrypy-0.6.6.dist-info/METADATA +108 -0
- scurrypy-0.6.6.dist-info/RECORD +47 -0
- {scurrypy-0.4.dist-info → scurrypy-0.6.6.dist-info}/licenses/LICENSE +1 -1
- scurrypy-0.6.6.dist-info/top_level.txt +1 -0
- discord/__init__.py +0 -223
- discord/client.py +0 -375
- discord/dispatch/command_dispatcher.py +0 -163
- discord/gateway.py +0 -155
- discord/http.py +0 -280
- discord/model.py +0 -90
- discord/models/__init__.py +0 -1
- discord/models/application.py +0 -37
- discord/models/emoji.py +0 -34
- discord/models/guild.py +0 -35
- discord/models/integration.py +0 -23
- discord/models/interaction.py +0 -26
- discord/models/member.py +0 -27
- discord/models/role.py +0 -53
- discord/models/user.py +0 -15
- discord/parts/action_row.py +0 -208
- discord/parts/channel.py +0 -20
- discord/parts/command.py +0 -102
- discord/parts/components_v2.py +0 -353
- discord/parts/embed.py +0 -154
- discord/parts/message.py +0 -194
- discord/parts/modal.py +0 -21
- scurrypy-0.4.dist-info/METADATA +0 -130
- scurrypy-0.4.dist-info/RECORD +0 -54
- scurrypy-0.4.dist-info/top_level.txt +0 -1
- {discord → scurrypy}/config.py +0 -0
- {discord → scurrypy}/dispatch/__init__.py +0 -0
- {discord → scurrypy}/events/__init__.py +0 -0
- {discord → scurrypy}/events/hello_event.py +0 -0
- {discord → scurrypy}/parts/__init__.py +0 -0
- {discord → scurrypy}/parts/component_types.py +0 -0
- {discord → scurrypy}/resources/__init__.py +0 -0
- {scurrypy-0.4.dist-info → scurrypy-0.6.6.dist-info}/WHEEL +0 -0
scurrypy/models.py
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from .model import DataModel
|
|
4
|
+
|
|
5
|
+
from urllib.parse import quote
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class EmojiModel(DataModel):
|
|
9
|
+
"""Represents a Discord emoji."""
|
|
10
|
+
name: str
|
|
11
|
+
"""Name of emoji."""
|
|
12
|
+
|
|
13
|
+
id: int = 0
|
|
14
|
+
"""ID of the emoji (if custom)."""
|
|
15
|
+
|
|
16
|
+
animated: bool = False
|
|
17
|
+
"""If the emoji is animated. Defaults to False."""
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def mention(self) -> str:
|
|
21
|
+
"""For use in message content."""
|
|
22
|
+
return f"<a:{self.name}:{self.id}>" if self.animated else f"<:{self.name}:{self.id}>"
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def api_code(self) -> str:
|
|
26
|
+
"""Return the correct API code for this emoji (URL-safe)."""
|
|
27
|
+
if not self.id:
|
|
28
|
+
# unicode emoji
|
|
29
|
+
return quote(self.name)
|
|
30
|
+
|
|
31
|
+
# custom emoji
|
|
32
|
+
if self.animated:
|
|
33
|
+
return quote(f"a:{self.name}:{self.id}")
|
|
34
|
+
|
|
35
|
+
return quote(f"{self.name}:{self.id}")
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def url(self) -> str:
|
|
39
|
+
"""
|
|
40
|
+
Return the full qualifying link for this emoji.
|
|
41
|
+
|
|
42
|
+
!!! warning "Important"
|
|
43
|
+
This only works for custom Discord emojis (those with an ID).
|
|
44
|
+
Unicode emojis will return `None`.
|
|
45
|
+
"""
|
|
46
|
+
if not self.id:
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
ext = 'gif' if self.animated else 'png'
|
|
50
|
+
|
|
51
|
+
return f"https://cdn.discordapp.com/emojis/{self.id}.{ext}"
|
|
52
|
+
|
|
53
|
+
# Guild Models
|
|
54
|
+
|
|
55
|
+
@dataclass
|
|
56
|
+
class ReadyGuildModel(DataModel):
|
|
57
|
+
"""Guild info from Ready event."""
|
|
58
|
+
id: int
|
|
59
|
+
"""ID of the associated guild."""
|
|
60
|
+
|
|
61
|
+
unavailable: bool
|
|
62
|
+
"""If the guild is offline."""
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class GuildModel(DataModel):
|
|
66
|
+
"""Represents a Discord guild."""
|
|
67
|
+
|
|
68
|
+
id: int
|
|
69
|
+
"""ID of the guild."""
|
|
70
|
+
|
|
71
|
+
name: str
|
|
72
|
+
"""Name of the guild."""
|
|
73
|
+
|
|
74
|
+
icon: Optional[str] = None
|
|
75
|
+
"""Icon hash of the guild."""
|
|
76
|
+
|
|
77
|
+
emojis: list[EmojiModel] = None
|
|
78
|
+
"""List of emojis reigstered in the guild."""
|
|
79
|
+
|
|
80
|
+
approximate_member_count: Optional[int] = None
|
|
81
|
+
"""Approximate member count."""
|
|
82
|
+
|
|
83
|
+
description: str = None
|
|
84
|
+
"""Description of the guild."""
|
|
85
|
+
|
|
86
|
+
# User Models
|
|
87
|
+
|
|
88
|
+
@dataclass
|
|
89
|
+
class UserModel(DataModel):
|
|
90
|
+
"""Describes the User object."""
|
|
91
|
+
id: int
|
|
92
|
+
"""ID of the user."""
|
|
93
|
+
|
|
94
|
+
username: str
|
|
95
|
+
"""Username of the user."""
|
|
96
|
+
|
|
97
|
+
avatar: str
|
|
98
|
+
"""Avatar hash of the user."""
|
|
99
|
+
|
|
100
|
+
@dataclass
|
|
101
|
+
class ApplicationModel(DataModel):
|
|
102
|
+
"""Represents a bot application object."""
|
|
103
|
+
id: int
|
|
104
|
+
"""ID of the app."""
|
|
105
|
+
|
|
106
|
+
name: str
|
|
107
|
+
"""Name of the app."""
|
|
108
|
+
|
|
109
|
+
icon: str
|
|
110
|
+
"""Icon hash of the app."""
|
|
111
|
+
|
|
112
|
+
description: str
|
|
113
|
+
"""Description of the app."""
|
|
114
|
+
|
|
115
|
+
bot_public: bool
|
|
116
|
+
"""If other users can add this app to a guild."""
|
|
117
|
+
|
|
118
|
+
bot: UserModel
|
|
119
|
+
"""Partial user obhect for the bot user associated with the app."""
|
|
120
|
+
|
|
121
|
+
owner: UserModel
|
|
122
|
+
"""Partial user object for the owner of the app."""
|
|
123
|
+
|
|
124
|
+
guild_id: int
|
|
125
|
+
"""Guild ID associated with the app (e.g., a support server)."""
|
|
126
|
+
|
|
127
|
+
guild: GuildModel
|
|
128
|
+
"""Partial guild object of the associated guild."""
|
|
129
|
+
|
|
130
|
+
approximate_guild_count: int
|
|
131
|
+
"""Approximate guild member count."""
|
|
132
|
+
|
|
133
|
+
@dataclass
|
|
134
|
+
class IntegrationModel(DataModel):
|
|
135
|
+
"""Represents a guild integration."""
|
|
136
|
+
|
|
137
|
+
id: int
|
|
138
|
+
"""ID of the integration."""
|
|
139
|
+
|
|
140
|
+
name: str
|
|
141
|
+
"""Name of the integration."""
|
|
142
|
+
|
|
143
|
+
type: str
|
|
144
|
+
"""Type of integration (e.g., twitch, youtube, discord, or guild_subscription)."""
|
|
145
|
+
|
|
146
|
+
enabled: bool
|
|
147
|
+
"""If the integration is enabled."""
|
|
148
|
+
|
|
149
|
+
application: Optional[ApplicationModel] = None
|
|
150
|
+
"""The bot aaplication for Discord integrations."""
|
|
151
|
+
|
|
152
|
+
@dataclass
|
|
153
|
+
class MemberModel(DataModel):
|
|
154
|
+
"""Represents a guild member."""
|
|
155
|
+
|
|
156
|
+
roles: list[int]
|
|
157
|
+
"""List of roles registered to the guild member."""
|
|
158
|
+
|
|
159
|
+
user: UserModel
|
|
160
|
+
"""User data associated with the guild member."""
|
|
161
|
+
|
|
162
|
+
nick: str
|
|
163
|
+
"""Server nickname of the guild member."""
|
|
164
|
+
|
|
165
|
+
avatar: str
|
|
166
|
+
"""Server avatar hash of the guild mmeber."""
|
|
167
|
+
|
|
168
|
+
joined_at: str
|
|
169
|
+
"""ISO8601 timestamp of when the guild member joined server."""
|
|
170
|
+
|
|
171
|
+
deaf: bool
|
|
172
|
+
"""If the member is deaf in a VC (input)."""
|
|
173
|
+
|
|
174
|
+
mute: bool
|
|
175
|
+
"""If the member is muted in VC (output)."""
|
|
176
|
+
|
|
177
|
+
# Interaction Models
|
|
178
|
+
|
|
179
|
+
@dataclass
|
|
180
|
+
class InteractionCallbackDataModel(DataModel):
|
|
181
|
+
"""Represents the interaction callback object."""
|
|
182
|
+
|
|
183
|
+
id: int
|
|
184
|
+
"""ID of the interaction."""
|
|
185
|
+
|
|
186
|
+
type: int
|
|
187
|
+
"""Type of interaction."""
|
|
188
|
+
|
|
189
|
+
activity_instance_id: str
|
|
190
|
+
"""Instance ID of activity if an activity was launched or joined."""
|
|
191
|
+
|
|
192
|
+
response_message_id: int
|
|
193
|
+
"""ID of the message created by the interaction."""
|
|
194
|
+
|
|
195
|
+
response_message_loading: bool
|
|
196
|
+
"""If the interaction is in a loading state."""
|
|
197
|
+
|
|
198
|
+
response_message_ephemeral: bool
|
|
199
|
+
"""If the interaction is ephemeral."""
|
|
200
|
+
|
|
201
|
+
@dataclass
|
|
202
|
+
class InteractionCallbackModel(DataModel):
|
|
203
|
+
"""Represents the interaction callback response object."""
|
|
204
|
+
|
|
205
|
+
interaction: InteractionCallbackDataModel
|
|
206
|
+
"""The interaction object associated with the interaction response."""
|
|
207
|
+
|
|
208
|
+
# Role Models
|
|
209
|
+
|
|
210
|
+
@dataclass
|
|
211
|
+
class RoleColors(DataModel):
|
|
212
|
+
"""Role color data."""
|
|
213
|
+
|
|
214
|
+
primary_color: int
|
|
215
|
+
"""Primary color of the role."""
|
|
216
|
+
|
|
217
|
+
secondary_color: int
|
|
218
|
+
"""Secondary color of the role. Creates a gradient."""
|
|
219
|
+
|
|
220
|
+
tertiary_color: int
|
|
221
|
+
"""Tertiary color of the role. Creates a holographic style."""
|
|
222
|
+
|
|
223
|
+
@dataclass
|
|
224
|
+
class RoleModel(DataModel):
|
|
225
|
+
"""Represents a Discord role."""
|
|
226
|
+
|
|
227
|
+
id: int
|
|
228
|
+
"""ID of the role."""
|
|
229
|
+
|
|
230
|
+
name: str
|
|
231
|
+
"""Name of the role."""
|
|
232
|
+
|
|
233
|
+
colors: RoleColors
|
|
234
|
+
"""Colors of the role."""
|
|
235
|
+
|
|
236
|
+
hoist: bool
|
|
237
|
+
"""If the role is pinned in user listing."""
|
|
238
|
+
|
|
239
|
+
position: int
|
|
240
|
+
"""Position of the role."""
|
|
241
|
+
|
|
242
|
+
permissions: str
|
|
243
|
+
"""Permission bit set."""
|
|
244
|
+
|
|
245
|
+
managed: bool
|
|
246
|
+
"""If the role is managed by an integration."""
|
|
247
|
+
|
|
248
|
+
mentionable: bool
|
|
249
|
+
"""If the role is mentionable."""
|
|
250
|
+
|
|
251
|
+
flags: int
|
|
252
|
+
"""Role flags combined as a bitfield."""
|
|
253
|
+
|
|
254
|
+
icon: Optional[str] = None
|
|
255
|
+
"""Icon hash of the role."""
|
|
256
|
+
|
|
257
|
+
unicode_emoji: Optional[str] = None
|
|
258
|
+
"""Unicode emoji of the role."""
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from ..model import DataModel
|
|
4
|
+
|
|
5
|
+
class ChannelTypes:
|
|
6
|
+
"""
|
|
7
|
+
Constants for channel types.
|
|
8
|
+
|
|
9
|
+
!!! note
|
|
10
|
+
Only supported Channel Types listed here
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
GUILD_TEXT = 0
|
|
14
|
+
"""Text channel within a server."""
|
|
15
|
+
|
|
16
|
+
GUILD_CATEGORY = 4
|
|
17
|
+
"""Organizational category that contains up to 50 channels."""
|
|
18
|
+
|
|
19
|
+
GUILD_ANNOUNCEMENT = 5
|
|
20
|
+
"""Channel that users can follow and crosspost into their own server (formerly news channels)."""
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class GuildChannel(DataModel):
|
|
24
|
+
"""Parameters for creating/editing a guild channel."""
|
|
25
|
+
|
|
26
|
+
name: Optional[str] = None
|
|
27
|
+
"""Name of the channel."""
|
|
28
|
+
|
|
29
|
+
type: Optional[int] = None
|
|
30
|
+
"""Type of channel. See [`ChannelTypes`][scurrypy.parts.channel.ChannelTypes]."""
|
|
31
|
+
|
|
32
|
+
topic: Optional[str] = None
|
|
33
|
+
"""Topic of channel."""
|
|
34
|
+
|
|
35
|
+
position: Optional[int] = None
|
|
36
|
+
"""Sorting position of the channel (channels with the same position are sorted by id)."""
|
|
37
|
+
|
|
38
|
+
parent_id: Optional[int] = None
|
|
39
|
+
"""ID of the parent category for a channel."""
|
|
40
|
+
|
|
41
|
+
nsfw: Optional[bool] = None
|
|
42
|
+
"""Whether the channel is NSFW."""
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
|
|
3
|
+
from ..model import DataModel
|
|
4
|
+
|
|
5
|
+
class CommandTypes:
|
|
6
|
+
CHAT_INPUT = 1
|
|
7
|
+
USER_COMMAND = 2
|
|
8
|
+
MESSAGE_COMMAND = 3
|
|
9
|
+
|
|
10
|
+
class CommandOptionTypes:
|
|
11
|
+
"""Slash command option input types."""
|
|
12
|
+
|
|
13
|
+
STRING = 3
|
|
14
|
+
"""string (text)"""
|
|
15
|
+
|
|
16
|
+
INTEGER = 4
|
|
17
|
+
"""integer (whole)"""
|
|
18
|
+
|
|
19
|
+
BOOLEAN = 5
|
|
20
|
+
"""boolean (true/false)"""
|
|
21
|
+
|
|
22
|
+
USER = 6
|
|
23
|
+
"""user pangination"""
|
|
24
|
+
|
|
25
|
+
CHANNEL = 7
|
|
26
|
+
"""channel pangination"""
|
|
27
|
+
|
|
28
|
+
ROLE = 8
|
|
29
|
+
"""role pangination"""
|
|
30
|
+
|
|
31
|
+
MENTIONABLE = 9
|
|
32
|
+
"""any pangination (role, channel, user)"""
|
|
33
|
+
|
|
34
|
+
NUMBER = 10
|
|
35
|
+
"""number (float, integer)"""
|
|
36
|
+
|
|
37
|
+
ATTACHMENT = 11
|
|
38
|
+
"""file upload"""
|
|
39
|
+
|
|
40
|
+
@dataclass
|
|
41
|
+
class CommandOption(DataModel):
|
|
42
|
+
"""Option for a slash command."""
|
|
43
|
+
|
|
44
|
+
type: int
|
|
45
|
+
"""Type of option. See [`CommandOptionTypes`][scurrypy.parts.command.CommandOptionTypes]."""
|
|
46
|
+
|
|
47
|
+
name: str
|
|
48
|
+
"""Name of option."""
|
|
49
|
+
|
|
50
|
+
description: str
|
|
51
|
+
"""Description of option."""
|
|
52
|
+
|
|
53
|
+
required: bool = False
|
|
54
|
+
"""Whether this option is required. Defaults to False."""
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class SlashCommand(DataModel):
|
|
58
|
+
"""Represents the slash command object."""
|
|
59
|
+
|
|
60
|
+
name: str
|
|
61
|
+
"""Name of the command."""
|
|
62
|
+
|
|
63
|
+
description: str
|
|
64
|
+
"""Description of the command."""
|
|
65
|
+
|
|
66
|
+
options: list[CommandOption] = field(default_factory=list)
|
|
67
|
+
"""Parameters or options for the command."""
|
|
68
|
+
|
|
69
|
+
type: int = field(init=False, default=CommandTypes.CHAT_INPUT)
|
|
70
|
+
"""Command type. Always `CommandTypes.CHAT_INPUT` for this class. See [`CommandTypes`][scurrypy.parts.command.CommandTypes]."""
|
|
71
|
+
|
|
72
|
+
@dataclass
|
|
73
|
+
class UserCommand(DataModel):
|
|
74
|
+
"""Represents the user command object"""
|
|
75
|
+
|
|
76
|
+
name: str
|
|
77
|
+
"""Name of the command."""
|
|
78
|
+
|
|
79
|
+
type: int = field(init=False, default=CommandTypes.USER_COMMAND)
|
|
80
|
+
"""Command type. Always `CommandTypes.USER_COMMAND` for this class. See [`CommandTypes`][scurrypy.parts.command.CommandTypes]."""
|
|
81
|
+
|
|
82
|
+
@dataclass
|
|
83
|
+
class MessageCommand(DataModel):
|
|
84
|
+
"""Represents the message command object."""
|
|
85
|
+
|
|
86
|
+
name: str
|
|
87
|
+
"""Name of the command."""
|
|
88
|
+
|
|
89
|
+
type: int = field(init=False, default=CommandTypes.MESSAGE_COMMAND)
|
|
90
|
+
"""Command type. Always `CommandTypes.MESSAGE_COMMAND` for this class. See [`CommandTypes`][scurrypy.parts.command.CommandTypes]."""
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Literal, Optional
|
|
3
|
+
from ..model import DataModel
|
|
4
|
+
|
|
5
|
+
from .component_types import *
|
|
6
|
+
|
|
7
|
+
from ..models import EmojiModel
|
|
8
|
+
|
|
9
|
+
class ComponentTypes:
|
|
10
|
+
ACTION_ROW = 1
|
|
11
|
+
BUTTON = 2
|
|
12
|
+
STRING_SELECT = 3
|
|
13
|
+
TEXT_INPUT = 4
|
|
14
|
+
USER_SELECT = 5
|
|
15
|
+
ROLE_SELECT = 6
|
|
16
|
+
MENTIONABLE_SELECT = 7
|
|
17
|
+
CHANNEL_SELECT = 8
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class ActionRowPart(DataModel, ContainerChild):
|
|
21
|
+
"""Represents a container of interactable components."""
|
|
22
|
+
|
|
23
|
+
components: list[ActionRowChild] = field(default_factory=list)
|
|
24
|
+
"""Up to 5 interactive button components or a single select component."""
|
|
25
|
+
|
|
26
|
+
type: int = field(init=False, default=ComponentTypes.ACTION_ROW)
|
|
27
|
+
"""Component type. Always `ComponentTypes.ACTION_ROW` for this class. See [`ComponentTypes`][scurrypy.parts.components.ComponentTypes]."""
|
|
28
|
+
|
|
29
|
+
class ButtonStyles:
|
|
30
|
+
"""Represents button styles for a Button component."""
|
|
31
|
+
|
|
32
|
+
PRIMARY = 1
|
|
33
|
+
"""The most important or recommended action in a group of options. (Blurple)"""
|
|
34
|
+
|
|
35
|
+
SECONDARY = 2
|
|
36
|
+
"""Alternative or supporting actions. (Gray)"""
|
|
37
|
+
|
|
38
|
+
SUCCESS = 3
|
|
39
|
+
"""Positive confirmation or completion actions. (Green)"""
|
|
40
|
+
|
|
41
|
+
DANGER = 4
|
|
42
|
+
"""An action with irreversible consequences. (Red)"""
|
|
43
|
+
|
|
44
|
+
LINK = 5
|
|
45
|
+
"""Navigates to a URL. (Gray + window)"""
|
|
46
|
+
|
|
47
|
+
@dataclass
|
|
48
|
+
class Button(DataModel, ActionRowChild, SectionAccessory):
|
|
49
|
+
"""Represents the Button component."""
|
|
50
|
+
|
|
51
|
+
style: int
|
|
52
|
+
"""A button style. See [`ButtonStyles`][scurrypy.parts.components.ButtonStyles]."""
|
|
53
|
+
|
|
54
|
+
custom_id: str
|
|
55
|
+
"""ID for the button."""
|
|
56
|
+
|
|
57
|
+
label: Optional[str] = None
|
|
58
|
+
"""Text that appears on the button."""
|
|
59
|
+
|
|
60
|
+
emoji: EmojiModel = None
|
|
61
|
+
"""Partial emoji icon."""
|
|
62
|
+
|
|
63
|
+
url: Optional[str] = None
|
|
64
|
+
"""URL for link-style buttons."""
|
|
65
|
+
|
|
66
|
+
disabled: Optional[bool] = False
|
|
67
|
+
"""Whether the button is disabled. Defaults to False."""
|
|
68
|
+
|
|
69
|
+
type: int = field(init=False, default=ComponentTypes.BUTTON)
|
|
70
|
+
"""Component type. Always `ComponentTypes.BUTTON` for this class. See [`ComponentTypes`][scurrypy.parts.components.ComponentTypes]."""
|
|
71
|
+
|
|
72
|
+
@dataclass
|
|
73
|
+
class SelectOption(DataModel):
|
|
74
|
+
"""Represents the Select Option component"""
|
|
75
|
+
|
|
76
|
+
label: str
|
|
77
|
+
"""User-facing name of the option."""
|
|
78
|
+
|
|
79
|
+
value: str
|
|
80
|
+
"""Developer-defined value of the option."""
|
|
81
|
+
|
|
82
|
+
description: Optional[str] = None
|
|
83
|
+
"""Additional description of the option."""
|
|
84
|
+
|
|
85
|
+
emoji: Optional[EmojiModel] = None
|
|
86
|
+
"""Partial emoji obhect."""
|
|
87
|
+
|
|
88
|
+
default: Optional[bool] = False
|
|
89
|
+
"""Whether this option is selected by default."""
|
|
90
|
+
|
|
91
|
+
@dataclass
|
|
92
|
+
class StringSelect(DataModel, ActionRowChild, LabelChild):
|
|
93
|
+
"""Represents the String Select component."""
|
|
94
|
+
|
|
95
|
+
custom_id: str
|
|
96
|
+
"""ID for the select menu."""
|
|
97
|
+
|
|
98
|
+
options: list[SelectOption] = field(default_factory=list)
|
|
99
|
+
"""Specified choices in a select menu. See [`SelectOption`][scurrypy.parts.components.SelectOption]."""
|
|
100
|
+
|
|
101
|
+
placeholder: Optional[str] = None
|
|
102
|
+
"""Placeholder text if nothing is selected or default."""
|
|
103
|
+
|
|
104
|
+
min_values: Optional[int] = 1
|
|
105
|
+
"""Minimum number of items that must be chosen."""
|
|
106
|
+
|
|
107
|
+
max_values: Optional[int] = 1
|
|
108
|
+
"""Maximum number of items that can be chosen."""
|
|
109
|
+
|
|
110
|
+
required: Optional[bool] = False
|
|
111
|
+
"""Whether the string select is required to answer in a modal. Defaults to False."""
|
|
112
|
+
|
|
113
|
+
disabled: Optional[bool] = False # does not work on Modals!
|
|
114
|
+
"""Whether select menu is disabled in a message. Defaults to False."""
|
|
115
|
+
|
|
116
|
+
type: int = field(init=False, default=ComponentTypes.STRING_SELECT)
|
|
117
|
+
"""Component type. Always `ComponentTypes.STRING_SELECT` for this class. See [`ComponentTypes`][scurrypy.parts.components.ComponentTypes]."""
|
|
118
|
+
|
|
119
|
+
class TextInputStyles:
|
|
120
|
+
"""Represents the types of Text Inputs."""
|
|
121
|
+
|
|
122
|
+
SHORT = 1
|
|
123
|
+
"""One line text input."""
|
|
124
|
+
|
|
125
|
+
PARAGRAPH = 2
|
|
126
|
+
"""Multi-line text input."""
|
|
127
|
+
|
|
128
|
+
@dataclass
|
|
129
|
+
class TextInput(DataModel, LabelChild):
|
|
130
|
+
"""Represents the Text Input component."""
|
|
131
|
+
|
|
132
|
+
style: TextInputStyles = TextInputStyles.SHORT
|
|
133
|
+
"""Text input style. See [`TextInputStyles`][scurrypy.parts.components.TextInputStyles]."""
|
|
134
|
+
|
|
135
|
+
custom_id: str = None
|
|
136
|
+
"""ID for the input."""
|
|
137
|
+
|
|
138
|
+
required: Optional[bool] = False
|
|
139
|
+
"""Whether this component is required to be filled."""
|
|
140
|
+
|
|
141
|
+
min_length: Optional[int] = None
|
|
142
|
+
"""Minimum input length for a text input."""
|
|
143
|
+
|
|
144
|
+
max_length: Optional[int] = None
|
|
145
|
+
"""Maximum input length for a text input."""
|
|
146
|
+
|
|
147
|
+
required: Optional[bool] = True
|
|
148
|
+
"""Whether this component is required to be filled. Defaults to True."""
|
|
149
|
+
|
|
150
|
+
value: Optional[str] = None
|
|
151
|
+
"""Pre-filled value for this component."""
|
|
152
|
+
|
|
153
|
+
placeholder: Optional[str] = None
|
|
154
|
+
"""Custom placeholder text if the input is empty."""
|
|
155
|
+
|
|
156
|
+
type: int = field(init=False, default=ComponentTypes.TEXT_INPUT)
|
|
157
|
+
"""Component type. Always `ComponentTypes.TEXT_INPUT` for this class. See [`ComponentTypes`][scurrypy.parts.components.ComponentTypes]."""
|
|
158
|
+
|
|
159
|
+
@dataclass
|
|
160
|
+
class DefaultValue(DataModel):
|
|
161
|
+
"""Represents the Default Value for Select components."""
|
|
162
|
+
|
|
163
|
+
id: int
|
|
164
|
+
"""ID of role, user, or channel."""
|
|
165
|
+
|
|
166
|
+
type: Literal["role", "user", "channel"]
|
|
167
|
+
"""Type of value that `id` represents."""
|
|
168
|
+
|
|
169
|
+
@dataclass
|
|
170
|
+
class SelectMenu(DataModel):
|
|
171
|
+
"""Represents common fields for Discord's select menus."""
|
|
172
|
+
|
|
173
|
+
custom_id: str
|
|
174
|
+
"""ID for the select menu."""
|
|
175
|
+
|
|
176
|
+
placeholder: Optional[str] = None
|
|
177
|
+
"""Placeholder text if nothing is selected."""
|
|
178
|
+
|
|
179
|
+
default_values: list[DefaultValue] = field(default_factory=list)
|
|
180
|
+
"""
|
|
181
|
+
List of default values for auto-populated select menu components. See [`DefaultValue`][scurrypy.parts.components.DefaultValue].
|
|
182
|
+
Number of default values must be in the range of `min_values` to `max_values`.
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
min_values: Optional[int] = 1
|
|
186
|
+
"""Minimum number of items that must be chosen. Defaults to 1."""
|
|
187
|
+
|
|
188
|
+
max_values: Optional[int] = 1
|
|
189
|
+
"""Maximum number of items that can be chosen. Defaults to 1."""
|
|
190
|
+
|
|
191
|
+
required: Optional[bool] = False
|
|
192
|
+
"""Whether the user select is required to answer in a modal. Defaults to False."""
|
|
193
|
+
|
|
194
|
+
disabled: Optional[bool] = False
|
|
195
|
+
"""Whether select menu is disabled in a message. Defaults to False."""
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@dataclass
|
|
199
|
+
class UserSelect(SelectMenu, ActionRowChild, LabelChild):
|
|
200
|
+
"""Represents the User Select component."""
|
|
201
|
+
|
|
202
|
+
type: int = field(init=False, default=ComponentTypes.USER_SELECT)
|
|
203
|
+
"""Component type. Always `ComponentTypes.USER_SELECT` for this class. See [`ComponentTypes`][scurrypy.parts.components.ComponentTypes]."""
|
|
204
|
+
|
|
205
|
+
@dataclass
|
|
206
|
+
class RoleSelect(SelectMenu, ActionRowChild, LabelChild):
|
|
207
|
+
"""Represents the Role Select component."""
|
|
208
|
+
|
|
209
|
+
type: int = field(init=False, default=ComponentTypes.ROLE_SELECT)
|
|
210
|
+
"""Component type. Always `ComponentTypes.ROLE_SELECT` for this class. See [`ComponentTypes`][scurrypy.parts.components.ComponentTypes]."""
|
|
211
|
+
|
|
212
|
+
@dataclass
|
|
213
|
+
class MentionableSelect(SelectMenu, ActionRowChild, LabelChild):
|
|
214
|
+
"""Represents the Mentionable Select component."""
|
|
215
|
+
|
|
216
|
+
type: int = field(init=False, default=ComponentTypes.MENTIONABLE_SELECT)
|
|
217
|
+
"""Component type. Always `ComponentTypes.MENTIONABLE_SELECT` for this class. See [`ComponentTypes`][scurrypy.parts.components.ComponentTypes]."""
|
|
218
|
+
|
|
219
|
+
@dataclass
|
|
220
|
+
class ChannelSelect(SelectMenu, ActionRowChild, LabelChild):
|
|
221
|
+
"""Represents the Channel Select component."""
|
|
222
|
+
|
|
223
|
+
type: int = field(init=False, default=ComponentTypes.CHANNEL_SELECT)
|
|
224
|
+
"""Component type. Always `ComponentTypes.CHANNEL_SELECT` for this class. See [`ComponentTypes`][scurrypy.parts.components.ComponentTypes]."""
|