scurrypy 0.1.0__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.

Potentially problematic release.


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

Files changed (52) hide show
  1. discord/__init__.py +9 -0
  2. discord/client.py +312 -0
  3. discord/dispatch/__init__.py +1 -0
  4. discord/dispatch/command_dispatcher.py +156 -0
  5. discord/dispatch/event_dispatcher.py +85 -0
  6. discord/dispatch/prefix_dispatcher.py +53 -0
  7. discord/error.py +63 -0
  8. discord/events/__init__.py +33 -0
  9. discord/events/channel_events.py +52 -0
  10. discord/events/guild_events.py +38 -0
  11. discord/events/hello_event.py +9 -0
  12. discord/events/interaction_events.py +145 -0
  13. discord/events/message_events.py +43 -0
  14. discord/events/reaction_events.py +99 -0
  15. discord/events/ready_event.py +30 -0
  16. discord/gateway.py +175 -0
  17. discord/http.py +292 -0
  18. discord/intents.py +87 -0
  19. discord/logger.py +147 -0
  20. discord/model.py +88 -0
  21. discord/models/__init__.py +8 -0
  22. discord/models/application.py +37 -0
  23. discord/models/emoji.py +34 -0
  24. discord/models/guild.py +35 -0
  25. discord/models/integration.py +23 -0
  26. discord/models/member.py +27 -0
  27. discord/models/role.py +53 -0
  28. discord/models/user.py +15 -0
  29. discord/parts/__init__.py +28 -0
  30. discord/parts/action_row.py +258 -0
  31. discord/parts/attachment.py +18 -0
  32. discord/parts/channel.py +20 -0
  33. discord/parts/command.py +102 -0
  34. discord/parts/component_types.py +5 -0
  35. discord/parts/components_v2.py +270 -0
  36. discord/parts/embed.py +154 -0
  37. discord/parts/message.py +179 -0
  38. discord/parts/modal.py +21 -0
  39. discord/parts/role.py +39 -0
  40. discord/resources/__init__.py +10 -0
  41. discord/resources/application.py +94 -0
  42. discord/resources/bot_emojis.py +49 -0
  43. discord/resources/channel.py +192 -0
  44. discord/resources/guild.py +265 -0
  45. discord/resources/interaction.py +155 -0
  46. discord/resources/message.py +223 -0
  47. discord/resources/user.py +111 -0
  48. scurrypy-0.1.0.dist-info/METADATA +8 -0
  49. scurrypy-0.1.0.dist-info/RECORD +52 -0
  50. scurrypy-0.1.0.dist-info/WHEEL +5 -0
  51. scurrypy-0.1.0.dist-info/licenses/LICENSE +5 -0
  52. scurrypy-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,35 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+ from ..model import DataModel
4
+ from .emoji import EmojiModel
5
+
6
+ @dataclass
7
+ class ReadyGuildModel(DataModel):
8
+ """Guild info from Ready event."""
9
+ id: int
10
+ """ID of the associated guild."""
11
+
12
+ unavailable: bool
13
+ """If the guild is offline."""
14
+
15
+ @dataclass
16
+ class GuildModel(DataModel):
17
+ """Represents a Discord guild."""
18
+
19
+ id: int
20
+ """ID of the guild."""
21
+
22
+ name: str
23
+ """Name of the guild."""
24
+
25
+ icon: Optional[str] = None
26
+ """Icon hash of the guild."""
27
+
28
+ emojis: list[EmojiModel] = None
29
+ """List of emojis reigstered in the guild."""
30
+
31
+ approximate_member_count: Optional[int] = None
32
+ """Approximate member count."""
33
+
34
+ description: str = None
35
+ """Description of the guild."""
@@ -0,0 +1,23 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+ from ..model import DataModel
4
+ from .application import ApplicationModel
5
+
6
+ @dataclass
7
+ class IntegrationModel(DataModel):
8
+ """Represents a guild integration."""
9
+
10
+ id: int
11
+ """ID of the integration."""
12
+
13
+ name: str
14
+ """Name of the integration."""
15
+
16
+ type: str
17
+ """Type of integration (e.g., twitch, youtube, discord, or guild_subscription)."""
18
+
19
+ enabled: bool
20
+ """If the integration is enabled."""
21
+
22
+ application: Optional[ApplicationModel] = None
23
+ """The bot aaplication for Discord integrations."""
@@ -0,0 +1,27 @@
1
+ from dataclasses import dataclass
2
+ from ..model import DataModel
3
+ from ..models.user import UserModel
4
+
5
+ @dataclass
6
+ class MemberModel(DataModel):
7
+ """Represents a guild member."""
8
+
9
+ roles: list[int]
10
+ """List of roles registered to the guild member."""
11
+
12
+ user: UserModel
13
+ """User data associated with the guild member."""
14
+
15
+ nick: str
16
+ """Server nickname of the guild member."""
17
+
18
+ avatar: str
19
+ """Server avatar hash of the guild mmeber."""
20
+
21
+ joined_at: str
22
+ """ISO8601 timestamp of when the guild member joined server."""
23
+ deaf: bool
24
+ """If the member is deaf in a VC (input)."""
25
+
26
+ mute: bool
27
+ """If the member is muted in VC (output)."""
discord/models/role.py ADDED
@@ -0,0 +1,53 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+ from ..model import DataModel
4
+
5
+ @dataclass
6
+ class RoleColors(DataModel):
7
+ """Role color data."""
8
+
9
+ primary_color: int
10
+ """Primary color of the role."""
11
+
12
+ secondary_color: int
13
+ """Secondary color of the role. Creates a gradient."""
14
+
15
+ tertiary_color: int
16
+ """Tertiary color of the role. Creates a holographic style."""
17
+
18
+ @dataclass
19
+ class RoleModel(DataModel):
20
+ """Represents a Discord role."""
21
+
22
+ id: int
23
+ """ID of the role."""
24
+
25
+ name: str
26
+ """Name of the role."""
27
+
28
+ colors: RoleColors
29
+ """Colors of the role."""
30
+
31
+ hoist: bool
32
+ """If the role is pinned in user listing."""
33
+
34
+ position: int
35
+ """Position of the role."""
36
+
37
+ permissions: str
38
+ """Permission bit set."""
39
+
40
+ managed: bool
41
+ """If the role is managed by an integration."""
42
+
43
+ mentionable: bool
44
+ """If the role is mentionable."""
45
+
46
+ flags: int
47
+ """Role flags combined as a bitfield."""
48
+
49
+ icon: Optional[str] = None
50
+ """Icon hash of the role."""
51
+
52
+ unicode_emoji: Optional[str] = None
53
+ """Unicode emoji of the role."""
discord/models/user.py ADDED
@@ -0,0 +1,15 @@
1
+ from dataclasses import dataclass
2
+
3
+ from ..model import DataModel
4
+
5
+ @dataclass
6
+ class UserModel(DataModel):
7
+ """Describes the User object."""
8
+ id: int
9
+ """ID of the user."""
10
+
11
+ username: str
12
+ """Username of the user."""
13
+
14
+ avatar: str
15
+ """Avatar hash of the user."""
@@ -0,0 +1,28 @@
1
+ # discord/parts
2
+
3
+ from .channel import GuildChannel
4
+ from .role import Role
5
+ from .message import MessageBuilder
6
+ from .modal import ModalBuilder
7
+ from .embed import EmbedBuilder
8
+ from .action_row import (
9
+ ActionRow,
10
+ StringSelect,
11
+ UserSelect,
12
+ RoleSelect,
13
+ ChannelSelect,
14
+ MentionableSelect
15
+ )
16
+
17
+ from .command import (
18
+ SlashCommand,
19
+ MessageCommand,
20
+ UserCommand
21
+ )
22
+
23
+ from .components_v2 import (
24
+ Container,
25
+ Section,
26
+ MediaGalleryItem,
27
+ Label
28
+ )
@@ -0,0 +1,258 @@
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.emoji import EmojiModel
8
+
9
+ class _ButtonStyles:
10
+ """Represents button styles for a Button component."""
11
+ PRIMARY = 1
12
+ SECONDARY = 2
13
+ SUCCESS = 3
14
+ DANGER = 4
15
+ LINK = 5
16
+
17
+ @dataclass
18
+ class _Button(DataModel, ActionRowChild, SectionAccessory):
19
+ """Represents the Button component."""
20
+ style: int
21
+ custom_id: str
22
+ label: Optional[str] = None
23
+ emoji: EmojiModel = None
24
+ url: Optional[str] = None
25
+ disabled: Optional[bool] = False
26
+ type: Literal[2] = field(init=False, default=2)
27
+
28
+ @dataclass
29
+ class _SelectOption(DataModel):
30
+ """Represents the Select Option component"""
31
+
32
+ label: str
33
+ value: str
34
+ description: Optional[str] = None # appears below the label
35
+ emoji: Optional[EmojiModel] = None
36
+ default: Optional[bool] = False
37
+
38
+ @dataclass
39
+ class StringSelect(DataModel, ActionRowChild, LabelChild):
40
+ """Represents the String Select component."""
41
+ custom_id: str
42
+ options: list[_SelectOption] = field(default_factory=list)
43
+ placeholder: Optional[str] = None
44
+ min_values: Optional[int] = 0
45
+ max_values: Optional[int] = 1
46
+ required: Optional[bool] = False
47
+ disabled: Optional[bool] = False # does not work on Modals!
48
+ type: Literal[3] = field(init=False, default=3)
49
+
50
+ def add_option(self,
51
+ *,
52
+ label: str,
53
+ value: str,
54
+ description: str = None,
55
+ emoji: str | EmojiModel = None,
56
+ default: bool = False
57
+ ):
58
+ """Add an option to this string select component.
59
+
60
+ Args:
61
+ label (str): option text
62
+ value (str): analogous to button's custom ID
63
+ description (str, optional): option subtext
64
+ emoji (str | EmojiModel, optional): string if unicode emoji, EmojiModel if custom
65
+ default (bool, optional): if this option should be the default option. Defaults to False.
66
+
67
+ Returns:
68
+ (StringSelect): self
69
+ """
70
+ if isinstance(emoji, str):
71
+ emoji = EmojiModel(name=emoji)
72
+
73
+ self.options.append(
74
+ _SelectOption(
75
+ label=label,
76
+ value=value,
77
+ description=description,
78
+ emoji=emoji,
79
+ default=default
80
+ )
81
+ )
82
+ return self
83
+
84
+ @dataclass
85
+ class _DefaultValue(DataModel):
86
+ """Represents the Default Value for Select components."""
87
+
88
+ id: int # ID of role, user, or channel
89
+ type: Literal["role", "user", "channel"]
90
+
91
+ @dataclass
92
+ class UserSelect(DataModel, ActionRowChild):
93
+ """Represents the User Select component."""
94
+ custom_id: str
95
+ placeholder: Optional[str] = None
96
+ default_values: list[_DefaultValue] = field(default_factory=list)
97
+ min_values: Optional[int] = 0
98
+ max_values: Optional[int] = 1
99
+ disabled: Optional[bool] = False
100
+ type: Literal[5] = field(init=False, default=5)
101
+
102
+ def add_default_value(self, user_id: int):
103
+ self.default_values.append(_DefaultValue(user_id, 'user'))
104
+ return self
105
+
106
+ @dataclass
107
+ class RoleSelect(DataModel, ActionRowChild):
108
+ """Represents the Role Select component."""
109
+ custom_id: str
110
+ placeholder: Optional[str] = None
111
+ default_values: list[_DefaultValue] = field(default_factory=list)
112
+ min_values: Optional[int] = 0
113
+ max_values: Optional[int] = 1
114
+ disabled: Optional[bool] = False
115
+ type: Literal[6] = field(init=False, default=6)
116
+
117
+ def add_default_value(self, role_id: int):
118
+ self.default_values.append(_DefaultValue(role_id, 'role'))
119
+ return self
120
+
121
+ @dataclass
122
+ class MentionableSelect(DataModel, ActionRowChild):
123
+ """Represents the Mentionable Select component."""
124
+ custom_id: str
125
+ placeholder: Optional[str] = None
126
+ default_values: list[_DefaultValue] = field(default_factory=list)
127
+ min_values: Optional[int] = 0
128
+ max_values: Optional[int] = 1
129
+ disabled: Optional[bool] = False
130
+ type: Literal[7] = field(init=False, default=7)
131
+
132
+ def add_default_value(self, role_or_user_id: int, role_or_user: Literal['user', 'role']):
133
+ self.default_values.append(_DefaultValue(role_or_user_id, role_or_user))
134
+ return self
135
+
136
+ @dataclass
137
+ class ChannelSelect(DataModel, ActionRowChild):
138
+ """Represents the Channel Select component."""
139
+ custom_id: str
140
+ placeholder: Optional[str] = None
141
+ default_values: list[_DefaultValue] = field(default_factory=list)
142
+ min_values: Optional[int] = 0
143
+ max_values: Optional[int] = 1
144
+ disabled: Optional[bool] = False
145
+ type: Literal[8] = field(init=False, default=8)
146
+
147
+ def add_default_value(self, channel_id: int):
148
+ self.default_values.append(_DefaultValue(channel_id, 'channel'))
149
+ return self
150
+
151
+ @dataclass
152
+ class ActionRow(DataModel, ContainerChild):
153
+ """Represents a container of interactable components."""
154
+ type: Literal[1] = field(init=False, default=1)
155
+ components: list[ActionRowChild] = field(default_factory=list)
156
+
157
+ def add_button(self,
158
+ *,
159
+ style: Literal['Primary', 'Secondary', 'Success', 'Danger', 'Link'],
160
+ label: str,
161
+ custom_id: str,
162
+ emoji: str | EmojiModel = None,
163
+ disable: bool = False
164
+ ):
165
+ """Add a button to this action row. (5 per row)
166
+
167
+ Args:
168
+ style (Literal['Primary', 'Secondary', 'Success', 'Danger', 'Link']):
169
+ button style as a string
170
+ label (str): button text
171
+ custom_id (str): developer-defined button ID
172
+ emoji (str | EmojiModel, Optional): str if unicode emoji, EmojiModal if custom
173
+ disable (bool, Optional): if this button should be pressable. Defaults to False.
174
+
175
+ Returns:
176
+ (ActionRow): self
177
+ """
178
+ _styles = {
179
+ 'PRIMARY': _ButtonStyles.PRIMARY,
180
+ 'SECONDARY': _ButtonStyles.SECONDARY,
181
+ 'SUCCESS': _ButtonStyles.SUCCESS,
182
+ 'DANGER': _ButtonStyles.DANGER,
183
+ 'LINK': _ButtonStyles.LINK
184
+ }
185
+
186
+ if isinstance(emoji, str):
187
+ emoji = EmojiModel(name=emoji)
188
+
189
+ self.components.append(
190
+ _Button(
191
+ style=_styles.get(style.upper()),
192
+ label=label,
193
+ custom_id=custom_id,
194
+ emoji=emoji,
195
+ disabled=disable
196
+ )
197
+ )
198
+ return self
199
+
200
+ def string_select(self, select: StringSelect):
201
+ """Add a string select to this action row. (1 per row)
202
+
203
+ Args:
204
+ select (StringSelect): the StringSelect option object
205
+
206
+ Returns:
207
+ (ActionRow): self
208
+ """
209
+ self.components.append(select)
210
+ return self
211
+
212
+ def user_select(self, select: UserSelect):
213
+ """Add a user select to this action row. (1 per row)
214
+
215
+ Args:
216
+ select (UserSelect): the UserSelect option object
217
+
218
+ Returns:
219
+ (ActionRow): self
220
+ """
221
+ self.components.append(select)
222
+ return self
223
+
224
+ def role_select(self, select: RoleSelect):
225
+ """Add a role select to this action row. (1 per row)
226
+
227
+ Args:
228
+ select (RoleSelect): the RoleSelect option object
229
+
230
+ Returns:
231
+ (ActionRow): self
232
+ """
233
+ self.components.append(select)
234
+ return self
235
+
236
+ def channel_select(self, select: ChannelSelect):
237
+ """Add a channel select to this action row. (1 per row)
238
+
239
+ Args:
240
+ select (ChannelSelect): the ChannelSelect option object
241
+
242
+ Returns:
243
+ (ActionRow): self
244
+ """
245
+ self.components.append(select)
246
+ return self
247
+
248
+ def mentionable_select(self, select: MentionableSelect):
249
+ """Add a mentionable select to this action row. (1 per row)
250
+
251
+ Args:
252
+ select (MentionableSelect): the MentionableSelect option object
253
+
254
+ Returns:
255
+ (ActionRow): self
256
+ """
257
+ self.components.append(select)
258
+ return self
@@ -0,0 +1,18 @@
1
+ from dataclasses import dataclass
2
+
3
+ from ..model import DataModel
4
+
5
+ @dataclass
6
+ class _Attachment(DataModel):
7
+ """Represents an attachment."""
8
+ id: int
9
+ path: str
10
+ filename: str
11
+ description: str
12
+
13
+ def _to_dict(self):
14
+ return {
15
+ 'id': self.id,
16
+ 'filename': self.filename,
17
+ 'description': self.description
18
+ }
@@ -0,0 +1,20 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+ from ..model import DataModel
4
+
5
+ # NOTE: Supported Channel Types listed here
6
+ class ChannelTypes:
7
+ """Constants for channel types."""
8
+ GUILD_TEXT = 0
9
+ GUILD_CATEGORY = 4
10
+ GUILD_ANNOUNCEMENT = 5
11
+
12
+ @dataclass
13
+ class GuildChannel(DataModel):
14
+ """Parameters for creating/editing a guild channel."""
15
+ name: Optional[str] = None
16
+ type: Optional[int] = None
17
+ topic: Optional[str] = None
18
+ position: Optional[int] = None
19
+ parent_id: Optional[int] = None
20
+ nsfw: Optional[bool] = None
@@ -0,0 +1,102 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Literal
3
+
4
+ from ..model import DataModel
5
+
6
+ class CommandOptionTypes:
7
+ """Slash command option input types."""
8
+
9
+ STRING = 3
10
+ """string (text)"""
11
+
12
+ INTEGER = 4
13
+ """integer (whole)"""
14
+
15
+ BOOLEAN = 5
16
+ """boolean (true/false)"""
17
+
18
+ USER = 6
19
+ """user pangination"""
20
+
21
+ CHANNEL = 7
22
+ """channel pangination"""
23
+
24
+ ROLE = 8
25
+ """role pangination"""
26
+
27
+ MENTIONABLE = 9
28
+ """any pangination (role, channel, user)"""
29
+
30
+ NUMBER = 10
31
+ """number (float, integer)"""
32
+
33
+ ATTACHMENT = 11
34
+ """file upload"""
35
+
36
+ @dataclass
37
+ class MessageCommand(DataModel):
38
+ """Represents the message command object."""
39
+ type: Literal[3] = field(init=False, default=3) # MESSAGE
40
+ name: str
41
+
42
+ @dataclass
43
+ class UserCommand(DataModel):
44
+ """Represents the user command object"""
45
+ type: Literal[2] = field(init=False, default=2) # USER
46
+ name: str
47
+
48
+ @dataclass
49
+ class _CommandOption(DataModel):
50
+ """Option for a slash command."""
51
+ type: int # refer to CommandOptionTypes
52
+ name: str
53
+ description: str
54
+ required: bool = True
55
+
56
+ @dataclass
57
+ class SlashCommand(DataModel):
58
+ type: Literal[1] = field(init=False, default=1) # CHAT_INPUT
59
+ name: str
60
+ description: str
61
+ options: list[_CommandOption] = field(default_factory=list)
62
+
63
+ def add_option(
64
+ self,
65
+ command_type: Literal['String', 'Integer', 'Boolean', 'User', 'Channel', 'Role', 'Mentionable', 'Number', 'Attachment'],
66
+ name: str,
67
+ description: str,
68
+ required: bool = False
69
+ ):
70
+ """Add an option to this slash command.
71
+
72
+ Args:
73
+ command_type (Literal['String', 'Integer', 'Boolean', 'User', 'Channel', 'Role', 'Mentionable', 'Number', 'Attachment']):
74
+ input type for the option
75
+ name (str): name of the option
76
+ description (str): description for the option
77
+ required (bool, optional): if the option is required. Defaults to False.
78
+
79
+ Returns:
80
+ (SlashCommand): self
81
+ """
82
+ _command_types = {
83
+ 'STRING': CommandOptionTypes.STRING,
84
+ 'INTEGER': CommandOptionTypes.INTEGER,
85
+ 'BOOLEAN': CommandOptionTypes.BOOLEAN,
86
+ 'USER': CommandOptionTypes.BOOLEAN,
87
+ 'CHANNEL': CommandOptionTypes.CHANNEL,
88
+ 'ROLE': CommandOptionTypes.ROLE,
89
+ 'MENTIONABLE': CommandOptionTypes.MENTIONABLE,
90
+ 'NUMBER': CommandOptionTypes.NUMBER,
91
+ 'ATTACHMENT': CommandOptionTypes.ATTACHMENT
92
+ }
93
+
94
+ self.options.append(
95
+ _CommandOption(
96
+ type=_command_types.get(command_type.upper()),
97
+ name=name,
98
+ description=description,
99
+ required=required
100
+ )
101
+ )
102
+ return self
@@ -0,0 +1,5 @@
1
+ class ActionRowChild: ...
2
+ class SectionChild: ...
3
+ class SectionAccessory: ...
4
+ class ContainerChild: ...
5
+ class LabelChild: ...