scurrypy 0.4.1__tar.gz → 0.5__tar.gz

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.

Potentially problematic release.


This version of scurrypy might be problematic. Click here for more details.

Files changed (65) hide show
  1. {scurrypy-0.4.1 → scurrypy-0.5}/PKG-INFO +6 -13
  2. {scurrypy-0.4.1 → scurrypy-0.5}/README.md +5 -12
  3. {scurrypy-0.4.1 → scurrypy-0.5}/discord/__init__.py +219 -66
  4. {scurrypy-0.4.1 → scurrypy-0.5}/discord/dispatch/command_dispatcher.py +10 -2
  5. {scurrypy-0.4.1 → scurrypy-0.5}/discord/dispatch/prefix_dispatcher.py +1 -5
  6. {scurrypy-0.4.1 → scurrypy-0.5}/discord/events/channel_events.py +1 -1
  7. {scurrypy-0.4.1 → scurrypy-0.5}/discord/events/interaction_events.py +19 -7
  8. {scurrypy-0.4.1 → scurrypy-0.5}/discord/http.py +5 -1
  9. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/emoji.py +1 -1
  10. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/interaction.py +5 -0
  11. scurrypy-0.5/discord/parts/channel.py +42 -0
  12. scurrypy-0.5/discord/parts/command.py +90 -0
  13. scurrypy-0.5/discord/parts/components.py +224 -0
  14. scurrypy-0.5/discord/parts/components_v2.py +144 -0
  15. scurrypy-0.5/discord/parts/embed.py +83 -0
  16. scurrypy-0.5/discord/parts/message.py +137 -0
  17. scurrypy-0.5/discord/parts/modal.py +16 -0
  18. {scurrypy-0.4.1 → scurrypy-0.5}/discord/parts/role.py +1 -13
  19. {scurrypy-0.4.1 → scurrypy-0.5}/discord/resources/channel.py +4 -4
  20. {scurrypy-0.4.1 → scurrypy-0.5}/discord/resources/guild.py +0 -1
  21. {scurrypy-0.4.1 → scurrypy-0.5}/discord/resources/interaction.py +20 -19
  22. {scurrypy-0.4.1 → scurrypy-0.5}/discord/resources/message.py +10 -10
  23. {scurrypy-0.4.1 → scurrypy-0.5}/pyproject.toml +1 -1
  24. {scurrypy-0.4.1 → scurrypy-0.5}/scurrypy.egg-info/PKG-INFO +6 -13
  25. {scurrypy-0.4.1 → scurrypy-0.5}/scurrypy.egg-info/SOURCES.txt +1 -1
  26. scurrypy-0.4.1/discord/parts/action_row.py +0 -208
  27. scurrypy-0.4.1/discord/parts/channel.py +0 -20
  28. scurrypy-0.4.1/discord/parts/command.py +0 -102
  29. scurrypy-0.4.1/discord/parts/components_v2.py +0 -353
  30. scurrypy-0.4.1/discord/parts/embed.py +0 -154
  31. scurrypy-0.4.1/discord/parts/message.py +0 -194
  32. scurrypy-0.4.1/discord/parts/modal.py +0 -21
  33. {scurrypy-0.4.1 → scurrypy-0.5}/LICENSE +0 -0
  34. {scurrypy-0.4.1 → scurrypy-0.5}/discord/client.py +0 -0
  35. {scurrypy-0.4.1 → scurrypy-0.5}/discord/client_like.py +0 -0
  36. {scurrypy-0.4.1 → scurrypy-0.5}/discord/config.py +0 -0
  37. {scurrypy-0.4.1 → scurrypy-0.5}/discord/dispatch/__init__.py +0 -0
  38. {scurrypy-0.4.1 → scurrypy-0.5}/discord/dispatch/event_dispatcher.py +0 -0
  39. {scurrypy-0.4.1 → scurrypy-0.5}/discord/error.py +0 -0
  40. {scurrypy-0.4.1 → scurrypy-0.5}/discord/events/__init__.py +0 -0
  41. {scurrypy-0.4.1 → scurrypy-0.5}/discord/events/guild_events.py +0 -0
  42. {scurrypy-0.4.1 → scurrypy-0.5}/discord/events/hello_event.py +0 -0
  43. {scurrypy-0.4.1 → scurrypy-0.5}/discord/events/message_events.py +0 -0
  44. {scurrypy-0.4.1 → scurrypy-0.5}/discord/events/reaction_events.py +0 -0
  45. {scurrypy-0.4.1 → scurrypy-0.5}/discord/events/ready_event.py +0 -0
  46. {scurrypy-0.4.1 → scurrypy-0.5}/discord/gateway.py +0 -0
  47. {scurrypy-0.4.1 → scurrypy-0.5}/discord/intents.py +0 -0
  48. {scurrypy-0.4.1 → scurrypy-0.5}/discord/logger.py +0 -0
  49. {scurrypy-0.4.1 → scurrypy-0.5}/discord/model.py +0 -0
  50. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/__init__.py +0 -0
  51. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/application.py +0 -0
  52. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/guild.py +0 -0
  53. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/integration.py +0 -0
  54. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/member.py +0 -0
  55. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/role.py +0 -0
  56. {scurrypy-0.4.1 → scurrypy-0.5}/discord/models/user.py +0 -0
  57. {scurrypy-0.4.1 → scurrypy-0.5}/discord/parts/__init__.py +0 -0
  58. {scurrypy-0.4.1 → scurrypy-0.5}/discord/parts/component_types.py +0 -0
  59. {scurrypy-0.4.1 → scurrypy-0.5}/discord/resources/__init__.py +0 -0
  60. {scurrypy-0.4.1 → scurrypy-0.5}/discord/resources/application.py +0 -0
  61. {scurrypy-0.4.1 → scurrypy-0.5}/discord/resources/bot_emojis.py +0 -0
  62. {scurrypy-0.4.1 → scurrypy-0.5}/discord/resources/user.py +0 -0
  63. {scurrypy-0.4.1 → scurrypy-0.5}/scurrypy.egg-info/dependency_links.txt +0 -0
  64. {scurrypy-0.4.1 → scurrypy-0.5}/scurrypy.egg-info/top_level.txt +0 -0
  65. {scurrypy-0.4.1 → scurrypy-0.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scurrypy
3
- Version: 0.4.1
3
+ Version: 0.5
4
4
  Summary: Dataclass-driven Discord API Wrapper in Python
5
5
  Author: Furmissile
6
6
  Requires-Python: >=3.10
@@ -8,7 +8,7 @@ Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
9
  Dynamic: license-file
10
10
 
11
- # __Welcome to ScurryPy__
11
+ # __ScurryPy__
12
12
 
13
13
  [![PyPI version](https://badge.fury.io/py/scurrypy.svg)](https://badge.fury.io/py/scurrypy)
14
14
 
@@ -20,22 +20,16 @@ A dataclass-driven Discord API wrapper in Python!
20
20
 
21
21
  While this wrapper is mainly used for various squirrel-related shenanigans, it can also be used for more generic bot purposes.
22
22
 
23
- ---
24
-
25
23
  ## Features
26
24
  * Command and event handling
27
25
  * Declarative style using decorators
28
26
  * Supports both legacy and new features
29
27
  * Respects Discord’s rate limits
30
28
 
31
- ---
32
-
33
- ## Some Things to Consider...
29
+ ## Notes & Early Status
34
30
  * This is an early version — feedback, ideas, and contributions are very welcome! That said, there may be bumps along the way, so expect occasional bugs and quirks.
35
31
  * Certain features are not yet supported, while others are intentionally omitted. See the [docs](https://furmissile.github.io/scurrypy) for full details.
36
32
 
37
- ---
38
-
39
33
  ## Getting Started
40
34
  *Note: This section also appears in the documentation, but here are complete examples ready to use with your bot credentials.*
41
35
 
@@ -58,7 +52,7 @@ load_dotenv(dotenv_path='./path/to/env')
58
52
 
59
53
  client = discord.Client(
60
54
  token=os.getenv("DISCORD_TOKEN"),
61
- application_id=APPLICATION_ID # replace with your bot's user ID
55
+ application_id=APPLICATION_ID # your bots application ID
62
56
  )
63
57
 
64
58
  @client.command(
@@ -84,7 +78,7 @@ load_dotenv(dotenv_path='./path/to/env')
84
78
 
85
79
  client = discord.Client(
86
80
  token=os.getenv("DISCORD_TOKEN"),
87
- application_id=APPLICATION_ID, # replace with your bot's user ID
81
+ application_id=APPLICATION_ID # your bots application ID
88
82
  intents=discord.set_intents(message_content=True),
89
83
  prefix='!' # your custom prefix
90
84
  )
@@ -126,5 +120,4 @@ If you plan to make substantial changes or release your own variant:
126
120
  See the [License](./LICENSE) for details.
127
121
 
128
122
  ## Like What You See?
129
- Check out the full [documentation](https://furmissile.github.io/scurrypy)
130
- for more examples, guides, and API reference!
123
+ Explore the full [documentation](https://furmissile.github.io/scurrypy) for more examples, guides, and API reference.
@@ -1,4 +1,4 @@
1
- # __Welcome to ScurryPy__
1
+ # __ScurryPy__
2
2
 
3
3
  [![PyPI version](https://badge.fury.io/py/scurrypy.svg)](https://badge.fury.io/py/scurrypy)
4
4
 
@@ -10,22 +10,16 @@ A dataclass-driven Discord API wrapper in Python!
10
10
 
11
11
  While this wrapper is mainly used for various squirrel-related shenanigans, it can also be used for more generic bot purposes.
12
12
 
13
- ---
14
-
15
13
  ## Features
16
14
  * Command and event handling
17
15
  * Declarative style using decorators
18
16
  * Supports both legacy and new features
19
17
  * Respects Discord’s rate limits
20
18
 
21
- ---
22
-
23
- ## Some Things to Consider...
19
+ ## Notes & Early Status
24
20
  * This is an early version — feedback, ideas, and contributions are very welcome! That said, there may be bumps along the way, so expect occasional bugs and quirks.
25
21
  * Certain features are not yet supported, while others are intentionally omitted. See the [docs](https://furmissile.github.io/scurrypy) for full details.
26
22
 
27
- ---
28
-
29
23
  ## Getting Started
30
24
  *Note: This section also appears in the documentation, but here are complete examples ready to use with your bot credentials.*
31
25
 
@@ -48,7 +42,7 @@ load_dotenv(dotenv_path='./path/to/env')
48
42
 
49
43
  client = discord.Client(
50
44
  token=os.getenv("DISCORD_TOKEN"),
51
- application_id=APPLICATION_ID # replace with your bot's user ID
45
+ application_id=APPLICATION_ID # your bots application ID
52
46
  )
53
47
 
54
48
  @client.command(
@@ -74,7 +68,7 @@ load_dotenv(dotenv_path='./path/to/env')
74
68
 
75
69
  client = discord.Client(
76
70
  token=os.getenv("DISCORD_TOKEN"),
77
- application_id=APPLICATION_ID, # replace with your bot's user ID
71
+ application_id=APPLICATION_ID # your bots application ID
78
72
  intents=discord.set_intents(message_content=True),
79
73
  prefix='!' # your custom prefix
80
74
  )
@@ -116,5 +110,4 @@ If you plan to make substantial changes or release your own variant:
116
110
  See the [License](./LICENSE) for details.
117
111
 
118
112
  ## Like What You See?
119
- Check out the full [documentation](https://furmissile.github.io/scurrypy)
120
- for more examples, guides, and API reference!
113
+ Explore the full [documentation](https://furmissile.github.io/scurrypy) for more examples, guides, and API reference.
@@ -4,32 +4,36 @@ import importlib
4
4
  from typing import TYPE_CHECKING
5
5
 
6
6
  __all__ = [
7
- # top-level
8
7
  "Logger",
9
8
  "Client",
10
9
  "Intents",
11
10
  "set_intents",
12
11
  "BaseConfig",
13
12
 
14
- # events
13
+ "InteractionTypes",
14
+
15
15
  "ReadyEvent",
16
+
16
17
  "ReactionAddEvent",
17
18
  "ReactionRemoveEvent",
18
19
  "ReactionRemoveEmojiEvent",
19
20
  "ReactionRemoveAllEvent",
21
+
20
22
  "GuildCreateEvent",
21
23
  "GuildUpdateEvent",
22
24
  "GuildDeleteEvent",
25
+
23
26
  "MessageCreateEvent",
24
27
  "MessageUpdateEvent",
25
28
  "MessageDeleteEvent",
29
+
26
30
  "GuildChannelCreateEvent",
27
31
  "GuildChannelUpdateEvent",
28
32
  "GuildChannelDeleteEvent",
29
33
  "ChannelPinsUpdateEvent",
34
+
30
35
  "InteractionEvent",
31
36
 
32
- # models
33
37
  "ApplicationModel",
34
38
  "EmojiModel",
35
39
  "GuildModel",
@@ -37,34 +41,73 @@ __all__ = [
37
41
  "UserModel",
38
42
  "RoleModel",
39
43
 
40
- # parts
44
+ "ChannelTypes",
41
45
  "GuildChannel",
42
- "Role",
43
- "MessageBuilder",
44
- "ModalBuilder",
45
- "EmbedBuilder",
46
- "ActionRow",
47
- "StringSelect",
48
- "UserSelect",
49
- "RoleSelect",
50
- "ChannelSelect",
51
- "MentionableSelect",
46
+
47
+ "CommandTypes",
48
+ "CommandOptionTypes",
52
49
  "SlashCommand",
53
- "MessageCommand",
54
50
  "UserCommand",
55
- "Container",
56
- "Section",
51
+ "MessageCommand",
52
+
53
+ "ComponentV2Types",
54
+ "SectionPart",
55
+ "TextDisplay",
56
+ "Thumbnail",
57
57
  "MediaGalleryItem",
58
+ "MediaGallery",
59
+ "File",
60
+ "SeparatorTypes",
61
+ "Separator",
62
+ "ContainerPart",
58
63
  "Label",
59
64
 
60
- # resources
61
- "Guild",
65
+ "ComponentTypes",
66
+ "ActionRowPart",
67
+ "ButtonStyles",
68
+ "Button",
69
+ "SelectOption",
70
+ "StringSelect",
71
+ "TextInputStyles",
72
+ "TextInput",
73
+ "DefaultValue",
74
+ "UserSelect",
75
+ "RoleSelect",
76
+ "MentionableSelect",
77
+ "ChannelSelect",
78
+
79
+ "EmbedAuthor",
80
+ "EmbedThumbnail",
81
+ "EmbedField",
82
+ "EmbedImage",
83
+ "EmbedFooter",
84
+ "EmbedPart",
85
+
86
+ "MessageFlags",
87
+ "MessageReferenceTypes",
88
+ "MessageReference",
89
+ "Attachment",
90
+ "MessagePart",
91
+
92
+ "ModalPart",
93
+ "Role",
94
+
95
+ "ApplicationFlags",
96
+ "Application",
97
+
98
+ "BotEmojis",
99
+
100
+ "PinnedMessage",
62
101
  "Channel",
102
+
103
+ "Guild",
104
+
105
+ "InteractionCallbackTypes",
106
+ "Interaction",
107
+
63
108
  "Message",
64
- "BotEmojis",
109
+
65
110
  "User",
66
- "Interaction",
67
- "Application",
68
111
  ]
69
112
 
70
113
  # For editor support / autocomplete
@@ -74,6 +117,8 @@ if TYPE_CHECKING:
74
117
  from .intents import Intents, set_intents
75
118
  from .config import BaseConfig
76
119
 
120
+ from .dispatch.command_dispatcher import InteractionTypes
121
+
77
122
  # events
78
123
  from .events.ready_event import ReadyEvent
79
124
  from .events.reaction_events import (
@@ -109,41 +154,105 @@ if TYPE_CHECKING:
109
154
  from .models.role import RoleModel
110
155
 
111
156
  # parts
112
- from .parts.channel import GuildChannel
113
- from .parts.role import Role
114
- from .parts.message import MessageBuilder
115
- from .parts.modal import ModalBuilder
116
- from .parts.embed import EmbedBuilder
117
- from .parts.action_row import (
118
- ActionRow,
119
- StringSelect,
120
- UserSelect,
121
- RoleSelect,
122
- ChannelSelect,
123
- MentionableSelect
157
+ from .parts.channel import (
158
+ ChannelTypes,
159
+ GuildChannel
124
160
  )
125
161
 
126
162
  from .parts.command import (
163
+ CommandTypes,
164
+ CommandOptionTypes,
127
165
  SlashCommand,
128
- MessageCommand,
129
- UserCommand
166
+ UserCommand,
167
+ MessageCommand
130
168
  )
131
169
 
132
170
  from .parts.components_v2 import (
133
- Container,
134
- Section,
171
+ ComponentV2Types,
172
+ SectionPart,
173
+ TextDisplay,
174
+ Thumbnail,
135
175
  MediaGalleryItem,
176
+ MediaGallery,
177
+ File,
178
+ SeparatorTypes,
179
+ Separator,
180
+ ContainerPart,
136
181
  Label
137
182
  )
138
183
 
184
+ from .parts.components import (
185
+ ComponentTypes,
186
+ ActionRowPart,
187
+ ButtonStyles,
188
+ Button,
189
+ SelectOption,
190
+ StringSelect,
191
+ TextInputStyles,
192
+ TextInput,
193
+ DefaultValue,
194
+ # SelectMenu,
195
+ UserSelect,
196
+ RoleSelect,
197
+ MentionableSelect,
198
+ ChannelSelect
199
+ )
200
+
201
+ from .parts.embed import (
202
+ EmbedAuthor,
203
+ EmbedThumbnail,
204
+ EmbedField,
205
+ EmbedImage,
206
+ EmbedFooter,
207
+ EmbedPart
208
+ )
209
+
210
+ from .parts.message import (
211
+ MessageFlags,
212
+ # MessageFlagParams,
213
+ MessageReferenceTypes,
214
+ MessageReference,
215
+ Attachment,
216
+ MessagePart
217
+ )
218
+
219
+ from .parts.modal import ModalPart
220
+ from .parts.role import Role
221
+
139
222
  # resources
140
- from .resources.guild import Guild
141
- from .resources.channel import Channel
142
- from .resources.message import Message
223
+ from .resources.application import (
224
+ ApplicationFlags,
225
+ Application
226
+ )
227
+
143
228
  from .resources.bot_emojis import BotEmojis
144
- from .resources.user import User
145
- from .resources.interaction import Interaction
146
- from .resources.application import Application
229
+
230
+ from .resources.channel import (
231
+ # MessagesFetchParams,
232
+ # PinsFetchParams,
233
+ # ThreadFromMessageParams,
234
+ PinnedMessage,
235
+ Channel
236
+ )
237
+
238
+ from .resources.guild import (
239
+ # FetchGuildMembersParams,
240
+ # FetchGuildParams,
241
+ Guild
242
+ )
243
+
244
+ from .resources.interaction import (
245
+ # InteractionDataTypes,
246
+ InteractionCallbackTypes,
247
+ Interaction
248
+ )
249
+
250
+ from .resources.message import Message
251
+
252
+ from .resources.user import (
253
+ # FetchUserGuildsParams,
254
+ User
255
+ )
147
256
 
148
257
  # Lazy loader
149
258
  def __getattr__(name: str):
@@ -158,25 +267,30 @@ def __getattr__(name: str):
158
267
  "set_intents": "discord.intents",
159
268
  "BaseConfig": "discord.config",
160
269
 
161
- # events
270
+ 'InteractionTypes': "discord.dispatch.command_dispatcher",
271
+
162
272
  "ReadyEvent": "discord.events.ready_event",
273
+
163
274
  "ReactionAddEvent": "discord.events.reaction_events",
164
275
  "ReactionRemoveEvent": "discord.events.reaction_events",
165
276
  "ReactionRemoveEmojiEvent": "discord.events.reaction_events",
166
277
  "ReactionRemoveAllEvent": "discord.events.reaction_events",
278
+
167
279
  "GuildCreateEvent": "discord.events.guild_events",
168
280
  "GuildUpdateEvent": "discord.events.guild_events",
169
281
  "GuildDeleteEvent": "discord.events.guild_events",
282
+
170
283
  "MessageCreateEvent": "discord.events.message_events",
171
284
  "MessageUpdateEvent": "discord.events.message_events",
172
285
  "MessageDeleteEvent": "discord.events.message_events",
286
+
173
287
  "GuildChannelCreateEvent": "discord.events.channel_events",
174
288
  "GuildChannelUpdateEvent": "discord.events.channel_events",
175
289
  "GuildChannelDeleteEvent": "discord.events.channel_events",
176
290
  "ChannelPinsUpdateEvent": "discord.events.channel_events",
291
+
177
292
  "InteractionEvent": "discord.events.interaction_events",
178
293
 
179
- # models
180
294
  'ApplicationModel': "discord.models.application",
181
295
  'EmojiModel': "discord.models.emoji",
182
296
  'GuildModel': "discord.models.guild",
@@ -184,34 +298,73 @@ def __getattr__(name: str):
184
298
  'UserModel': "discord.models.user",
185
299
  'RoleModel': "discord.models.role",
186
300
 
187
- # parts
301
+ 'ChannelTypes': "discord.parts.channel",
188
302
  'GuildChannel': "discord.parts.channel",
189
- 'Role': "discord.parts.role",
190
- 'MessageBuilder': "discord.parts.message",
191
- 'ModalBuilder': "discord.parts.modal",
192
- 'EmbedBuilder': "discord.parts.embed",
193
- 'ActionRow': "discord.parts.action_row",
194
- 'StringSelect': "discord.parts.action_row",
195
- 'UserSelect': "discord.parts.action_row",
196
- 'RoleSelect': "discord.parts.action_row",
197
- 'ChannelSelect': "discord.parts.action_row",
198
- 'MentionableSelect': "discord.parts.action_row",
303
+
304
+ 'CommandTypes': "discord.parts.command",
305
+ 'CommandOptionTypes': "discord.parts.command",
199
306
  'SlashCommand': "discord.parts.command",
200
- 'MessageCommand': "discord.parts.command",
201
307
  'UserCommand': "discord.parts.command",
202
- 'Container': "discord.parts.components_v2",
203
- 'Section': "discord.parts.components_v2",
308
+ 'MessageCommand': "discord.parts.command",
309
+
310
+ 'ComponentV2Types': "discord.parts.components_v2",
311
+ 'SectionPart': "discord.parts.components_v2",
312
+ 'TextDisplay': "discord.parts.components_v2",
313
+ 'Thumbnail': "discord.parts.components_v2",
204
314
  'MediaGalleryItem': "discord.parts.components_v2",
315
+ 'MediaGallery': "discord.parts.components_v2",
316
+ 'File': "discord.parts.components_v2",
317
+ 'SeparatorTypes': "discord.parts.components_v2",
318
+ 'Separator': "discord.parts.components_v2",
319
+ 'ContainerPart': "discord.parts.components_v2",
205
320
  'Label': "discord.parts.components_v2",
206
321
 
207
- # resources
208
- 'Guild': "discord.resources.guild",
209
- 'Channel': "discord.resources.channel",
210
- 'Message': "discord.resources.message",
322
+ 'ComponentTypes': "discord.parts.components",
323
+ 'ActionRowPart': "discord.parts.components",
324
+ 'ButtonStyles': "discord.parts.components",
325
+ 'Button': "discord.parts.components",
326
+ 'SelectOption': "discord.parts.components",
327
+ 'StringSelect': "discord.parts.components",
328
+ 'TextInputStyles': 'discord.parts.components',
329
+ 'TextInput': "discord.parts.components",
330
+ 'DefaultValue': "discord.parts.components",
331
+ 'UserSelect': "discord.parts.components",
332
+ 'RoleSelect': "discord.parts.components",
333
+ 'MentionableSelect': "discord.parts.components",
334
+ 'ChannelSelect': "discord.parts.components",
335
+
336
+ 'EmbedAuthor': "discord.parts.embed",
337
+ 'EmbedThumbnail': "discord.parts.embed",
338
+ 'EmbedField': "discord.parts.embed",
339
+ 'EmbedImage': "discord.parts.embed",
340
+ 'EmbedFooter': "discord.parts.embed",
341
+ 'EmbedPart': "discord.parts.embed",
342
+
343
+ 'MessageFlags': "discord.parts.message",
344
+ 'MessageReferenceTypes': "discord.parts.message",
345
+ 'MessageReference': "discord.parts.message",
346
+ 'Attachment': "discord.parts.message",
347
+ 'MessagePart': "discord.parts.message",
348
+
349
+ 'ModalPart': "discord.parts.modal",
350
+ 'Role': "discord.parts.role",
351
+
352
+ 'ApplicationFlags': "discord.resources.application",
353
+ 'Application': "discord.resources.application",
354
+
211
355
  'BotEmojis': "discord.resources.bot_emojis",
212
- 'User': "discord.resources.user",
356
+
357
+ 'PinnedMessage': "discord.resources.channel",
358
+ 'Channel': "discord.resources.channel",
359
+
360
+ 'Guild': "discord.resources.guild",
361
+
362
+ 'InteractionCallbackTypes': "discord.resources.interaction",
213
363
  'Interaction': "discord.resources.interaction",
214
- 'Application': "discord.resources.application"
364
+
365
+ 'Message': "discord.resources.message",
366
+
367
+ 'User': "discord.resources.user"
215
368
  }
216
369
 
217
370
  module = importlib.import_module(mapping[name])
@@ -1,3 +1,5 @@
1
+ import fnmatch
2
+
1
3
  from ..client_like import ClientLike
2
4
 
3
5
  from ..events.interaction_events import ApplicationCommandData, MessageComponentData, ModalData, InteractionEvent
@@ -146,11 +148,17 @@ class CommandDispatcher:
146
148
 
147
149
  case InteractionTypes.MESSAGE_COMPONENT:
148
150
  name = event.data.custom_id
149
- handler = self._component_handlers.get(name)
151
+ for k, v in self._component_handlers.items():
152
+ if fnmatch.fnmatch(name, k) == True:
153
+ handler = v
154
+ # handler = self._component_handlers.get(name)
150
155
 
151
156
  case InteractionTypes.MODAL_SUBMIT:
152
157
  name = event.data.custom_id
153
- handler = self._component_handlers.get(name)
158
+ for k, v in self._component_handlers.items():
159
+ if fnmatch.fnmatch(name, k) == True:
160
+ handler = v
161
+ # handler = self._component_handlers.get(name)
154
162
 
155
163
  if not handler:
156
164
  self._logger.log_warn(f"No handler registered for interaction '{name}'")
@@ -57,8 +57,4 @@ class PrefixDispatcher:
57
57
  self._logger.log_info(f"Prefix Event '{command}' Acknowledged.")
58
58
  except Exception as e:
59
59
  self._logger.log_error(f"Error in prefix command '{command}': {e}")
60
-
61
- if self._logger.dev_mode:
62
- import traceback
63
- traceback.print_exc()
64
- print("-----------------------------------\n")
60
+ self._logger.log_traceback()
@@ -46,7 +46,7 @@ class GuildChannelDeleteEvent(GuildChannelEvent):
46
46
  pass
47
47
 
48
48
  @dataclass
49
- class ChannelPinsUpdateEvent:
49
+ class ChannelPinsUpdateEvent(DataModel):
50
50
  """Pin update event."""
51
51
  channel_id: int
52
52
  """ID of channel where the pins were updated."""
@@ -3,12 +3,14 @@ from typing import Optional
3
3
  from ..model import DataModel
4
4
 
5
5
  from ..resources.interaction import Interaction
6
+ from ..parts.components import ComponentTypes
6
7
 
7
8
  # ----- Command Interaction -----
8
9
 
9
10
  @dataclass
10
11
  class ApplicationCommandOptionData(DataModel):
11
12
  """Represents the response options from a slash command."""
13
+
12
14
  name: str
13
15
  """Name of the command option."""
14
16
 
@@ -21,6 +23,7 @@ class ApplicationCommandOptionData(DataModel):
21
23
  @dataclass
22
24
  class ApplicationCommandData(DataModel):
23
25
  """Represents the response from a command."""
26
+
24
27
  id: int
25
28
  """ID of the command."""
26
29
 
@@ -39,7 +42,7 @@ class ApplicationCommandData(DataModel):
39
42
  options: Optional[list[ApplicationCommandOptionData]] = field(default_factory=list)
40
43
  """Options of the command (slash command only)."""
41
44
 
42
- def get_command_option_value(self, option_name: str):
45
+ def get_command_option_value(self, option_name: str, default = None):
43
46
  """Get the input for a command option by name.
44
47
 
45
48
  Args:
@@ -52,12 +55,13 @@ class ApplicationCommandData(DataModel):
52
55
  (str | int | float | bool): input data of specified option
53
56
  """
54
57
  for option in self.options:
55
- if option_name != option.name:
56
- continue
57
-
58
- return option.value
58
+ if option.name == option_name:
59
+ return option.value
59
60
 
60
- raise ValueError(f"Option name '{option_name}' could not be found.")
61
+ if default is not None:
62
+ return default
63
+
64
+ raise ValueError(f"Option '{option_name}' not found")
61
65
 
62
66
  # ----- Component Interaction -----
63
67
 
@@ -79,6 +83,7 @@ class MessageComponentData(DataModel):
79
83
  @dataclass
80
84
  class ModalComponentData(DataModel):
81
85
  """Represents the modal field response from a modal."""
86
+
82
87
  type: int
83
88
  """Type of component."""
84
89
 
@@ -94,6 +99,7 @@ class ModalComponentData(DataModel):
94
99
  @dataclass
95
100
  class ModalComponent(DataModel):
96
101
  """Represents the modal component response from a modal."""
102
+
97
103
  type: int
98
104
  """Type of component."""
99
105
 
@@ -128,7 +134,13 @@ class ModalData(DataModel):
128
134
 
129
135
  t = component.component.type
130
136
 
131
- if t in [3,5,6,7,8]: # select menus (w. possibly many option selects!)
137
+ if t in [
138
+ ComponentTypes.STRING_SELECT,
139
+ ComponentTypes.USER_SELECT,
140
+ ComponentTypes.ROLE_SELECT,
141
+ ComponentTypes.MENTIONABLE_SELECT,
142
+ ComponentTypes.CHANNEL_SELECT # select menus (w. possibly many option selects!)
143
+ ]:
132
144
  return component.component.values
133
145
 
134
146
  # text input
@@ -6,6 +6,7 @@ import json
6
6
  from typing import Any, Optional
7
7
 
8
8
  from .logger import Logger
9
+ from .error import DiscordError
9
10
 
10
11
  class HTTPException(Exception):
11
12
  """Represents an HTTP error response from Discord."""
@@ -151,7 +152,7 @@ class HTTPClient:
151
152
  if data.get("global"):
152
153
  self.global_reset = asyncio.get_event_loop().time() + retry
153
154
  self.logger.log_warn(
154
- f"Rate limited {retry}s ({'global' if data.get('global') else 'bucket'})"
155
+ f"Rate limited {retry}s ({endpoint})"
155
156
  )
156
157
  await asyncio.sleep(retry + 0.5)
157
158
  continue
@@ -163,6 +164,9 @@ class HTTPClient:
163
164
  return await resp.json()
164
165
  except aiohttp.ContentTypeError:
165
166
  return await resp.text()
167
+
168
+ if resp.status == 400:
169
+ raise DiscordError(resp.status, await resp.json())
166
170
 
167
171
  text = await resp.text()
168
172
  raise HTTPException(resp, text)
@@ -13,7 +13,7 @@ class EmojiModel(DataModel):
13
13
  """ID of the emoji (if custom)."""
14
14
 
15
15
  animated: bool = False
16
- """If the emoji is animated. Defaults to `False`."""
16
+ """If the emoji is animated. Defaults to False."""
17
17
 
18
18
  @property
19
19
  def mention(self) -> str: