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.
Files changed (72) hide show
  1. scurrypy/__init__.py +429 -0
  2. scurrypy/client.py +335 -0
  3. {discord → scurrypy}/client_like.py +8 -1
  4. scurrypy/dispatch/command_dispatcher.py +205 -0
  5. {discord → scurrypy}/dispatch/event_dispatcher.py +21 -21
  6. {discord → scurrypy}/dispatch/prefix_dispatcher.py +31 -12
  7. {discord → scurrypy}/error.py +6 -18
  8. {discord → scurrypy}/events/channel_events.py +2 -1
  9. scurrypy/events/gateway_events.py +31 -0
  10. {discord → scurrypy}/events/guild_events.py +2 -1
  11. {discord → scurrypy}/events/interaction_events.py +28 -13
  12. {discord → scurrypy}/events/message_events.py +8 -5
  13. {discord → scurrypy}/events/reaction_events.py +1 -2
  14. {discord → scurrypy}/events/ready_event.py +1 -3
  15. scurrypy/gateway.py +183 -0
  16. scurrypy/http.py +310 -0
  17. {discord → scurrypy}/intents.py +5 -7
  18. {discord → scurrypy}/logger.py +14 -61
  19. scurrypy/model.py +71 -0
  20. scurrypy/models.py +258 -0
  21. scurrypy/parts/channel.py +42 -0
  22. scurrypy/parts/command.py +90 -0
  23. scurrypy/parts/components.py +224 -0
  24. scurrypy/parts/components_v2.py +144 -0
  25. scurrypy/parts/embed.py +83 -0
  26. scurrypy/parts/message.py +134 -0
  27. scurrypy/parts/modal.py +16 -0
  28. {discord → scurrypy}/parts/role.py +2 -14
  29. {discord → scurrypy}/resources/application.py +1 -2
  30. {discord → scurrypy}/resources/bot_emojis.py +1 -1
  31. {discord → scurrypy}/resources/channel.py +9 -8
  32. {discord → scurrypy}/resources/guild.py +14 -16
  33. {discord → scurrypy}/resources/interaction.py +50 -43
  34. {discord → scurrypy}/resources/message.py +15 -16
  35. {discord → scurrypy}/resources/user.py +3 -4
  36. scurrypy-0.6.6.dist-info/METADATA +108 -0
  37. scurrypy-0.6.6.dist-info/RECORD +47 -0
  38. {scurrypy-0.4.dist-info → scurrypy-0.6.6.dist-info}/licenses/LICENSE +1 -1
  39. scurrypy-0.6.6.dist-info/top_level.txt +1 -0
  40. discord/__init__.py +0 -223
  41. discord/client.py +0 -375
  42. discord/dispatch/command_dispatcher.py +0 -163
  43. discord/gateway.py +0 -155
  44. discord/http.py +0 -280
  45. discord/model.py +0 -90
  46. discord/models/__init__.py +0 -1
  47. discord/models/application.py +0 -37
  48. discord/models/emoji.py +0 -34
  49. discord/models/guild.py +0 -35
  50. discord/models/integration.py +0 -23
  51. discord/models/interaction.py +0 -26
  52. discord/models/member.py +0 -27
  53. discord/models/role.py +0 -53
  54. discord/models/user.py +0 -15
  55. discord/parts/action_row.py +0 -208
  56. discord/parts/channel.py +0 -20
  57. discord/parts/command.py +0 -102
  58. discord/parts/components_v2.py +0 -353
  59. discord/parts/embed.py +0 -154
  60. discord/parts/message.py +0 -194
  61. discord/parts/modal.py +0 -21
  62. scurrypy-0.4.dist-info/METADATA +0 -130
  63. scurrypy-0.4.dist-info/RECORD +0 -54
  64. scurrypy-0.4.dist-info/top_level.txt +0 -1
  65. {discord → scurrypy}/config.py +0 -0
  66. {discord → scurrypy}/dispatch/__init__.py +0 -0
  67. {discord → scurrypy}/events/__init__.py +0 -0
  68. {discord → scurrypy}/events/hello_event.py +0 -0
  69. {discord → scurrypy}/parts/__init__.py +0 -0
  70. {discord → scurrypy}/parts/component_types.py +0 -0
  71. {discord → scurrypy}/resources/__init__.py +0 -0
  72. {scurrypy-0.4.dist-info → scurrypy-0.6.6.dist-info}/WHEEL +0 -0
@@ -1,208 +0,0 @@
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
- label: str
32
- value: str
33
- description: Optional[str] = None # appears below the label
34
- emoji: Optional[EmojiModel] = None
35
- default: Optional[bool] = False
36
-
37
- @dataclass
38
- class StringSelect(DataModel, ActionRowChild, LabelChild):
39
- """Represents the String Select component."""
40
- custom_id: str
41
- options: list[_SelectOption] = field(default_factory=list)
42
- placeholder: Optional[str] = None
43
- min_values: Optional[int] = 0
44
- max_values: Optional[int] = 1
45
- required: Optional[bool] = False
46
- disabled: Optional[bool] = False # does not work on Modals!
47
- type: Literal[3] = field(init=False, default=3)
48
-
49
- def add_option(self,
50
- *,
51
- label: str,
52
- value: str,
53
- description: str = None,
54
- emoji: str | EmojiModel = None,
55
- default: bool = False
56
- ):
57
- """Add an option to this string select component.
58
-
59
- Args:
60
- label (str): option text
61
- value (str): analogous to button's custom ID
62
- description (str, optional): option subtext
63
- emoji (str | EmojiModel, optional): string if unicode emoji, EmojiModel if custom
64
- default (bool, optional): if this option should be the default option. Defaults to False.
65
-
66
- Returns:
67
- (StringSelect): self
68
- """
69
- if isinstance(emoji, str):
70
- emoji = EmojiModel(name=emoji)
71
-
72
- self.options.append(
73
- _SelectOption(
74
- label=label,
75
- value=value,
76
- description=description,
77
- emoji=emoji,
78
- default=default
79
- )
80
- )
81
- return self
82
-
83
- @dataclass
84
- class _DefaultValue(DataModel):
85
- """Represents the Default Value for Select components."""
86
- id: int # ID of role, user, or channel
87
- type: Literal["role", "user", "channel"]
88
-
89
- @dataclass
90
- class UserSelect(DataModel, ActionRowChild, LabelChild):
91
- """Represents the User Select component."""
92
- custom_id: str
93
- placeholder: Optional[str] = None
94
- default_values: list[_DefaultValue] = field(default_factory=list)
95
- min_values: Optional[int] = 0
96
- max_values: Optional[int] = 1
97
- disabled: Optional[bool] = False
98
- type: Literal[5] = field(init=False, default=5)
99
-
100
- def add_default_value(self, user_id: int):
101
- self.default_values.append(_DefaultValue(user_id, 'user'))
102
- return self
103
-
104
- @dataclass
105
- class RoleSelect(DataModel, ActionRowChild, LabelChild):
106
- """Represents the Role Select component."""
107
- custom_id: str
108
- placeholder: Optional[str] = None
109
- default_values: list[_DefaultValue] = field(default_factory=list)
110
- min_values: Optional[int] = 0
111
- max_values: Optional[int] = 1
112
- disabled: Optional[bool] = False
113
- type: Literal[6] = field(init=False, default=6)
114
-
115
- def add_default_value(self, role_id: int):
116
- self.default_values.append(_DefaultValue(role_id, 'role'))
117
- return self
118
-
119
- @dataclass
120
- class MentionableSelect(DataModel, ActionRowChild, LabelChild):
121
- """Represents the Mentionable Select component."""
122
- custom_id: str
123
- placeholder: Optional[str] = None
124
- default_values: list[_DefaultValue] = field(default_factory=list)
125
- min_values: Optional[int] = 0
126
- max_values: Optional[int] = 1
127
- disabled: Optional[bool] = False
128
- type: Literal[7] = field(init=False, default=7)
129
-
130
- def add_default_value(self, role_or_user_id: int, role_or_user: Literal['user', 'role']):
131
- self.default_values.append(_DefaultValue(role_or_user_id, role_or_user))
132
- return self
133
-
134
- @dataclass
135
- class ChannelSelect(DataModel, ActionRowChild, LabelChild):
136
- """Represents the Channel Select component."""
137
- custom_id: str
138
- placeholder: Optional[str] = None
139
- default_values: list[_DefaultValue] = field(default_factory=list)
140
- min_values: Optional[int] = 0
141
- max_values: Optional[int] = 1
142
- disabled: Optional[bool] = False
143
- type: Literal[8] = field(init=False, default=8)
144
-
145
- def add_default_value(self, channel_id: int):
146
- self.default_values.append(_DefaultValue(channel_id, 'channel'))
147
- return self
148
-
149
- @dataclass
150
- class ActionRow(DataModel, ContainerChild):
151
- """Represents a container of interactable components."""
152
- type: Literal[1] = field(init=False, default=1)
153
- components: list[ActionRowChild] = field(default_factory=list)
154
-
155
- def add_button(self,
156
- *,
157
- style: Literal['Primary', 'Secondary', 'Success', 'Danger', 'Link'],
158
- label: str,
159
- custom_id: str,
160
- emoji: str | EmojiModel = None,
161
- disable: bool = False
162
- ):
163
- """Add a button to this action row. (5 per row)
164
-
165
- Args:
166
- style (Literal['Primary', 'Secondary', 'Success', 'Danger', 'Link']):
167
- button style as a string
168
- label (str): button text
169
- custom_id (str): developer-defined button ID
170
- emoji (str | EmojiModel, Optional): str if unicode emoji, EmojiModal if custom
171
- disable (bool, Optional): if this button should be pressable. Defaults to False.
172
-
173
- Returns:
174
- (ActionRow): self
175
- """
176
- _styles = {
177
- 'PRIMARY': _ButtonStyles.PRIMARY,
178
- 'SECONDARY': _ButtonStyles.SECONDARY,
179
- 'SUCCESS': _ButtonStyles.SUCCESS,
180
- 'DANGER': _ButtonStyles.DANGER,
181
- 'LINK': _ButtonStyles.LINK
182
- }
183
-
184
- if isinstance(emoji, str):
185
- emoji = EmojiModel(name=emoji)
186
-
187
- self.components.append(
188
- _Button(
189
- style=_styles.get(style.upper()),
190
- label=label,
191
- custom_id=custom_id,
192
- emoji=emoji,
193
- disabled=disable
194
- )
195
- )
196
- return self
197
-
198
- def set_select_menu(self, select: StringSelect | UserSelect | RoleSelect | ChannelSelect | MentionableSelect):
199
- """Add a select menu component to this action row. (1 per row)
200
-
201
- Args:
202
- select (StringSelect | UserSelect | RoleSelect | ChannelSelect | MentionableSelect): the select menu component
203
-
204
- Returns:
205
- (ActionRow): self
206
- """
207
- self.components.append(select)
208
- return self
discord/parts/channel.py DELETED
@@ -1,20 +0,0 @@
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
discord/parts/command.py DELETED
@@ -1,102 +0,0 @@
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
@@ -1,353 +0,0 @@
1
- from dataclasses import dataclass, field
2
- from typing import Literal, Optional
3
- from ..model import DataModel
4
-
5
- from .component_types import *
6
- from ..models.emoji import EmojiModel
7
-
8
- from .action_row import (
9
- StringSelect,
10
- ActionRow,
11
- ChannelSelect,
12
- MentionableSelect,
13
- RoleSelect,
14
- UserSelect,
15
- _Button,
16
- _ButtonStyles
17
- )
18
-
19
- class _TextInputStyles:
20
- """Represents the types of Text Inputs."""
21
- SHORT = 1 # one line
22
- PARAGRAPH = 2 # multiple lines
23
-
24
- @dataclass
25
- class _TextInput(DataModel, LabelChild):
26
- """Represents the Text Input component."""
27
- type: Literal[4] = field(init=False, default=4)
28
- style: _TextInputStyles = _TextInputStyles.SHORT # refer to _TextInputStyles for details
29
- custom_id: str = None
30
- required: Optional[bool] = False
31
- min_length: Optional[int] = None
32
- max_length: Optional[int] = None
33
- value: Optional[str] = None
34
- placeholder: Optional[str] = None
35
-
36
- @dataclass
37
- class Section(DataModel, ContainerChild):
38
- """Represents the Section component."""
39
- type: Literal[9] = field(init=False, default=9)
40
-
41
- accessory: Optional[SectionAccessory] = None
42
- """A component that is contextually associated to the content of the section."""
43
-
44
- components: list[SectionChild] = field(default_factory=list)
45
- """Component(s) representing the content of the section that is contextually associated to the accessory"""
46
-
47
- def set_thumbnail(self, media: str, description: str = None, has_spoiler: bool = False):
48
- """Set the thumbnail for this section.
49
-
50
- Args:
51
- media (str): Image data. http or attachment://<filename> scheme.
52
- description (str, optional): Alt text for the media
53
- has_spoiler (bool, optional): If the media should be blurred out. Defaults to False.
54
-
55
- Returns:
56
- (Section): self
57
- """
58
- self.accessory = _Thumbnail(media, description, has_spoiler)
59
- return self
60
-
61
- def add_text_display(self, content: str):
62
- """Add a text display to this section.
63
-
64
- Args:
65
- content (str): the content to display
66
-
67
- Returns:
68
- (Section): self
69
- """
70
- self.components.append(_TextDisplay(content))
71
- return self
72
-
73
- def set_button(self,
74
- *,
75
- style: Literal['Primary', 'Secondary', 'Success', 'Danger', 'Link'],
76
- label: str,
77
- custom_id: str,
78
- emoji: str | EmojiModel = None,
79
- disable: bool = False
80
- ):
81
- """Set this section's accessory as a button.
82
-
83
- Args:
84
- style (Literal['Primary', 'Secondary', 'Success', 'Danger', 'Link']):
85
- button style as a string
86
- label (str): button text
87
- custom_id (str): developer-defined button ID
88
- emoji (str | EmojiModel, Optional): str if unicode emoji, EmojiModal if custom
89
- disable (bool, Optional): if this button should be pressable. Defaults to False.
90
-
91
- Returns:
92
- (Section): self
93
- """
94
- _styles = {
95
- 'PRIMARY': _ButtonStyles.PRIMARY,
96
- 'SECONDARY': _ButtonStyles.SECONDARY,
97
- 'SUCCESS': _ButtonStyles.SUCCESS,
98
- 'DANGER': _ButtonStyles.DANGER,
99
- 'LINK': _ButtonStyles.LINK
100
- }
101
-
102
- if isinstance(emoji, str):
103
- emoji = EmojiModel(name=emoji)
104
-
105
- self.accessory = _Button(
106
- style=_styles.get(style.upper()),
107
- label=label,
108
- custom_id=custom_id,
109
- emoji=emoji,
110
- disabled=disable
111
- )
112
- return self
113
-
114
- @dataclass
115
- class _TextDisplay(DataModel, ContainerChild, SectionChild):
116
- """Represents the Text Display component."""
117
- type: Literal[10] = field(init=False, default=10)
118
- content: str
119
-
120
-
121
- @dataclass
122
- class _Thumbnail(DataModel, SectionAccessory):
123
- """Represents the _Thumbnail component."""
124
- type: Literal[11] = field(init=False, default=11)
125
- media: str # http or attachment://<filename>
126
- description: Optional[str] = None
127
- spoiler: Optional[bool] = False
128
-
129
-
130
- @dataclass
131
- class MediaGalleryItem(DataModel):
132
- """Represents the Media Gallery Item component."""
133
-
134
- media: str
135
- """Image data. http or attachment://<filename> scheme."""
136
-
137
- description: Optional[str] = None
138
- """Alt text for the media."""
139
-
140
- spoiler: Optional[bool] = False
141
- """If the media should be blurred out."""
142
-
143
- @dataclass
144
- class _MediaGallery(DataModel, ContainerChild):
145
- """Represents the Media Gallery component."""
146
- type: Literal[12] = field(init=False, default=12)
147
- items: list[MediaGalleryItem] = field(default_factory=list)
148
-
149
-
150
- @dataclass
151
- class _File(DataModel, ContainerChild):
152
- """Represents the File component."""
153
- type: Literal[13] = field(init=False, default=13)
154
- file: str # http or attachment://<filename>
155
- spoiler: Optional[bool] = False
156
-
157
- class _SeparatorTypes:
158
- """Represents separator types constants."""
159
- SMALL_PADDING = 1
160
- LARGE_PADDING = 2
161
-
162
- @dataclass
163
- class _Separator(DataModel, ContainerChild):
164
- """Represents the Separator component."""
165
- type: Literal[14] = field(init=False, default=14)
166
- divider: bool = True
167
- spacing: Optional[int] = _SeparatorTypes.SMALL_PADDING # refer to _SeparatorTypes
168
-
169
- @dataclass
170
- class Label(DataModel):
171
- """Represents the Discord Label component."""
172
-
173
- label: str
174
- """Label text."""
175
-
176
- component: LabelChild = None
177
- """A component within the label."""
178
-
179
- description: Optional[str] = None
180
- """An optional description text for the label."""
181
-
182
- type: Literal[18] = field(init=False, default=18)
183
-
184
- def set_select_menu(self, select: StringSelect | UserSelect | RoleSelect | ChannelSelect | MentionableSelect):
185
- """Set this label to be a select menu component.
186
-
187
- Args:
188
- select (StringSelect | UserSelect | RoleSelect | ChannelSelect | MentionableSelect): the select menu component
189
-
190
- Returns:
191
- (Label): self
192
- """
193
- self.component = select
194
- return self
195
-
196
- def set_text_input(self,
197
- *,
198
- custom_id: str,
199
- min_length: int,
200
- max_length: int,
201
- value: str = None,
202
- style: Literal['Short', 'Paragraph'] = 'Short',
203
- placeholder: str = None,
204
- require: bool = False
205
- ):
206
- """Set this label to be a text input component.
207
-
208
- Args:
209
- custom_id (str): developer-defined component ID
210
- min_length (int): minimum number of characters required
211
- max_length (int): maximum number of characters required
212
- value (str, optional): component value
213
- style (Literal['Short', 'Paragraph'], optional):
214
- text format. Defaults to 'Short'.
215
- placeholder (str, optional): custom placeholder text if empty
216
- require (bool, optional): if input is required. Defaults to False.
217
-
218
- Returns:
219
- (Label): self
220
- """
221
- _styles = {
222
- 'SHORT': _TextInputStyles.SHORT,
223
- 'PARAGRAPH': _TextInputStyles.PARAGRAPH
224
- }
225
-
226
- self.component = _TextInput(
227
- style = _styles.get(style.upper()),
228
- placeholder=placeholder,
229
- custom_id=custom_id,
230
- min_length=min_length,
231
- max_length=max_length,
232
- value=value,
233
- required=require
234
- )
235
- return self
236
-
237
- @dataclass
238
- class Container(DataModel):
239
- """Represents a container of display and interactable components."""
240
- type: Literal[17] = field(init=False, default=17)
241
-
242
- components: list[ContainerChild] = field(default_factory=list)
243
- """Child components that are encapsulated within the Container."""
244
-
245
- accent_color: Optional[int] = None
246
- """Color for the accent as an integer."""
247
-
248
- spoiler: Optional[bool] = False
249
- """If the container should be blurred out."""
250
-
251
- def set_color(self, hex: str):
252
- """Set this container's color with a hex. (format: #FFFFFF)
253
-
254
- Args:
255
- hex (str): color as a hex code
256
-
257
- Returns:
258
- (Container): self
259
- """
260
- self.accent_color = int(hex.strip('#'), 16)
261
- return self
262
-
263
- def add_row(self, row: ActionRow):
264
- """Add an action row to this container.
265
-
266
- Args:
267
- row (ActionRow): the ActionRow object
268
-
269
- Returns:
270
- (Container): self
271
- """
272
- self.components.append(row)
273
- return self
274
-
275
- def add_section(self, section: Section):
276
- """Add a section to this container.
277
-
278
- Args:
279
- section (Section): the Section object
280
-
281
- Returns:
282
- (Container): self
283
- """
284
- self.components.append(section)
285
- return self
286
-
287
- def add_text_display(self, content: str):
288
- """Add a text display to this container.
289
-
290
- Args:
291
- content (str): the content to display
292
-
293
- Returns:
294
- (Container): self
295
- """
296
- self.components.append(_TextDisplay(content))
297
- return self
298
-
299
- def set_thumbnail(self, media: str, description: str = None, has_spoiler: bool = False):
300
- """Set the thumbnail for this container
301
-
302
- Args:
303
- media (str): Image data. http or attachment://<filename> scheme.
304
- description (str, optional): Alt text for the media
305
- has_spoiler (bool, optional): If the media should be blurred out. Defaults to False.
306
-
307
- Returns:
308
- (Container): self
309
- """
310
- self.components.append(_Thumbnail(media, description, has_spoiler))
311
- return self
312
-
313
- def set_media_gallery(self, items: list[MediaGalleryItem]):
314
- """Add a media gallery to this container.
315
-
316
- Args:
317
- items (list[MediaGalleryItem]): list of media gallery images
318
-
319
- Returns:
320
- (Container): self
321
- """
322
- self.components.append(_MediaGallery(items))
323
- return self
324
-
325
- def add_attachment(self, file: str, has_spoiler: bool = False):
326
- """Add a single attachment to this container.
327
-
328
- Args:
329
- file (str): Image data. http or attachment://<filename> scheme
330
- has_spoiler (bool, optional): If the media should be blurred out. Defaults to False.
331
-
332
- Returns:
333
- (Container): self
334
- """
335
- self.components.append(_File(file, has_spoiler))
336
- return self
337
-
338
- def add_separator(self, spacing: Literal['Small', 'Large'] = 'Small', has_divider: bool = True):
339
- """Add a separator to this container. Positionally accurate.
340
-
341
- Args:
342
- spacing (Literal['Small', 'Large'], optional): size of separator padding. Defaults to 'Small'.
343
- has_divider (bool, optional): if a visual divider should be shown. Defaults to True.
344
-
345
- Returns:
346
- (Container): self
347
- """
348
- _spacing_types = {
349
- 'SMALL': _SeparatorTypes.SMALL_PADDING,
350
- 'LARGE': _SeparatorTypes.LARGE_PADDING
351
- }
352
- self.components.append(_Separator(divider=has_divider, spacing=_spacing_types.get(spacing.upper())))
353
- return self