scurrypy 0.4.2__py3-none-any.whl → 0.5__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.

@@ -1,131 +1,57 @@
1
1
  from dataclasses import dataclass, field
2
- from typing import Literal, Optional
2
+ from typing import Optional
3
3
  from ..model import DataModel
4
4
 
5
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
6
 
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
7
+ class ComponentV2Types:
8
+ SECTION = 9
9
+ TEXT_DISPLAY = 10
10
+ THUMBNAIL = 11
11
+ MEDIA_GALLERY = 12
12
+ FILE = 13
13
+ SEPARATOR = 14
14
+ CONTAINER = 17
15
+ LABEL = 18
35
16
 
36
17
  @dataclass
37
- class Section(DataModel, ContainerChild):
18
+ class SectionPart(DataModel, ContainerChild):
38
19
  """Represents the Section component."""
39
- type: Literal[9] = field(init=False, default=9)
40
20
 
41
21
  accessory: Optional[SectionAccessory] = None
42
22
  """A component that is contextually associated to the content of the section."""
43
23
 
44
24
  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
25
+ """Component(s) representing the content of the section that is contextually associated to the accessory."""
26
+
27
+ type: int = field(init=False, default=ComponentV2Types.SECTION)
28
+ """Component type. Always `ComponentV2Types.SECTION` for this class. See [`ComponentV2Types`][discord.parts.components_v2.ComponentV2Types]."""
113
29
 
114
30
  @dataclass
115
- class _TextDisplay(DataModel, ContainerChild, SectionChild):
31
+ class TextDisplay(DataModel, ContainerChild, SectionChild):
116
32
  """Represents the Text Display component."""
117
- type: Literal[10] = field(init=False, default=10)
33
+
118
34
  content: str
35
+ """Text that will be displayed similar to a message."""
119
36
 
37
+ type: int = field(init=False, default=ComponentV2Types.TEXT_DISPLAY)
38
+ """Component type. Always `ComponentV2Types.TEXT_DISPLAY` for this class. See [`ComponentV2Types`][discord.parts.components_v2.ComponentV2Types]."""
120
39
 
121
40
  @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>
41
+ class Thumbnail(DataModel, SectionAccessory):
42
+ """Represents the Thumbnail component."""
43
+
44
+ media: str
45
+ """Media of the thumbnail. http or attachment://<filename> scheme."""
46
+
126
47
  description: Optional[str] = None
48
+ """Description for the media."""
49
+
127
50
  spoiler: Optional[bool] = False
51
+ """Whether the thumbnail should be a spoiler (or blurred out)."""
128
52
 
53
+ type: int = field(init=False, default=ComponentV2Types.THUMBNAIL)
54
+ """Component type. Always `ComponentV2Types.THUMBNAIL` for this class. See [`ComponentV2Types`][discord.parts.components_v2.ComponentV2Types]."""
129
55
 
130
56
  @dataclass
131
57
  class MediaGalleryItem(DataModel):
@@ -138,106 +64,56 @@ class MediaGalleryItem(DataModel):
138
64
  """Alt text for the media."""
139
65
 
140
66
  spoiler: Optional[bool] = False
141
- """If the media should be blurred out."""
67
+ """Whether the thumbnail should be a spoiler (or blurred out)."""
142
68
 
143
69
  @dataclass
144
- class _MediaGallery(DataModel, ContainerChild):
70
+ class MediaGallery(DataModel, ContainerChild):
145
71
  """Represents the Media Gallery component."""
146
- type: Literal[12] = field(init=False, default=12)
72
+
147
73
  items: list[MediaGalleryItem] = field(default_factory=list)
74
+ """1 to 10 nedia gallery items. See [`MediaGalleryItem`][discord.parts.components_v2.MediaGalleryItem]."""
148
75
 
76
+ type: int = field(init=False, default=ComponentV2Types.MEDIA_GALLERY)
77
+ """Component type. Always `ComponentV2Types.MEDIA_GALLERY` for this class. See [`ComponentV2Types`][discord.parts.components_v2.ComponentV2Types]."""
149
78
 
150
79
  @dataclass
151
- class _File(DataModel, ContainerChild):
80
+ class File(DataModel, ContainerChild):
152
81
  """Represents the File component."""
153
- type: Literal[13] = field(init=False, default=13)
154
- file: str # http or attachment://<filename>
82
+
83
+ file: str
84
+ """File name. ONLY supports attachment://<filename> scheme."""
85
+
155
86
  spoiler: Optional[bool] = False
87
+ """Whether the thumbnail should be a spoiler (or blurred out)."""
88
+
89
+ type: int = field(init=False, default=ComponentV2Types.FILE)
90
+ """Component type. Always `ComponentV2Types.File` for this class. See [`ComponentV2Types`][discord.parts.components_v2.ComponentV2Types]."""
156
91
 
157
- class _SeparatorTypes:
92
+ class SeparatorTypes:
158
93
  """Represents separator types constants."""
94
+
159
95
  SMALL_PADDING = 1
96
+ """Small separator padding."""
97
+
160
98
  LARGE_PADDING = 2
99
+ """Large separator padding."""
161
100
 
162
101
  @dataclass
163
- class _Separator(DataModel, ContainerChild):
102
+ class Separator(DataModel, ContainerChild):
164
103
  """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
104
 
173
- label: str
174
- """Label text."""
175
-
176
- component: LabelChild = None
177
- """A component within the label."""
105
+ divider: bool = True
106
+ """Whether a visual divider should be displayed in the component. Defaults to True."""
178
107
 
179
- description: Optional[str] = None
180
- """An optional description text for the label."""
108
+ spacing: Optional[int] = SeparatorTypes.SMALL_PADDING
109
+ """Size of separator padding. Defaults to `SMALL_PADDING`. See [`SeparatorTypes`][discord.parts.components_v2.SeparatorTypes]."""
181
110
 
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
111
+ type: int = field(init=False, default=ComponentV2Types.SEPARATOR)
112
+ """Component type. Always `ComponentV2Types.SEPARATOR` for this class. See [`ComponentV2Types`][discord.parts.components_v2.ComponentV2Types]."""
236
113
 
237
114
  @dataclass
238
- class Container(DataModel):
115
+ class ContainerPart(DataModel):
239
116
  """Represents a container of display and interactable components."""
240
- type: Literal[17] = field(init=False, default=17)
241
117
 
242
118
  components: list[ContainerChild] = field(default_factory=list)
243
119
  """Child components that are encapsulated within the Container."""
@@ -246,108 +122,23 @@ class Container(DataModel):
246
122
  """Color for the accent as an integer."""
247
123
 
248
124
  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.
125
+ """If the container should be blurred out. Defaults to False."""
315
126
 
316
- Args:
317
- items (list[MediaGalleryItem]): list of media gallery images
127
+ type: int = field(init=False, default=ComponentV2Types.CONTAINER)
128
+ """Component type. Always `ComponentV2Types.CONTAINER` for this class. See [`ComponentV2Types`][discord.parts.components_v2.ComponentV2Types]."""
318
129
 
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
130
+ @dataclass
131
+ class Label(DataModel):
132
+ """Represents the Discord Label component."""
133
+
134
+ label: str
135
+ """Label text."""
136
+
137
+ component: LabelChild = None
138
+ """A component within the label."""
139
+
140
+ description: Optional[str] = None
141
+ """An optional description text for the label."""
142
+
143
+ type: int = field(init=False, default=ComponentV2Types.LABEL)
144
+ """Component type. Always `ComponentV2Types.LABEL` for this class. See [`ComponentV2Types`][discord.parts.components_v2.ComponentV2Types]."""
discord/parts/embed.py CHANGED
@@ -1,42 +1,58 @@
1
- from dataclasses import dataclass
1
+ from dataclasses import dataclass, field
2
2
  from typing import Optional
3
- from discord.model import DataModel
4
- from datetime import datetime, timezone
5
- from ..models.user import UserModel
3
+ from ..model import DataModel
6
4
 
7
5
  @dataclass
8
- class _EmbedAuthor(DataModel):
6
+ class EmbedAuthor(DataModel):
9
7
  """Embed author parameters."""
8
+
10
9
  name: str
10
+ """Name of the author."""
11
+
11
12
  url: Optional[str] = None
13
+ """URL of the author. http or attachment://<filename> scheme."""
14
+
12
15
  icon_url: Optional[str] = None
16
+ """URL of author's icon. http or attachment://<filename> scheme."""
13
17
 
14
18
  @dataclass
15
- class _EmbedThumbnail(DataModel):
19
+ class EmbedThumbnail(DataModel):
16
20
  """Embed thumbnail."""
21
+
17
22
  url: str
23
+ """Thumbnail content. http or attachment://<filename> scheme."""
18
24
 
19
25
  @dataclass
20
- class _EmbedImage(DataModel):
26
+ class EmbedField(DataModel):
27
+ """Embed field."""
28
+
29
+ name: str
30
+ """Name of the field."""
31
+
32
+ value: str
33
+ """Value of the field."""
34
+
35
+ inline: Optional[bool] = None
36
+ """Whether or not this field should display inline."""
37
+
38
+ @dataclass
39
+ class EmbedImage(DataModel):
21
40
  """Embed image."""
41
+
22
42
  url: str
43
+ """Image content. http or attachment://<filename> scheme."""
23
44
 
24
45
  @dataclass
25
- class _EmbedFooter(DataModel):
46
+ class EmbedFooter(DataModel):
26
47
  """Embed footer."""
27
48
  text: str
28
- url: Optional[str] = None
29
- icon_url: Optional[str] = None
49
+ """Footer text."""
30
50
 
31
- @dataclass
32
- class _EmbedField(DataModel):
33
- """Embed field."""
34
- name: str
35
- value: str
36
- inline: Optional[bool] = None
51
+ icon_url: Optional[str] = None
52
+ """URL of the footer icon. http or attachment://<filename> scheme."""
37
53
 
38
54
  @dataclass
39
- class EmbedBuilder(DataModel):
55
+ class EmbedPart(DataModel):
40
56
  """Represents the Embed portion of a message."""
41
57
 
42
58
  title: Optional[str] = None
@@ -51,104 +67,17 @@ class EmbedBuilder(DataModel):
51
67
  color: Optional[int] = None
52
68
  """Embed's accent color."""
53
69
 
54
- author: Optional[_EmbedAuthor] = None
70
+ author: Optional[EmbedAuthor] = None
55
71
  """Embed's author."""
56
72
 
57
- thumbnail: Optional[_EmbedThumbnail] = None
73
+ thumbnail: Optional[EmbedThumbnail] = None
58
74
  """Embed's thumbnail attachment."""
59
75
 
60
- image: Optional[_EmbedImage] = None
76
+ image: Optional[EmbedImage] = None
61
77
  """Embed's image attachment."""
62
78
 
63
- fields: Optional[list[_EmbedField]] = None
79
+ fields: Optional[list[EmbedField]] = field(default_factory=list)
64
80
  """List of embed's fields."""
65
81
 
66
- footer: Optional[_EmbedFooter] = None
82
+ footer: Optional[EmbedFooter] = None
67
83
  """Embed's footer."""
68
-
69
- def set_color(self, hex: str):
70
- """Set this embed's color with a hex.
71
-
72
- Args:
73
- hex (str): color as a hex code (format: #FFFFFF)
74
-
75
- Returns:
76
- (EmbedBuilder): self
77
- """
78
- self.color=int(hex.strip('#'), 16)
79
- return self
80
-
81
- def set_user_author(self, user: UserModel):
82
- """Set this embed's author.
83
-
84
- Args:
85
- user (UserModel): the user model
86
-
87
- Returns:
88
- (EmbedBuilder): self
89
- """
90
- self.author = _EmbedAuthor(
91
- name=user.username,
92
- icon_url=f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}.png"
93
- )
94
- return self
95
-
96
- def set_image(self, url: str):
97
- """Set this embed's image.
98
-
99
- Args:
100
- url (str): attachment://<file> scheme or http(s) URL
101
-
102
- Returns:
103
- (EmbedBuilder): self
104
- """
105
- self.image = _EmbedImage(url=url)
106
- return self
107
-
108
- def set_thumbnail(self, url: str):
109
- """Set this embed's thumbnail.
110
-
111
- Args:
112
- url (str): attachment://<file> scheme or http(s) URL
113
-
114
- Returns:
115
- (EmbedBuilder): self
116
- """
117
- self.thumbnail = _EmbedThumbnail(url=url)
118
- return self
119
-
120
- def set_footer(self, text: str, icon_url: str = None):
121
- """Set this embed's footer.
122
-
123
- Args:
124
- text (str): footer's text
125
- icon_url (str, optional): attachment://<file> scheme or http(s) URL.
126
-
127
- Returns:
128
- (EmbedBuilder): self
129
- """
130
- self.footer = _EmbedFooter(text=text, icon_url=icon_url)
131
- return self
132
-
133
- def add_field(self, name: str, value: str, is_inline: bool = False):
134
- """Add a field to this embed.
135
-
136
- Args:
137
- name (str): field's title
138
- value (str): field's text
139
- is_inline (bool): if this field should be inlined
140
-
141
- Returns:
142
- (EmbedBuilder): self
143
- """
144
- self.fields.append(_EmbedField(name=name, value=value, inline=is_inline))
145
- return self
146
-
147
- def set_timestamp(self):
148
- """Set this embed's timestamp.
149
-
150
- Returns:
151
- (EmbedBuilder): self
152
- """
153
- self.timestamp = datetime.now(timezone.utc).isoformat()
154
- return self